Message ID | 1403534578-41451-1-git-send-email-paul.gortmaker@windriver.com |
---|---|
State | New |
Headers | show |
On 06/23/14 08:42, Paul Gortmaker wrote: > We see the following on a 32bit gcc installed on 64 bit host: > > Reading symbols from ./i586-pokymllib32-linux-gcc...done. > (gdb) run > Starting program: x86-pokymllib32-linux/lib32-gcc/4.9.0-r0/image/usr/bin/i586-pokymllib32-linux-gcc > > Program received signal SIGSEGV, Segmentation fault. > 0xf7e957e0 in free () from /lib/i386-linux-gnu/libc.so.6 > (gdb) bt > #0 0xf7e957e0 in free () from /lib/i386-linux-gnu/libc.so.6 > #1 0x0804b73c in set_multilib_dir () at gcc-4.9.0/gcc/gcc.c:7827 > #2 main (argc=1, argv=0xffffd504) at gcc-4.9.0/gcc/gcc.c:6688 > (gdb) > > The problem arises because the check on whether we are using > the internal string "." or an allocated one is reversed. > We should be calling free() when the string is not equal to > the internal "." string. > > Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> > --- > > [Found and fixed on gcc-4.9.0 but applies to git/master too] > > gcc/gcc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/gcc/gcc.c b/gcc/gcc.c > index 6870a840e1b7..a580975a7057 100644 > --- a/gcc/gcc.c > +++ b/gcc/gcc.c > @@ -7822,7 +7822,7 @@ set_multilib_dir (void) > } > > if (multilib_dir == NULL && multilib_os_dir != NULL > - && strcmp (multilib_os_dir, ".") == 0) > + && strcmp (multilib_os_dir, ".") != 0) > { > free (CONST_CAST (char *, multilib_os_dir)); > multilib_os_dir = NULL; > Thanks. Installed on the trunk. jeff
This patch broke bootstrapping for me on x86-64-gnu-linux: /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: i386 architecture of input file `/usr/lib/crti.o' is incompatible with i386:x86-64 output If I revert the patch, it works for me. Tobias Paul Gortmaker wrote: > We see the following on a 32bit gcc installed on 64 bit host: > > Reading symbols from ./i586-pokymllib32-linux-gcc...done. > (gdb) run > Starting program: x86-pokymllib32-linux/lib32-gcc/4.9.0-r0/image/usr/bin/i586-pokymllib32-linux-gcc > > Program received signal SIGSEGV, Segmentation fault. > 0xf7e957e0 in free () from /lib/i386-linux-gnu/libc.so.6 > (gdb) bt > #0 0xf7e957e0 in free () from /lib/i386-linux-gnu/libc.so.6 > #1 0x0804b73c in set_multilib_dir () at gcc-4.9.0/gcc/gcc.c:7827 > #2 main (argc=1, argv=0xffffd504) at gcc-4.9.0/gcc/gcc.c:6688 > (gdb) > > The problem arises because the check on whether we are using > the internal string "." or an allocated one is reversed. > We should be calling free() when the string is not equal to > the internal "." string. > > Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> > --- > > [Found and fixed on gcc-4.9.0 but applies to git/master too] > > gcc/gcc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/gcc/gcc.c b/gcc/gcc.c > index 6870a840e1b7..a580975a7057 100644 > --- a/gcc/gcc.c > +++ b/gcc/gcc.c > @@ -7822,7 +7822,7 @@ set_multilib_dir (void) > } > > if (multilib_dir == NULL && multilib_os_dir != NULL > - && strcmp (multilib_os_dir, ".") == 0) > + && strcmp (multilib_os_dir, ".") != 0) > { > free (CONST_CAST (char *, multilib_os_dir)); > multilib_os_dir = NULL; >
On 06/23/14 14:09, Tobias Burnus wrote: > This patch broke bootstrapping for me on x86-64-gnu-linux: > > /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: > i386 architecture of input file `/usr/lib/crti.o' is incompatible with > i386:x86-64 output > > If I revert the patch, it works for me. Reverted. Will have to look deeper. Paul, did you bootstrap with this patch on the trunk? jeff
On Mon, Jun 23, 2014 at 02:32:37PM -0600, Jeff Law wrote: > On 06/23/14 14:09, Tobias Burnus wrote: > >This patch broke bootstrapping for me on x86-64-gnu-linux: > > > >/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: > >i386 architecture of input file `/usr/lib/crti.o' is incompatible with > >i386:x86-64 output > > > > >If I revert the patch, it works for me. > Reverted. Will have to look deeper. Paul, did you bootstrap with this > patch on the trunk? I can see one spot where multilib_os_dir is set to non-malloced string literal, and at that point we also leak memory. So, supposedly: new_multilib_os_dir = XNEWVEC (char, ml_end - q); memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1); new_multilib_os_dir[ml_end - q - 1] = '\0'; multilib_os_dir = *new_multilib_os_dir ? new_multilib_os_dir : "."; should be instead: if (ml_end - q == 1) multilib_os_dir = xstrdup ("."); else { new_multilib_os_dir = XNEWVEC (char, ml_end - q); memcpy (new_multilib_os_dir, q + 1, ml_end - q - 1); new_multilib_os_dir[ml_end - q - 1] = '\0'; multilib_os_dir = new_multilib_os_dir; } or so (completely untested). Bet this got broken when the multiarch support has been added, before that multilib_os_dir has always been malloced. Alternatively, multilib_os_dir could be set to NULL instead of setting it to ".". Jakub
[Re: [PATCH] gcc: fix segfault from calling free on non-malloc'd area] On 23/06/2014 (Mon 14:32) Jeff Law wrote: > On 06/23/14 14:09, Tobias Burnus wrote: > >This patch broke bootstrapping for me on x86-64-gnu-linux: > > > >/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: > >i386 architecture of input file `/usr/lib/crti.o' is incompatible with > >i386:x86-64 output > > > > >If I revert the patch, it works for me. > Reverted. Will have to look deeper. Paul, did you bootstrap with > this patch on the trunk? Hi Jeff, I was using the yocto/oe-core build system, and hence it was creating gcc-cross-initial from its own build system (with ~50 other patches on gcc-4.9.0 baseline) -- so it isn't 100% identical to a manual bootstrapping on trunk. It sounds like Jakub has provided additional details on why this may have broken bootstrap, as the issue appears to be possibly of wider scope than I originally reported. I'll revisit it tomorrow morning, and see what additional details I can provide. Thanks, Paul. -- > > jeff > >
diff --git a/gcc/gcc.c b/gcc/gcc.c index 6870a840e1b7..a580975a7057 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -7822,7 +7822,7 @@ set_multilib_dir (void) } if (multilib_dir == NULL && multilib_os_dir != NULL - && strcmp (multilib_os_dir, ".") == 0) + && strcmp (multilib_os_dir, ".") != 0) { free (CONST_CAST (char *, multilib_os_dir)); multilib_os_dir = NULL;
We see the following on a 32bit gcc installed on 64 bit host: Reading symbols from ./i586-pokymllib32-linux-gcc...done. (gdb) run Starting program: x86-pokymllib32-linux/lib32-gcc/4.9.0-r0/image/usr/bin/i586-pokymllib32-linux-gcc Program received signal SIGSEGV, Segmentation fault. 0xf7e957e0 in free () from /lib/i386-linux-gnu/libc.so.6 (gdb) bt #0 0xf7e957e0 in free () from /lib/i386-linux-gnu/libc.so.6 #1 0x0804b73c in set_multilib_dir () at gcc-4.9.0/gcc/gcc.c:7827 #2 main (argc=1, argv=0xffffd504) at gcc-4.9.0/gcc/gcc.c:6688 (gdb) The problem arises because the check on whether we are using the internal string "." or an allocated one is reversed. We should be calling free() when the string is not equal to the internal "." string. Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> --- [Found and fixed on gcc-4.9.0 but applies to git/master too] gcc/gcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)