As of Sat Jul 12 08:46:21 PDT 2008, on Fedora 9/x86-64, I got bash-3.2$ ./addr2line -e addr2line 0x401f49 ??:0 *** glibc detected *** ./addr2line: munmap_chunk(): invalid pointer: 0x00007f850706909c *** ======= Backtrace: ========= /lib64/libc.so.6[0x3362278158] ./addr2line[0x41f87a] ./addr2line[0x40a719] ./addr2line[0x4025d4] /lib64/libc.so.6(__libc_start_main+0xfa)[0x336221e32a] ./addr2line(calloc+0x149)[0x401f49] ======= Memory map: ======== 00400000-004c9000 r-xp 00000000 08:11 14418847 /export/build/gnu/binutils/build-x86_64-linux.old/binutils/addr2line 006c8000-006cb000 rw-p 000c8000 08:11 14418847 /export/build/gnu/binutils/build-x86_64-linux.old/binutils/addr2line 006cb000-006cf000 rw-p 006cb000 00:00 0 021c0000-0228e000 rw-p 021c0000 00:00 0 [heap] 3361000000-336101d000 r-xp 00000000 08:06 9297034 /lib64/ld-2.8.so 336121c000-336121d000 r--p 0001c000 08:06 9297034 /lib64/ld-2.8.so 336121d000-336121e000 rw-p 0001d000 08:06 9297034 /lib64/ld-2.8.so 3362200000-3362362000 r-xp 00000000 08:06 9297035 /lib64/libc-2.8.so 3362362000-3362562000 ---p 00162000 08:06 9297035 /lib64/libc-2.8.so 3362562000-3362566000 r--p 00162000 08:06 9297035 /lib64/libc-2.8.so 3362566000-3362567000 rw-p 00166000 08:06 9297035 /lib64/libc-2.8.so 3362567000-336256c000 rw-p 3362567000 00:00 0 3363600000-3363615000 r-xp 00000000 08:06 9297066 /lib64/libz.so.1.2.3 3363615000-3363814000 ---p 00015000 08:06 9297066 /lib64/libz.so.1.2.3 3363814000-3363815000 rw-p 00014000 08:06 9297066 /lib64/libz.so.1.2.3 3368a00000-3368a16000 r-xp 00000000 08:06 9297068 /lib64/libgcc_s-4.3.0-20080428.so.1 3368a16000-3368c15000 ---p 00016000 08:06 9297068 /lib64/libgcc_s-4.3.0-20080428.so.1 3368c15000-3368c16000 rw-p 00015000 08:06 9297068 /lib64/libgcc_s-4.3.0-20080428.so.1 7f8506ed9000-7f850709a000 rw-p 7f8506ed9000 00:00 0 7f85070be000-7f85070c2000 rw-p 7f85070be000 00:00 0 7fff0f0ad000-7fff0f0c2000 rw-p 7ffffffea000 00:00 0 [stack] 7fff0f1fe000-7fff0f200000 r-xp 7fff0f1fe000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted bash-3.2$
Hi Craig, your patch: http://sourceware.org/ml/binutils/2008-06/msg00203.html caused this regression.
The correct behaviour should be bash-3.2$ ./addr2line -e addr2line 0x401f49 /export/gnu/import/binutils-last/src/binutils/addr2line.c:341 bash-3.2$
bash-3.2$ ./addr2line -e ./addr2line `nm -n --defined-only ./addr2line |head -1 | awk '{print $1}'` ??:0 *** glibc detected *** ./addr2line: munmap_chunk(): invalid pointer: 0x00007f60c57010a2 *** ======= Backtrace: ========= /lib64/libc.so.6[0x3362278158] ./addr2line[0x41f87a] ./addr2line[0x40a719] ./addr2line[0x4025d4] /lib64/libc.so.6(__libc_start_main+0xfa)[0x336221e32a] ./addr2line(calloc+0x149)[0x401f49] ======= Memory map: ======== 00400000-004c9000 r-xp 00000000 08:11 14549834 /export/build/gnu/binutils/next/binutils/addr2line 006c9000-006cc000 rw-p 000c9000 08:11 14549834 /export/build/gnu/binutils/next/binutils/addr2line 006cc000-006d0000 rw-p 006cc000 00:00 0 02603000-026d1000 rw-p 02603000 00:00 0 [heap] 3361000000-336101d000 r-xp 00000000 08:06 9297034 /lib64/ld-2.8.so 336121c000-336121d000 r--p 0001c000 08:06 9297034 /lib64/ld-2.8.so 336121d000-336121e000 rw-p 0001d000 08:06 9297034 /lib64/ld-2.8.so 3362200000-3362362000 r-xp 00000000 08:06 9297035 /lib64/libc-2.8.so 3362362000-3362562000 ---p 00162000 08:06 9297035 /lib64/libc-2.8.so 3362562000-3362566000 r--p 00162000 08:06 9297035 /lib64/libc-2.8.so 3362566000-3362567000 rw-p 00166000 08:06 9297035 /lib64/libc-2.8.so 3362567000-336256c000 rw-p 3362567000 00:00 0 3363600000-3363615000 r-xp 00000000 08:06 9297066 /lib64/libz.so.1.2.3 3363615000-3363814000 ---p 00015000 08:06 9297066 /lib64/libz.so.1.2.3 3363814000-3363815000 rw-p 00014000 08:06 9297066 /lib64/libz.so.1.2.3 3368a00000-3368a16000 r-xp 00000000 08:06 9297068 /lib64/libgcc_s-4.3.0-20080428.so.1 3368a16000-3368c15000 ---p 00016000 08:06 9297068 /lib64/libgcc_s-4.3.0-20080428.so.1 3368c15000-3368c16000 rw-p 00015000 08:06 9297068 /lib64/libgcc_s-4.3.0-20080428.so.1 7f60c5571000-7f60c5732000 rw-p 7f60c5571000 00:00 0 7f60c5756000-7f60c575a000 rw-p 7f60c5756000 00:00 0 7fffcd745000-7fffcd75a000 rw-p 7ffffffea000 00:00 0 [stack] 7fffcd7fe000-7fffcd800000 r-xp 7fffcd7fe000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted bash-3.2$ /usr/bin/addr2line -e ./addr2line `nm -n --defined-only ./addr2line |head -1 | awk '{print $1}'` ??:0 bash-3.2$
On Linux, to reproduce it, you may try [hjl@gnu-26 binutils]$ MALLOC_CHECK_=1 ./addr2line -e ./addr2line `nm -n --defined-only ./addr2line |head -1 | awk '{print $1}'` malloc: using debugging hooks ??:0 *** glibc detected *** free(): invalid pointer: 0x0000002a95734d53 *** [hjl@gnu-26 binutils]$
I've figured out the crashing bug, and can fix that. I tried your test and it gave a different line number than you got, but I assume that's due to build differences. But just to make sure, do you mind applying the following patch, and verifying it fixes things at your end? craig --- Index: bfd/dwarf2.c =================================================================== RCS file: /cvs/src/src/bfd/dwarf2.c,v retrieving revision 1.110 diff -u -r1.110 dwarf2.c --- bfd/dwarf2.c 11 Jul 2008 09:18:19 -0000 1.110 +++ bfd/dwarf2.c 13 Jul 2008 23:45:20 -0000 @@ -104,6 +104,12 @@ asection *sec; bfd_byte *sec_info_ptr; + /* A pointer to the memory block allocated for info_ptr. Neither + info_ptr nor sec_info_ptr are guaranteed to stay pointing to the + beginning of the malloc block. This is used only to free the + memory later. */ + bfd_byte *info_ptr_memory; + /* Pointer to the symbol table. */ asymbol **syms; @@ -2915,8 +2921,9 @@ total_size = msec->size; if (! read_section (debug_bfd, ".debug_info", ".zdebug_info", symbols, 0, - &stash->info_ptr, &total_size)) + &stash->info_ptr_memory, &total_size)) goto done; + stash->info_ptr = stash->info_ptr_memory; stash->info_ptr_end = stash->info_ptr + total_size; } else @@ -2931,10 +2938,11 @@ if (all_uncompressed) { /* Case 2: multiple sections, but none is compressed. */ - stash->info_ptr = bfd_malloc (total_size); - if (stash->info_ptr == NULL) + stash->info_ptr_memory = bfd_malloc (total_size); + if (stash->info_ptr_memory == NULL) goto done; + stash->info_ptr = stash->info_ptr_memory; stash->info_ptr_end = stash->info_ptr; for (msec = find_debug_info (debug_bfd, NULL); @@ -2963,7 +2971,8 @@ else { /* Case 3: multiple sections, some or all compressed. */ - stash->info_ptr = bfd_malloc (1); + stash->info_ptr_memory = bfd_malloc (1); + stash->info_ptr = stash->info_ptr_memory; stash->info_ptr_end = stash->info_ptr; for (msec = find_debug_info (debug_bfd, NULL); msec; @@ -3292,5 +3301,5 @@ free (stash->dwarf_abbrev_buffer); free (stash->dwarf_line_buffer); free (stash->dwarf_ranges_buffer); - free (stash->sec_info_ptr); + free (stash->info_ptr_memory); }
(In reply to comment #5) > I've figured out the crashing bug, and can fix that. I tried your test and it > gave a different line number than you got, but I assume that's due to build > differences. But just to make sure, do you mind applying the following patch, > and verifying it fixes things at your end? > Yes, it fixed the crash. Thanks.
OK, I've committed it to the CVS repository. Thanks for the report.
Subject: Re: PATCH COMMITTED: new variable for malloc It turns out a variable I thought would always point to the beginning of the malloc-block, can actually change value. This was causing crashes in some cases. I've fixed this by adding a new pointer, that always points to the malloc-location, so we can always free it safely. I'm comitting this under the "obvious fix" principle. This is probably the least obvious of the obvious fixes I've done so far, but I hope it still safely falls into that category. craig --cut here-- 2008-07-13 Craig Silverstein <csilvers@google.com> * dwarf2.c (struct dwarf2_debug): New variable info_ptr_memory. (find_line): Use info_ptr_memory instead of sec_info_ptr. (_bfd_dwarf2_cleanup_debug_info): Likewise. Index: bfd/dwarf2.c =================================================================== RCS file: /cvs/src/src/bfd/dwarf2.c,v retrieving revision 1.110 diff -u -r1.110 dwarf2.c --- bfd/dwarf2.c 11 Jul 2008 09:18:19 -0000 1.110 +++ bfd/dwarf2.c 14 Jul 2008 00:09:17 -0000 @@ -104,6 +104,12 @@ asection *sec; bfd_byte *sec_info_ptr; + /* A pointer to the memory block allocated for info_ptr. Neither + info_ptr nor sec_info_ptr are guaranteed to stay pointing to the + beginning of the malloc block. This is used only to free the + memory later. */ + bfd_byte *info_ptr_memory; + /* Pointer to the symbol table. */ asymbol **syms; @@ -2915,8 +2921,9 @@ total_size = msec->size; if (! read_section (debug_bfd, ".debug_info", ".zdebug_info", symbols, 0, - &stash->info_ptr, &total_size)) + &stash->info_ptr_memory, &total_size)) goto done; + stash->info_ptr = stash->info_ptr_memory; stash->info_ptr_end = stash->info_ptr + total_size; } else @@ -2931,10 +2938,11 @@ if (all_uncompressed) { /* Case 2: multiple sections, but none is compressed. */ - stash->info_ptr = bfd_malloc (total_size); - if (stash->info_ptr == NULL) + stash->info_ptr_memory = bfd_malloc (total_size); + if (stash->info_ptr_memory == NULL) goto done; + stash->info_ptr = stash->info_ptr_memory; stash->info_ptr_end = stash->info_ptr; for (msec = find_debug_info (debug_bfd, NULL); @@ -2963,7 +2971,8 @@ else { /* Case 3: multiple sections, some or all compressed. */ - stash->info_ptr = bfd_malloc (1); + stash->info_ptr_memory = bfd_malloc (1); + stash->info_ptr = stash->info_ptr_memory; stash->info_ptr_end = stash->info_ptr; for (msec = find_debug_info (debug_bfd, NULL); msec; @@ -3292,5 +3301,5 @@ free (stash->dwarf_abbrev_buffer); free (stash->dwarf_line_buffer); free (stash->dwarf_ranges_buffer); - free (stash->sec_info_ptr); + free (stash->info_ptr_memory); }