Date: Sun, 31 Jan 2016 05:16:25 -0800 From: Mark Millard <markmi@dsl-only.net> To: Roman Divacky <rdivacky@vlakno.cz> Cc: FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>, FreeBSD Toolchain <freebsd-toolchain@freebsd.org> Subject: Re: clang 3.8.0 based powerpc (32 bit) buildworld runs on a PowerMac! [stack alignment related problem for signals] Message-ID: <DB0F40F0-DA36-4365-B6A6-C24841E77133@dsl-only.net> In-Reply-To: <5AD9FDBA-BAFF-43F6-A50C-8F2CC0CEB7EF@dsl-only.net> References: <DEF41968-FFC4-417D-A31A-E392CB888C35@dsl-only.net> <55814789-0489-48B5-867C-F678AE4EA5FF@dsl-only.net> <20160130112913.GA7950@vlakno.cz> <E2771C4A-4CC9-4394-A2D7-10CCB5F13BDE@dsl-only.net> <2CA42792-245D-48F3-9FC7-285C52D14A6A@dsl-only.net> <ED8F1D16-A097-40D9-AAFB-9134A36A9995@dsl-only.net> <5AD9FDBA-BAFF-43F6-A50C-8F2CC0CEB7EF@dsl-only.net>
next in thread | previous in thread | raw e-mail | index | archive | help
[Next to figure out after noting the below: In FreeBSD what controls the = stack alignment produced by a signal for its handler routine? I've not = gotten that far yet. My guess is that stack alignments larger than 4 are = supposed to be in use for powerpc (32-bit) and that signal generation = should be causing the correct alignment for the handler.] I've discovered that the stack alignment varies between direct calls to = the routine that is also used to handle the signal vs. when the routine = is used via a signal. Below shows first a non-signal call then a signal = call. > (gdb) run > Starting program: /root/c_tests/a.out=20 >=20 > Breakpoint 10, 0x018006d4 in handler () > (gdb) bt > #0 0x018006d4 in handler () > #1 0x01800760 in main () > (gdb) info frame > Stack level 0, frame at 0xffffdcb0: > pc =3D 0x18006d4 in handler; saved pc =3D 0x1800760 > called by frame at 0xffffdcd0 > Arglist at 0xffffdc60, args:=20 > Locals at 0xffffdc60, Previous frame's sp is 0xffffdcb0 > Saved registers: > r31 at 0xffffdcac, pc at 0xffffdcb4, lr at 0xffffdcb4 > (gdb) cont > Continuing. >=20 > Breakpoint 10, 0x018006d4 in handler () > (gdb) bt > #0 0x018006d4 in handler () > #1 <signal handler called> > #2 0x00000000 in ?? () > (gdb) info frame > Stack level 0, frame at 0xffffd73c: > pc =3D 0x18006d4 in handler; saved pc =3D 0xffffe008 > called by frame at 0xffffd73c > Arglist at 0xffffd6ec, args:=20 > Locals at 0xffffd6ec, Previous frame's sp is 0xffffd73c > Saved registers: > r31 at 0xffffd738, pc at 0xffffd740, lr at 0xffffd740 In direct calls "Locals at 0xffffdc60" is a multiple of 8,16,32 but not = of 64. In signal based calls "Locals at 0xffffd6ec" is a multiple of 4 but not = of 8. (Similar points could be made about the "frame at" figures.) __vfprintf in both cases gets a similar sort of stack alignment as = handler does: > (gdb) info frame > Stack level 0, frame at 0xffffdad0: > pc =3D 0x41931590 in __vfprintf = (/usr/src/lib/libc/stdio/vfprintf.c:454); saved pc =3D 0x4199c644 > called by frame at 0xffffdc60 > source language c. > Arglist at 0xffffd880, args: fp=3D0xffffdb40, locale=3D0x419cba40 = <__xlocale_global_locale>, fmt0=3D0x180085c "%d", ap=3D0xffffdc30 > Locals at 0xffffd880, Previous frame's sp is 0xffffdad0 > Saved registers: > r14 at 0xffffda88, r15 at 0xffffda8c, r16 at 0xffffda90, r17 at = 0xffffda94, r18 at 0xffffda98, r19 at 0xffffda9c, r20 at 0xffffdaa0, r21 = at 0xffffdaa4, r22 at 0xffffdaa8, r23 at 0xffffdaac, > r24 at 0xffffdab0, r25 at 0xffffdab4, r26 at 0xffffdab8, r27 at = 0xffffdabc, r28 at 0xffffdac0, r29 at 0xffffdac4, r30 at 0xffffdac8, r31 = at 0xffffdacc, pc at 0xffffdad4, lr at 0xffffdad4 vs. > (gdb) info frame > Stack level 0, frame at 0xffffd55c: > pc =3D 0x41931590 in __vfprintf = (/usr/src/lib/libc/stdio/vfprintf.c:454); saved pc =3D 0x4199c644 > called by frame at 0xffffd6ec > source language c. > Arglist at 0xffffd30c, args: fp=3D0xffffd5cc, locale=3D0x419cba40 = <__xlocale_global_locale>, fmt0=3D0x180085c "%d", ap=3D0xffffd6bc > Locals at 0xffffd30c, Previous frame's sp is 0xffffd55c > Saved registers: > r14 at 0xffffd514, r15 at 0xffffd518, r16 at 0xffffd51c, r17 at = 0xffffd520, r18 at 0xffffd524, r19 at 0xffffd528, r20 at 0xffffd52c, r21 = at 0xffffd530, r22 at 0xffffd534, r23 at 0xffffd538, > r24 at 0xffffd53c, r25 at 0xffffd540, r26 at 0xffffd544, r27 at = 0xffffd548, r28 at 0xffffd54c, r29 at 0xffffd550, r30 at 0xffffd554, r31 = at 0xffffd558, pc at 0xffffd560, lr at 0xffffd560 In the __vfprintf code below r31 (once set) is either Locals at = 0xffffd880 or Locals at 0xffffd30c, depending on the alignment. For = reference: > #define NIOV 8 > struct io_state { > FILE *fp; > struct __suio uio; /* output information: summary */ > struct __siov iov[NIOV];/* ... and individual io vectors */ > }; I've examined the code and __vfprintf (which has lots of in-lined = material from other places) has the code: > (gdb) x/64i __vfprintf > 0x41931504 <__vfprintf>: mflr r0 > 0x41931508 <__vfprintf+4>: stw r31,-4(r1) > 0x4193150c <__vfprintf+8>: stw r30,-8(r1) > 0x41931510 <__vfprintf+12>: stw r0,4(r1) > 0x41931514 <__vfprintf+16>: stwu r1,-592(r1) > 0x41931518 <__vfprintf+20>: mr r31,r1 (r31 gets = the Locals address here) > . . . > 0x41931574 <__vfprintf+112>: mr r29,r3 (FILE* passed in) > . . . > 0x4193165c <__vfprintf+344>: stw r29,296(r31) (r31+296=3D=3D= & of fp field of io_state io) > . . . > 0x4193168c <__vfprintf+392>: li r3,4 > 0x41931690 <__vfprintf+396>: addi r23,r31,296 (r31+296=3D=3D= & of fp field of io_state io) > . . . > 0x419316b0 <__vfprintf+428>: rlwimi r23,r3,0,29,29 (& of uio = field of io_state intended) Note r31+296 is either 0xFFFFD9A8 or 0xFFFFD434 depending on the stack = alignment. The rlwimi works fine for alignment by 8 or higher powers of 2 by = masking in a 4 into the address stored in r23 (equivalent to adding the = 4 in such a context). The 0xFFFFD9A8 becomes 0xFFFFD9AC in r23 after the = rlwimi. But for alignment by 4 that is not aligned by larger powers of 2 the = rlwimi leaves r23 with the value : r31+296=3D=3D& of fp field of = io_state io instead of the uio field that it should be. For the direct call sequence, not signal, > (gdb) print (struct io_state*)&buf[32] > $79 =3D (struct io_state *) 0xffffd9a8 > (gdb) print &((struct io_state*)&buf[32])->uio > $80 =3D (struct __suio *) 0xffffd9ac > (gdb) print *(struct io_state*)&buf[32] > $82 =3D {fp =3D 0xffffdb40, uio =3D {uio_iov =3D 0xffffd9b8, = uio_iovcnt =3D 1, uio_resid =3D 1}, iov =3D {{iov_base =3D 0xffffd9a7, = iov_len =3D 1}, {iov_base =3D 0x18109c8 <snprintf@plt>, iov_len =3D = 1100596480}, { > iov_base =3D 0x4183f1c8, iov_len =3D 4294957520}, {iov_base =3D = 0xffffd9e0, iov_len =3D 1098984872}, {iov_base =3D 0x4183f1c8, iov_len =3D= 4294957536}, {iov_base =3D 0xffffda00, iov_len =3D 1099023964}, { > iov_base =3D 0x41832200, iov_len =3D 25233864}, {iov_base =3D = 0x1800310, iov_len =3D 1100596480}}} > . . . > Breakpoint 12, __sfvwrite (fp=3D0xffffdb40, uio=3D0xffffd9ac) at = /usr/src/lib/libc/stdio/fvwrite.c:61 vs. for the signal call sequence: > (gdb) print (struct io_state*)&buf[32] > $83 =3D (struct io_state *) 0xffffd434 > (gdb) print &((struct io_state*)&buf[32])->uio > $84 =3D (struct __suio *) 0xffffd438 > (gdb) print *(struct io_state*)&buf[32] > $85 =3D {fp =3D 0xffffd5cc, uio =3D {uio_iov =3D 0xffffd444, = uio_iovcnt =3D 1, uio_resid =3D 2}, iov =3D {{iov_base =3D 0xffffd432, = iov_len =3D 2}, {iov_base =3D 0xffffd450, iov_len =3D 4294956192}, { > iov_base =3D 0x4181bb50 <symlook_list+252>, iov_len =3D = 1099266711}, {iov_base =3D 0x4a115f, iov_len =3D 4294956144}, {iov_base = =3D 0x41831370, iov_len =3D 4}, {iov_base =3D 0xffffd470,=20 > iov_len =3D 1099212600}, {iov_base =3D 0x0, iov_len =3D 0}, = {iov_base =3D 0x4, iov_len =3D 0}}} > . . . > Breakpoint 12, __sfvwrite (fp=3D0xffffd5cc, uio=3D0xffffd434) at = /usr/src/lib/libc/stdio/fvwrite.c:61 Note that uio in __sfvwrite does not agree with &((struct = io_state*)&buf[32])->uio for the signal case. Instead it matches (struct = io_state*)&buf[32] (and its ->fp (first field) field address). =3D=3D=3D Mark Millard markmi at dsl-only.net On 2016-Jan-30, at 7:15 PM, Mark Millard <markmi at dsl-only.net> wrote: Hmm. Too much time at this I guess. . . Reviewing again I do not find any paths that are without PRINT (i.e., = io_print) use. That should mean that io.uio.uio_iov->iov_base was = initialized but somehow changed. I still have not replicated the problem with smaller/simpler code, only = with libc/stdio use. I will back off Bug 206770 before taking a break. =3D=3D=3D Mark Millard markmi at dsl-only.net On 2016-Jan-30, at 5:59 PM, Mark Millard <markmi at dsl-only.net> wrote: I have submitted a minor variation of this analysis text for the = uninitialized pointer use in in libc/stdio "string output" routine = implementations as Bug 206770. If anyone finds that I missed the initialization let me know and I'll = change the status of the bug. =3D=3D=3D Mark Millard markmi at dsl-only.net On 2016-Jan-30, at 5:13 PM, Mark Millard <markmi at dsl-only.net> wrote: So far I'm unable to reproduce the problem with simple code replacing = the library code. And I expect that I have have a smoking gun for why. Care to check the = below and see if I missed something? As far as I can tell this is a = FreeBSD libc/stdio defect, not a clang 3.8.0 one. Unfortunately the reason is spread out in the code so it takes a bit to = describe the context for the uninitialized pointer that I expect is = involved. To start the description I note the actual, low-level failure point: > #0 0x419a89c8 in memcpy (dst0=3D0xffffd734, src0=3D<optimized out>, = length=3D<optimized out>) at /usr/src/lib/libc/string/bcopy.c:124 > 124 TLOOP1(*--dst =3D *--src); In the assembler code for this is the the *--src access that gets the = segmentation violation. I do not justify that claim here but use that = fact later. So what leads up to that? Going the other way, starting from the use of = snprintf. . . snprintf(char * __restrict str, size_t n, char const * __restrict fmt, = ...) sets up its __vfprintf(FILE *fp, locale_t locale, const char *fmt0, = va_list ap) use via: > va_list ap; > FILE f =3D FAKE_FILE; . . . > va_start(ap, fmt); > f._flags =3D __SWR | __SSTR; > f._bf._base =3D f._p =3D (unsigned char *)str; > f._bf._size =3D f._w =3D n; > ret =3D __vfprintf(&f, __get_locale(), fmt, ap); so at the __vfprintf call f._p reference the buffer that __vfprintf's = str references. __vfprintf in turn does (in part): > struct io_state io; /* I/O buffering state */ . . . > io_init(&io, fp); where io is on-stack (not implicitly initialized). The io_init does: > #define NIOV 8 > struct io_state { > FILE *fp; > struct __suio uio; /* output information: summary */ > struct __siov iov[NIOV];/* ... and individual io vectors */ > }; >=20 > static inline void > io_init(struct io_state *iop, FILE *fp) > { >=20 > iop->uio.uio_iov =3D iop->iov; > iop->uio.uio_resid =3D 0; > iop->uio.uio_iovcnt =3D 0; > iop->fp =3D fp; > } where (on stack as part of __vfprintf's io): > struct __siov { > void *iov_base; > size_t iov_len; > }; > struct __suio { > struct __siov *uio_iov; > int uio_iovcnt; > int uio_resid; > }; So via __vfprintf's io.fp->_p the str buffer is accessible for = outputting to. But in none of this or other code that I've looked at for this snprintf = use case have I found code that initializes the involved = io.uio.uio_iov->iov_base (i.e., io.iov[0].iov_base) to point to anything = specific. (Nor is iov_base's matching iov_len initialized.) Here is a stab at finding all the initializations of iov_base fields: > # grep "iov_base.*=3D" /usr/src/lib/libc/stdio/* > /usr/src/lib/libc/stdio/fputs.c: iov.iov_base =3D (void *)s; > /usr/src/lib/libc/stdio/fputws.c: iov.iov_base =3D buf; > /usr/src/lib/libc/stdio/fwrite.c: iov.iov_base =3D (void *)buf; > /usr/src/lib/libc/stdio/perror.c: v->iov_base =3D (char = *)s; > /usr/src/lib/libc/stdio/perror.c: v->iov_base =3D ": "; > /usr/src/lib/libc/stdio/perror.c: v->iov_base =3D msgbuf; > /usr/src/lib/libc/stdio/perror.c: v->iov_base =3D "\n"; > /usr/src/lib/libc/stdio/printfcommon.h: = iop->iov[iop->uio.uio_iovcnt].iov_base =3D (char *)ptr; > /usr/src/lib/libc/stdio/puts.c: iov[0].iov_base =3D (void *)s; > /usr/src/lib/libc/stdio/puts.c: iov[1].iov_base =3D "\n"; > /usr/src/lib/libc/stdio/putw.c: iov.iov_base =3D &w; > /usr/src/lib/libc/stdio/vfwprintf.c: iov.iov_base =3D buf; > /usr/src/lib/libc/stdio/xprintf.c: io->iovp->iov_base =3D = __DECONST(void *, ptr); The only file above involved in common for this context turns out to be: = /usr/src/lib/libc/stdio/printfcommon.h and the above assignment in that = file is in io_print(struct io_state *iop, const CHAR * __restrict ptr, = int len, locale_t locale), which is not in use for this context. Here is = the assignment anyway (for reference): > static inline int > io_print(struct io_state *iop, const CHAR * __restrict ptr, int len, = locale_t locale) > { >=20 > iop->iov[iop->uio.uio_iovcnt].iov_base =3D (char *)ptr; > iop->iov[iop->uio.uio_iovcnt].iov_len =3D len; > iop->uio.uio_resid +=3D len; . . . In other words: The segmentation violation is for use of __vfprintf's = uninitialized io.uio.uio_iov->iov_base . Returning to tracing the actually used code for this context to support = that claim some more. . . The __vfprintf (FILE *fp, locale_t locale, const char *fmt0, va_list ap) = eventually does: if (io_flush(&io, locale)) and io_flush(struct io_state *iop, locale_t locale) does: return (__sprint(iop->fp, &iop->uio, locale)); and _sprintf(FILE *fp, struct __suio *uio, locale_t locale) does: err =3D __sfvwrite(fp, uio); and __sfvwrite(FILE *fp, struct __suio *uio) does: p =3D iov->iov_base; len =3D iov->iov_len; where iov->iov_base is another name for __vfprintf's = io.uio.uio_iov->iov_base . __sfvwrite then uses: #define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n)) which fails dereferencing p (i.e., __vfprintf's io.uio.uio_iov->iov_base = ).=20 In other words (again): The segmentation violation is for use of the = uninitialized iop->uio.uio_iov->iov_base. =3D=3D=3D Mark Millard markmi at dsl-only.net On 2016-Jan-30, at 5:58 AM, Mark Millard <markmi at dsl-only.net> wrote: On 2016-Jan-30, at 3:29 AM, Roman Divacky <rdivacky at vlakno.cz> wrote: > Can you file a bug in llvm bugzilla? I could try for the example code. But I'd like to make the example more = self contained first, avoiding snprintf from library code and hopefully = with a much smaller, simpler implementation involved than the = very-general library code. Separately: I'm not sure any llvm folks are going to have a way to test = unless someone shows the problem outside a FreeBSD context. = powerpc-clang (32-bit) based FreeBSD buildworld's are not exactly a = normal context at this point. My files with powerpc (32-bit) tied differences from svn for = projects/clang380-import -r294962 are: Index: /media/usr/src/sys/boot/powerpc/Makefile =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /media/usr/src/sys/boot/powerpc/Makefile (revision 294962) +++ /media/usr/src/sys/boot/powerpc/Makefile (working copy) @@ -1,5 +1,9 @@ # $FreeBSD$ -SUBDIR=3D boot1.chrp kboot ofw ps3 uboot +SUBDIR=3D boot1.chrp +.if ${MACHINE_ARCH} =3D=3D "powerpc64" +SUBDIR+=3D kboot +.endif +SUBDIR+=3D ofw ps3 uboot .include <bsd.subdir.mk> Index: /media/usr/src/sys/conf/Makefile.powerpc =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /media/usr/src/sys/conf/Makefile.powerpc (revision 294962) +++ /media/usr/src/sys/conf/Makefile.powerpc (working copy) @@ -35,7 +35,11 @@ INCLUDES+=3D -I$S/contrib/libfdt +.if ${COMPILER_TYPE} =3D=3D "gcc" CFLAGS+=3D -msoft-float -Wa,-many +.else +CFLAGS+=3D -msoft-float +.endif # Build position-independent kernel CFLAGS+=3D -fPIC Index: /media/usr/src/sys/conf/kern.mk =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /media/usr/src/sys/conf/kern.mk (revision 294962) +++ /media/usr/src/sys/conf/kern.mk (working copy) @@ -144,7 +144,11 @@ # .if ${MACHINE_CPUARCH} =3D=3D "powerpc" CFLAGS+=3D -mno-altivec +.if ${COMPILER_TYPE} =3D=3D "clang" && ${COMPILER_VERSION} < 30800 CFLAGS.clang+=3D -mllvm -disable-ppc-float-in-variadic=3Dtrue +.else +CFLAGS.clang+=3D -msoft-float +.endif CFLAGS.gcc+=3D -msoft-float INLINE_LIMIT?=3D 15000 .endif Index: /media/usr/src/sys/conf/kmod.mk =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /media/usr/src/sys/conf/kmod.mk (revision 294962) +++ /media/usr/src/sys/conf/kmod.mk (working copy) @@ -137,8 +137,12 @@ .endif .if ${MACHINE_CPUARCH} =3D=3D powerpc +.if ${COMPILER_TYPE} =3D=3D "gcc" CFLAGS+=3D -mlongcall -fno-omit-frame-pointer +.else +CFLAGS+=3D -fno-omit-frame-pointer .endif +.endif .if ${MACHINE_CPUARCH} =3D=3D mips CFLAGS+=3D -G0 -fno-pic -mno-abicalls -mlong-calls (I can not actually buildkernel for powerpc via clang 3.8.0. Still some = of the above is for the kernel context.) src.conf content: KERNCONF=3DGENERICvtsc-NODEBUG TARGET=3Dpowerpc TARGET_ARCH=3Dpowerpc # WITH_FAST_DEPEND=3D WITH_LIBCPLUSPLUS=3D WITH_BOOT=3D WITH_BINUTILS_BOOTSTRAP=3D WITH_CLANG_BOOTSTRAP=3D WITH_CLANG=3D WITH_CLANG_IS_CC=3D WITH_CLANG_FULL=3D WITH_CLANG_EXTRAS=3D # # lldb requires missing atomic 8-byte operations for powerpc (non-64) WITHOUT_LLDB=3D # WITHOUT_LIB32=3D WITHOUT_GCC_BOOTSTRAP=3D WITHOUT_GCC=3D WITHOUT_GCC_IS_CC=3D WITHOUT_GNUCXX=3D # NO_WERROR=3D MALLOC_PRODUCTION=3D # WITH_DEBUG_FILES=3D On Sat, Jan 30, 2016 at 03:00:26AM -0800, Mark Millard wrote: > I got around to trying some more use of the 3.8.0 clang based world on = powerpc (32 bit) (now -r294962 based) and ran into: >=20 > A) Segmentation faults during signal handlers in syslogd, nfsd, = mountd, and (for SIGNFO) make. >=20 > B) ls sometimes segmentation faulting >=20 > C) make -j 6 buildworld segmentation faulting in make eventually but = make buildworld works. >=20 > I have reduced (A) to a simple program that demonstrates the behavior: >=20 >> # more sig_snprintf_use_test.c=20 >> #include <stdio.h> >> #include <signal.h> >>=20 >> volatile sig_atomic_t sat =3D 0; >>=20 >> void >> handler(int sig) >> { >> char uidbuf[32]; >> (void) snprintf(uidbuf, sizeof uidbuf, "%d", 10); >> sat =3D uidbuf[0]; >> } >>=20 >> int >> main(void) >> { >> if (signal(SIGINT, handler) !=3D SIG_ERR) raise(SIGINT); >> return sat; >> } >=20 >> # ./a.out >> Segmentation fault (core dumped) >> # /usr/local/bin/gdb a.out /var/crash/a.out.1510.core >> GNU gdb (GDB) 7.10 [GDB v7.10 for FreeBSD] > . . . >> warning: Unexpected size of section `.reg2/100167' in core file. >> #0 0x419a89c8 in memcpy (dst0=3D0xffffd734, src0=3D<optimized out>, = length=3D<optimized out>) at /usr/src/lib/libc/string/bcopy.c:124 >> 124 TLOOP1(*--dst =3D *--src); >> (gdb) bt >> #0 0x419a89c8 in memcpy (dst0=3D0xffffd734, src0=3D<optimized out>, = length=3D<optimized out>) at /usr/src/lib/libc/string/bcopy.c:124 >> #1 0x419a3984 in __sfvwrite (fp=3D<optimized out>, uio=3D<optimized = out>) at /usr/src/lib/libc/stdio/fvwrite.c:128 >> #2 0x41934468 in __sprint (fp=3D<optimized out>, uio=3D<optimized = out>, locale=3D<optimized out>) at = /usr/src/lib/libc/stdio/vfprintf.c:164 >> #3 io_flush (iop=3D<optimized out>, locale=3D<optimized out>) at = /usr/src/lib/libc/stdio/printfcommon.h:155 >> #4 __vfprintf (fp=3D<optimized out>, locale=3D<optimized out>, = fmt0=3D<optimized out>, ap=3D<optimized out>) at = /usr/src/lib/libc/stdio/vfprintf.c:1020 >> #5 0x4199c644 in snprintf (str=3D0xffffd734 "", n=3D<optimized out>, = fmt=3D0x1800850 "%d") at /usr/src/lib/libc/stdio/snprintf.c:72 >> #6 0x01800708 in handler () >> Backtrace stopped: Cannot access memory at address 0xffffd760 >=20 > (The "Unexpected size . . ." is a known problem in powerpc land at = this point, not tied to clang 3.8.0 .) >=20 > The syslogd, nfsd, mountd, and SIGINFO-related make backtraces are = similar. I got the program above from simplifying the mountd failure = context. >=20 > A direct call, handler(0), does not get the segmentation fault. >=20 > I'll note that in C the handler calling snprintf or other such is a = no-no for the general case: only abort(), _Exit(), or signal() as of C99 = as I understand. But the restriction is not true of use of raise so the = small program is still valid C99 code. Of course it appears FreeBSD = allows more than C99 does in this area. >=20 > I've not yet investigated what the original signals are in syslogd, = nfsd, or mountd. They may well indicate another problem. >=20 >=20 > I've not gotten as far classifying (B) or (C) as well. >=20 > (B) is a xo_emit context each time so far (so C elipsis use again, = like (A)) but no signal handler seems to be active. It stops in = xo_format_string_direct. My attempts at simpler code have not produced = the problem so far. >=20 > (C) is such that GDB 7.10 reports "previous frame to this frame = (corrupt stack?)" or otherwise gives up. It shows Var_Value called by = Make_Update before reporting that. gdb 6.1.1 shows more after that: = JobFinish, JobReapChild, Job_CatchChildern, Job_CatchOutput, Make_Run, = main). SIGCHLD or other such use may well be involved here. >=20 >=20 > =3D=3D=3D > Mark Millard > markmi at dsl-only.net >=20 > On 2016-Jan-19, at 2:35 AM, Mark Millard <markmi@dsl-only.net> wrote: >=20 > I now have an SSD that contains: >=20 > 0) installkernel material from a gcc 4.2.1 based buildkernel >=20 > 1) installworld material from a clang 3.8.0 based buildworld > (clang 3.8.0, libc++, etc.) >=20 > It boots and seems to be operating fine after booting --in both a G5 = and a G4 PowerMac. >=20 > Apparently the clang code generation has been updated to not require = an explicit -mlongcall. I had to remove those since clang rejects them = on command lines. It linked without complaint (and later seems to be = running fine). (I've seen llvm review notes mentioning the "medium = model" or some phrase like that for powerpc.) >=20 > (I've not been able to buildkernel yet for powerpc (non-64) from my = amd64 environment: rejected command lines for other issues. Thus the = current limitation to buildworld.) >=20 >=20 >=20 > To get to (1) I did the following sort of sequence: > (The first few steps deal with other issues in order to have = sufficient context.) >=20 >=20 > A) Started by installing the latest powerpc (non-64) snapshot. > ( = http://ftp1.freebsd.org/pub/FreeBSD/snapshots/ISO-IMAGES/11.0/FreeBSD-11.0= -CURRENT-powerpc-20160113-r293801-disc1.iso ) >=20 > (I had to use a PowerMac with video hardware that vt would handle.) > (Basic display, no X-windows involvement here.) >=20 >=20 > B) Rebuild, including using my usual kernel configuration that has > both vt and sc. I did this based on projects/clang380-import > -r294201 /usr/src but still using gcc 4.2.1 (native on the > PowerMac). The configuration turns off kernel debugging extras too. >=20 >=20 > C) installkernel, installworld, etc., set to use sc instead of vt, and = rebooted. >=20 > (As of this I could use the SSD in more PowerMacs by using sc instead = of vt via a /boot/loader.conf assignment.) >=20 >=20 > D) dump/restore the file systems to another SSD (after partitioning = it). > Adjust the host name and the like on the copy. >=20 > (This copy later ends up having new installworld materials overlaid.) >=20 >=20 > E) In a projects/clang380-import -r294201 amd64 environment, = buildworld for > TARGET_ARCH=3Dpowerpc . WITH_LIBCPLUSPLUS=3D and clang related = material built, > gcc 4.2.1 related material not built. WITH_BOOT=3D as well. I choose > WITHOUT_DEBUG=3D and WITHOUT_DEBUG_FILES=3D . (I've not tried enabling = them yet.) > binutils is not from ports. >=20 >=20 > F) Use DESTDIR=3D with installworld to an initially empty directory = tree. tar the tree. >=20 >=20 > G) Transfer the tar file to the PowerMac. Mount the to-be-updated SSD = to > /mnt and /mnt/var. After chflags -R noschg on /mnt and /mnt/var use > tar xpf to replace things from the buildworld on /mnt and /mnt/var. >=20 > (This does leave older gcc 4.2.1 related materials in place.) >=20 > H) Dismounts, shutdown, and then boot from the updated SSD. >=20 >=20 >=20 > Note: I've never manage to get powerpc64-xtoolchain-gcc/powerpc64-gcc = to produce working 32-bit code. So I've never gotten this far via that = path. >=20 >=20 > =3D=3D=3D > Mark Millard > markmi at dsl-only.net >=20 >=20 > _______________________________________________ > freebsd-toolchain@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain > To unsubscribe, send any mail to = "freebsd-toolchain-unsubscribe@freebsd.org" =3D=3D=3D Mark Millard markmi at dsl-only.net
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?DB0F40F0-DA36-4365-B6A6-C24841E77133>