Hi all, I have a quick problem that I am sure someone here has an
elegant solution for.
I have a ruby script that runs in a loop an external linux process via
gdb:
...
until checks.empty? do
...
begin
Timeout::timeout(5) {
system("/usr/bin/gdb --args #{proc} 2>/dev/null")}
rescue Timeout::Error
end
...
end
...
What I am trying to do is have gdb terminate after 5 seconds of activity
and move on to debugging the next task. What I am finding however is
that after 5 seconds, my ruby script quits and returns to the command
line and the gdb and debugged processes are left running in the
background.
I can then hit fg and it will start again but this is not what I want; I
want my script to execute gdb and launch it to debug a program, after 5
seconds to terminate debugging and move on to the next binary to debug.
much regards
on 2013-01-24 18:04
on 2013-01-24 18:56
Subject: Processes and forks Date: Fri 25 Jan 13 02:04:38AM +0900 Sorry for the delay! Quoting baq s. (lists@ruby-forum.com): > Timeout::timeout(5) { > line and the gdb and debugged processes are left running in the > background. > > I can then hit fg and it will start again but this is not what I want; I > want my script to execute gdb and launch it to debug a program, after 5 > seconds to terminate debugging and move on to the next binary to > debug. The biggest reason why your process does not die is most probably because you use system (which starts a shell). The signal reaches the shell but not gdb. I believe that gdb has a bit special way to handle interrupts. So, instead of system, you should use Process::spawn. But even then, read carefully the doc: if you pass a command line (like in your example), you will still have a shell process in the middle. To avoid that, you must pass the parts of the command in an array. Every time I do this, I have to spend a decent amount of time finding how to correctly split the command. Anyway, you may try with something like: pid=Process::spawn(array) begin Timeout::timeout(5) do Process::waitpid(pid) end rescue Timeout::Error Process::kill(pid,'KILL') Process::waitpid(pid) end You will have to experiment... Carlo
on 2013-01-24 19:55
Hi Carlo, many thanks for the detailed reply, much appreciated as you have given me very useful information to read about and test. All the best to you.
on 2013-01-24 19:58
Subject: Re: Processes and forks Date: Fri 25 Jan 13 03:55:03AM +0900 Quoting baqtwo front (lists@ruby-forum.com): > many thanks for the detailed reply, much appreciated as you have given > me very useful information to read about and test. All the best to > you. Glad to have been of help! Carlo
on 2013-01-24 21:34
On Thu, Jan 24, 2013 at 6:56 PM, Carlo E. Prelz <fluido@fluido.as> wrote: > The biggest reason why your process does not die is most probably > because you use system (which starts a shell). The signal reaches the > shell but not gdb. I don't think there is a signal at all because system just blocks until the process dies and the timeout exception is raised *after* the process has terminated and control comes back into the Ruby interpreter. Proof: Test script: $ cat k.sh #!/usr/bin/bash echo "PID $$" for i in {0..30}; do trap "echo signal $i" $i done read -p ENTER # block Demo to show signal output via pressing Ctrl-C: $ ./k.sh PID 2296 ENTERsignal 2 signal 2 signal 2 signal 2 signal 0 Now with Timeout: $ time ruby -r timeout -e 'Timeout.timeout(2) { system "./k.sh" }' PID 3552 ENTER signal 0 -e:1:in `system': execution expired (Timeout::Error) from -e:1:in `block in <main>' from -e:1:in `<main>' real 0m18.096s user 0m0.046s sys 0m0.201s As you can see from real time I waited much longer than the timeout of 2 seconds before I pressed enter. > So, instead of system, you should use Process::spawn. But even then, > read carefully the doc: if you pass a command line (like in your > example), you will still have a shell process in the middle. To avoid > that, you must pass the parts of the command in an array. Every time I > do this, I have to spend a decent amount of time finding how to > correctly split the command. That's generally good advice but I believe in this case not important for the issue (see above). > Process::waitpid(pid) > end That looks like a good solution. Kind regards robert
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.