linuxforkvalgrindmemcheckdr-memory

Is it feasible to record a program state in Valgrind/DrMemory and then restore that?


I have a program that loads a big chunk of data at startup. That takes up a rather long time and therefore creates an overhead when running Valgrind (memcheck)/DrMemory. So when invoking the program several times with different arguments, it takes up a considerable amount of time

My idea would be to use fork() right after the data loading phase and then hand the children off to Valgrind/DrMemory. Even if the loading phase runs under Valgrind/DrMemory, the overhead would only occur once and all forked child processes should be able to use the preloaded data from there.

Is it feasible to record a program state and declare it as untainted and then later restore that state in Valgrind (memcheck) or DrMemory?

Note: I'm only interested in unixoid platforms, limiting it to Linux alone would also be fine.


Solution

  • My idea would be to use fork() right after the data loading phase and then hand the children off to Valgring/DrMemory.

    That's not feasible for many reasons. For example, glibc will cache results of syscall(SYS_getpid) in an internal variable, and having multiple processes that believe they have the same pid (which != their real pid) is an obvious recipe for disaster.

    That said, what stops you from running valgrind --trace-children=yes and then forking child processes after initialization? Each of the child processes can do something like this:

    char buf[PATH_MAX];
    sprintf(buf, "/tmp/parameters-for-%d", getpid());
    while (true) {
      if (FILE *fp = fopen(buf, "r")) {
        // read parameters for this child, and exercise appropriate code paths
        return run_with_parameters(fp);
      }
      sleep(1);
    }
    

    When you want child N to run, simply echo "foo bar baz" > /tmp/parameters-for-N and wait for it to complete. All other children will be nicely busy-waiting until you are ready to use them.