Open Razz4780 opened 3 months ago
my guess is we run post-fork and new stack size is too small for us so we overflow (just a guess tho)
How I would approach this:
trace!
to be like #[mirrord_layer_macro::instrument(level = "trace")]
that would help reducing stack sizeWhat I found while digging in this issue:
fork
:
vfork
, which I had to hook (copied fork_detour
as vfork_detour
);syscall.releaseForkLock
function);morestack on g0
doesn't seem to mean anything, it's just an error you'll get when Rust crashes?execve("echo")
:
syscall
s we were missing from the go hooks, looks like the sample was calling dup3
, so added our dup3_detour
to the go handling;dup3
was the culprit for crashing before execve
, more specifically, dup3(fd, 2)
which piping fd
to stderr
(?). The other 2 pipes dup3(n, 0|1)
were not causing the crash;dup3(fd, n + 20)
, and this got the sample "working", due to all the fds being just Bypass
es, I guess that's how it didn't explode further with this change. After making this change, the parent process still crashed, but the child was able to finish and do its thing. Which means the issue is parent only (vfork
, execve
, and potentially pipe2
);syscall
s:// This is kind of what I was seeing from the trace logs (syscall_abi logs):
int fcntl_getfd_0 = fcntl(0, F_GETFD);
int fcntl_getfd_1 = fcntl(1, F_GETFD);
int fcntl_getfd_2 = fcntl(2, F_GETFD);
int fcntl_getfl_0 = fcntl(0, F_GETFL);
int fcntl_getfl_1 = fcntl(1, F_GETFL);
int fcntl_getfl_2 = fcntl(2, F_GETFL);
int pipefd_0[2];
pipe2(pipefd_0, O_CLOEXEC);
int fcntl_getfl_5 = fcntl(pipefd_0[0], F_GETFL);
int fcntl_getfl_6 = fcntl(pipefd_0[1], F_GETFL);
int pipefd_1[2];
pipe2(pipefd_1, O_CLOEXEC);
int fcntl_getfl_10 = fcntl(pipefd_1[0], F_GETFL);
int fcntl_getfl_11 = fcntl(pipefd_1[1], F_GETFL);
int fcntl_getfl_5_5 = fcntl(pipefd_0[0], F_GETFL);
int fcntl_getfl_10_10 = fcntl(pipefd_1[0], F_GETFL);
dup3(pipefd_0[0], 0, 0);
dup3(pipefd_1[0], 1, 0);
dup3(pipefd_1[1], 2, 0);
pid_t pid = vfork();
"morestack on g0" is coming from the Go runtime whenever it cant grow the scheduler stack. https://github.com/golang/go/blob/2707d42966f8985a6663c93e943b9a44b9399fca/src/runtime/asm_amd64.s#L594-L598
Bug Description
Go binary fails panics on executing command
Steps to Reproduce
Build the snippet below using go 1.22.0, run with
mirrord exec
Backtrace
Relevant Logs
No response
Your operating system and version
Local process
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=fivcHJLRmnzGWcG5-3dM/82M8sLYGI_Jh1IAqMFHE/zrv4NnR3nyiWFytLQ1kn/X02rZMTVxVLHc23KfJsv, with debug_info, not stripped
Local process version
No response
Additional Info
No response