This is the mail archive of the archer@sourceware.org mailing list for the Archer 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] Proposal for a new DWARF name index section


On Mon, 10 Aug 2009 11:04:13 +0200, Dodji Seketeli wrote:
> * Only public names are indexed.  However, historically GDB has
>   allowed users to inspect and break on private objects as well,
>   without specifying a scope.

I think this requirement should be discussed more.

Still I find the goal is that the expression evaluation in debugger should
match the expression evaluation in compiler.

In practice the results are tricky due to the static symbols resolution:
$ echo 'main(){}' >libm.c;cc -o libm libm.c -lm -g;gdb -q -ex start -ex 'p b' ./libm
...
$1 = {i = {0, 1068498944}, d = 0.0625}
$ nm /lib64/libm.so.6 |grep ' b$'
0000003bb1e4bad8 r b


There could be an option to support backward-compatible "slow" mode and use
the (possible DWARF) indexes only for the new compiler-compliant mode.


Including also a C++ overloading example at the bottom but it may be offtopic.


> * It is unclear from the standard whether enumerators should be listed
>   in .debug_pubnames.
+
> * There is no way to know whether if a name references an enumerator,
>   and object or a function. This makes it hard for debuggers to
>   implement lazy debug information loading schemes.

A fixup by http://dwarfstd.org/Issues.php looks as appropriate in each case.


> * There is no way to know whether if a name references an enumerator,
>   and object or a function. This makes it hard for debuggers to
>   implement lazy debug information loading schemes.
+
> * The .debug_pubtypes section does not encode whether a name is a
>   typedef or a struct, union, or enum tag.

Are there any serious consequences?  Occasional needless read of a CU to find
out the type should not be a real performance hit.


> * Compilers are not required to emit index entries for inlined
>   functions which have no concrete out-of-line instance.  This implies
>   that a command like "break function", if it is to work for an
>   inlined function, must read all the .debug_info sections even if it
>   turns out that no such function exists anywhere.

Both
	http://dwarf.freestandards.org/Dwarf3.pdf
	http://www.dwarfstd.org/doc/DWARF4-draft3-090522.pdf
say
	C++ member functions with a definition in the class declaration are
	definitions in every compilation unit containing the class
	declaration, but if there is no concrete out-of-line instance there is
	no need to have a .debug_pubnames entry for the member function.

"no need to have" (and you say "are not required") so GCC is free to emit such
index entries.  Excessive index entries hopefully should not break debuggers.

GDB could check DW_AT_producer against known GCC versions to skip the slow
reading of '.debug_info's and rely just on '.debug_pubnames' - to find out all
the inlined instances of a specified function.



Regards,
Jan


C++ example:

(set -ex; g++ -o main main.C other.C -Wall -ggdb2; ./main)
gdb ./main
(gdb) start
(gdb) p &c
$1 = (C *) 0x7fffffffd3df
(gdb) call c.main()
main-main
(gdb) call C::main()
main-main
(gdb) call c.other()
Couldn't find method C::other
(gdb) call C::other()
other-other
	# Isn't it wrong here?  C::other() comes from a different CU.
(gdb) 

C++ class with the same name should be probably always fully equivalent as all
the methods are global ("W" nm symbol class) by default.  Thus my example is
an invalid C++ program probably.  Automatically limiting the C++ scope only to
the current CU would not be able to call methods having instances in other CUs
and just accidentally missing at the current CU due to being unused.


==> main.C <==
#include <stdio.h>

class C
  {
  public:
    static void m (int x) { puts ("main-int"); }
//    static void m (long x) { puts ("main-long"); }
    static void main () { puts ("main-main"); }
  };

extern void other ();

int
main ()
{
  C c;

  c.m (1);
  c.m (1L);
  c.main ();

  other ();

  return 0;
}

==> other.C <==
#include <stdio.h>

class C
  {
  public:
//    static void m (int x) { puts ("other-int"); }
    static void m (long x) { puts ("other-long"); }
    static void other () { puts ("other-other"); }
  };

void
other ()
{
  C c;

  c.m (1);
  c.m (1L);
  c.other ();
}


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