[skip to the end if you just want the patches without the storyline] Jochen Voss writes the following: > >when trying to debug one of my programs I encountered a case where gdb >crashed on the command "break main" before my programm was even >started. The problem occurs on a powerpc machine.
After investigating, I don't see anything ppc-specific about this bug. The actual occurrence of the segfault may vary between architectures, but that's just because some may get lucky when dereferencing the bad pointer. > http://seehuhn.de/data/gdb-bug - the binary > http://seehuhn.de/data/gdb-bug.i - the preprocessed source [...] > (gdb) break main > Segmentation fault It also has nothing to do with setting a breakpoint, or with your main function. You can also try "print main", "break load_matrix", ... the key is convincing gdb that it needs to parse the debugging symbols. >2) Regenerating the binary. The binary gdb-bug was compiled from >gdb-bug.i using the following two commands: > > [EMAIL PROTECTED] [~/y] gcc -ggdb3 -c gdb-bug.i > [EMAIL PROTECTED] [~/y] gcc -ggdb3 -o gdb-bug gdb-bug.o -lm -llapack > -lblas -lg2c When done with gcc 3.3 or 3.4, the resulting executable does not segfault gdb. I can see from your binary that you were using Debian's gcc 4.0.1-1. I can also reproduce the bug with the current upstream source, 4.0.2. (gcc 4.0 hasn't made it into Debian stable yet). Also, your use of -ggdb3 is an important part of reproducing the bug. Normal -g doesn't include debugging information for macros, and that's where the problem is. (-gdwarf-2 -g3 is also sufficient, or just -g3 since DWARF2 seems to be the default format now) To see what is going wrong, do a "readelf -w gdb-bug.o" and look at the .debug_macinfo section. You'll see that it references sources files by number, starting at 1 and ending at 47: ... DW_MACINFO_start_file - lineno: 21 filenum: 46 DW_MACINFO_end_file DW_MACINFO_start_file - lineno: 22 filenum: 47 Those filenums refer to "The File Name Table" (located earlier in the readelf -w output). If you take a look at The File Name Table, you'll see that it has only 46 entries. And that's why gdb segfaults. Now we know how to fix gdb: make it check that filenum is in the proper range. But we want to fix the bad debugging information, not just the segfault. Go back to the .debug_macinfo section, look closer, and you'll see that there are no references to filenum 16. It goes 1,2,3,...15,17,18,...47 (some numbers are repeated because files get #included more than once, but if you look just at the first appearance of each number, they are in order.) When gcc was building this table of #included files, it was also keeping track of #includes for error reporting purposes. There are 2 lists of #included files: one for errors and warnings, and the other for DWARF2 debugging information. The missing file number 16 corresponds to the special pseudo-file "<built-in>" in the list of source files. "<built-in>" is omitted from the DWARF2 file table because it's not an actual file. There is a function called maybe_emit_file() in gcc, which assigns the filenums, and takes care of mapping the file numbers in the main file list to the file numbers in the DWARF2 list. Someone forgot to use the return value of maybe_emit_file() when creating the DW_MACINFO_start_file record, so what should be a reference to file number 16 comes out instead as a reference to file number 17. After the 16th entry, every filenum is 1 larger than it should be. The reference to file number 47 should really be a reference to file number 46. Because all file numbers after the missing one are off by 1, most of the macro debugging information is going to be referring to the wrong file. So even if gdb doesn't segfault, it's still going to report the wrong origin for macros defined after the bug's trigger point (file 16 in the sample). It would be possible to make gdb detect an out-of-sequence filenum and automatically adjust it and all of the following filenums, with a warning message like "Detected GCC 4.0.<=2 macinfo breakage, working around it". My patch doesn't go that far; it just prevents the segfault. Here are the patches. In case of mail corruption, they're also here: http://world.std.com/~pacman/gcc4-dwarf-macinfo.diff http://world.std.com/~pacman/gdb-macinfo-segfault.diff --- gdb-6.3.orig/gdb/dwarf2read.c 2005-10-17 23:22:46.000000000 -0500 +++ gdb-6.3/gdb/dwarf2read.c 2005-10-18 00:38:48.000000000 -0500 @@ -9087,9 +9087,14 @@ file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read); mac_ptr += bytes_read; - current_file = macro_start_file (file, line, - current_file, comp_dir, - lh, cu->objfile); + if (file > lh->num_file_names) + warning ("macro debug info references file %d, " + "but file table only contains %u entries.", + file, lh->num_file_names); + else + current_file = macro_start_file (file, line, + current_file, comp_dir, + lh, cu->objfile); } break; --- gcc-4.0.2.orig/gcc/dwarf2out.c 2005-09-01 09:04:38.000000000 -0500 +++ gcc-4.0.2/gcc/dwarf2out.c 2005-10-17 22:19:47.000000000 -0500 @@ -13339,8 +13339,7 @@ dw2_asm_output_data (1, DW_MACINFO_start_file, "Start new file"); dw2_asm_output_data_uleb128 (lineno, "Included from line number %d", lineno); - maybe_emit_file (lookup_filename (filename)); - dw2_asm_output_data_uleb128 (lookup_filename (filename), + dw2_asm_output_data_uleb128 (maybe_emit_file (lookup_filename (filename)), "Filename we just started"); } } _______________________________________________ Bug-gdb mailing list Bug-gdb@gnu.org http://lists.gnu.org/mailman/listinfo/bug-gdb