Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a certain Linux executable that is called from a bigger application to perform some calculations. I want to modify the way the calculations are performed, for that I first need to understand how the executable is called and in what way the parameters and data are transferred.

So, I'd like to monitor the command line parameters, stdin and stdout if this executable is called. The normal operation of the executable should not be disturbed.

Is there an easy way to do that?

Update:

I tried the shell script placeholder idea to grab all the data using the following script:

#!/bin/bash
export LOGFILE=/tmp/logname
echo `env` > $LOGFILE-env
echo "$@" >> $LOGFILE-arguments
tee -a $LOGFILE-stdin | /path/to/real/executable 2>&1 | tee -a $LOGFILE-stdout

This works fine for test input, but it just hangs if it is called for real. Probably there is even more going on than I suspected.

share|improve this question
    
That's unusual. The system doesn't give the caller any indication of whether it's calling a binary or a script, the application would have to go out of its way to even find out. What's the exact error message? Are you trying to work around some kind of content protection mechanism (in which case there'll probably be other hurdles)? –  Gilles May 4 '11 at 20:26
    
My previously described error was caused by a mistake in the shebang of the script. –  Mad Scientist May 5 '11 at 7:54
add comment

3 Answers

up vote 5 down vote accepted

Option 1 would be to modify the source code of the calling app and insert tee into the output pipeline to get a copy of the output for review at that stage.

Option 2 would be to write a wrapper script around the executable in question. A quick script that passes on stdin and arguments to the real app, then tee's the output to a location for you to review and also spits it back out the same way the app would should be just a couple lines to whip up. Put it someplace special and make add that location to the front of your PATH variable, then run your application.

#!/bin/sh
cat - | /path/to/realapp $@ | tee /tmp/debug_output
share|improve this answer
    
Thanks for the idea, I tried it but replacing the executable with a shell script does not work, unfortunately. I can't change the source code of the calling app either. –  Mad Scientist May 4 '11 at 14:48
    
@Fabian In general this DOES work, I've had to do it several times. You do need to know what to wire up to each end; basically all the input/output options on both ends need to be directly patched through. This could include trapping and passing signals. Can you explain why this "doesn't work" for you? –  Caleb May 4 '11 at 20:11
    
I've added my progress to my question. You're right that it works, my script works exactly as it should with test input. But it is not executed by a shell for some reason when called from the big program. –  Mad Scientist May 4 '11 at 20:22
    
Sorry for the confusion, it was just an error in the shebang causing the problem. –  Mad Scientist May 5 '11 at 7:53
add comment

Rather than changing your path, you should move the binary you are interested in from "binary" to "binary.orig" then replace it with a script. You said you are interested in the arguments, so you'll want to write those out to a file as well. You will probably also be interested in the output of the command "env". It dumps all the environment variables currently active. Environment variables are often used by one program to influence the behavior of another program that it calls.

share|improve this answer
add comment

You can obtain a lot of information about a program by calling it under strace. This shows every system call that the program makes, which can be too much information sometimes, but can be a big help to find what's going wrong.

Approach one is to run your big application under strace. This is likely to produce a lot of output and slow your application down.

strace -s9999 -efile,process -f -o bigapp.strace bigapp

If the big application is interactive, you may prefer to start it, and connect strace to it once you're ready to trigger the calculations. Note the application's process ID, say 12345, and run

strace -s9999 -efile,process -f -o bigapp-calculations.strace -p12345

If it's enough to observe that external executable, then as other answers have already suggested, replace that executable by a wrapper script. You can move the executable to a different name and put the wrapper script in its place, or put the wrapper script ahead of the usual executable in the PATH, or configure the application to call your wrapper script instead of the usual executable, whatever is convenient. Make that wrapper script

#!/bin/sh
exec strace -s9999 -efile -o auxapp-$$.strace /path/to/original/executable "$@"

Explanation of the strace parameters used:

  • -e selects the system calls to trace. You can specify system calls by name or use a few categories such as file (open, close, read, write, …) and process (fork, execve, …).
  • -f makes strace follows forks, i.e. trace subprocesses as well as the original process.
  • -o selects the name of the file containing the trace. $$ is a shell construct that stands for the process ID of the shell process (due to the use of exec in the last wrapper script, that will also be the auxiliary application's process ID).
  • -s9999 makes it display that many bytes for read and write and other calls.
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.