From: Simon Marchi via Gdb <gdb@sourceware.org>
To: psmith@gnu.org, gdb@sourceware.org
Subject: Re: GDB 13.2: breakpoint at wrong line after unrelated change
Date: Mon, 11 Mar 2024 15:50:38 -0400 [thread overview]
Message-ID: <06c7a0d1-6ba7-440a-a21a-616ed05cb5b0@simark.ca> (raw)
In-Reply-To: <7fcf12fbd4a106af488168d0e740e0d8ca9b3022.camel@gnu.org>
On 3/11/24 15:38, Paul Smith via Gdb wrote:
> On Mon, 2024-03-11 at 15:14 -0400, Simon Marchi wrote:
>>> I have noticed that if I only include the templated function
>>> definition but don't call it, then the problem doesn't happen.
>>
>> When you say that, does it mean that you just define the templated
>> function, or do you manually instantiate it? In other words, does it
>> cause any code to be generated?
>
> If I just define the templated function I don't see the issue. If I
> invoke the templated function, I get the problem.
>
> FYI I'm switching to the fmt library (if you're familiar with that)
Yes, I love it, we should use it in GDB :).
> and
> the templated function invokes it; it's something like this:
>
> void criticalErrorV(fmt::string_view fmt, const char *file, int line,
> fmt::format_args args);
>
> template <typename... Args>
> void criticalError(fmt::format_string<Args...> fmt,
> const char* file, int line, Args &&...args)
> {
> criticalErrorV(fmt, file, line, fmt::make_format_args(args...));
> }
>
> If I never call criticalError() then it works fine (or in my previous
> implementation, which used printf-style calls with stdarg, it worked
> fine as well).
If you never call it, if never generates code, so it kinda make sense
that it doesn't change anything.
> If I have some invocation of criticalError() somewhere in the
> translation unit, I get this problem. I haven't checked moving it
> around to see if it needs to be invoked before/after the "problem"
> method in the TU to get this behavior.
>
>> I don't really have an idea of what's happening, but you could try
>> showing what the "disas" command shows after hitting the breakpoint
>> in both cases (the `=>` should show where you are stopped, so where
>> the breakpoint was set).
>
> Good idea; here's what I get for the correct behavior:
>
> 0x000000000053209c <+0>: push %rbp
> 0x000000000053209d <+1>: mov %rsp,%rbp
> 0x00000000005320a0 <+4>: lea -0x10(%rsp),%rsp
> 0x00000000005320a5 <+9>: mov %rdi,-0x8(%rbp)
> 0x00000000005320a9 <+13>: mov %rsi,-0x10(%rbp)
> => 0x00000000005320ad <+17>: mov -0x10(%rbp),%rax
> 0x00000000005320b1 <+21>: mov %rax,%rsi
> 0x00000000005320b4 <+24>: lea 0x17e9a9(%rip),%rax # 0x6b0a64
> 0x00000000005320bb <+31>: mov %rax,%rdi
> 0x00000000005320be <+34>: mov $0x0,%eax
> 0x00000000005320c3 <+39>: call 0x52bc00 <printf@plt>
> 0x00000000005320c8 <+44>: nop
> 0x00000000005320c9 <+45>: mov %rbp,%rsp
> 0x00000000005320cc <+48>: pop %rbp
> 0x00000000005320cd <+49>: ret
>
> Here's what I get for the incorrect behavior:
>
> => 0x00000000005320ee <+0>: push %rbp
> 0x00000000005320ef <+1>: mov %rsp,%rbp
> 0x00000000005320f2 <+4>: lea -0x10(%rsp),%rsp
> 0x00000000005320f7 <+9>: mov %rdi,-0x8(%rbp)
> 0x00000000005320fb <+13>: mov %rsi,-0x10(%rbp)
> 0x00000000005320ff <+17>: mov -0x10(%rbp),%rax
> 0x0000000000532103 <+21>: mov %rax,%rsi
> 0x0000000000532106 <+24>: lea 0x17e9d6(%rip),%rax # 0x6b0ae3
> 0x000000000053210d <+31>: mov %rax,%rdi
> 0x0000000000532110 <+34>: mov $0x0,%eax
> 0x0000000000532115 <+39>: call 0x52bc00 <printf@plt>
> 0x000000000053211a <+44>: nop
> 0x000000000053211b <+45>: mov %rbp,%rsp
> 0x000000000053211e <+48>: pop %rbp
> 0x000000000053211f <+49>: ret
>
> It seems to have given up and just picked the first instruction :)
>
> Here's the compile line args (removed extraneous stuff like warnings
> and preprocessor options):
>
> g++ -std=gnu++20 -ggdb3 -fPIC -march=haswell -mtune=intel \
> -fno-omit-frame-pointer -O0 -pthread \
> -o TestClass.o -c TestClass.cpp
Ok, so clearly GDB failed to analyze the prologue. Which is weird
because the two functions are identical (modulo the addresses). To get
to the bottom of this, you (or someone else) would need to debug GDB
itself. If you want to do this, I would start at function
skip_prologue_using_sal, in symtab.c. Off hand, I don't think we have a
debug switch to enable logging for prologue skipping. It would be
useful to have some here, as we would be able to compare the logging
shown in both cases.
When you have DWARF debug info (which is your case), prologue skipping
is done using the DWARF line tables. You could try to extract the line
tables for both versions of the function and see what's different. But
that would probably only be useful if you're debugging GDB already.
Simon
next prev parent reply other threads:[~2024-03-11 19:51 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-11 18:28 Paul Smith via Gdb
2024-03-11 19:14 ` Simon Marchi via Gdb
2024-03-11 19:38 ` Paul Smith via Gdb
2024-03-11 19:50 ` Simon Marchi via Gdb [this message]
2024-03-11 20:17 ` Paul Smith via Gdb
2024-03-15 21:11 ` Paul Smith via Gdb
2024-03-15 22:19 ` Paul Smith via Gdb
2024-03-16 16:33 ` Simon Marchi via Gdb
2024-03-16 19:57 ` Paul Smith via Gdb
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=06c7a0d1-6ba7-440a-a21a-616ed05cb5b0@simark.ca \
--to=gdb@sourceware.org \
--cc=psmith@gnu.org \
--cc=simark@simark.ca \
/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