* [RFA/commit/dwarf] Create partial symbols for nested subprograms
@ 2008-09-10 20:20 Joel Brobecker
2008-09-10 20:35 ` Daniel Jacobowitz
0 siblings, 1 reply; 22+ messages in thread
From: Joel Brobecker @ 2008-09-10 20:20 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1349 bytes --]
Hello,
I just realized that we are missing the nested subprograms in our
partial symbol list. Normally, this should cause us to fail when
trying to break on a nested procedure until we have loaded the full
symbols for that unit. But there is in fact a bit of code that
I couldn't understand in ada_lookup_symbol_list which works around
this issue: It searches the minimal symbols for a match, derives
the associated symbol address, then determines the associated psymtab,
converts the psymtab into a symtab; Contrary to the partial symtab,
the full symtab does contain a symbol for our nested procedure, and
thus the lookup succeeds.
I stumbled on this because I am about to remove the piece of code
mentioned above (in ada_lookup_symbol_list), as it introduces
a pretty significant performance penalty - I will post a separate
patch with more details later on. But at the same time, I think
it is important by itself, as I want the partial symtab and full
symtab to be consistent.
2008-09-10 Joel Brobecker <brobecker@adacore.com>
* dwarf2read.c (add_partial_subprogram): New procedure.
(scan_partial_symbols): Use it.
(load_partial_dies): Read in children of subprogram and lexical
blocks.
Tested on x86-linux. No regression. I would like to commit in a week
if there are no objections.
Thanks,
--
Joel
[-- Attachment #2: 03-nested_psym.diff --]
[-- Type: text/plain, Size: 2747 bytes --]
diff -r d71d6b13aae1 -r ad68e435fc43 gdb/dwarf2read.c
--- a/gdb/dwarf2read.c Wed Sep 10 12:23:56 2008 -0700
+++ b/gdb/dwarf2read.c Wed Sep 10 12:24:48 2008 -0700
@@ -766,6 +766,10 @@
static void add_partial_enumeration (struct partial_die_info *enum_pdi,
struct dwarf2_cu *cu);
+
+static void add_partial_subprogram (struct partial_die_info *pdi,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct dwarf2_cu *cu);
static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi,
gdb_byte *info_ptr,
@@ -1783,21 +1787,7 @@
switch (pdi->tag)
{
case DW_TAG_subprogram:
- if (pdi->has_pc_info)
- {
- if (pdi->lowpc < *lowpc)
- {
- *lowpc = pdi->lowpc;
- }
- if (pdi->highpc > *highpc)
- {
- *highpc = pdi->highpc;
- }
- if (!pdi->is_declaration)
- {
- add_partial_symbol (pdi, cu);
- }
- }
+ add_partial_subprogram (pdi, lowpc, highpc, cu);
break;
case DW_TAG_variable:
case DW_TAG_typedef:
@@ -2145,6 +2135,45 @@
if (pdi->has_children)
scan_partial_symbols (pdi->die_child, lowpc, highpc, cu);
+}
+
+/* Read a partial die corresponding to a subprogram and create a partial
+ symbol for that subprogram. Also define a partial symbol for each
+ nested subprogram defined inside it.
+
+ DIE my also be a lexical block, in which case we simply search
+ recursively for suprograms defined inside that lexical block. */
+
+static void
+add_partial_subprogram (struct partial_die_info *pdi,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct dwarf2_cu *cu)
+{
+ if (pdi->tag == DW_TAG_subprogram)
+ {
+ if (pdi->has_pc_info)
+ {
+ if (pdi->lowpc < *lowpc)
+ *lowpc = pdi->lowpc;
+ if (pdi->highpc > *highpc)
+ *highpc = pdi->highpc;
+ if (!pdi->is_declaration)
+ add_partial_symbol (pdi, cu);
+ }
+ }
+
+ if (! pdi->has_children)
+ return;
+
+ pdi = pdi->die_child;
+ while (pdi != NULL)
+ {
+ fixup_partial_die (pdi, cu);
+ if (pdi->tag == DW_TAG_subprogram
+ || pdi->tag == DW_TAG_lexical_block)
+ add_partial_subprogram (pdi, lowpc, highpc, cu);
+ pdi = pdi->die_sibling;
+ }
}
/* See if we can figure out if the class lives in a namespace. We do
@@ -5696,6 +5725,8 @@
&& (load_all
|| last_die->tag == DW_TAG_namespace
|| last_die->tag == DW_TAG_enumeration_type
+ || last_die->tag == DW_TAG_subprogram
+ || last_die->tag == DW_TAG_lexical_block
|| (cu->language != language_c
&& (last_die->tag == DW_TAG_class_type
|| last_die->tag == DW_TAG_interface_type
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-10 20:20 [RFA/commit/dwarf] Create partial symbols for nested subprograms Joel Brobecker
@ 2008-09-10 20:35 ` Daniel Jacobowitz
2008-09-10 21:38 ` Tom Tromey
2008-09-11 17:55 ` Joel Brobecker
0 siblings, 2 replies; 22+ messages in thread
From: Daniel Jacobowitz @ 2008-09-10 20:35 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
On Wed, Sep 10, 2008 at 01:19:59PM -0700, Joel Brobecker wrote:
> I stumbled on this because I am about to remove the piece of code
> mentioned above (in ada_lookup_symbol_list), as it introduces
> a pretty significant performance penalty - I will post a separate
> patch with more details later on. But at the same time, I think
> it is important by itself, as I want the partial symtab and full
> symtab to be consistent.
>
> 2008-09-10 Joel Brobecker <brobecker@adacore.com>
>
> * dwarf2read.c (add_partial_subprogram): New procedure.
> (scan_partial_symbols): Use it.
> (load_partial_dies): Read in children of subprogram and lexical
> blocks.
:-(
Do you have any performance data for GDB startup with this change?
Not that I see any useful way around it, if subprograms really can be
children of lexical blocks. But it's going to cause us to read in a
ton more DIEs, including all scopes and local variables.
The lexical block check won't work as is; we'd walk children of
lexical blocks, except we'll never read one in the first place.
See the skip_one_die call earlier in load_partial_dies.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-10 20:35 ` Daniel Jacobowitz
@ 2008-09-10 21:38 ` Tom Tromey
2008-09-11 5:01 ` Joel Brobecker
2008-09-11 17:55 ` Joel Brobecker
1 sibling, 1 reply; 22+ messages in thread
From: Tom Tromey @ 2008-09-10 21:38 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:
Daniel> Not that I see any useful way around it, if subprograms really
Daniel> can be children of lexical blocks.
Can we do it only for languages where we know this can occur?
IOW, Ada?
Tom
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-10 21:38 ` Tom Tromey
@ 2008-09-11 5:01 ` Joel Brobecker
2008-09-11 22:15 ` Tom Tromey
0 siblings, 1 reply; 22+ messages in thread
From: Joel Brobecker @ 2008-09-11 5:01 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> Daniel> Not that I see any useful way around it, if subprograms really
> Daniel> can be children of lexical blocks.
>
> Can we do it only for languages where we know this can occur?
> IOW, Ada?
That's what I was going to propose, but I wanted to do some measurement
too (tomorrow). Nested subprograms are possible in C, and aren't they
also available in C++? I don't mind supporting this only in Ada, though.
--
Joel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-10 20:35 ` Daniel Jacobowitz
2008-09-10 21:38 ` Tom Tromey
@ 2008-09-11 17:55 ` Joel Brobecker
2008-09-11 18:38 ` Daniel Jacobowitz
1 sibling, 1 reply; 22+ messages in thread
From: Joel Brobecker @ 2008-09-11 17:55 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 3233 bytes --]
Hi Daniel,
> > 2008-09-10 Joel Brobecker <brobecker@adacore.com>
> >
> > * dwarf2read.c (add_partial_subprogram): New procedure.
> > (scan_partial_symbols): Use it.
> > (load_partial_dies): Read in children of subprogram and lexical
> > blocks.
>
> :-(
Sorry! :-(.
> Not that I see any useful way around it, if subprograms really can be
> children of lexical blocks. But it's going to cause us to read in a
> ton more DIEs, including all scopes and local variables.
Unfortunately, it is possible to define a subprogram inside a lexical
block in Ada, so we have to search lexical blocks as well...
For instance:
procedure Foo is
begin
declare
procedure Bar is [...]
begin
Bar;
end;
end Foo;
> The lexical block check won't work as is; we'd walk children of
> lexical blocks, except we'll never read one in the first place.
> See the skip_one_die call earlier in load_partial_dies.
Arg, you are absolutely right. That's another part of the change
that we forgot to contribute (we now have setup strict rules where
all our changes should be contributed very soon after we make them,
precisely to avoid this sort of mistake). While I was at it, I also
noticed that we have a comment in our code that we also forgot to
contribute and which I find informative. Added as well. Let me know
if you don't think it bring anything.
> Do you have any performance data for GDB startup with this change?
I am not sure I am doing the right kind of performance test, so if you
have some better suggestions, please let me know. For now, here is what
I did:
. I used one of the large Ada applications we have:
It is 290MB in size - reduced to 160MB when I strip the debugging
info => the debugging info size is roughly 130MB.
The number of real lines of code is 700K spread in ~3500 files,
and it has a total of 39,000 subprograms declared in the debugging
info.
. To measure the startup time, I used the --statistics command-line
switch.
Here are the times reported before I apply the patch:
Startup time: 12.076754
Startup time: 12.096756
Startup time: 12.200762
Startup time: 11.904744
(average = 12.069754)
Startup size: data size 132330172
Here are the same times reported after:
Startup time: 12.600787
Startup time: 12.640790
Startup time: 12.432777
Startup time: 12.628789
(average = 12.575786)
Startup size: data size 133001788 (+700KB).
It looks like roughly a 4% increase in startup time. Not sure whether
that's considered a large increase or not - I just think that it's not
noticeable. None of our users have reported issues with startup time.
But, to make sure that only languages that have this feature get hit,
I adjusted the patch to only search nested procedure when the language
allows them.
2008-09-11 Joel Brobecker <brobecker@adacore.com>
* dwarf2read.c (add_partial_subprogram): New procedure.
(scan_partial_symbols): Use it.
(load_partial_dies): Read in children of subprogram and lexical
blocks.
Tested on x86-linux. No regression.
OK to commit?
Thanks,
--
Joel
[-- Attachment #2: nested.diff --]
[-- Type: text/plain, Size: 3994 bytes --]
diff -r d71d6b13aae1 -r a7f96d0b3354 gdb/dwarf2read.c
--- a/gdb/dwarf2read.c Wed Sep 10 12:23:56 2008 -0700
+++ b/gdb/dwarf2read.c Thu Sep 11 10:32:58 2008 -0700
@@ -766,6 +766,10 @@
static void add_partial_enumeration (struct partial_die_info *enum_pdi,
struct dwarf2_cu *cu);
+
+static void add_partial_subprogram (struct partial_die_info *pdi,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct dwarf2_cu *cu);
static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi,
gdb_byte *info_ptr,
@@ -1783,21 +1787,7 @@
switch (pdi->tag)
{
case DW_TAG_subprogram:
- if (pdi->has_pc_info)
- {
- if (pdi->lowpc < *lowpc)
- {
- *lowpc = pdi->lowpc;
- }
- if (pdi->highpc > *highpc)
- {
- *highpc = pdi->highpc;
- }
- if (!pdi->is_declaration)
- {
- add_partial_symbol (pdi, cu);
- }
- }
+ add_partial_subprogram (pdi, lowpc, highpc, cu);
break;
case DW_TAG_variable:
case DW_TAG_typedef:
@@ -2145,6 +2135,51 @@
if (pdi->has_children)
scan_partial_symbols (pdi->die_child, lowpc, highpc, cu);
+}
+
+/* Read a partial die corresponding to a subprogram and create a partial
+ symbol for that subprogram. When the CU language allows it, this
+ routine also defines a partial symbol for each nested subprogram
+ that this subprogram contains.
+
+ DIE my also be a lexical block, in which case we simply search
+ recursively for suprograms defined inside that lexical block.
+ Again, this is only performed when the CU language allows this
+ type of definitions. */
+
+static void
+add_partial_subprogram (struct partial_die_info *pdi,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct dwarf2_cu *cu)
+{
+ if (pdi->tag == DW_TAG_subprogram)
+ {
+ if (pdi->has_pc_info)
+ {
+ if (pdi->lowpc < *lowpc)
+ *lowpc = pdi->lowpc;
+ if (pdi->highpc > *highpc)
+ *highpc = pdi->highpc;
+ if (!pdi->is_declaration)
+ add_partial_symbol (pdi, cu);
+ }
+ }
+
+ if (! pdi->has_children)
+ return;
+
+ if (cu->language == language_ada)
+ {
+ pdi = pdi->die_child;
+ while (pdi != NULL)
+ {
+ fixup_partial_die (pdi, cu);
+ if (pdi->tag == DW_TAG_subprogram
+ || pdi->tag == DW_TAG_lexical_block)
+ add_partial_subprogram (pdi, lowpc, highpc, cu);
+ pdi = pdi->die_sibling;
+ }
+ }
}
/* See if we can figure out if the class lives in a namespace. We do
@@ -5567,6 +5602,7 @@
&& !is_type_tag_for_partial (abbrev->tag)
&& abbrev->tag != DW_TAG_enumerator
&& abbrev->tag != DW_TAG_subprogram
+ && abbrev->tag != DW_TAG_lexical_block
&& abbrev->tag != DW_TAG_variable
&& abbrev->tag != DW_TAG_namespace
&& abbrev->tag != DW_TAG_member)
@@ -5689,13 +5725,19 @@
sizeof (struct partial_die_info));
/* For some DIEs we want to follow their children (if any). For C
- we have no reason to follow the children of structures; for other
+ we have no reason to follow the children of structures; for other
languages we have to, both so that we can get at method physnames
- to infer fully qualified class names, and for DW_AT_specification. */
+ to infer fully qualified class names, and for DW_AT_specification.
+ We need to scan the children of procedures and lexical blocks
+ because certain languages such as Ada allow the definition of
+ nested entities that could be interesting for the debugger, such
+ as nested procedures for instance. */
if (last_die->has_children
&& (load_all
|| last_die->tag == DW_TAG_namespace
|| last_die->tag == DW_TAG_enumeration_type
+ || last_die->tag == DW_TAG_subprogram
+ || last_die->tag == DW_TAG_lexical_block
|| (cu->language != language_c
&& (last_die->tag == DW_TAG_class_type
|| last_die->tag == DW_TAG_interface_type
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-11 17:55 ` Joel Brobecker
@ 2008-09-11 18:38 ` Daniel Jacobowitz
2008-09-11 21:53 ` Joel Brobecker
2008-09-11 22:44 ` Tom Tromey
0 siblings, 2 replies; 22+ messages in thread
From: Daniel Jacobowitz @ 2008-09-11 18:38 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
On Thu, Sep 11, 2008 at 10:54:22AM -0700, Joel Brobecker wrote:
> > Do you have any performance data for GDB startup with this change?
>
> I am not sure I am doing the right kind of performance test, so if you
> have some better suggestions, please let me know. For now, here is what
> I did:
>
> . I used one of the large Ada applications we have:
> It is 290MB in size - reduced to 160MB when I strip the debugging
> info => the debugging info size is roughly 130MB.
> The number of real lines of code is 700K spread in ~3500 files,
> and it has a total of 39,000 subprograms declared in the debugging
> info.
>
> . To measure the startup time, I used the --statistics command-line
> switch.
I usually use 'gdb -batch foo.exe' to time reading partial symbols,
and 'gdb -readnow -batch foo.exe' to time full symbols (only partial
symbols are at issue here).
> It looks like roughly a 4% increase in startup time. Not sure whether
> that's considered a large increase or not - I just think that it's not
> noticeable. None of our users have reported issues with startup time.
Your users must be more patient than mine or Tom's :-) I consider
startup time to be pretty important, and I've been working on bringing
it down... Tom's been working on an even more drastic version.
> But, to make sure that only languages that have this feature get hit,
> I adjusted the patch to only search nested procedure when the language
> allows them.
Does it work / help to do the check here too:
> && (load_all
> || last_die->tag == DW_TAG_namespace
> || last_die->tag == DW_TAG_enumeration_type
> + || last_die->tag == DW_TAG_subprogram
> + || last_die->tag == DW_TAG_lexical_block
> || (cu->language != language_c
> && (last_die->tag == DW_TAG_class_type
> || last_die->tag == DW_TAG_interface_type
That'll bring the memory usage back down for non-Ada.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-11 18:38 ` Daniel Jacobowitz
@ 2008-09-11 21:53 ` Joel Brobecker
2008-09-13 15:14 ` Daniel Jacobowitz
2008-09-11 22:44 ` Tom Tromey
1 sibling, 1 reply; 22+ messages in thread
From: Joel Brobecker @ 2008-09-11 21:53 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1985 bytes --]
> I usually use 'gdb -batch foo.exe' to time reading partial symbols,
> and 'gdb -readnow -batch foo.exe' to time full symbols (only partial
> symbols are at issue here).
And use the "time" command to measure the time elapsed? Somehow,
I got reported user times and total times that fluctuated a little
more than when I used the --statistics.
> Your users must be more patient than mine or Tom's :-) I consider
> startup time to be pretty important, and I've been working on bringing
> it down... Tom's been working on an even more drastic version.
They must be :). I wish I had time to try to make this time shorter,
but the truth is we some other areas where I think improving performance
is more critical. For instance, we could still do better with symbol
lookups, but we are limited by the fact that we do our lookups by
linkage name. We need to change that, but the initial reason for doing
it that way is that because we had customers whose program was so big
that we exceeded the maximum amount of memory we could allocate. I have
some ideas on how to fix this and hopefully bring Ada back closer to
what C++ does, but that'll have to wait for a moment when things are
less hectic for me.
> Does it work / help to do the check here too:
>
> > && (load_all
> > || last_die->tag == DW_TAG_namespace
> > || last_die->tag == DW_TAG_enumeration_type
> > + || last_die->tag == DW_TAG_subprogram
> > + || last_die->tag == DW_TAG_lexical_block
> > || (cu->language != language_c
> > && (last_die->tag == DW_TAG_class_type
> > || last_die->tag == DW_TAG_interface_type
Sure! Is that what you had in mind?
2008-09-11 Joel Brobecker <brobecker@adacore.com>
* dwarf2read.c (add_partial_subprogram): New procedure.
(scan_partial_symbols): Use it.
(load_partial_dies): Read in children of subprogram and lexical
blocks for Ada compilation units.
Tested on x86-linux, no regression.
--
Joel
[-- Attachment #2: nested.diff --]
[-- Type: text/plain, Size: 4414 bytes --]
diff -r d71d6b13aae1 -r 23f6a0ad1bee gdb/dwarf2read.c
--- a/gdb/dwarf2read.c Wed Sep 10 12:23:56 2008 -0700
+++ b/gdb/dwarf2read.c Thu Sep 11 14:41:11 2008 -0700
@@ -766,6 +766,10 @@ static void add_partial_namespace (struc
static void add_partial_enumeration (struct partial_die_info *enum_pdi,
struct dwarf2_cu *cu);
+
+static void add_partial_subprogram (struct partial_die_info *pdi,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct dwarf2_cu *cu);
static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi,
gdb_byte *info_ptr,
@@ -1783,21 +1787,7 @@ scan_partial_symbols (struct partial_die
switch (pdi->tag)
{
case DW_TAG_subprogram:
- if (pdi->has_pc_info)
- {
- if (pdi->lowpc < *lowpc)
- {
- *lowpc = pdi->lowpc;
- }
- if (pdi->highpc > *highpc)
- {
- *highpc = pdi->highpc;
- }
- if (!pdi->is_declaration)
- {
- add_partial_symbol (pdi, cu);
- }
- }
+ add_partial_subprogram (pdi, lowpc, highpc, cu);
break;
case DW_TAG_variable:
case DW_TAG_typedef:
@@ -2145,6 +2135,51 @@ add_partial_namespace (struct partial_di
if (pdi->has_children)
scan_partial_symbols (pdi->die_child, lowpc, highpc, cu);
+}
+
+/* Read a partial die corresponding to a subprogram and create a partial
+ symbol for that subprogram. When the CU language allows it, this
+ routine also defines a partial symbol for each nested subprogram
+ that this subprogram contains.
+
+ DIE my also be a lexical block, in which case we simply search
+ recursively for suprograms defined inside that lexical block.
+ Again, this is only performed when the CU language allows this
+ type of definitions. */
+
+static void
+add_partial_subprogram (struct partial_die_info *pdi,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct dwarf2_cu *cu)
+{
+ if (pdi->tag == DW_TAG_subprogram)
+ {
+ if (pdi->has_pc_info)
+ {
+ if (pdi->lowpc < *lowpc)
+ *lowpc = pdi->lowpc;
+ if (pdi->highpc > *highpc)
+ *highpc = pdi->highpc;
+ if (!pdi->is_declaration)
+ add_partial_symbol (pdi, cu);
+ }
+ }
+
+ if (! pdi->has_children)
+ return;
+
+ if (cu->language == language_ada)
+ {
+ pdi = pdi->die_child;
+ while (pdi != NULL)
+ {
+ fixup_partial_die (pdi, cu);
+ if (pdi->tag == DW_TAG_subprogram
+ || pdi->tag == DW_TAG_lexical_block)
+ add_partial_subprogram (pdi, lowpc, highpc, cu);
+ pdi = pdi->die_sibling;
+ }
+ }
}
/* See if we can figure out if the class lives in a namespace. We do
@@ -5567,6 +5602,7 @@ load_partial_dies (bfd *abfd, gdb_byte *
&& !is_type_tag_for_partial (abbrev->tag)
&& abbrev->tag != DW_TAG_enumerator
&& abbrev->tag != DW_TAG_subprogram
+ && abbrev->tag != DW_TAG_lexical_block
&& abbrev->tag != DW_TAG_variable
&& abbrev->tag != DW_TAG_namespace
&& abbrev->tag != DW_TAG_member)
@@ -5689,9 +5725,14 @@ load_partial_dies (bfd *abfd, gdb_byte *
sizeof (struct partial_die_info));
/* For some DIEs we want to follow their children (if any). For C
- we have no reason to follow the children of structures; for other
+ we have no reason to follow the children of structures; for other
languages we have to, both so that we can get at method physnames
- to infer fully qualified class names, and for DW_AT_specification. */
+ to infer fully qualified class names, and for DW_AT_specification.
+
+ For Ada, we need to scan the children of subprograms and lexical
+ blocks as well because Ada allows the definition of nested
+ entities that could be interesting for the debugger, such as
+ nested subprograms for instance. */
if (last_die->has_children
&& (load_all
|| last_die->tag == DW_TAG_namespace
@@ -5700,7 +5741,10 @@ load_partial_dies (bfd *abfd, gdb_byte *
&& (last_die->tag == DW_TAG_class_type
|| last_die->tag == DW_TAG_interface_type
|| last_die->tag == DW_TAG_structure_type
- || last_die->tag == DW_TAG_union_type))))
+ || last_die->tag == DW_TAG_union_type))
+ || (cu->language == language_ada
+ && (last_die->tag == DW_TAG_subprogram
+ || last_die->tag == DW_TAG_lexical_block))))
{
nesting_level++;
parent_die = last_die;
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-11 5:01 ` Joel Brobecker
@ 2008-09-11 22:15 ` Tom Tromey
2008-09-11 22:28 ` Daniel Jacobowitz
0 siblings, 1 reply; 22+ messages in thread
From: Tom Tromey @ 2008-09-11 22:15 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
>>>>> "Joel" == Joel Brobecker <brobecker@adacore.com> writes:
Daniel> Not that I see any useful way around it, if subprograms really
Daniel> can be children of lexical blocks.
Tom> Can we do it only for languages where we know this can occur?
Tom> IOW, Ada?
Joel> That's what I was going to propose, but I wanted to do some measurement
Joel> too (tomorrow). Nested subprograms are possible in C, and aren't they
Joel> also available in C++? I don't mind supporting this only in Ada, though.
GNU C has nested functions. Standard C does not. I wrote a simple
test case and compiled it with GCC. The resulting DWARF (I appended a
snippet) does not nest functions here .. but perhaps this is a bug in
GCC, I couldn't say.
I don't know the situation with C++.
Tom
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
< c> DW_AT_stmt_list : 0
<10> DW_AT_high_pc : 0x17
<14> DW_AT_low_pc : 0
<18> DW_AT_producer : GNU C 4.1.2 20070925 (Red Hat 4.1.2-33)
<40> DW_AT_language : 1 (ANSI C)
<41> DW_AT_name : q.c
<45> DW_AT_comp_dir : /tmp
<1><4a>: Abbrev Number: 2 (DW_TAG_subprogram)
<4b> DW_AT_sibling : <84>
<4f> DW_AT_external : 1
<50> DW_AT_name : outer
<56> DW_AT_decl_file : 1
<57> DW_AT_decl_line : 2
<58> DW_AT_prototyped : 1
<59> DW_AT_type : <84>
<5d> DW_AT_low_pc : 0
<61> DW_AT_high_pc : 0xd
<65> DW_AT_frame_base : 0 (location list)
<2><69>: Abbrev Number: 3 (DW_TAG_subprogram)
<6a> DW_AT_name : inner
<70> DW_AT_decl_file : 1
<71> DW_AT_decl_line : 3
<72> DW_AT_prototyped : 1
<73> DW_AT_type : <84>
<77> DW_AT_low_pc : 0xd
<7b> DW_AT_high_pc : 0x17
<7f> DW_AT_frame_base : 0x2c (location list)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-11 22:15 ` Tom Tromey
@ 2008-09-11 22:28 ` Daniel Jacobowitz
2008-09-11 22:33 ` Tom Tromey
2008-09-12 4:19 ` Joel Brobecker
0 siblings, 2 replies; 22+ messages in thread
From: Daniel Jacobowitz @ 2008-09-11 22:28 UTC (permalink / raw)
To: Tom Tromey; +Cc: Joel Brobecker, gdb-patches
On Thu, Sep 11, 2008 at 04:13:24PM -0600, Tom Tromey wrote:
> GNU C has nested functions. Standard C does not. I wrote a simple
> test case and compiled it with GCC. The resulting DWARF (I appended a
> snippet) does not nest functions here .. but perhaps this is a bug in
> GCC, I couldn't say.
Doesn't it?
> <1><4a>: Abbrev Number: 2 (DW_TAG_subprogram)
> <2><69>: Abbrev Number: 3 (DW_TAG_subprogram)
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-11 22:28 ` Daniel Jacobowitz
@ 2008-09-11 22:33 ` Tom Tromey
2008-09-12 4:19 ` Joel Brobecker
1 sibling, 0 replies; 22+ messages in thread
From: Tom Tromey @ 2008-09-11 22:33 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:
Daniel> Doesn't it?
>> <1><4a>: Abbrev Number: 2 (DW_TAG_subprogram)
>> <2><69>: Abbrev Number: 3 (DW_TAG_subprogram)
Yeah, duh. Whoops.
Tom
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-11 18:38 ` Daniel Jacobowitz
2008-09-11 21:53 ` Joel Brobecker
@ 2008-09-11 22:44 ` Tom Tromey
2008-09-12 4:18 ` Joel Brobecker
1 sibling, 1 reply; 22+ messages in thread
From: Tom Tromey @ 2008-09-11 22:44 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:
Joel> . To measure the startup time, I used the --statistics command-line
Joel> switch.
Daniel> I usually use 'gdb -batch foo.exe' to time reading partial
Daniel> symbols
FWIW -- me too.
Joel> It looks like roughly a 4% increase in startup time. Not sure whether
Joel> that's considered a large increase or not - I just think that it's not
Joel> noticeable. None of our users have reported issues with startup time.
How much memory do you have on your machine? Are you using a 32- or
64-bit machine? And how many objfiles are made with this test
program?
I am just curious to know what differs between my tests and yours. In
my case, I start the system OpenOffice writer and then attach to it.
I have all the debuginfo packages installed. I'm using x86, and on
this machine with that test, gdb takes 256569344 bytes (measured by
maint space 1) and it takes about 1:00 elapsed time to start up. I
think there are 262 objfiles created, half of them for separate
debuginfo (this is from memory, I could be off by a little).
Daniel> Your users must be more patient than mine or Tom's :-) I consider
Daniel> startup time to be pretty important, and I've been working on bringing
Daniel> it down... Tom's been working on an even more drastic version.
FWIW I don't think Joel's patch will negatively affect my current
approach.
Tom
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-11 22:44 ` Tom Tromey
@ 2008-09-12 4:18 ` Joel Brobecker
2008-09-12 16:51 ` Tom Tromey
0 siblings, 1 reply; 22+ messages in thread
From: Joel Brobecker @ 2008-09-12 4:18 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> Joel> It looks like roughly a 4% increase in startup time. Not sure whether
> Joel> that's considered a large increase or not - I just think that it's not
> Joel> noticeable. None of our users have reported issues with startup time.
>
> How much memory do you have on your machine? Are you using a 32- or
> 64-bit machine? And how many objfiles are made with this test
> program?
Phew, all these technical questions :). I'm using a 32bit machine
(Intel(R) Core(TM)2 CPU T7400 @ 2.16GHz) with 2GB of memory.
I'm running a 2.6.19.3 Linux kernel.
Because I cannot run the test program (all these large programs that
we got from our customers require a very precise environement to start),
I can only time "gdb EXE". As a result, I think we only end up creating
one object file for that executable.
> I am just curious to know what differs between my tests and yours. In
> my case, I start the system OpenOffice writer and then attach to it.
Yes, that's a little different, because the shared libraries have been
mapped, and so debugging info for these are loaded in as well.
> FWIW I don't think Joel's patch will negatively affect my current
> approach.
Just curious, I think I either forgot a previous discussion or missed
it entirely. What approach are you going to take?
--
Joel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-11 22:28 ` Daniel Jacobowitz
2008-09-11 22:33 ` Tom Tromey
@ 2008-09-12 4:19 ` Joel Brobecker
1 sibling, 0 replies; 22+ messages in thread
From: Joel Brobecker @ 2008-09-12 4:19 UTC (permalink / raw)
To: Tom Tromey, gdb-patches
> > GNU C has nested functions. Standard C does not. I wrote a simple
> > test case and compiled it with GCC. The resulting DWARF (I appended a
> > snippet) does not nest functions here .. but perhaps this is a bug in
> > GCC, I couldn't say.
>
> Doesn't it?
>
> > <1><4a>: Abbrev Number: 2 (DW_TAG_subprogram)
> > <2><69>: Abbrev Number: 3 (DW_TAG_subprogram)
Yes, I confirm it does. The readelf output can be confusing the first
time. That nesting level on the left is hard to notice...
--
Joel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-12 4:18 ` Joel Brobecker
@ 2008-09-12 16:51 ` Tom Tromey
2008-09-12 16:56 ` Joel Brobecker
0 siblings, 1 reply; 22+ messages in thread
From: Tom Tromey @ 2008-09-12 16:51 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
>>>>> "Joel" == Joel Brobecker <brobecker@adacore.com> writes:
Tom> FWIW I don't think Joel's patch will negatively affect my current
Tom> approach.
Joel> Just curious, I think I either forgot a previous discussion or missed
Joel> it entirely.
It is on the archer list.
Joel> What approach are you going to take?
My patch defers reading partial symbol tables until they are needed.
This is done on a per-objfile basis, so some user requests can be
satisfied without reading all the psymbols for the inferior.
FWIW, initial results are pretty good. Attach time drops from 1
minute to 20 seconds, and memory use after attach drops 35% (I
expected more -- I'm curious to know where all the memory goes).
Operations like "bt" still seem responsive.
There are still a couple FIXMEs to sort out. And, I am not completely
sure that I've found all the spots where a call to
require_partial_symbols is needed.
Tom
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-12 16:51 ` Tom Tromey
@ 2008-09-12 16:56 ` Joel Brobecker
2008-09-12 17:19 ` Tom Tromey
0 siblings, 1 reply; 22+ messages in thread
From: Joel Brobecker @ 2008-09-12 16:56 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> Joel> What approach are you going to take?
>
> My patch defers reading partial symbol tables until they are needed.
> This is done on a per-objfile basis, so some user requests can be
> satisfied without reading all the psymbols for the inferior.
Oh, wow. How do you detect when partial symbols are needed or not?
(it's ok if you don't have time to answer my question now - I will
find out anyways when you do submit the patch here, so...)
--
Joel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-12 16:56 ` Joel Brobecker
@ 2008-09-12 17:19 ` Tom Tromey
2008-09-12 17:43 ` Joel Brobecker
0 siblings, 1 reply; 22+ messages in thread
From: Tom Tromey @ 2008-09-12 17:19 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
>>>>> "Joel" == Joel Brobecker <brobecker@adacore.com> writes:
Tom> My patch defers reading partial symbol tables until they are needed.
Tom> This is done on a per-objfile basis, so some user requests can be
Tom> satisfied without reading all the psymbols for the inferior.
Joel> Oh, wow. How do you detect when partial symbols are needed or not?
To find the places needing a call to require_partial_symbols, first I
read a bunch of code, then I ran the test suite, and finally I did
some interactive tests while debugging the modified gdb.
Essentially, the drawback of this approach is that, before writing
code that uses psymbols, you must decide whether they should be loaded
or not.
In some cases, other sorts of changes are appropriate. E.g., I
changed have_partial_symbols() to have two loops -- one that first
checks whether any partial symbols exist, and then a second to try to
demand-load partial symbols.
Joel> (it's ok if you don't have time to answer my question now - I will
Joel> find out anyways when you do submit the patch here, so...)
If you want to see it sooner, I posted it to the archer list.
Also it is in the archer git repository.
Tom
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-12 17:19 ` Tom Tromey
@ 2008-09-12 17:43 ` Joel Brobecker
2008-09-12 18:08 ` Tom Tromey
2008-09-12 18:43 ` Frank Ch. Eigler
0 siblings, 2 replies; 22+ messages in thread
From: Joel Brobecker @ 2008-09-12 17:43 UTC (permalink / raw)
To: Tom Tromey; +Cc: gdb-patches
> Essentially, the drawback of this approach is that, before writing
> code that uses psymbols, you must decide whether they should be loaded
> or not.
I quickly looked at the patch, and it doesn't seem as bad as it sounds.
I just joined the archer list, so we can discuss the details there
when you have found what the issue is with number of symtabs, but
the one thing that I am wondering is how users will respond to an
unexpectedly long delay when entering a command that is usually fast
and yet takes a noticeably long time that one time. For intance, imagine
the following scenario:
% gdb my_300MB_exe
(gdb) break main
[12 secs later...]
Breakpoint 1, ...
--
Joel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-12 17:43 ` Joel Brobecker
@ 2008-09-12 18:08 ` Tom Tromey
2008-09-12 18:43 ` Frank Ch. Eigler
1 sibling, 0 replies; 22+ messages in thread
From: Tom Tromey @ 2008-09-12 18:08 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
>>>>> "Joel" == Joel Brobecker <brobecker@adacore.com> writes:
Joel> but the one thing that I am wondering is how users will respond
Joel> to an unexpectedly long delay when entering a command that is
Joel> usually fast and yet takes a noticeably long time that one
Joel> time. For intance, imagine the following scenario:
Joel> % gdb my_300MB_exe
Joel> (gdb) break main
Joel> [12 secs later...]
Joel> Breakpoint 1, ...
Yeah, I wonder that too.
One thing to note is that, on average, we should expect the delay here
to be half of the startup delay that users experience today. My
reasoning is that, on average, we should only have to load half the
psymtabs before finding a symbol. (Of course, the worst case does
happen regularly, so this is not entirely satisfactory.)
I will do some more tests and fixing of this patch sometime soon. If
this is a big problem perhaps I'll reopen the pubnames investigation.
Or maybe we can use the minimal symbols as a guide somehow, in some
common cases (or maybe we do already, I did not look at this in
depth). (FWIW I'm also curious about lazily reading minimal symbols.)
Tom
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-12 17:43 ` Joel Brobecker
2008-09-12 18:08 ` Tom Tromey
@ 2008-09-12 18:43 ` Frank Ch. Eigler
2008-09-12 20:31 ` Tom Tromey
1 sibling, 1 reply; 22+ messages in thread
From: Frank Ch. Eigler @ 2008-09-12 18:43 UTC (permalink / raw)
To: Joel Brobecker; +Cc: Tom Tromey, gdb-patches
Joel Brobecker <brobecker@adacore.com> writes:
>>[...]
> the one thing that I am wondering is how users will respond to an
> unexpectedly long delay when entering a command that is usually fast
> and yet takes a noticeably long time that one time. [...]
Could gdb use something like alarm(2) to issue progress notifications?
- FChE
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-12 18:43 ` Frank Ch. Eigler
@ 2008-09-12 20:31 ` Tom Tromey
0 siblings, 0 replies; 22+ messages in thread
From: Tom Tromey @ 2008-09-12 20:31 UTC (permalink / raw)
To: Frank Ch. Eigler; +Cc: Joel Brobecker, gdb-patches
Joel> the one thing that I am wondering is how users will respond to an
Joel> unexpectedly long delay when entering a command that is usually fast
Joel> and yet takes a noticeably long time that one time. [...]
Frank> Could gdb use something like alarm(2) to issue progress notifications?
One open question with this patch is what to do about notifications.
There are two things to consider.
One problem is that gdb prints "(no debugging symbols found)" when
reading partial symbols. With lazy loading, this is always printed,
even though it is not correct. In my patch I removed this code. This
is not really satisfying, at least if we assume that people want and
pay attention to these messages (I certainly have on occasion).
The other problem is whether to print something when reading partial
symbols. This is a problem because it might print any time,
potentially messing up other output.
I'm not sure how this affects MI.
Tom
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-11 21:53 ` Joel Brobecker
@ 2008-09-13 15:14 ` Daniel Jacobowitz
2008-09-13 22:21 ` Joel Brobecker
0 siblings, 1 reply; 22+ messages in thread
From: Daniel Jacobowitz @ 2008-09-13 15:14 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
On Thu, Sep 11, 2008 at 02:52:24PM -0700, Joel Brobecker wrote:
> > I usually use 'gdb -batch foo.exe' to time reading partial symbols,
> > and 'gdb -readnow -batch foo.exe' to time full symbols (only partial
> > symbols are at issue here).
>
> And use the "time" command to measure the time elapsed? Somehow,
> I got reported user times and total times that fluctuated a little
> more than when I used the --statistics.
Yes, I have a script to time things repeatedly and give me
average/stddev.
> Sure! Is that what you had in mind?
>
> 2008-09-11 Joel Brobecker <brobecker@adacore.com>
>
> * dwarf2read.c (add_partial_subprogram): New procedure.
> (scan_partial_symbols): Use it.
> (load_partial_dies): Read in children of subprogram and lexical
> blocks for Ada compilation units.
>
> Tested on x86-linux, no regression.
Yes, this is OK. I agree it's the right compromise, at least for the
moment.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms
2008-09-13 15:14 ` Daniel Jacobowitz
@ 2008-09-13 22:21 ` Joel Brobecker
0 siblings, 0 replies; 22+ messages in thread
From: Joel Brobecker @ 2008-09-13 22:21 UTC (permalink / raw)
To: gdb-patches
> > 2008-09-11 Joel Brobecker <brobecker@adacore.com>
> >
> > * dwarf2read.c (add_partial_subprogram): New procedure.
> > (scan_partial_symbols): Use it.
> > (load_partial_dies): Read in children of subprogram and lexical
> > blocks for Ada compilation units.
> >
> > Tested on x86-linux, no regression.
>
> Yes, this is OK. I agree it's the right compromise, at least for the
> moment.
Thanks! Now checked in.
--
Joel
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2008-09-13 22:21 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-10 20:20 [RFA/commit/dwarf] Create partial symbols for nested subprograms Joel Brobecker
2008-09-10 20:35 ` Daniel Jacobowitz
2008-09-10 21:38 ` Tom Tromey
2008-09-11 5:01 ` Joel Brobecker
2008-09-11 22:15 ` Tom Tromey
2008-09-11 22:28 ` Daniel Jacobowitz
2008-09-11 22:33 ` Tom Tromey
2008-09-12 4:19 ` Joel Brobecker
2008-09-11 17:55 ` Joel Brobecker
2008-09-11 18:38 ` Daniel Jacobowitz
2008-09-11 21:53 ` Joel Brobecker
2008-09-13 15:14 ` Daniel Jacobowitz
2008-09-13 22:21 ` Joel Brobecker
2008-09-11 22:44 ` Tom Tromey
2008-09-12 4:18 ` Joel Brobecker
2008-09-12 16:51 ` Tom Tromey
2008-09-12 16:56 ` Joel Brobecker
2008-09-12 17:19 ` Tom Tromey
2008-09-12 17:43 ` Joel Brobecker
2008-09-12 18:08 ` Tom Tromey
2008-09-12 18:43 ` Frank Ch. Eigler
2008-09-12 20:31 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox