strace -f cannot trace failing execve()
Michael Holzheu
HOLZHEU at de.ibm.com
Mon Feb 23 01:13:02 UTC 2004
Hi all,
I found a problem running strace 4.5.1 under s390(x) using the -f option
with a program that calls execve() which fails.
Here is the testprogram:
========================
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
pid_t child;
if(child = fork()){
int status;
printf("parent\n");
waitpid(child,&status,0);
} else {
printf("child\n");
execve("blubber",NULL,NULL);
printf("child\n");
}
return 0;
}
If I call "strace -f ./testme" under Linux 2.6.2 strace hangs:
==============================================================
clone(Process 2224 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0x4016d2e8) = 2224
[pid 2223] fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1),
...}) = 0
[pid 2223] mmap(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40018000
[pid 2223] write(1, "parent\n", 7parent
) = 7
[pid 2223] wait4(2224, Process 2223 suspended
<unfinished ...>
[pid 2224] fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1),
...}) = 0
[pid 2224] mmap(NULL, 4096, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40018000
[pid 2224] write(1, "child\n", 6child
) = 6
[pid 2224] execve("blubber", [0], [/* 0 vars */]) = -1 ENOENT (No such
file or directory)
child
[pid 2224] close(1) = 91
[pid 2224] setup() = 248
PANIC: attached pid 2224 exited
<<< Here hangs strace
If I call "strace -f ./testme" under Linux 2.4.21 strace prints wrong
systemcalls:
==================================================================================
fork(Process 597 attached (waiting for parent)
Process 597 resumed (parent 596 ready)
) = 597
[pid 597] fstat64(1, <unfinished ...>
[pid 596] fstat64(1, <unfinished ...>
[pid 597] <... fstat64 resumed> {st_mode=S_IFCHR|0620,
st_rdev=makedev(136, 0), ...}) = 0
[pid 596] <... fstat64 resumed> {st_mode=S_IFCHR|0620,
st_rdev=makedev(136, 0), ...}) = 0
....
[pid 596] <... write resumed> ) = 7
[pid 597] execve("blubber", [0], [/* 0 vars */] <unfinished ...>
[pid 596] wait4(597, Process 596 suspended
<unfinished ...>
[pid 597] <... execve resumed> ) = -1 ENOENT (No such file or
directory)
child
[pid 597] close(1) = -1 ENOSYS (Function not
implemented) >>>>> Wrong system call: Should be write
[pid 597] setup() = -1 ENOSYS (Function not
implemented) >>>>> Wrong system call: Should be munmap
[pid 597] exit_group(0) = ?
Process 596 resumed
Process 597 detached
<... wait4 resumed> [WIFEXITED(s) && WEXITSTATUS(s) == 0], 0, NULL) = 597
--- SIGCHLD (Child exited) @ 0 (0) ---
munmap(0x40018000, 4096) = 0
exit_group(0) = ?
The problem occurs, if execve fails with an error code. E.g. if the file
to excecute is not available/readable.
If the execve systemcall is traced, strace sets TCB_WAITEXECVE in the
flags an then "forgets" the next SIGTRAP. This works, if the execve was
successfull, but does not work, if execve failed. Therefore I think that
we have to check if execve failed and reset the flags in this case:
I have a bugfix for the problem:
syscall.c:
--- syscall.c.orig 2004-02-20 15:55:32.576657126 +0100
+++ syscall.c 2004-02-20 15:57:16.276657126 +0100
@@ -2183,6 +2183,12 @@
tprintf("= %#lx", tcp->u_rval);
}
else if (!(sys_res & RVAL_NONE) && u_error) {
+#ifdef TCB_WAITEXECVE
+ if(tcp->scno == SYS_execve){
+ tcp->flags &= ~TCB_WAITEXECVE;
+ }
+#endif
+
switch (u_error) {
#ifdef LINUX
case ERESTARTSYS:
(See attached file: strace-4.5.1-execve.diff)
What do you think?
Best Regards
Michael
------------------------------------------------------------------------
Linux for E-Server Development
Phone: +49-7031-16-2360, Bld 71032-03-U09
Email: holzheu at de.ibm.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: strace-4.5.1-execve.diff
Type: application/octet-stream
Size: 390 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20040223/9f4be138/attachment.obj>
More information about the Strace-devel
mailing list