Vijay
Vijay

Reputation:

how do i valgrind memcheck on every instance of Process without starting it via valgrind command options

how do i do a valgrind memcheck on every instance of Process without starting it via valgrind command options.

Is there a way to keep the monitoring options saved on a process rather than starting up the process every-time with valgrind command?

In Microsoft Application Verifier if an application is specified to be monitored, then any number of instances of that application gets monitored, whether its a child process or started otherwise.

Any ideas to do same in Valgrind?

I have tried --trace-children=yes option of valgrind memcheck ...but my application xyz signals another application zzz to start a new intance of xyz(process), which i want to analyze. in this case, valgrind exits when xyz finishes signalling zzz. it does not follow up on what process zzz started.

Thanks, Vijay

Upvotes: 3

Views: 2252

Answers (3)

Craig Ringer
Craig Ringer

Reputation: 324841

Regarding wrapper executables, I've landed up with the following script for PostgreSQL. (I've trimmed out various postgres-specific parts like discovering the supplied valgrind suppressions file).

#!/bin/bash
set -e -u -x

# Pop top two elements from path; the first is added by pg_regress
# and the next is us.
function join_by { local IFS="$1"; shift; echo "$*"; }
IFS=':' read -r -a PATHA <<< "$PATH"
export PATH=$(join_by ":" "${PATHA[@]:2}")

NEXT_POSTGRES=$(which postgres)
if [ "${NEXT_POSTGRES}" -ef "./valgrind/postgres" ]; then
    echo "ERROR: attempt to execute self"
    exit 1
fi

echo "Running ${NEXT_POSTGRES} under Valgrind"

valgrind --leak-check=full --show-leak-kinds=definite,possible \
    --gen-suppressions=all --verbose --time-stamp=yes  \
    --log-file=valgrind-$$-%p.log --trace-children=yes \
    --track-origins=yes --read-var-info=yes --malloc-fill=8f \
    --free-fill=9f --num-callers=30 postgres "$@"

Note the PATH manipulation to ensure that we don't try to exec postgres from the same place again. In this case it was necessary that the wrapper script also be named exactly postgres so I had to make sure it didn't recursively execute its self.

An alternative is to use whatis -a to find the next executable in the path and run it directly. But I found that caused other issues for my use case.


BTW, if you get an error like

   valgrind: mmap(0x58000000, 2347008) failed in UME with error 22 (Invalid argument).
   valgrind: this can be caused by executables with very large text, data or bss segments.

... then it's quite possible you're trying to run valgrind under valgrind by mistake.

Upvotes: 0

Aiden Bell
Aiden Bell

Reputation: 28384

IIRC, Valgrind must execute the application because it alters the read-only symbols to replace common library functions like malloc and so on.

This means you can't attach memcheck to an already running process because it can't alter that section of the program in memory (and it would probably corrupt running state).

There are probably other reasons too. A quick google suggests that you can't attach memcheck to a running process too. As suggested, you can wrap your executables in a bash script such as. So if program myprog creates new processes of newprog then do:

]$ mv /path/to/myprog /path/to/newprog

then

#!/bin/bash
valgrind (options) /path/to/newprog $@

and call it myprog the $@ ensures arguments are passed. Then when your program creates a new process, using myprog -a b -c d then it is wrapped in valgrind.

This only applies to certain C calls like execve() and others, whereas other obscure ways of creating processes may not take advantage of the wrapping.

If I am wrong, it would be a good thing to know :)

Upvotes: 5

Adam Liss
Adam Liss

Reputation: 48330

Can you wrap xyz either in a batch file or another executable that launches it within valgrind?

In other words, rename xyz to run_me_under_valgrind, then create a new xyz that launches the original run_me_under_valgrind under valgrind.

Upvotes: 2

Related Questions