Index: gdb/symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.283 diff -u -p -r1.283 symtab.c --- gdb/symtab.c 21 Jul 2011 15:13:29 -0000 1.283 +++ gdb/symtab.c 25 Oct 2011 17:28:46 -0000 @@ -2474,6 +2474,7 @@ skip_prologue_sal (struct symtab_and_lin struct gdbarch *gdbarch; struct block *b, *function_block; int force_skip, skip; + const struct symtab_and_line start_sal_orig = *sal; /* Do not change the SAL is PC was specified explicitly. */ if (sal->explicit_pc) @@ -2627,6 +2628,29 @@ skip_prologue_sal (struct symtab_and_lin sal->line = SYMBOL_LINE (BLOCK_FUNCTION (function_block)); sal->symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block)); } + else + { + /* Check if line number of apparent prologue end comes after + the next line information. If so, do not skip prologue + as something odd has happened. Probably gcc bug 49906. + Instead of giving awkward location for the function start, + give the previous good line (fuction start). */ + const struct symtab_and_line prologue_sal_next + = find_pc_line (sal->end, 0); + + if ((sym? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= prologue_sal_next.end + && prologue_sal_next.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) + : (lookup_minimal_symbol_by_pc_section (prologue_sal_next.end, + section) + == lookup_minimal_symbol_by_pc_section (sal->pc, section))) + && prologue_sal_next.line != 0 + && prologue_sal_next.symtab == sal->symtab + && prologue_sal_next.line >= start_sal_orig.line + && prologue_sal_next.line < sal->line) + { + *sal = start_sal_orig; + } + } } /* If P is of the form "operator[ \t]+..." where `...' is @@ -4432,7 +4456,24 @@ skip_prologue_using_sal (struct gdbarch /* Assume that a consecutive SAL for the same (or larger) line mark the prologue -> body transition. */ if (sal.line >= prologue_sal.line) - break; + { + /* If the sal following SAL has line number lower than + SAL.LINE, then something is fishy. + Possibly gcc bug 49906 */ + const struct symtab_and_line prologue_sal_next + = find_pc_line (sal.end, 0); + + if (prologue_sal_next.end < end_pc + && prologue_sal_next.line != 0 + && prologue_sal_next.symtab == sal.symtab + && prologue_sal_next.line >= prologue_sal.line + && prologue_sal_next.line < sal.line) + /* Fishy: we have something past prologue that appears + in the source as before. Be conservative and return + start of the prologue. That's the best guess anyway. */ + prologue_sal.end = prologue_sal.pc; + break; + } /* The line number is smaller. Check that it's from the same function, not something inlined. If it's inlined,