From: Andrew Burgess <aburgess@redhat.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCHv2 2/3] gdb: introduce program_space::get_entry_point_info function
Date: Mon, 15 Jun 2026 11:14:38 +0100 [thread overview]
Message-ID: <87ik7kp0tt.fsf@redhat.com> (raw)
In-Reply-To: <86ecicnvfk.fsf@gnu.org>
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Andrew Burgess <aburgess@redhat.com>
>> Cc: Andrew Burgess <aburgess@redhat.com>
>> Date: Thu, 11 Jun 2026 22:59:05 +0100
>>
>> I noticed that when debugging a dynamically linked executable, if I
>> started the inferior with 'starti' then used 'bt' I would see some
>> bogus frames:
>>
>> (gdb) starti
>> Starting program: /tmp/hello
>>
>> Program stopped.
>> 0x00007ffff7fd3110 in _start () from /lib64/ld-linux-x86-64.so.2
>> (gdb) bt
>> #0 0x00007ffff7fd3110 in _start () from /lib64/ld-linux-x86-64.so.2
>> #1 0x0000000000000001 in ?? ()
>> #2 0x00007fffffffac13 in ?? ()
>> #3 0x0000000000000000 in ?? ()
>> (gdb)
>>
>> This surprised me as 'backtrace past-entry' was off:
>>
>> (gdb) show backtrace past-entry
>> Whether backtraces should continue past the entry point of a program is off.
>>
>> I was expecting GDB to stop the backtrace at the inferior's entry
>> address.
>>
>> Frame unwinding starts in get_prev_frame, and in here we find this
>> block:
>>
>> if (this_frame->level >= 0
>> && get_frame_type (this_frame) == NORMAL_FRAME
>> && !user_set_backtrace_options.backtrace_past_entry
>> && frame_pc.has_value ()
>> && inside_entry_func (this_frame))
>> {
>> frame_debug_got_null_frame (this_frame, "inside entry func");
>> return NULL;
>> }
>>
>> Which uses inside_entry_func to terminate the backtrace when we reach
>> the entry frame. The inside_entry_func function calls
>> current_program_space->exec_entry_point_address_if_available and uses
>> the result to figure out if we are in the entry frame.
>>
>> And here the problem becomes obvious, we are only checking if we are
>> in the "entry frame" for the main executable, not for the inferior as
>> a whole. And indeed, if I compile the same test program as a static
>> binary, where there will be no run-time linker, and the entry point of
>> the executable is the entry point for the inferior, then the 'bt'
>> problem I saw above goes away.
>>
>> This suggests, I think, that we need to track two different entry
>> addresses, the entry address for the executable file, and the entry
>> address for the entire inferior. Then, for dynamically linked
>> executables, these two addresses can be different, the former will
>> still be the same address within the main executable file, while the
>> latter will be the address of the entry point within the run-time
>> linker.
>>
>> If we had this information then we could extend inside_entry_func to
>> check both addresses, and the 'bt' problem seen above will be
>> resolved.
>>
>> To make this information available I added a new solib_ops method,
>> solib_ops::inferior_entry_point_address, for svr4 targets this figures
>> out if the main executable is dynamically linked, and if it is, finds
>> the run-time linker and uses that to compute the entry address.
>>
>> I then added program_space::get_entry_point_info, which returns a
>> struct containing the two entry point addresses, one comes from the
>> new solib_ops method, and one comes from the existing method
>> program_space::exec_entry_point_address_if_available.
>>
>> With the infrastructure in place I can then update inside_entry_func
>> to check against both entry addresses.
>>
>> To aid in debugging GDB, I added a new maintenance command:
>>
>> maintenance info entry-address
>>
>> which just calls program_space::get_entry_point_info and then prints
>> the two addresses. I left this as a maintenance command as I don't
>> see much user utility in this right now, but it made it easier for me
>> to see what GDB was doing, so I left the command in this commit.
>> ---
>> gdb/NEWS | 7 +
>> gdb/doc/gdb.texinfo | 14 ++
>> gdb/frame.c | 10 +-
>> gdb/progspace.c | 60 ++++++++
>> gdb/progspace.h | 48 +++++++
>> gdb/solib-svr4.c | 102 ++++++++++++++
>> gdb/solib-svr4.h | 1 +
>> gdb/solib.h | 14 ++
>> gdb/testsuite/gdb.base/bt-after-starti.exp | 153 +++++++++++++++++++++
>> 9 files changed, 404 insertions(+), 5 deletions(-)
>> create mode 100644 gdb/testsuite/gdb.base/bt-after-starti.exp
>>
>> diff --git a/gdb/NEWS b/gdb/NEWS
>> index d5214a98a57..99c9fb6999c 100644
>> --- a/gdb/NEWS
>> +++ b/gdb/NEWS
>> @@ -146,6 +146,13 @@ disable skip
>> These are new aliases for 'skip delete', 'skip enable', and 'skip
>> disable' respectively.
>>
>> +maint info entry-address
>> + Display the inferior and main executable entry addresses for the
>> + current inferior. The inferior entry address is the address of the
>> + first instruction in the inferior that was executed. The main
>> + executable entry address is the address of the first instruction in
>> + the main executable that was executed.
>> +
>> * MI changes
>>
>> ** The "-trace-save" command no longer supports the "-ctf" flag.
>> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
>> index a698b2b8451..dd6cfd04011 100644
>> --- a/gdb/doc/gdb.texinfo
>> +++ b/gdb/doc/gdb.texinfo
>> @@ -43212,6 +43212,20 @@ Maintenance Commands
>> Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M
>> Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M
>> @end smallexample
>> +
>> +@kindex maint info entry-address
>> +@item maint info entry-address
>> +Display the entry addresses for the currently selected inferior. Two
>> +addresses are displayed, the first is the address of the first
>> +instruction in the inferior, and the second is for the first
>> +instruction in the main executable, see @kbd{file} in @ref{Files,
>> +,Commands to Specify Files}.
>> +
>> +For statically linked inferiors, these addresses will usually be the
>> +same, but for dynamically linked executables these addresses can be
>> +different, with the inferior's entry address being an address within
>> +the run-time linker, while the main executable's entry address will
>> +always be an address within the executable file.
>> @end table
>
> Thanks, the documentation parts are okay. Although I would suggest to
> perhaps clarify the description in the manual by explaining how these
> addresses are related to the first instruction in the 'main' function
> of the program. As written, the description is highly-technical, and
> I think it will only be clear enough for people who are intimately
> familiar with the program's startup code on different systems.
>
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
I rewrote the doc/ part to try and make it more approachable. I
included some text describing how the reported addresses relate to the
address of 'main', and why the inferior entry address exists, and is
different for dynamically linked executables. Obviously the text
relating to dynamically linked executables is a massive simplification,
but I don't see it as our job to be teaching about dynamic linking, I
figure what I've written is correct enough.
If I don't hear any feedback I'll assume this is OK.
Thanks,
Andrew
---
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index a698b2b8451..4c0c4709a23 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -43212,6 +43212,28 @@ Maintenance Commands
Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M
Ignoring SystemTap probe libc longjmp in /lib64/libc.so.6.^M
@end smallexample
+
+@kindex maint info entry-address
+@item maint info entry-address
+Display the entry addresses for the currently selected inferior. Two
+addresses are displayed, the inferior entry address and the executable
+entry address.
+
+Neither address is the address of @code{main}. When a program is
+started, low-level startup code (typically a function called
+@code{_start}) runs before @code{main} is called.
+
+The executable entry address is the address of this startup code
+within the main executable (@pxref{Files, ,Commands to Specify
+Files}).
+
+The inferior entry address is the address of the very first
+instruction executed when the inferior is started. For statically
+linked programs this is the same as the executable entry address. For
+dynamically linked programs the run-time linker must execute first in
+order to load shared libraries, so the inferior entry address will be
+an address within the run-time linker rather than within the main
+executable.
@end table
The following command is useful for non-interactive invocations of
next prev parent reply other threads:[~2026-06-15 10:15 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-08 18:14 [PATCH] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-11 19:24 ` Guinevere Larsen
2026-06-11 20:40 ` Andrew Burgess
2026-06-12 12:49 ` Guinevere Larsen
2026-06-11 21:59 ` [PATCHv2 0/3] " Andrew Burgess
2026-06-11 21:59 ` [PATCHv2 1/3] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-12 15:41 ` Pedro Alves
2026-06-11 21:59 ` [PATCHv2 2/3] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-12 6:07 ` Eli Zaretskii
2026-06-15 10:14 ` Andrew Burgess [this message]
2026-06-15 12:01 ` Eli Zaretskii
2026-06-12 15:41 ` Pedro Alves
2026-06-15 10:29 ` Andrew Burgess
2026-06-16 18:36 ` Pedro Alves
2026-06-23 9:46 ` Andrew Burgess
2026-06-23 10:20 ` Pedro Alves
2026-06-11 21:59 ` [PATCHv2 3/3] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-12 15:57 ` Pedro Alves
2026-06-16 19:47 ` [PATCHv3 0/4] " Andrew Burgess
2026-06-16 19:47 ` [PATCHv3 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-16 19:47 ` [PATCHv3 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-17 11:52 ` Eli Zaretskii
2026-06-16 19:47 ` [PATCHv3 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-16 19:47 ` [PATCHv3 4/4] gdb: cache program space entry point information Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 4/4] gdb: cache program space entry point information Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 4/4] gdb: cache program space entry point information Andrew Burgess
2026-07-10 14:24 ` [PATCHv6 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-10 14:24 ` [PATCHv6 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-07-10 14:24 ` [PATCHv6 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-07-10 15:39 ` Simon Marchi
2026-07-10 14:24 ` [PATCHv6 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-10 17:00 ` Simon Marchi
2026-07-10 17:01 ` Simon Marchi
2026-07-16 15:06 ` Andrew Burgess
2026-07-10 14:24 ` [PATCHv6 4/4] gdb: cache program space entry point information Andrew Burgess
2026-07-10 17:07 ` Simon Marchi
2026-07-18 13:11 ` [PATCHv7 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-18 13:11 ` [PATCHv7 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-07-18 13:11 ` [PATCHv7 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-07-18 13:11 ` [PATCHv7 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-18 13:11 ` [PATCHv7 4/4] gdb: cache program space entry point information Andrew Burgess
2026-07-20 9:52 ` [PATCHv8 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-20 9:52 ` [PATCHv8 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-07-20 9:52 ` [PATCHv8 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-07-20 9:52 ` [PATCHv8 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-20 9:52 ` [PATCHv8 4/4] gdb: cache program space entry point information Andrew Burgess
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=87ik7kp0tt.fsf@redhat.com \
--to=aburgess@redhat.com \
--cc=eliz@gnu.org \
--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