Calling StepOut() and EvaluateExpression() in immediate sequence - lldb

Calling StepOut() and then EvaluateExpression() in immediate sequence, for example from a script, does not return the expected value.
It does work when manually and separately calling these functions from the console:
(lldb) script lldb.thread.StepOut()
(lldb) script print lldb.frame.EvaluateExpression("$rax").description
However, it does not work when combining them into one statement:
(lldb) script lldb.thread.StepOut(); print lldb.frame.EvaluateExpression("$rax").description
This prints None to the console.
Checking the process's state shows that there's a difference between the two forms:
(lldb) script lldb.thread.StepOut()
(lldb) script print lldb.process.state
The state value is lldb.eStateStopped.
When running in sequence, the state immediately after StepOut is different:
(lldb) script lldb.thread.StepOut(); print lldb.process.state
Here the state is lldb.eStateRunning.
So the questions is:
How should code be written to ensure StepOut has fully completed? I'm assuming that requires the state to be back to stopped, and the frame to be initialized/setup, before calls to EvaluateExpression()?

The lldb SBDebugger can run in either synchronous or asynchronous mode.
In async mode, the commands that cause the debugee to run return as soon as it starts running. That's useful if you are planning control the whole debug session, handling events yourself, etc. There's an example of doing that here:
http://llvm.org/svn/llvm-project/lldb/trunk/examples/python/process_events.py
In synchronous mode, StepOut won't return till the debugee stops again. That mode is more convenient for one-off commands like the ones you show.
You can set the mode on the debugee using the "SBDebugger.SetAsync" call, passing True for async, and False for sync.

Related

How to avoid C thread blocking by a child process opened with io.popen from lua?

I have a C pthread running a non-blocking event loop which executes lua scripts. A lua script runs io.popen to execute a shell script which takes some time to complete.
I am only interested in capturing the first few characters from the output of the script even though the script takes time to complete. As the lua script reads those first few characters and reaches its end it returns execution to C as expected. The problem is that the shell script that was opened with io.popen keeps running in the background until it completes. Calling f.close() in lua after reading the first few characters does not seem to halt its execution (it appears to only close the read side of the pipe?). Unfortunately, it starts blocking my C thread and displays "write error: broken pipe" messages until the shell script ends. This would make sense if the read end of the pipe is closed (and garbage collected) as the lua script ends execution, and the write end is still being written to by the shell script. The question is, how do I either kill the shell script since i am no longer interested in the rest of its output/execution, or silence it in a way that will not block my parent process?
I have tried redirecting 2>/dev/null on the io.popen command but that only silenced the "write error: broken pipe" messages - the blocking is still there.
If there is a way to get the child process (from C) of what lua openes with io.popen and kill that? (I'm thinking that might also help).
Any thoughts/suggestions are greatly appreciated!

Automatically connect to a CGI process and break in GDB before it exits?

For a C application accessed via CGI-BIN, documentation online for accessing the process and breaking in GDB relies on manipulating the source code (i.e. adding an infinite loop), in order for the process to be available long enough for a developer to attach, exit the loop, and debug.
Is it feasible that a tool could monitor the process list, and attach via GDB, immediately breaking in order for a developer to achieve this without requiring source code changes?
The rough structure of what I have in mind to develop is something along the lines of:
1. My process monitors the process list on the system.
2. A process matching the name of my application, and owner Apache appears in the list.
3. My process immediately performs a 'pgrep' and 'gdb -p' command, then sending a break-point command to pause the process.
4. The developer can then access the process and look at the flow of execution.
Is this feasible as an idea or not possible due to some constraints (i.e. a race condition which may not always be fufilled?)
Is this feasible
Sure: a trivial shell script will do:
while true; do
PID=$(pgrep my_app)
if [[ -n "$PID" ]]; then
gdb -p "$PID"
fi
done
a race condition
The problem is that between pgrep and gdb -p the application may make significant progress, or even run to completion.
The only way to avoid that is to intercept all execve system calls on the system, as Tom Tromey's preattach.stp does.

How to disable timeout in LLDB?

In LLDB console, my process is stopped. I run thread step-in and eventually get:
Command timed out
How do I extend or disable this timeout?
In my case, this timeout is expected it because the program requires external interaction before going to the next line.
thread step-in has no timeout. That wouldn't make any sense, as your last comment demonstrates.
The print command can take a timeout, but by default does not. If you run po the object description printing part of that command is run with a timeout. And if you have any code-running variable formatters, they are also run with a timeout. lldb has removed most of the built-in code-running formatters, though there a few of them still around and they could also be responsible for the timeout message. But other than printing, there aren't really that many things lldb does with a timeout...
Anyway, what you are probably seeing is that after the previous stop happened some code was being run to present locals or something similar and that command was what timed out.
If you can get this to happen reliably, then please file a bug with http://bugreporter.apple.com.

Executing more with "exec()" function corrupts line breaking in bash

I had an exercise to write a program that will do the following pipe processing:
ls -la | grep "^d" | more
After executing my program however, the bash interpreter would not break line nor display commands correctly, however after executing them the result is showed, it looks like the input for the console is not getting on stdout but somewhere else and i cant find the reason of this behavior.
I am using 3 child process with stdio redirected to connect the pipe between them.
The program finishes successfully it shows the good result, no errors are showed or whatever, also when i am using the cat instead of more everything works normally after execution, is it possible that more changes some system values and does not change them back?
It's likely that more is turning off echo and canonical mode on your TTY (see man 3 termios), and never switching them back on before it exits (either because it gets killed without a chance to, or because it doesn't think it's attached to a TTY). You can attach to more with gdb to find out why that's ahppening, or you could simply reset the terminal yourself before exiting.

create process independent of bash

I have written a program which calculates the amount of battery level available in my laptop. I have also defined a threshold value in the program. Whenever the battery level falls below threshold i would like to call another process. I have used system("./invoke.o") where invoke.o is the program that i have to run. I am running a script which runs the battery level checker program for every 5 seconds. Everything is working fine but when i close the bash shell the automatic invocation of invoke.o is not happening. How should i make the invoke.o to be invoked irrespective of whether bash is closed or not??. I am using UBUNTU LINUX
Try running it as: nohup ./myscript.sh, where the nohup command allows you to close the shell without terminating the process.
You could run your script as a cron job. This lets cron set up standard input and output for you, reschedule the job, and it will send you email if it fails.
The alternative is to run a script in the background with all input and output, including standard error output, redirected.
While you could make a proper daemon out of your program that kind of effort is probably not necessary.
man nohup
man upstart
man 2 setsid (more complex, leads to longer trail of breadcrumbs on daemon launching).

Resources