Tested against: GNU gdb (GDB) Fedora (6.8.91.20090930-2.fc12) Take the following program: struct foo { const int i; const long j; }; typedef struct foo fooer; static int bar (const int i, const long j) { return i * j; } static int func (int (*f) ()) { const fooer baz = { .i = 2, .j = 21 }; return f(baz.i, baz.j); } int main (int argc, char *argv[], char *envp[]) { return func (&bar) - 42; } Compiled with gcc -g -O2 -o const const.c (gdb) break func Function "func" not defined. Make breakpoint pending on future shared library load? (y or [n]) While it is possible to break on the function by line: (gdb) break const.c:18 Breakpoint 1 at 0x400490: file const.c, line 18. func is marked as inlined in the dwarf debuginfo: <1><71>: Abbrev Number: 8 (DW_TAG_subprogram) <72> DW_AT_name : (indirect string, offset: 0x0): func <76> DW_AT_decl_file : 1 <77> DW_AT_decl_line : 16 <78> DW_AT_prototyped : 1 <79> DW_AT_type : <0x53> <7d> DW_AT_inline : 1 (inlined) <7e> DW_AT_sibling : <0xa8> [...] <2><147>: Abbrev Number: 18 (DW_TAG_inlined_subroutine) <148> DW_AT_abstract_origin: <0x71> <14c> DW_AT_low_pc : 0x400490 <154> DW_AT_high_pc : 0x4004a4 <15c> DW_AT_call_file : 1 <15d> DW_AT_call_line : 25
Tested against GNU gdb (GDB) 7.2. Able to produce the same error Taking the same program from Mark GNU gdb (GDB) 7.2 Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-unknown-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/tongxin1/gdb-7.2/gdb/test...done. (gdb) b func Function "func" not defined. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) b test.c:18 Breakpoint 1 at 0x400460: file test.c, line 18. (gdb) list 10 bar (const int i, const long j) 11 { 12 return i * j; 13 } 14 15 static int 16 func (int (*f) ()) 17 { 18 const fooer baz = { .i = 2, .j = 21 }; 19 return f(baz.i, baz.j); (gdb) r Starting program: /home/tongxin1/gdb-7.2/gdb/test Breakpoint 1, main (argc=1, argv=0x7fffffffe298, envp=0x7fffffffe2a8) at test.c:25 25 return func (&bar) - 42; (gdb) DWARF file <2><fc>: Abbrev Number: 14 (DW_TAG_inlined_subroutine) DW_AT_abstract_origin: <7f> DW_AT_low_pc : 0x400460 DW_AT_high_pc : 0x400472 DW_AT_call_file : 1 DW_AT_call_line : 25
No reason for this to be in "WAIT".
This is my first time contributing to gdb. I am an developer from IBM Java Just-In-Time compiler team. I would like to give this defect a try. Is there help i can resort to if I am stuck ?
(In reply to comment #3) > This is my first time contributing to gdb. I am an developer from IBM Java > Just-In-Time compiler team. I would like to give this defect a try. Is there > help i can resort to if I am stuck ? You can ask questions here, or on the gdb list, or on the gdb irc channel.
After spending sometime with gdb. i found that gdb uses two ways for the user (or much of the code in the debugger) to reference a symbol: 1. By its address (e.g. execution stops at some address which is inside a function in this file). The address will be noticed to be in the range of this psymtab, and the full symtab will be read in. find_pc_function, find_pc_line, and other find_pc_... functions handle this. 2. By its name (e.g. the user asks to print a variable, or set a breakpoint on a function). Global names and file-scope names will be found in the psymtab, which will cause the symtab to be pulled in. Local names will have to be qualified by a global name, or a file-scope name, in which case we will have already read in the symtab as we evaluated the qualifier. Or, a local symbol can be referenced when we are "in" a local scope, in which case the first case applies. lookup_symbol does most of the work here. In this case, "func" is referenced by name. However, taking a look at the psymtab Partial symtab for source file test.c (object 0xa5e9d60) Read from object file /home/tongxin1/gdb-7.2/gdb/defect_10738/test (0xa5dd980) Relocate symbols by 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 Symbols cover text addresses 0x0-0x0 Depends on 1 other partial symtabs. 0 0xa5e9b20 test.c Partial symtab for source file test.c (object 0xa5e9b20) Read from object file /home/tongxin1/gdb-7.2/gdb/defect_10738/test (0xa5dd980) Relocate symbols by 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 Symbols cover text addresses 0x400450-0x400473 Depends on 0 other partial symtabs. Global partial symbols: `main', function, 0x400460 Static partial symbols: `size_t', type, 0x0 `long unsigned int', type, 0x0 `unsigned char', type, 0x0 `short unsigned int', type, 0x0 `unsigned int', type, 0x0 `signed char', type, 0x0 `short int', type, 0x0 `int', type, 0x0 `long int', type, 0x0 `__off_t', type, 0x0 `__off64_t', type, 0x0 `long unsigned int', type, 0x0 `char', type, 0x0 `_IO_lock_t', type, 0x0 `_IO_FILE', struct domain, type, 0x0 `_IO_marker', struct domain, type, 0x0 `bar', function, 0x400450 "func" is not even included in the psymtab. I would like some pointers at this point. should I investigate why "func" is in dwarf2 but not in psymtab ? Any help would be greatly appreciated. Xin
(In reply to comment #5) > "func" is not even included in the psymtab. I would like some pointers at this > point. should I investigate why "func" is in dwarf2 but not in psymtab ? Any > help would be greatly appreciated. First, I'd like to note that what I am about to say may be wrong. You will want to check it before making any decisions based on it. Second, there are at least two cases to consider. One case is the one where all instances of a given function have been inlined. Another case is where the function has been inlined but also still exists as an "out of line" function. I think "break function" works ok if all instances have been inlined. In the case where there is an out-of-line copy, I think it may be best if "break function" noticed that "function" was inlined somewhere, and then treat it as though "break file:line" were used instead. You may want to trace through the "file:line" logic in this case to see what happens. That should tell you where to modify the gdb core to make this happen. You'll also need to change dwarf2read.c to read and respect DW_AT_inline. Right now this is ignored. In particular I think you need to check for DW_INL_inlined, and use that to decide when to look for multiple locations. You may need to add a flag to function symbols to indicate when the special inline processing should be done.
(In reply to comment #6) > I think "break function" works ok if all instances have been inlined. > > In the case where there is an out-of-line copy, I think it may be best > if "break function" noticed that "function" was inlined somewhere, > and then treat it as though "break file:line" were used instead. > In this case, I do not think there is out-of-line copy for "func" . "func" is only used in one place and is inlined there. unless you mean "out-of-line"( not marked as inline) on the source code level. (In reply to comment #6) > You'll also need to change dwarf2read.c to read and respect DW_AT_inline. > Right now this is ignored. In particular I think you need to check > for DW_INL_inlined, and use that to decide when to look for multiple > locations. > > You may need to add a flag to function symbols to indicate when the special > inline processing should be done. I agree with you that further reading of dwarf section is needed and converting break function into break file:line might be the way to go.
(In reply to comment #7) > In this case, I do not think there is out-of-line copy for "func" . "func" is > only used in one place and is inlined there. unless you mean "out-of-line"( not > marked as inline) on the source code level. It may be gcc-version-dependent. Or maybe I am misremembering the result of my experiment :-)
(In reply to comment #3) > This is my first time contributing to gdb. I am an developer from IBM Java > Just-In-Time compiler team. I would like to give this defect a try. Is there > help i can resort to if I am stuck ? Hello Xin, I would like to know if you're working on this feature. Thank you very much!
I have been busy with my work in IBM recently and will have spare time in May. you can either save the bug for me to work on in May or assign it to someone else if there is someone who is willing to take it Thank you Xin On Mon, Apr 4, 2011 at 3:01 PM, sergiodj at redhat dot com < sourceware-bugzilla@sourceware.org> wrote: > http://sourceware.org/bugzilla/show_bug.cgi?id=10738 > > Sergio Durigan Junior <sergiodj at redhat dot com> changed: > > What |Removed |Added > > ---------------------------------------------------------------------------- > CC| |sergiodj at redhat dot com > > --- Comment #9 from Sergio Durigan Junior <sergiodj at redhat dot com> > 2011-04-04 19:01:11 UTC --- > (In reply to comment #3) > > This is my first time contributing to gdb. I am an developer from IBM > Java > > Just-In-Time compiler team. I would like to give this defect a try. Is > there > > help i can resort to if I am stuck ? > > Hello Xin, > > I would like to know if you're working on this feature. > > Thank you very much! > > -- > Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email > ------- You are receiving this mail because: ------- > You are on the CC list for the bug. > You are the assignee for the bug. >
Another case to consider: File name Line number Starting address 4.c 5 0x400490 4.c 5 0x40049a 4.c 5 0x400383 4.c 5 0x40038a (other line numbers filtered out) (gdb) b f Breakpoint 1 at 0x400490: file 4.c, line 5. But 0x400383 - the inlind instance in main - is filtered out because the function name there is different. -g -O2 -fno-omit-frame-pointer gcc (GCC) 4.7.0 20110414 (experimental) (the version should not matter much) volatile int v; __attribute__((always_inline)) void f (void) { v--; } int main (void) { v++; f (); v++; return 0; }
(In reply to comment #11) > But 0x400383 - the inlind instance in main - is filtered out because the > function name there is different. Why is that? The inlined_subroutine that covers 0x400383 should have an abstract_origin with as name "f".
(In reply to comment #12) > Why is that? The inlined_subroutine that covers 0x400383 should have > an abstract_origin with as name "f". #0 block_linkage_function #1 find_pc_sect_function #2 find_pc_partial_function_gnu_ifunc #3 find_pc_partial_function #4 expand_line_sal_maybe block_linkage_function /* The return value will not be an inlined function; the containing function will be returned instead. */ It may be a simple bug, not sure.
FYI, RMS has taken an interest in this issue, as an instance of his longstanding emphasis on being able to debug optimized code.
(In reply to comment #14) > FYI, RMS has taken an interest in this issue, as an instance of his > longstanding emphasis on being able to debug optimized code. As a workaround, right now "break file:line" will do the right thing for inlined functions.
Note that this is related to PR 13105 now.
CVSROOT: /cvs/src Module name: src Changes by: gary@sourceware.org 2012-03-16 16:47:34 Modified files: gdb : ChangeLog NEWS dwarf2read.c linespec.c main.c symfile.h gdb/doc : ChangeLog gdb.texinfo gdb/testsuite : ChangeLog gdb/testsuite/gdb.base: annota1.exp async-shell.exp gdb/testsuite/lib: mi-support.exp Added files: gdb/testsuite/gdb.dwarf2: dw2-inline-break.S dw2-inline-break.exp gdb/testsuite/gdb.opt: inline-break.c inline-break.exp Log message: gdb: PR breakpoints/10738 * dwarf2read.c (use_deprecated_index_sections): New global. (struct partial_die_info): New member may_be_inlined. (read_partial_die): Set may_be_inlined where appropriate. (add_partial_subprogram): Add partial symbols for partial DIEs that may be inlined. (new_symbol_full): Add inlined subroutines to the current scope. (write_psymtabs_to_index): Bump version number. (dwarf2_read_index): Read only version 6 indices unless use_deprecated_index_sections is set. * linespec.c (symbol_and_data_callback): New structure. (iterate_inline_only): New function. (iterate_over_all_matching_symtabs): New argument "include_inline". If nonzero, also call the callback for symbols representing inlined subroutines. (lookup_prefix_sym): Pass extra argument to the above. (find_function_symbols): Likewise. (add_matching_symbols_to_info): Likewise. * NEWS: Mention that GDB can now set breakpoints on inlined functions. gdb/doc: PR breakpoints/10738 * gdb.texinfo (Inline Functions): Remove the now-unnecessary @item stating that GDB cannot set breakpoints on inlined functions. (Mode Options): Document --use-deprecated-index-sections. (Index Section Format): Document new index section version format. gdb/testsuite: PR breakpoints/10738 * gdb.opt/inline-break.exp: New file. * gdb.opt/inline-break.c: Likewise. * gdb.dwarf2/inline-break.exp: Likewise. * gdb.dwarf2/inline-break.S: Likewise. * gdb.base/annota1.exp: Cope with old .gdb_index warnings. * gdb.base/async-shell.exp: Likewise. * lib/mi-support.exp (library_loaded_re): Likewise. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.14019&r2=1.14020 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/NEWS.diff?cvsroot=src&r1=1.499&r2=1.500 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/dwarf2read.c.diff?cvsroot=src&r1=1.624&r2=1.625 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/linespec.c.diff?cvsroot=src&r1=1.152&r2=1.153 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/main.c.diff?cvsroot=src&r1=1.101&r2=1.102 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/symfile.h.diff?cvsroot=src&r1=1.105&r2=1.106 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/doc/ChangeLog.diff?cvsroot=src&r1=1.1286&r2=1.1287 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/doc/gdb.texinfo.diff?cvsroot=src&r1=1.933&r2=1.934 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&r1=1.3140&r2=1.3141 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/annota1.exp.diff?cvsroot=src&r1=1.46&r2=1.47 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/async-shell.exp.diff?cvsroot=src&r1=1.4&r2=1.5 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.dwarf2/dw2-inline-break.S.diff?cvsroot=src&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.dwarf2/dw2-inline-break.exp.diff?cvsroot=src&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.opt/inline-break.c.diff?cvsroot=src&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.opt/inline-break.exp.diff?cvsroot=src&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/lib/mi-support.exp.diff?cvsroot=src&r1=1.109&r2=1.110
I fixed it.