rr icon indicating copy to clipboard operation
rr copied to clipboard

x86_64 processes that execve i386 processes cause "Truncated register n in remote 'g' packet" on replay

Open lf- opened this issue 2 years ago • 2 comments

I was debugging a system where a 32 bit executable is run by a wrapper script that runs in the host 64-bit bash, and I hit this issue. I minimized it to be the case of a 64 bit program exec'ing a 32 bit one in general.

hello.c:

#include <stdio.h>

int main(void) {
    printf("hello world\n");
}

test.c:

#include <stdio.h>
#include <unistd.h>

int main(void) {
    char *argv[] = {"hi", NULL};
    printf("test\n");
    execv("./hello", argv);
}

Compile:

gcc -m32 hello.c -o hello
gcc test.c

Reproduce:

/tmp » rr a.out
rr: Saving execution to trace directory `/home/jade/.local/share/
rr/a.out-5'.
test
hello world
/tmp » rr replay
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licens
es/gpl.html>
This is free software: you are free to change and redistribute it
.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/jade/.local/share/rr/a.out-5/mmap_copy
_5_a.out...
(No debugging symbols found in /home/jade/.local/share/rr/a.out-5
/mmap_copy_5_a.out)
Remote debugging using 127.0.0.1:61317
Reading symbols from /lib64/ld-linux-x86-64.so.2...
(No debugging symbols found in /lib64/ld-linux-x86-64.so.2)
BFD: warning: system-supplied DSO at 0x6fffd000 has a section ext
ending past end of file
0x00007f789f1ed090 in _start () from /lib64/ld-linux-x86-64.so.2
=> 0x00007f789f1ed090 <_start+0>:       48 89 e7        mov    rd
i,rsp
(rr) c
Continuing.
test
hello world
Truncated register 50 in remote 'g' packet
Truncated register 50 in remote 'g' packet
(rr) c
Continuing.
Truncated register 50 in remote 'g' packet
(rr)

Incidentally, if you want a bonus bug I accidentally found while looking at this one, change the initialization of argv in test.c to char *argv[] = NULL; and there will be fireworks when rr records the trace, but the program will execute normally outside rr, on my linux 5.13.10:

[FATAL /home/jade/.dotfiles/configs/pkg/rr-git/src/rr-git/src/record_syscall.cc:5984:rec_process_syscall_arch()] (task 3668707 (rec:3668707) at time 225) -> Assertion `t->regs().syscall_result_signed() == -syscall_state.expect_errno' failed to hold. Expected EFAULT for 'execve' but got result 0 (errno SUCCESS)

rr version: 1817b9d4

lf- avatar Sep 13 '21 08:09 lf-

A workaround might be to just activate gdb after the process reached its "32-bit state" e.g. by "rr replay -g 200"

benutzer@debian:~/rr$ rr replay
...
0x00007fb617e49090 in _start () from /lib64/ld-linux-x86-64.so.2
(rr) b execve
Function "execve" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (execve) pending.
(rr) cont
Continuing.
test

Breakpoint 1, execve () at ../sysdeps/unix/syscall-template.S:120
120     ../sysdeps/unix/syscall-template.S: Datei oder Verzeichnis nicht gefunden.
(rr) when
Current event: 181
(rr) kill
Kill the program being debugged? (y or n) y
[Inferior 1 (process 630044) killed]
(rr) q

benutzer@debian:~/rr$ rr replay -g 183
test
...
Remote debugging using 127.0.0.1:40463

--------------------------------------------------
 ---> Reached target process 630044 at event 184.
--------------------------------------------------
Reading symbols from /lib/ld-linux.so.2...
Reading symbols from /usr/lib/debug/.build-id/84/18f45e8884ce73538211215a1cb607e0a635a6.debug...
0xf7f110b0 in _start () from /lib/ld-linux.so.2
(rr)

Another workaround might be to build a 32-bit rr with the cmake option: -Dforce32bit=true (But such a rr would not allow to record any 64-bit child process, so all recorded processes would need to be 32-bit.)

bernhardu avatar Sep 13 '21 13:09 bernhardu

Just for completeness - gdbserver seems to be able to handle the transition from a 64 to a 32-bit process somehow:

benutzer@debian:~/rr$ gcc -O0 -g test.c
benutzer@debian:~/rr$ gcc -O0 -g -m32 hello.c -o hello
benutzer@debian:~/rr$ gdbserver localhost:1234 a.out
Process /home/benutzer/rr/a.out created; pid = 20214
Listening on port 1234
Remote debugging from host ::1, port 48230
test
benutzer@debian:~/rr$
benutzer@debian:~/rr$ gdb -q
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
Reading /home/benutzer/rr/a.out from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /home/benutzer/rr/a.out from remote target...
Reading symbols from target:/home/benutzer/rr/a.out...
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading symbols from target:/lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/32/438eb3b034da54caf58c7a65446639f7cfe274.debug...
0x00007ffff7fd3090 in _start () from target:/lib64/ld-linux-x86-64.so.2
(gdb) set breakpoint pending on
(gdb) set follow-fork-mode child
(gdb) set follow-exec-mode new
(gdb) b main
Breakpoint 1 at 0x55555555514d: file test.c, line 5.
(gdb) ignore 1 1
Will ignore next crossing of breakpoint 1.
(gdb) b execve
Function "execve" not defined.
Breakpoint 2 (execve) pending.
(gdb) cont
Continuing.
Reading /lib/x86_64-linux-gnu/libc.so.6 from remote target...

Breakpoint 2, execve () at ../sysdeps/unix/syscall-template.S:120
120     ../sysdeps/unix/syscall-template.S: Datei oder Verzeichnis nicht gefunden.
(gdb) pipe info target | grep "Local exec file" -A1
Local exec file:
        `target:/home/benutzer/rr/a.out', file type elf64-x86-64.
(gdb) display/i $pc
1: x/i $pc
=> 0x7ffff7ec96c0 <execve>:     mov    $0x3b,%eax
(gdb) stepi
0x00007ffff7ec96c5      120     in ../sysdeps/unix/syscall-template.S
1: x/i $pc
=> 0x7ffff7ec96c5 <execve+5>:   syscall 
(gdb) stepi
process 20214 is executing new program: /home/benutzer/rr/hello
[New inferior 2]
[New Thread 20214.20214]
Reading /home/benutzer/rr/hello from remote target...
Reading /home/benutzer/rr/hello from remote target...
Reading /lib/ld-linux.so.2 from remote target...
Reading /lib/ld-linux.so.2 from remote target...
Reading /lib/18f45e8884ce73538211215a1cb607e0a635a6.debug from remote target...
Reading /lib/.debug/18f45e8884ce73538211215a1cb607e0a635a6.debug from remote target...
Reading /usr/lib/debug//lib/18f45e8884ce73538211215a1cb607e0a635a6.debug from remote target...
Reading /usr/lib/debug/lib//18f45e8884ce73538211215a1cb607e0a635a6.debug from remote target...
Reading target:/usr/lib/debug/lib//18f45e8884ce73538211215a1cb607e0a635a6.debug from remote target...
Reading /lib32/libc.so.6 from remote target...
Reading /lib32/6320961f7f4181312f9149e33761b86fd3ce95.debug from remote target...
Reading /lib32/.debug/6320961f7f4181312f9149e33761b86fd3ce95.debug from remote target...
Reading /usr/lib/debug//lib32/6320961f7f4181312f9149e33761b86fd3ce95.debug from remote target...
Reading /usr/lib/debug/lib32//6320961f7f4181312f9149e33761b86fd3ce95.debug from remote target...
Reading target:/usr/lib/debug/lib32//6320961f7f4181312f9149e33761b86fd3ce95.debug from remote target...

Thread 2.1 "hello" hit Breakpoint 1, main () at hello.c:4
4           printf("hello world\n");
(gdb) pipe info target | grep "Local exec file" -A1
Local exec file:
        `target:/home/benutzer/rr/hello', file type elf32-i386.
(gdb) kill
Kill the program being debugged? (y or n) y
[Inferior 2 (process 20214) killed]
(gdb) q
benutzer@debian:~/rr$

bernhardu avatar Sep 13 '21 21:09 bernhardu

Generally we don't support continuing through an exec. So I don't get this behavior, I see us just stop at the exec without errors, which is expected.

rocallahan avatar Dec 26 '23 19:12 rocallahan