Get the output of multiple strace calls in one file - file

I want to get the Output of multiple strace calls in one file,
but i do not know how.
At the moment i am using:
strace -o tmpfile, but this just puts the output of one file in and then overrites the file with the new output.
Has anyone an idea, how to do this?
I hope this is no dumb question.
Thanks in advance.

Under the bash shell use the following command
strace -o >(cat >>outputfile) command [args] ...
This will pass to the -o flag an argument that will appear like a file, but will be instead a file descriptor to the standard input of the
cat >>outputfile
process. This process will append its input to the specified output file.

Instead of strace -o somefile command, can you just do strace command >> somefile? Alternatively, assuming a similar version of strace, my manual for strace indicates this should work: strace -o "|tail -a somefile" command (the -o "|command" functionality is implemented by strace itself, not by the shell).

I could not manage to do this via the call itself (in the Android Shell).
I just read through all files and write them to one Log file.
This solution slows the whole process down, but was the only solution I found.

The strace output is on stderr, strace 2>> outfile did the trick for me. If you invoke strace as single command you have to call it like this: adb -e shell "strace -p pid 2>> file"

Related

Why should one exec "sh -c a.out" instead of a.out itself?

I'm studying Apple's implementation of popen() at https://opensource.apple.com/source/Libc/Libc-167/gen.subproj/popen.c.auto.html and noticed that they do execl(_PATH_BSHELL, "sh", "-c", command, NULL) instead of execl(_PATH_BSHELL, command, NULL).
Why would you want to (or should you) exec an executable, e.g. a.out via sh -c instead of just the executable itself?
If you exec sh -c a.out instead of just a.out itself, does the actual a.out process end up being a "grandchild" process and not a child process?
Why would you want to (or should you) exec an executable, e.g. a.out via sh -c instead of just the executable itself?
popen() is designed to run shell commands that include shell syntax like > redirection, | pipes, and && command chaining. It needs to pass the string through sh -c in order to support those constructs. If it didn't those syntactical features would be passed verbatim to the program in question as arguments.
For example, popen("make clean && make") should trigger two make invocations. Without sh -c it would call make once with three arguments, as if one had typed
$ make clean '&&' make
at the terminal.
If you exec sh -c a.out instead of just a.out itself, does the actual a.out process end up being a "grandchild" process and not a child process?
Yes, that is correct. There will be a sh process in between the current process and a.out.
that they do execl(_PATH_BSHELL, "sh", "-c", command, NULL) instead of execl(_PATH_BSHELL, command, NULL)
The latter would NOT have executed command directly, but _PATH_BSHELL (/bin/sh) with its $0 set to command and no arguments, resulting in an shell expecting commands from its stdin.
Also, that syntax relies on NULL being defined to an explicit pointer (e.g. ((void*)0)), and not just 0, which is not guaranteed anywhere. While they can do that in their implementation (because they control all the headers), it's not what you should do in application code.
And no, execl(command, command, (void*)NULL) wouldn't have executed command directly either, unless command is a) a full path and b) in an executable format (binary or a script starting with a she-bang #! -- the latter being a non-standard extension). If command was a simple command name to be looked up in PATH (like pwd or a.out) or an executable script not starting with a she-bang, you should've used execlp instead of execl.
The exec[lv]p[e] functions do some of the things a shell does (like looking through the PATH), but not all of them (like running multiple commands or expanding variables): that's why functions like system(3) or popen(3) pass the command to /bin/sh -c. Notice that with both it's /bin/sh, not the user's login shell or the $SHELL from the environment which is used.
If you exec sh -c a.out instead of just a.out itself, does the actual a.out process end up being a "grandchild" process and not a child process?
Only with some shells like dash. Not with bash, ksh93, mksh, zsh, yash, busybox, etc, which will execute a.out directly instead of forking and waiting for it.

C program that executes bash commands inside xterm with execl

I have a command that execute well in the normal terminal on Linux:
xterm -e bash -c "some commands"
I want to execute the above command using c program execXX system calls. I try to use the following codes but it gives me a normal xterm window.
execl("/usr/bin/xterm", "/usr/bin/xterm -e bash -c \"some commands\"", NULL);
Is there any way I can execute the above command using execXX system calls? Thank you!
You need to call it like:
execl("/usr/bin/xterm", "/usr/bin/xterm", "-e", "bash", "-c", "some commands", (void*)NULL);
The convention is to let the first argument be the same as the path to the program. If you have spaces in the arguments, it will be the same effect as calling xterm 'something with spaces' instead of xterm something with spaces.
A possible tangent: is there any reason why you need these to run specifically within xterm? If you just want to run some shell commands, then running them within /bin/sh or /bin/bash would be more natural, and probably more reliable.

Watching new entries on Linux Syslog from a C program

I want to write a program that monitors syslog and performs an action when PPP authentication fails.
I think "tail -f /var/log/syslog" could help, but I'm not sure how to use it... probably using pipes?
I have found something similar written in bash, but I'm not sure how to implement it in C.
This is the bash method:
First create a named pipe using mkfifo:
$ mkfifo -p /home/mezgani/syslog.pipe
Make syslog.conf to points to this file:
*.info |/home/mezgani/syslog.pipe
Restart syslog:
$ sudo pkill -HUP syslogd
Create processing script that read the pipe
$ cat > foo
#!/bin/bash
cat /home/mezgani/syslog.pipe | while read input
do
# some stuff
echo ${input}
# ….
done
Finally I could found the solution!!
The solution was using named pipes!
First, I need to create a named pipe:
mkfifo /pipe
Then, I feed the pipe with the log info:
tail -f /var/log/syslog > /pipe
And then, I read the pipe from the C program using OPEN
int pipefd;
pipefd = open("/tmp/myFIFO", O_WRONLY);
Try to use inotify function. Using it you can monitor if a file or directory has changed.

Executing shell script with system() returns 256. What does that mean?

I've written a shell script to soft-restart HAProxy (reverse proxy). Executing the script from the shell works. But I want a daemon to execute the script. That doesn't work. system() returns 256. I have no clue what that might mean.
#!/bin/sh
# save previous state
mv /home/haproxy/haproxy.cfg /home/haproxy/haproxy.cfg.old
mv /var/run/haproxy.pid /var/run/haproxy.pid.old
cp /tmp/haproxy.cfg.new /home/haproxy/haproxy.cfg
kill -TTOU $(cat /var/run/haproxy.pid.old)
if haproxy -p /var/run/haproxy.pid -f /home/haproxy/haproxy.cfg; then
kill -USR1 $(cat /var/run/haproxy.pid.old)
rm -f /var/run/haproxy.pid.old
exit 1
else
kill -TTIN $(cat /var/run/haproxy.pid.old)
rm -f /var/run/haproxy.pid
mv /var/run/haproxy.pid.old /var/run/haproxy.pid
mv /home/haproxy/haproxy.cfg /home/haproxy/haproxy.cfg.err
mv /home/haproxy/haproxy.cfg.old /home/haproxy/haproxy.cfg
exit 0
fi
HAProxy is executed with user haproxy. My daemon has it's own user too. Both run with sudo.
Any hints?
According to this and that, Perl's system() returns exit values multiplied by 256. So it's actually exiting with 1. It seems this happens in C too.
Unless system returns -1 its return value is of the same format as the status value from the wait family of system calls (man 2 wait). There are macros to help you interpret this status:
man 3 wait
Lists these macros and what they tell you.
A code of 256 probably means that the system command cannot locate the binary to run it. Remember that it may not be calling bash and that it may not have paths setup. Try again with full paths to the binaries!
I have the same problem when call script that contains `kill' command in a daemon.
The daemon must have closed the stdout, stderr...
Use something like system("scrips.sh > /dev/null") should work.

system command hanged in C program, but when I run the command on bash it is successfull

I need to send the arp of a IP to get it's mac address which is configured on different machine. I am arping this ip from a C program by "system(arping -c 3 -i eth0 ) but I see that this is hanged in there.
But if I run the same command from bash "arping -c 3 -i eth0 " it get executed successfully.
I could not understand why system command hanged in this case while the command is successfully completed when run from bash.
Thanks,
Since you said it was hanging you can try:
strace -o my_prog.strace -f ./my_prog
and then kill it after it hangs. Then you can view the strace output file my_prog.strace and try to figure out what went wrong.
You may want to look at the strace man page to see other options that you might like use -- of particular use to me are ones that make it show more data in buffer (and string) input/output.
If it's not really hanging you should check the return value from your call to system( ) and then inspect errno.
edit
Something that I just thought of that could cause a hang would be if arping was actually a link to a setuid root program that did sudo on the real arping and it is waiting on a password to be typed in, but the terminal for that program isn't set correctly.
try system("arping -c 3 -I eth0 ip-addr");
something like:
main()
{
system("arping -c 3 -I eth0 192.168.10.1");
}
Are you using any child process to execute above ?
From Definition of system() :
The system() function shall ignore the SIGINT and SIGQUIT signals, and shall block the SIGCHLD signal, while waiting for the command to terminate. The system() function shall not return until the child process has terminated.
Recommendations:
1.check on the return value of system() & take appropriate decision.
Eg: If return value is zero it means command processor is not available.If a child process cannot be created, or if the termination status for the command language interpreter cannot be obtained, system() shall return -1 and set errno to indicate the error.
2.Use complete shell commands to be executed.
Eg: system("arping -c 3 -I eth0 10.203.198.10");

Resources