I have written a DTrace script which measures the time spent inside a function in my C program. The program itself runs, outputs some data and then exits.
The problem is that it finishes way to fast for me to get the process id and start DTrace.
At the moment I have a sleep() statement inside my code which gives me enough time to start DTrace. Having to modify your code in order to get information on it kinda defeats the purpose of Dtrace... right.
Basically what I'm after is to make DTrace wait for a process id to show up and then run my script against it.
Presumably you're using the pid provider, in which case there's no way to enable those probes before the process has been created. The usual solution to this is to invoke the program from dtrace itself with its "-c" option.
If for some reason you can't do that (i.e. your process has to be started in some environment set up by some other process), you can try a more complex approach: use proc:::start or proc:::exec-success to trace when your program is actually started, use the stop() action to stop the program at that point, and then use system() to run another DTrace invocation that uses the pid provider, and then "prun" the program again.
Related
I'm trying to control the way my cursor looks during certain points of my program execution. To be specific, I want it to be a "spinner" when a Python script is executing, and then a standard pointer when it's done executing. Right now, I have a leave-event-notify callback in Glade that changes the spinner when it leaves a certain area, but this is non-ideal since the user might not know to move the cursor and the cursor doesn't accurately represent the state of the program.
I have my Python program signalling SIGUSR1 at the end of execution. I am spawning the Python script from a C file using GLib's g_spawn_async_with_pipes. Is there any way to catch a signal from the child process that this creates? Thanks!
Pass the G_SPAWN_DO_NOT_REAP_CHILD flag to g_spawn_async_with_pipes() and then call g_child_watch_add() to get a notification when your Python subprocess exits. You don’t need to bother with SIGUSR1 if the process exits when it’s done.
It’s a bit hard to provide a more specific answer unless you post a minimal reproducible example of your code.
I´m trying to get some values displayed on an eInk-Display (via SPI). I already wrote the software to initialize the display and display the values passed as command-line arguments. The problem is, because of the eInk-technology it takes a few seconds for the display to have fully actualized, so the display-program is also running for this time.
The other ("Master"-) program collects the values and does other stuff. It has a main loop, which has to be cycled through at least 10x/second.
So I want to start the displaying program from within the main loop and immediately continue with the loop.
When using system() or execl(), the Master-program either waits till the display program is finished or exits into the new process.
Is there a way to just start other programs out of other ones without any further connection between them? It should run on Linux.
May fork() be a solution?
quick and dirty way: use system with a background suffix (&)
char cmd[200];
sprintf("%190s &","your_command");
system(cmd);
note that it's not portable because it depends on the underlying shell. For windows you would do:
sprintf("start %190s","your_command");
The main drawback of the quick & dirty solution is that it's "fire & forget". If the program fails to execute properly, you'll still have a 0 return code as long as the shell could launch the process.
A portable method (also allowing to take care of the return code of the process) is slightly more complex, involving running a system call from a thread or a forked executable. The quick & dirty solution does a fork + exec of a shell command behind the scenes.
I have an executable file which performs data acquisition from an interfaced FPGA and stores it in a specific format. Once in a while, randomly, the acquisition code stops citing receive error. However, re-running the executable works.
Hence one temporary arrangement is to run the executable in a shell script. The corresponding process needs to be monitored. If the acquisition stops (and the process ends), the script should re-run the executable.
Any hints on how to go about it?
By your description, it sounds like you simply want an endless loop which calls the collector again and again.
while true; do
collector
done >output
Redirecting the output outside of the loop is more efficient (you only open the file for writing once) as well as simpler (you don't have to figure out within the loop whether to overwrite or append). If your collector doesn't produce data on standard output, then of course, this detail is moot.
grep for the executable process in the shell script wrapper. If the PID is not found, then restart. You need to schedule the Shell wrapper as a cron job.
If the fork and exec patter is used just to run a program without freeze the current program, what's the advantage, for example, over using this single line:
system("program &"); // run in background, don't freeze
The system function creates a new shell instance for running the program, which is why you can run it in the background. The main difference from fork/exec is that using system like this actually creates two processes, the shell and the program, and that you can't communicate directly with the new program via anonymous pipes.
fork+exec is much more lightweight than system(). The later will create a process for the shell, the shell will parse the command line given and invoke the required executables. This means more memory, more execution time, etc. Obviously, if the program will run in background, these extra resources will be consumed only temporarily, but depending on how frequently you use it, the difference will be quite noticeable.
The man page for system clearly says that system executes the command by "calling /bin/sh -c command", which means system creates at least two processes: /bin/sh and then the program (the shell startup files may spawn much more than one process)
This can cause a few problems:
portability (what if a system doesn't have access to /bin/sh, or does not use & to run a process in the background?)
error handling (you can't know if the process exited with an error)
talking with the process (you can't send anything to the process, or get anything out of it)
performance, etc
The proper way to do this is fork+exec, which creates exactly one process. It gives you better control over the performance and resource consumption, and it's much easier to modify to do simple, important things (like error handling).
I'm writing a linux daemon in C which gets values from an ADC by SPI interface (ioctl). The SPI (spidev - userland) seems to be a bit unstable and freezes the daemon at random times.
I need to have some better control of the calls to the functions getting the values, and I was thinking of making it as a thread which I could wait for to finish and get the return value and if it times out assume that it froze and kill it without this new thread taking down the daemon itself. Then I could apply measures like resetting the ADC before restarting. Is this possible?
Pseudo example of what I want to achieve:
(function int get_adc_value(int adc_channel, float *value) )
pid = thread( get_adc_value(1,&value); //makes thread calling the function
wait_until_finish(pid, timeout); //waits until function finishes/timesout
if(timeout) kill pid, start over //if thread do not return in given time, kill it (it is frozen)
else if return value sane, continue //if successful, handle return variable value and continue
Thanks for any input on the matter, examples highly appreciated!
I would try looking at using the pthreads library. I have used it for some of my c projects with good success and it gives you pretty good control over what is running and when.
A pretty good tutorial can be found here:
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
In glib there is too a way to check the threads, using GCond (look for it in the glib help).
In resume you should periodically set a GCond in the child thread and check it in the main thread with a g_cond_timed_wait. It's the same with the glib or the pthread.
Here is an example with the pthread:
http://koders.com/c/fidA03D565734AE2AD9F5B42AFC740B9C17D75A33E3.aspx?s=%22pthread_cond_timedwait%22#L46
I'd recommend a different approach.
Write a program that takes samples and writes them to standard output. It simply need have alarm(TIMEOUT); before every sample collection, and should it hang the program will exit automatically.
Write another program that runs that first program. If it exits, it runs it again. It looks something like this:
main(){for(;;){system("sampler");sleep(1);}}
Then in your other program, use FILE*fp=popen("supervise_sampler","r"); and read the samples from fp. Better still: Have the program simply read the samples from stdin and insist users start your program like this:
(while true;do sampler;sleep 1; done)|program
Splitting up the task like this makes it easier to develop and easier to test, for example, you can collect samples and save them to a file and then run your program on that file:
sampler > data
program < data
Then, as you make changes to program, you can simply run it again on the same data over and over again.
It's also trivial to enable data logging- so should you find a serious issue you can run all your data through your program again to find the bugs.
Something very interesting happens to a thread when it executes an ioctl(), it goes into a very special kind of sleep known as disk sleep where it can not be interrupted or killed until the call returns. This is by design and prevents the kernel from rotting from the inside out.
If your daemon is getting stuck in ioctl(), its conceivable that it may stay that way forever (at least till the ADC is re-set).
I'd advise dropping something, like a file with a timestamp prior to calling ioctl() on a known buggy interface. If your thread does not unlink that file in xx amount of seconds, something else needs to re-start the ADC.
I also agree with the use of pthreads, if you need example code, just update your question.