From: Joel Brobecker <brobecker@adacore.com>
To: gdb-patches@sourceware.org
Subject: [RFA/DWARF2] Handle nested subprograms in CU pc bound calculation
Date: Tue, 30 Sep 2008 15:28:00 -0000 [thread overview]
Message-ID: <20080930152757.GC23135@adacore.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 2575 bytes --]
Hello,
We just recently encountered a situation where GDB was emitting the following
warning:
| (gdb) b f1
| warning: (Internal error: pc 0x80495ce in read in psymtab, but not in symtab.)
| warning: (Internal error: pc 0x80495d1 in read in psymtab, but not in symtab.)
| warning: (Internal error: pc 0x80495d1 in read in psymtab, but not in symtab.)
| warning: (Internal error: pc 0x80495d1 in read in psymtab, but not in symtab.)
| Breakpoint 1 at 0x80495d1: file gen1.adb, line 3.
This happened after compiling the CU with -ffunction-sections, and
is related to the fact that f1 is a nested subprogram. The code looks
like this:
procedure Foo is
procedure F1 is new Gen;
begin
...
Here is what happens:
1. When compiling with -ffunction-sections, the compiler is not
providing the CU PC bounds (DW_AT_low_pc and DW_AT_high_pc).
I would imagine that this is because functions might be removed
later during the link, and thus bounds might be affected.
2. As a result, GDB ends up having to compute the PC bounds itself
by inspecting the children of the CU. This is done inside
get_scope_pc_bounds. However, this function only handles
non-nested functions. As a result, after having determined
the bounds of the main procedure Foo, it goes directly to
the next sibling of that function, past the two nested
subprograms. The net effect is that the low/high PC range
is too short, missing the range for our nested subprogram.
3. Later, when the user inserts a breakpoint on the nested
subprogram, GDB finds symbol f1, converts the associated
psymtab into a symtab, and then tries to find the first
"real" line of code, and so ends up searching the symtab
associated to a PC inside our subprogram. The search
among known symtabs fails because of the incorrect PC bounds.
So the next step is searching through the psymtabs, where
we find the correct one, and realize that it has already
been read in, meaning that the previous search should have
found it -> warning.
The attached patch fixes this problem by handling nested subprograms.
Similarly to what was done earlier, I am limiting this to languages
that allow nested subprogram, which means only Ada for now. Other
languages should be unaffected.
2008-09-30 Joel Brobecker <brobecker@adacore.com>
* dwarf2read.c (dwarf2_get_subprogram_pc_bounds): New function.
(get_scope_pc_bounds): Use it.
Tested on x86-linux. No regression. Any objection?
Thanks,
--
Joel
[-- Attachment #2: dwarf2read.c.diff --]
[-- Type: text/plain, Size: 2401 bytes --]
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.284
diff -u -p -r1.284 dwarf2read.c
--- dwarf2read.c 23 Sep 2008 17:36:51 -0000 1.284
+++ dwarf2read.c 30 Sep 2008 14:54:29 -0000
@@ -3324,6 +3324,43 @@ dwarf2_get_pc_bounds (struct die_info *d
return ret;
}
+/* Assuming that DIE represents a subprogram DIE or a lexical block, get
+ its low and high PC addresses. Do nothing if these addresses could not
+ be determined. Otherwise, set LOWPC to the low address if it is smaller,
+ and HIGHPC to the high address if greater than HIGHPC. */
+
+static void
+dwarf2_get_subprogram_pc_bounds (struct die_info *die,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct dwarf2_cu *cu)
+{
+ CORE_ADDR low, high;
+ struct die_info *child = die->child;
+
+ if (dwarf2_get_pc_bounds (die, &low, &high, cu))
+ {
+ *lowpc = min (*lowpc, low);
+ *highpc = max (*highpc, high);
+ }
+
+ /* If the language does not allow nested subprograms (either inside
+ subprograms or lexical blocks), we're done. */
+ if (cu->language != language_ada)
+ return;
+
+ /* Check all the children of the given DIE. If it contains nested
+ subprograms, then check their pc bounds. Likewise, we need to
+ check lexical blocks as well, as they may also contain subprogram
+ definitions. */
+ while (child && child->tag)
+ {
+ if (child->tag == DW_TAG_subprogram
+ || child->tag == DW_TAG_lexical_block)
+ dwarf2_get_subprogram_pc_bounds (child, lowpc, highpc, cu);
+ child = sibling_die (child);
+ }
+}
+
/* Get the low and high pc's represented by the scope DIE, and store
them in *LOWPC and *HIGHPC. If the correct values can't be
determined, set *LOWPC to -1 and *HIGHPC to 0. */
@@ -3350,11 +3387,7 @@ get_scope_pc_bounds (struct die_info *di
{
switch (child->tag) {
case DW_TAG_subprogram:
- if (dwarf2_get_pc_bounds (child, ¤t_low, ¤t_high, cu))
- {
- best_low = min (best_low, current_low);
- best_high = max (best_high, current_high);
- }
+ dwarf2_get_subprogram_pc_bounds (child, &best_low, &best_high, cu);
break;
case DW_TAG_namespace:
/* FIXME: carlton/2004-01-16: Should we do this for
next reply other threads:[~2008-09-30 15:28 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-30 15:28 Joel Brobecker [this message]
2008-09-30 15:43 ` Pierre Muller
2008-09-30 17:07 ` Joel Brobecker
2008-09-30 17:39 ` Daniel Jacobowitz
2008-10-01 1:16 ` Joel Brobecker
2008-10-01 7:43 ` Pierre Muller
2008-10-01 8:33 ` [Core] " Jonas Maebe
2008-10-01 16:40 ` Joel Brobecker
2008-10-01 21:56 ` [Core] " Jonas Maebe
2008-10-02 6:45 ` Daniël Mantione
2008-10-02 9:07 ` Pierre Muller
2008-10-02 10:36 ` Daniël Mantione
2008-10-03 0:31 ` Joel Brobecker
2008-09-30 15:43 ` Daniel Jacobowitz
2008-09-30 16:56 ` Joel Brobecker
2008-09-30 17:05 ` Daniel Jacobowitz
2008-09-30 16:58 ` Joel Brobecker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080930152757.GC23135@adacore.com \
--to=brobecker@adacore.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox