Summary: | pthread_create() returns incorrect error code under valgrind | ||
---|---|---|---|
Product: | [Developer tools] valgrind | Reporter: | Lemon Lime <lemonlime51> |
Component: | general | Assignee: | Julian Seward <jseward> |
Status: | CONFIRMED --- | ||
Severity: | normal | CC: | bart.vanassche+kde, lemonlime51 |
Priority: | NOR | ||
Version: | 3.5.0 | ||
Target Milestone: | --- | ||
Platform: | Debian testing | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Lemon Lime
2009-11-25 18:25:27 UTC
The sys_clone wrappers do some pretty serious magic in order to retain control of the child thread. I wonder if we are somehow mishandling the return value from sys_clone when it fails. hi... I'm not sure how much it helps, but I did some more testing, and the failure seems to come from sys_mmap2, and not sys_clone. This is the output of strace of a normal run (without valgrind): (...) clone(child_stack=0xbe727494, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xbe727bd8, {entry_number:6, base_addr:0xbe727b70, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}, child_tidptr=0xbe727bd8) = 23291 mmap2(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0xbe728000 mprotect(0xbe728000, 4096, PROT_NONE) = 0 clone(child_stack=0xbef28494, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xbef28bd8, {entry_number:6, base_addr:0xbef28b70, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}, child_tidptr=0xbef28bd8) = 23292 mmap2(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0xbef29000 mprotect(0xbef29000, 4096, PROT_NONE) = 0 clone(child_stack=0xbf729494, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xbf729bd8, {entry_number:6, base_addr:0xbf729b70, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}, child_tidptr=0xbf729bd8) = 23293 mmap2(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = -1 ENOMEM (Cannot allocate memory) munmap(0xbef29000, 8392704) = 0 munmap(0xbe728000, 8392704) = 0 munmap(0xbdf27000, 8392704) = 0 (...) And this is the output of valgrind --trace-syscalls=yes: (...) SYSCALL[26205,1](120) sys_clone ( 3d0f00, 0xbd753494, 0xbd753bd8, 0xbee4638c, 0xbd753bd8 ) --> [pre-success] Success(0x0:0x67c9) SYSCALL[26205,2](311) sys_set_robust_list ( 0xbd753be0, 12 )[sync] --> Success(0x0:0x0) SYSCALL[26205,2]( 1) exit( 0 ) --> [pre-success] Success(0x0:0x0) SYSCALL[26205,1](192) sys_mmap2 ( 0x0, 8392704, 3, 131106, -1, 0 ) --> [pre-success] Success(0x0:0xbd754000) SYSCALL[26205,1](125) sys_mprotect ( 0xbd754000, 4096, 0 )[sync] --> Success(0x0:0x0) SYSCALL[26205,1](120) sys_clone ( 3d0f00, 0xbdf54494, 0xbdf54bd8, 0xbee4638c, 0xbdf54bd8 ) --> [pre-success] Success(0x0:0x67ca) SYSCALL[26205,2](311) sys_set_robust_list ( 0xbdf54be0, 12 )[sync] --> Success(0x0:0x0) SYSCALL[26205,2]( 1) exit( 0 ) --> [pre-success] Success(0x0:0x0) SYSCALL[26205,1](192) sys_mmap2 ( 0x0, 8392704, 3, 131106, -1, 0 ) --> [pre-success] Success(0x0:0xbee47000) SYSCALL[26205,1](125) sys_mprotect ( 0xbee47000, 4096, 0 )[sync] --> Success(0x0:0x0) SYSCALL[26205,1](120) sys_clone ( 3d0f00, 0xbf647494, 0xbf647bd8, 0xbee4638c, 0xbf647bd8 ) --> [pre-success] Success(0x0:0x67cb) SYSCALL[26205,2](311) sys_set_robust_list ( 0xbf647be0, 12 )[sync] --> Success(0x0:0x0) SYSCALL[26205,2]( 1) exit( 0 ) --> [pre-success] Success(0x0:0x0) SYSCALL[26205,1](192) sys_mmap2 ( 0x0, 8392704, 3, 131106, -1, 0 ) --> [pre-fail] Failure(0x16) SYSCALL[26205,1]( 4) sys_write ( 1, 0x4029000, 26 ) --> [async] ... *** 361: Invalid argument SYSCALL[26205,1]( 4) ... [async] --> Success(0x0:0x1a) SYSCALL[26205,1]( 91) sys_munmap ( 0xbee47000, 8392704 )[sync] --> Success(0x0:0x0) SYSCALL[26205,1]( 91) sys_munmap ( 0xbd754000, 8392704 )[sync] --> Success(0x0:0x0) (...) In both cases, clone() succeeds but the following mmap2() fails. hi... The problem is that ML_(generic_PRE_sys_mmap) returns EINVAL when VG_(am_get_advisory) fails. My understanding is that if VG_(am_get_advisory) fails, this means we are out of memory and therefore the caller should return ENOMEM. If I am correct, this patch should fix the problem: diff -rupN src/valgrind-3.5.0/coregrind/m_syswrap/syswrap-generic.c testsrc/valgrind-3.5.0/coregrind/m_syswrap/syswrap-generic.c --- src/valgrind-3.5.0/coregrind/m_syswrap/syswrap-generic.c 2009-08-19 16:37:42.000000000 +0300 +++ testsrc/valgrind-3.5.0/coregrind/m_syswrap/syswrap-generic.c 2009-11-28 11:53:46.000000000 +0200 @@ -1994,7 +1994,7 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok ); if (!mreq_ok) { /* Our request was bounced, so we'd better fail. */ - return VG_(mk_SysRes_Error)( VKI_EINVAL ); + return VG_(mk_SysRes_Error)( VKI_ENOMEM ); } /* Otherwise we're OK (so far). Install aspacem's choice of When applying this and recompiling, the testcase above runs correctly and outputs "Resource temporarily unavailable" as it should. |