Bug 401578 - drd crashes on fork if previous thread finished
Summary: drd crashes on fork if previous thread finished
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: drd (other bugs)
Version First Reported In: 3.11.0
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Bart Van Assche
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-11-30 14:42 UTC by esther.bergter
Modified: 2018-12-01 19:08 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description esther.bergter 2018-11-30 14:42:47 UTC
SUMMARY

The newly created thread makes fork/exec. If one child terminates, the following fork makes "valgrind --tool=drd" crash.
If the children do not terminate, forks do not cause errors.
(memcheck and helgrind report no errors.)

STEPS TO REPRODUCE
valgrind --tool=drd forksequent
(source see below) 

OBSERVED RESULT
==24772== drd, a thread error detector
==24772== Copyright (C) 2006-2015, and GNU GPL'd, by Bart Van Assche.
==24772== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==24772== Command: forksequent
==24772==
/bin/ls
--24776-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--24776-- si_code=1;  Faulting address: 0x80;  sp: 0x803f79c60

valgrind: the 'impossible' happened:
   Killed by fatal signal

host stacktrace:
==24776==    at 0x38054702: ??? (in /usr/lib/valgrind/drd-amd64-linux)
==24776==    by 0x3805922C: ??? (in /usr/lib/valgrind/drd-amd64-linux)
==24776==    by 0x380F4A0D: ??? (in /usr/lib/valgrind/drd-amd64-linux)
==24776==    by 0x380BE0B4: ??? (in /usr/lib/valgrind/drd-amd64-linux)
==24776==    by 0x380BABAA: ??? (in /usr/lib/valgrind/drd-amd64-linux)
==24776==    by 0x380BC25E: ??? (in /usr/lib/valgrind/drd-amd64-linux)
==24776==    by 0x380CB7C6: ??? (in /usr/lib/valgrind/drd-amd64-linux)
==24776==    by 0x380CBC9A: ??? (in /usr/lib/valgrind/drd-amd64-linux)
==24776==    by 0x380F44AD: ??? (in /usr/lib/valgrind/drd-amd64-linux)
==24776==    by 0xDEADBEEFDEADBEEE: ???
==24776==    by 0xDEADBEEFDEADBEEE: ???
==24776==    by 0xDEADBEEFDEADBEEE: ???

sched status:
  running_tid=2

Thread 2: status = VgTs_Runnable (lwpid 24776)
==24776==    at 0x513541A: fork (fork.c:145)
==24776==    by 0x400899: startproc (in /tmp/forksequent)
==24776==    by 0x4C3458B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==24776==    by 0x4E536B9: start_thread (pthread_create.c:333)



Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.

==24772==
==24772== For counts of detected and suppressed errors, rerun with: -v
==24772== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 20 from 10)


EXPECTED RESULT
valgrind should not crash

SOFTWARE/OS VERSIONS
Linux: Description:    Ubuntu 16.04.5 LTS (and e.g. CentOS7) 
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609

several (older) valgrind versions also crash (output differs)

ADDITIONAL INFORMATION

minimal test program:
testfork.c
-------------------
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

pthread_t tid[2];

void *startproc()
{
        pid_t pid;
        char *const parmList[] = { "/bin/ls", "/bin/ls", NULL };


        if ((pid = fork()) == -1)
                perror("fork error");
        else if (pid == 0) {
                execv("/bin/ls", parmList);
        }
        else {// the parent
                return NULL;
        }

}

int main(void)
{
        int i = 0;
        int err;

        while (i < 2)
        {
                err = pthread_create(&(tid[i]), NULL, &startproc, NULL);
                if (err != 0)
                        printf("\ncan't create thread :[%s]", strerror(err));
#ifdef FORK_SEQUENTIALLY
                pthread_join(tid[i], NULL);
                printf("thread %d joined\n", i);
#endif
                i++;
        }
#ifndef FORK_SEQUENTIALLY
        pthread_join(tid[0], NULL);
        pthread_join(tid[1], NULL);
#endif
        printf("\n");
        return 0;
}
----------
demonstration script
runtest
--------
gcc -D_REENTRANT testfork.c -lpthread -o forkparallel
gcc -D_REENTRANT -DFORK_SEQUENTIALLY  testfork.c -lpthread -o forksequent
echo valgrind --tool=drd forkparallel
valgrind --tool=drd forkparallel
echo
echo
echo valgrind --tool=drd forksequent
valgrind --tool=drd forksequent
Comment 1 Bart Van Assche 2018-12-01 19:08:59 UTC
Thank you for having reported this. A candidate fix has been checked in on the master branch.