public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: Simon Marchi <simark@simark.ca>, gdb-patches@sourceware.org
Cc: Pedro Alves <pedro@palves.net>
Subject: Re: [PATCHv3 1/3] gdb: more debug output for displaced stepping
Date: Wed, 29 Mar 2023 10:42:49 +0100	[thread overview]
Message-ID: <87bkkbevvq.fsf@redhat.com> (raw)
In-Reply-To: <fc5050c6-c433-1b8a-d5c9-4fc2ec2fb007@simark.ca>

Simon Marchi <simark@simark.ca> writes:

> On 3/28/23 11:08, Andrew Burgess wrote:
>> Simon Marchi <simark@simark.ca> writes:
>> 
>>> On 3/27/23 08:32, Andrew Burgess wrote:
>>>> While investigating a displaced stepping issue I wanted an easy way to
>>>> see what GDB thought the original instruction was, and what
>>>> instruction GDB replaced that with when performing the displaced step.
>>>>
>>>> We do print out the address that is being stepped, so I can track down
>>>> the original instruction, I just need to go find the information
>>>> myself.
>>>>
>>>> And we do print out the bytes of the new instruction, so I can figure
>>>> out what the replacement instruction was, but it's not really easy.
>>>>
>>>> Also, the code that prints the bytes of the replacement instruction
>>>> only prints 4 bytes, which clearly isn't always going to be correct.
>>>>
>>>> In this commit I remove the existing code that prints the bytes of the
>>>> replacement instruction, and add two new blocks of code to
>>>> displaced_step_prepare_throw.  This new code prints the original
>>>> instruction, and the replacement instruction.  In each case we print
>>>> both the bytes that make up the instruction and the completely
>>>> disassembled instruction.
>>>>
>>>> Here's an example of what the output looks like on x86-64 (this is
>>>> with 'set debug displaced on').  The two interesting lines contain the
>>>> strings 'original insn' and 'replacement insn':
>>>>
>>>>   (gdb) step
>>>>   [displaced] displaced_step_prepare_throw: displaced-stepping 2892655.2892655.0 now
>>>>   [displaced] displaced_step_prepare_throw: original insn 0x401030: ff 25 e2 2f 00 00	jmp    *0x2fe2(%rip)        # 0x404018 <puts@got.plt>
>>>>   [displaced] prepare: selected buffer at 0x401052
>>>>   [displaced] prepare: saved 0x401052: 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4 f0 50
>>>>   [displaced] fixup_riprel: %rip-relative addressing used.
>>>>   [displaced] fixup_riprel: using temp reg 2, old value 0x7ffff7f8a578, new value 0x401036
>>>>   [displaced] amd64_displaced_step_copy_insn: copy 0x401030->0x401052: ff a1 e2 2f 00 00 68 00 00 00 00 e9 e0 ff ff ff
>>>>   [displaced] displaced_step_prepare_throw: prepared successfully thread=2892655.2892655.0, original_pc=0x401030, displaced_pc=0x401052
>>>>   [displaced] displaced_step_prepare_throw: replacement insn 0x401052: ff a1 e2 2f 00 00	jmp    *0x2fe2(%rcx)
>>>>   [displaced] finish: restored 2892655.2892655.0 0x401052
>>>>   [displaced] amd64_displaced_step_fixup: fixup (0x401030, 0x401052), insn = 0xff 0xa1 ...
>>>>   [displaced] amd64_displaced_step_fixup: restoring reg 2 to 0x7ffff7f8a578
>>>>   0x00007ffff7e402c0 in puts () from /lib64/libc.so.6
>>>>   (gdb)
>>>>
>>>> One final note.  For many targets that support displaced stepping (in
>>>> fact all targets except ARM) the replacement instruction is always a
>>>> single instruction.  But on ARM the replacement could actually be a
>>>> series of instructions.
>>>>
>>>> The debug code tries to handle this by disassembling the entire
>>>> displaced stepping buffer.  Obviously this might actually print more
>>>> than is necessary, but there's (currently) no easy way to know how
>>>> many instructions to disassemble; that knowledge is all locked in the
>>>> architecture specific code.  Still I don't think it really hurts, if
>>>> someone is looking at this debug then hopefully they known what to
>>>> expect.
>>>>
>>>> Obviously we can imagine schemes where the architecture specific
>>>> displaced stepping code could communicate back how many bytes its
>>>> replacement sequence was, and then our debug print code could use this
>>>> to limit the disassembly.  But this seems like a lot of effort just to
>>>> save printing a few additional instructions in some debug output.
>>>>
>>>> I'm not proposing to do anything about this issue for now.
>>>> ---
>>>>  gdb/infrun.c | 85 +++++++++++++++++++++++++++++++++++++++++-----------
>>>>  1 file changed, 68 insertions(+), 17 deletions(-)
>>>>
>>>> diff --git a/gdb/infrun.c b/gdb/infrun.c
>>>> index 5c9babb9104..8c56a9a4dfb 100644
>>>> --- a/gdb/infrun.c
>>>> +++ b/gdb/infrun.c
>>>> @@ -74,6 +74,7 @@
>>>>  #include "gdbsupport/common-debug.h"
>>>>  #include "gdbsupport/buildargv.h"
>>>>  #include "extension.h"
>>>> +#include "disasm.h"
>>>>  
>>>>  /* Prototypes for local functions */
>>>>  
>>>> @@ -1807,6 +1808,31 @@ displaced_step_prepare_throw (thread_info *tp)
>>>>    CORE_ADDR original_pc = regcache_read_pc (regcache);
>>>>    CORE_ADDR displaced_pc;
>>>>  
>>>> +  /* Display the instruction we are going to displaced step.  */
>>>> +  if (debug_displaced)
>>>> +    {
>>>> +      string_file tmp_stream;
>>>> +      int dislen = gdb_print_insn (gdbarch, original_pc, &tmp_stream,
>>>> +				   nullptr);
>>>> +
>>>> +      if (dislen > 0)
>>>> +	{
>>>> +	  gdb::byte_vector insn_buf (dislen);
>>>> +	  read_memory (original_pc, insn_buf.data (), insn_buf.size ());
>>>> +
>>>> +	  std::string insn_bytes
>>>> +	    = displaced_step_dump_bytes (insn_buf.data (), insn_buf.size ());
>>>> +
>>>> +	  displaced_debug_printf ("original insn %s: %s \t %s",
>>>> +				  paddress (gdbarch, original_pc),
>>>> +				  insn_bytes.c_str (),
>>>> +				  tmp_stream.string ().c_str ());
>>>
>>> If the bytes disassemble to more than one instruction, does tmp_stream
>>> contain new lines characters?  Just wondering what the output would look
>>> like (not a big deal in any case).
>> 
>> No.  gdb_print_insn will only disassemble a single instruction and
>> return its length.  In this bit of debug, we assume the original
>> instruction is always a single instruction.  If that's not true then
>> I've seriously not understood how displaced stepping works.
>
> Eh yeah, that's the input instruction, you're right.
>
>> 
>> For the replacement instructions the call to gdb_print_insn is placed
>> inside a loop which calls gdb_print_insn multiple times, so you'll see
>> multiple lines like:
>> 
>>   [displaced] displaced_step_prepare_throw: replacement insn <ADDRESS>: <BYTES> <DISASSEMBLY>
>> 
>> I use this trick:
>> 
>>   CORE_ADDR end
>>     = addr + (gdbarch_displaced_step_hw_singlestep (gdbarch)
>>               ? 1 : gdbarch_displaced_step_buffer_length (gdbarch));
>> 
>> Which means for targets that do a 1:1 replacement we only disassemble a
>> single instruction.  But for everyone else we'll always disassemble the
>> entire displaced step buffer.  Currently this is just ARM.
>
> Ok I missed that, that makes sense.

I pushed this patch.

Thanks,
Andrew


  reply	other threads:[~2023-03-29  9:42 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-23 15:46 [PATCH 0/3] AMD64 Displaced Stepping Fix Andrew Burgess
2023-02-23 15:46 ` [PATCH 1/3] gdb: more debug output for displaced stepping Andrew Burgess
2023-02-23 15:46 ` [PATCH 2/3] gdb: remove gdbarch_displaced_step_fixup_p Andrew Burgess
2023-02-23 15:46 ` [PATCH 3/3] gdb: fix reg corruption from displaced stepping on amd64 Andrew Burgess
2023-03-16 16:39 ` [PATCHv2 0/4] AMD64 Displaced Stepping Fix Andrew Burgess
2023-03-16 16:39   ` [PATCHv2 1/4] gdb: more debug output for displaced stepping Andrew Burgess
2023-03-21 12:29     ` Pedro Alves
2023-03-21 14:41       ` Simon Marchi
2023-03-22 21:17         ` [PATCHv2 0/2] displaced stepping debug improvements Andrew Burgess
2023-03-22 21:17           ` [PATCHv2 1/2] gdb: more debug output for displaced stepping Andrew Burgess
2023-03-22 21:17           ` [PATCHv2 2/2] gdb: move displaced_step_dump_bytes into gdbsupport (and rename) Andrew Burgess
2023-03-27 12:35           ` [PATCHv2 0/2] displaced stepping debug improvements Andrew Burgess
2023-03-21 14:45     ` [PATCHv2 1/4] gdb: more debug output for displaced stepping Simon Marchi
2023-03-16 16:39   ` [PATCHv2 2/4] gdb: remove gdbarch_displaced_step_fixup_p Andrew Burgess
2023-03-21 13:10     ` Pedro Alves
2023-03-22 21:22       ` Andrew Burgess
2023-03-16 16:39   ` [PATCHv2 3/4] gdb: fix reg corruption from displaced stepping on amd64 Andrew Burgess
2023-03-21 13:23     ` Pedro Alves
2023-03-16 16:39   ` [PATCHv2 4/4] gdb: remove redundant signal passing Andrew Burgess
2023-03-27 12:32   ` [PATCHv3 0/3] AMD64 Displaced Stepping Fix Andrew Burgess
2023-03-27 12:32     ` [PATCHv3 1/3] gdb: more debug output for displaced stepping Andrew Burgess
2023-03-28 13:05       ` Simon Marchi
2023-03-28 15:08         ` Andrew Burgess
2023-03-28 15:11           ` Simon Marchi
2023-03-29  9:42             ` Andrew Burgess [this message]
2023-03-27 12:32     ` [PATCHv3 2/3] gdb: move displaced_step_dump_bytes into gdbsupport (and rename) Andrew Burgess
2023-03-28 13:10       ` Simon Marchi
2023-03-29  9:43         ` Andrew Burgess
2023-03-27 12:32     ` [PATCHv3 3/3] gdb: fix reg corruption from displaced stepping on amd64 Andrew Burgess
2023-03-29  9:43       ` Pedro Alves
2023-03-28 12:33     ` [PATCHv3 0/3] AMD64 Displaced Stepping Fix Simon Marchi
2023-03-28 15:29       ` Andrew Burgess
2023-03-29 13:46     ` [PATCHv4] gdb: fix reg corruption from displaced stepping on amd64 Andrew Burgess
2023-04-04 13:03       ` Pedro Alves
2023-04-06 13:29         ` Andrew Burgess
2023-04-06 15:38           ` 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=87bkkbevvq.fsf@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=pedro@palves.net \
    --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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).