Patchwork Process record: Log %rax after syscall under amd64-linux

login
register
mail settings
Submitter Andrew D'Addesio
Date May 10, 2018, 7:35 p.m.
Message ID <CANcDefWPs9VhTHN0O8xYTMNgGeSHYneut8N6tFd-CnQ1XGm4+A@mail.gmail.com>
Download mbox | patch
Permalink /patch/27207/
State New
Headers show

Comments

Andrew D'Addesio - May 10, 2018, 7:35 p.m.
Hi all,

This is my first patch for gdb, so if there are any issues with my
patch, just tell me and I'll fix it.

Here's a longer explanation of the bug I'm fixing:

Description:

While recording execution using the "record" command under 64-bit Linux,
gdb forgets to log the return value (%rax) after executing a 'syscall'
instruction. If the user seeks backwards to before the syscall (via
"record goto"), %rax will not revert to the old value.

Steps to reproduce the bug:

1. Compile the following hello world using:
gcc -Wall -nostartfiles -o helloworld helloworld.S

    #include <asm/unistd.h>

    .intel_syntax noprefix
    .global _start

    .data
    msg:
        .ascii "hello, world!\n"
    msg_end:

    .text
    _start:
        mov rax, __NR_write
        mov rdi, 1 # STDOUT_FILENO
        lea rsi, [rip + msg]
        mov rdx, (msg_end - msg)
        syscall
        mov rax, __NR_exit
        mov rdi, 0 # EXIT_SUCCESS
        syscall

2. Launch gdb using: gdb ./helloworld

3. Execute these commands:

    break _start
    run
    record
    stepi 4

    # %rax is 0x1 just before executing the syscall
    disassemble
    info reg

    stepi

    # %rax is 0xe just after executing the syscall
    disassemble
    info reg

    record goto 4

    # Oops! %rax is still 0xe when we rewind to before the syscall.
    disassemble
    info reg

Notes:
* The existing code tries to save the return value, but it only saves
  %rcx and %r11, not %rax.
* On other archs (i386-linux-tdep.c, etc.), we do properly save the
  return value. Grep the *-tdep.c files for this comment:
  /* Record the return value of the system call.  */
* Passing test suite results are attached.

Andrew

On Thu, May 10, 2018 at 2:28 PM, Andrew D'Addesio <modchipv12@gmail.com> wrote:
> Log the return value after executing a system call instruction, as
> we do for other archs (i386-linux, arm-linux, etc.)
>
> gdb/ChangeLog:
> 2018-05-10  Andrew D'Addesio  <modchipv12@gmail.com>
>
>         * amd64-linux-tdep.c (amd64_linux_syscall_record_common): Record
>         %rax.
> ---
>  gdb/amd64-linux-tdep.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
> index 2bd3d31..917ecf5 100644
> --- a/gdb/amd64-linux-tdep.c
> +++ b/gdb/amd64-linux-tdep.c
> @@ -1510,6 +1510,9 @@ amd64_linux_syscall_record_common (struct regcache *regcache,
>
>   record_regs:
>    /* Record the return value of the system call.  */
> +  if (record_full_arch_list_add_reg (regcache, AMD64_RAX_REGNUM))
> +    return -1;
> +  /* Record registers clobbered by the 'syscall' instruction.  */
>    if (record_full_arch_list_add_reg (regcache, AMD64_RCX_REGNUM))
>      return -1;
>    if (record_full_arch_list_add_reg (regcache, AMD64_R11_REGNUM))
> --
> 2.7.4
>

Patch

1c1
< Test Run By daddesio on Thu May 10 12:52:45 2018
---
> Test Run By daddesio on Thu May 10 13:26:51 2018
48196c48196
< FAIL: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: stop with control-c (the program is no longer running)
---
> FAIL: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: stop with control-c
48206c48206
< FAIL: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=tty: stop with control-c
---
> PASS: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=tty: stop with control-c
56094c56094
< PASS: gdb.threads/non-ldr-exit.exp: program exits normally
---
> KFAIL: gdb.threads/non-ldr-exit.exp: program exits normally (PRMS: gdb/18717)
56713c56713
< KFAIL: gdb.threads/process-dies-while-handling-bp.exp: non_stop=on: cond_bp_target=1: inferior 1 exited (prompt) (PRMS: gdb/18749)
---
> KFAIL: gdb.threads/process-dies-while-handling-bp.exp: non_stop=on: cond_bp_target=1: inferior 1 exited (memory error) (PRMS: gdb/18749)
56717c56717,56718
< KFAIL: gdb.threads/process-dies-while-handling-bp.exp: non_stop=on: cond_bp_target=0: inferior 1 exited (prompt) (PRMS: gdb/18749)
---
> PASS: gdb.threads/process-dies-while-handling-bp.exp: non_stop=on: cond_bp_target=0: inferior 1 exited
> PASS: gdb.threads/process-dies-while-handling-bp.exp: non_stop=on: cond_bp_target=0: no threads left
56726c56727,56728
< KFAIL: gdb.threads/process-dies-while-handling-bp.exp: non_stop=off: cond_bp_target=0: inferior 1 exited (prompt) (PRMS: gdb/18749)
---
> PASS: gdb.threads/process-dies-while-handling-bp.exp: non_stop=off: cond_bp_target=0: inferior 1 exited
> PASS: gdb.threads/process-dies-while-handling-bp.exp: non_stop=off: cond_bp_target=0: no threads left
57142c57144
< FAIL: gdb.threads/signal-while-stepping-over-bp-other-thread.exp: step (pattern 3)
---
> PASS: gdb.threads/signal-while-stepping-over-bp-other-thread.exp: step
58389,58390c58391,58392
< # of expected passes		54578
< # of unexpected failures	1623
---
> # of expected passes		54583
> # of unexpected failures	1621
58393c58395
< # of known failures		65
---
> # of known failures		64