end, in which the return value of the process was not correctly propagated.
MERGE TO HEAD
git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_1_0_BRANCH@594
/* This is the ThreadId of the last thread the scheduler ran. */
extern ThreadId VG_(last_run_tid);
+/* This is the argument to __NR_exit() supplied by the first thread to
+ call that syscall. We eventually pass that to __NR_exit() for
+ real. */
+extern UInt VG_(exitcode);
+
/* --- Counters, for informational purposes only. --- */
/* This is the ThreadId of the last thread the scheduler ran. */
ThreadId VG_(last_run_tid) = 0;
+/* This is the argument to __NR_exit() supplied by the first thread to
+ call that syscall. We eventually pass that to __NR_exit() for
+ real. */
+UInt VG_(exitcode) = 0;
+
/* ---------------------------------------------------------------------
Counters, for informational purposes only.
vg_assert(tst->status == VgTs_Runnable);
/* The thread's %EBX will hold the arg to exit(), so we just
do exit with that arg. */
- VG_(exit)( tst->m_ebx );
+ VG_(exit)( VG_(exitcode) );
/* NOT ALIVE HERE! */
VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
break; /* what the hell :) */
If not valgrinding (cachegrinding, etc) don't do this.
__libc_freeres does some invalid frees which crash
the unprotected malloc/free system. */
+
+ /* If __NR_exit, remember the supplied argument. */
+ if (VG_(threads)[tid].m_eax == __NR_exit)
+ VG_(exitcode) = VG_(threads)[tid].m_ebx; /* syscall arg1 */
+
if (VG_(threads)[tid].m_eax == __NR_exit
&& !VG_(clo_instrument)) {
if (VG_(clo_trace_syscalls) || VG_(clo_trace_sched)) {