[PATCH] gdb: continue start command if 'main' can be resolved
Rohr, Stephan
stephan.rohr@intel.com
Fri Dec 6 10:08:31 GMT 2024
Hi Guinevere,
thanks for your feedback.
I agree on your concerns, 'main_name ()' might not be the best solution for this issue.
I also think that moving the whole breakpoint setup into 'start_command' is not
feasible. I modified ' run_command_1' to report an error if the (temporary) breakpoint
cannot be inserted, this also fixes the issue. I had to do some modifications:
* Make 'break_command_1' externally visible.
* Use 'break_command_1' to insert the temporary breakpoint instead of 'tbreak_command'.
I wonder if making 'break_command_1' externally visible could be an acceptable solution?
Thanks
Stephan
> -----Original Message-----
> From: Guinevere Larsen <guinevere@redhat.com>
> Sent: Wednesday, 4 December 2024 14:44
> To: Rohr, Stephan <stephan.rohr@intel.com>; gdb-patches@sourceware.org
> Subject: Re: [PATCH] gdb: continue start command if 'main' can be resolved
>
> On 12/4/24 10:16 AM, Stephan Rohr wrote:
> > From: "Rohr, Stephan" <stephan.rohr@intel.com>
> >
> > GDB aborts the 'start' command if the minimal symbols cannot be
> > resolved. On Windows, GDB reads the minimal symbols from the COFF
> > header of the PE file. The symbol table is deprecated and the
> > number of symbols in the COFF header may be zero [1]. For example,
> > the LLVM clang compiler for Windows MSVC can be instructed to generate
> > DWARF:
> >
> > clang++ -g -O0 -gdwarf -fuse-ld=lld test.cpp -o test_clang
> >
> > The corresponding COFF file header shows:
> >
> > FILE HEADER VALUES
> > 8664 machine (x64)
> > E number of sections
> > 66E889EC time date stamp Mon Sep 16 21:41:32 2024
> > FB400 file pointer to symbol table
> > 0 number of symbols
> > F0 size of optional header
> > 22 characteristics
> >
> > GDB is not able to read the minimal symbols; the `start' command fails
> > with an error:
> >
> > (gdb) start
> > No symbol table loaded. Use the "file" command.
> >
> > Manually inserting a breakpoint in main works fine:
> >
> > (gdb) tbreak main
> > Temporary breakpoint 1 at 0x14000100c: file test.cpp, line 6.
> > (gdb) run
> > Starting program: C:\test-clang
> >
> > Temporary breakpoint 1, main () at test.cpp:6
> > 6 std::cout << "Hello World.\n";
> >
> > Fix this by testing if `main' can be resolved instead of checking the
> > minimal symbol table:
> >
> > (gdb) start
> > Temporary breakpoint 1 at 0x14000100c: file test.cpp, line 6.
> > Starting program: C:\test-clang
> >
> > Temporary breakpoint 1, main () at test.cpp:6
> > 6 std::cout << "Hello World.\n";
> > (gdb)
> >
> > [1]: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format
> > ---
> > gdb/infcmd.c | 9 +++++----
> > 1 file changed, 5 insertions(+), 4 deletions(-)
> >
> > diff --git a/gdb/infcmd.c b/gdb/infcmd.c
> > index 5c0e3f51162..39b7e50b582 100644
> > --- a/gdb/infcmd.c
> > +++ b/gdb/infcmd.c
> > @@ -516,10 +516,11 @@ run_command (const char *args, int from_tty)
> > static void
> > start_command (const char *args, int from_tty)
> > {
> > - /* Some languages such as Ada need to search inside the program
> > - minimal symbols for the location where to put the temporary
> > - breakpoint before starting. */
> > - if (!have_minimal_symbols (current_program_space))
> > + /* Abort the start command if `main` cannot be resolved, e.g., the
> > + minimal / partial symbols are not available. Some languages such
> > + as Ada need to search inside the program minimal symbols for the
> > + location where to put the temporary breakpoint before starting. */
> > + if (main_name () == nullptr)
> > error (_("No symbol table loaded. Use the \"file\" command."));
> >
> > /* Run the program until reaching the main procedure... */
>
> I agree that minimal symbols shouldn't be required (obviously by your
> example), but I don't think knowing the name of the main function is enough.
>
> If you look at how main_name works, it calls find_main_name if the name
> isn't cached yet, and find_main_name has a default fallback of guessing
> "main" with an unknown language if needed. In other words, even if we
> can't find that data in the inferior, we'll still guess something. I
> bring this up because if there is no minimal symbols and no debug info,
> I think GDB wouldn't be able to set a breakpoint because main can't be
> translated in any way, and so "start" would end up being silently
> converted to "run" and confuse the user. If this assumption is wrong,
> feel free to ignore the rest of the message.
>
> I think the central issue for whether "start" works should be whether we
> can set the temporary breakpoint or not, rather than whether we can
> guess where to set it. I'm not sure if setting the tbreak would be
> possible here in the start_command due to all the preparatory work in
> run_command_1 before setting the bp (especially due to the commend in
> infcmd.c:411), but I think it would be ideal if it is possible. If that
> doesn't work, I would imagine run_command_1 should check if
> tbreak_command succeeds and return early if it fails. The issues with
> this second strategy is that the inferior is stopped and info is cleared
> before we're sure that we can run the full command, which is pretty
> annoying for the user, but I'it might be better than having to set a
> breakpoint twice (in case someone is using a slow connection to a
> gdbserver, for instance).
>
> --
> Cheers,
> Guinevere Larsen
> She/Her/Hers
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
More information about the Gdb-patches
mailing list