This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] While processing a struct die, store the method's address in its fn_field


On Tue, Nov 25, 2014 at 3:37 PM, Siva Chandra <sivachandra@google.com> wrote:
> On Tue, Nov 25, 2014 at 2:09 PM, Doug Evans <dje@google.com> wrote:
>> For functions/methods gdb already uses lowpc as the start address.
>
> May be I am reading wrong somewhere, but if I am correct, GDB
> currently gets to a low pc (the address of the method) of a method via
> its symbol. So, I agree that GDB uses low pc anyway.

GDB's symbol handling is pretty confusing.

A better way to phrase this:

"GDB currently gets to a low pc (the address of the method) of a method via
its symbol"

is to write it as:

"One way GDB currently gets to a low pc (the address of the method)
of a method via its ELF symbol."

[Not only is "symtab" ambiguous in GDB, so is "symbol" ...]

GDB tries a myriad of different ways to look up a symbol.
If one way doesn't work it tries another.
If that doesn't work it tries another.
And on and on.

Typically the last way GDB tries is to look the symbol up
in the minsym symtab (the ELF symbol table).
Note that this works for demangled c++ symbols
not because we mangle them and then look up the
linkage name (note: even "linkage name"
is ambiguous in GDB!), but rather because we pre-demangle
ELF symbols (*1) and match them that way.
So while gdb uses minsyms for lookup, it does that
as a last resort (as always there are exceptions,
e.g., LOC_UNRESOLVED).

(*1): At a cost of 10 of the 13 seconds of GDB startup time and
a cost of 480MB of memory, for one of my benchmarks.
Besides the performance cost, looking up minsyms
this way hides bugs: PRs 17602, 17603.
IOW, what if one of the preceding lookups *should* have worked?

One useful experiment that I do from time to time is
hack out minsyms, and see what happens.
E.g., What still works? What broke? How much faster is gdb?

diff --git a/gdb/elfread.c b/gdb/elfread.c
index 19aaed3..655872f 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1126,6 +1126,8 @@ elf_read_minimal_symbols (struct objfile
*objfile, int symfile_flags,
   set_objfile_data (objfile, dbx_objfile_data_key, dbx);
   make_cleanup (free_elfinfo, (void *) objfile);

+  if (0) {
+
   /* Process the normal ELF symbol table first.  This may write some
      chain of info into the dbx_symfile_info of the objfile, which can
      later be used by elfstab_offset_sections.  */
@@ -1213,6 +1215,8 @@ elf_read_minimal_symbols (struct objfile
*objfile, int symfile_flags,
                       synth_symbol_table, 1);
     }

+  }
+
   /* Install any minimal symbols that have been collected as the current
      minimal symbols for this objfile.  The debug readers below this point
      should not generate new minimal symbols; if they do it's their

[N.B. That patch may not apply properly due to cut-n-paste errors.]

btw, One interesting thing this experiment shows is that (currently)
"start" != "tb main; run".
IIRC, "start" needs the minsym for main, "tb main; run" does not.


>> [IOW it doesn't use the linkage name, though even recently
>> I'd forgotten this and thought otherwise.
>> Also, GDB doesn't take a demangled name, mangle it,
>> and then try to look that up in the ELF symbol table.]
>
> May be I messed up some terminology somewhere, symbol handling side of
> GDB is new to me. But, looking at value_fn_field, it appears to me
> that GDB gets a method's address via its linkage name (first looking
> up its symbol/minsym). Also, value_fn_field uses lookup_symbol which
> uses lookup_symbol_in_language which demangles the linkage name. Based
> on this, I concluded that GDB cannot get the address of a method if
> the linkage name is missing. This is my understanding now, which could
> be wrong ofcourse!

fwiw, GDB is bad enough that I often can't trust just reading the code.
I often punt on that and actually single step through
the relevant code to REALLY see what is happening.

While lookup_symbol_in_language will demangle a mangled
name for lookup, a good first question to answer is what name
is being passed?  Typically it is not a mangled name.
[In another email I mentioned that the handling of lookup
of mangled vs demangled symbols is a cleanup topic in itself. :-)]

>>>  [Clang
>>> actually does not put out the low pc value for the subprogram die
>>> under a structure die, but it puts out a separate (not under a
>>> structure die) subprogram die for the operator() method with the low
>>> pc value.]
>>
>> DWARF can be hard to read at times.
>> Note that GCC can do this too.  E.g.,
>> It will output a declaration in the proper context
>> (e.g., inside a class definition for a method) without DW_AT_low_pc
>> and then it will output another DIE at the top level with DW_AT_low_pc
>> and with a DW_AT_specification referring back to previous DIE in its context.
>
> Yes, Clang takes this exact route and things work fine with a Clang
> generated binary. GCC does not generate the top level DIE at all, but
> stuffs in DW_AT_low_pc into the DIE under the class definition and
> does not specify the linkage name. So, there is no DIE specifying the
> linkage name of operator(). IMO however, what GCC is emitting is
> logical sufficient. In which case, GDB needs to store the low pc value
> somewhere, and my patch puts it in the type struct.

GDB already has a place to store the start address for functions.
Why is that not working here?

Note that in my previous message, where I dumped the symbols,
there is a symbol for operator() and it has the correct start address.
IOW, GDB already has the start address.
I still don't see the need for the new field.
It seems to me that what's wrong is the lookup.
Why isn't GDB finding that symbol, and how do we fix that?

btw, when I try your patch I get one fail:

p lambda(10)^M
Invalid data type for function to be called.^M
(gdb) FAIL: gdb.dwarf2/dw2-member-function-addr.exp: p lambda()

Do you see this?
I see this with clang too.

I think the problem we need to solve is connecting the object
to its operator().


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]