How to execute commands conditionally in gdbinit functions - gdb

I have a gdb function, defined in gdbinit file:
define myfunc
set $retval = SOMEHOW_RET_VALUE_OF shell my-shell-command
if $retval == 0
load my-output
else
echo command not succeeded, not doing anything.\n
end
end
How can I get my-shell-func return status and use it to control loading new binary output?

There are two ways to do this.
The simplest way is to use gdb's built-in Python scripting capability. For a case like the above, you could write a new convenience function that does what you like. A convenience function is appropriate here because it can be used directly in an expression.
To write a convenience function, look through the docs for gdb.Function.
Then you would use it like:
set $retval = $_shellcommand("shell command")
If you'd rather not dive into Python, there is still a way; although it is somewhat more painful.
For a simple shell command, the idea would be to write the exit status of the shell command to a gdb script file, which you then source:
(gdb) shell false; echo "set \$retval = $?" > /tmp/q
(gdb) source /tmp/q
(gdb) print $retval
$1 = 1
This gets somewhat hairier if you want more than just the exit status, or if you want to use output from gdb commands in the computation.

Related

What is the safe way of get the return status from an executed shell command in c++

Since the function std::system(const char* command) from cstdlib doesn't guarantee that will return the correct return status from the shell, then how can I run a command in shell using c/c++ and have a guarantee that will give me the right return value?
In my case, for example, I ran a command with:
bool is_process_running(std::string p_name){
std::string command_str= "ps aux | grep '" + p_name + "' | egrep -v '(grep|bash)'";
int result(0);
result= system(command_str.c_str());
return result == 0;
}
If I run, for example, ps aux | grep 'my_process' | egrep -v '(grep|bash)' directly into the terminal and after that echo $?, I see it returning 0 because my_process is running and also returning 1 when I use a non running process. But, the code above returns a different value. This code used to work when I tested in CentOs 6 but now in CentOs 7 doesn't work anymore. So, what can I use to run the shell command and get the correct result?
I also found a solution using pidof command but I can't use this because pidof doesn't consider the parameters passed to my_process which I need since I have many instances of this process each with different arguments.
The problem is that the exit status of Bash isn't guaranteed to be the exit status of the last executed command. If there's an error in the command you pass, you can't really distinguish it from egrep failing to match anything.
What you need to do is to do is to both get the exit status and parse the output (both to standard output and standard error). This can be accomplished by copying much of what the system function does: First create a pipe for the output (both stderr and stdout could be using the same pipe), then fork a new process to run the shell, and then execute the shell and the pipeline.
In the parent process you wait for the child to exit, and get its exit status. If it's zero then you know everything worked fine, and you can discard all the output from the pipe. If it's non-zero you have to read the output from the pipe to see what happened, if there was some error except egrep failing.

lldb command if statement

Hi I need to write a lldb breakpoint command that evaluates a value and prints out a value.
In gdb I could do it like this:
if ($value==2)
printf "Value is 2\n"
end
But in lldb the 'if-statement' is invalid it seems:
failed with error: 'if' is not a valid command.
error: Unrecognized command 'if'.
Can anyone tell me how to write this comparison inside my breakpoint command? Thanks!
You can use the expression parser to achieve this effect in some cases, and you can use the lldb Python interpreter for whatever complex work you want to do in response to a breakpoint hit. Given the fairly deep level of Python support, we felt if you don't know Python, you time would be better spent learning a little bit of that so you could really script lldb, rather than learning whatever little micro-language we would come up with.
Anyway, so using the interpreter, you could for instance do:
expr if ($value == 2) { (int) printf("Value is 2\n"); }
And using the python interpreter you can write a callback like:
def myCallback (frame, breakpoint_location, dict):
value = frame.FindValue("$value", lldb.eValueTypeConstResult)
if (value.unsigned == 10):
print "Value is 10"
put that in a file called myModule.py, do:
(lldb) command script import myModule.py
and then assign the command to your breakpoint with:
(lldb) breakpoint command add -F myModule.myCallback <BREAKPOINT_NUMBER>
That python example was a little more complex than normal because you were looking up lldb's equivalent of gdb's "convenience variable". If you were looking up a local, you could use frame.FindVariable.
More details on this at:
http://lldb.llvm.org/python-reference.html

How to get the return code from a batch/shell script that launched from C++ code

We have a C++ program, sometimes this program need to execute a user defined batch/shell/ant script. We are not able to control how this script runs. Is there a way to get the return code from C++ program?
Something like:
exec a script.sh > status.tmp ?
We need to support both Windows and Linux.
Any ideas?
Another simple of going this is get the return using the marco WEXITSTATUS. Pretty much the same way that you get return values of child process using waitpid call (in Unix based systems).
Here is the sample program. I have one C/C++ program, and one simple bash script.
Sample bash script
#!/bin/bash
echo "I am in Script"
exit 5;
Sample C/C++ program
int i, ret = system("./b.sh 2>&1 > /dev/null");
i=WEXITSTATUS(ret);
printf("My val= %d\n",i);
Output
./a.out
My val= 5
If you want more advanced approach to have multiple return code from the script or want an interactive session then perhaps you should use popen
Hope this helps.
in linux just use
int ret=system("myshellscrtipt.sh");
since the return value of the script is the return value of the system function.
In Windows I'dont't know wether there is a similar function.
If you used the Qt toolkit you could do something like this
QProcess process;
process.start( "yourShellCommand", QStringList( args );
and this would be really cross-platform..
In bash the status code is stored in a special variable:
C:/myprogram.exe
echo $?

Running a shellscript from a C++ application and check if it succeeds

I am creating an interpreter for my extension to HQ9+, which has the following extra command called V:
V: Interpretes the code as Lua, Brainfuck, INTERCAL, Ruby, ShellScript, Perl, Python, PHP in that order, and if even one error has occoured, run the HQ9+-ABC code again
most of them have libraries, BF and INTERCAL can be interpreted without a library, but the problem lies in ShellScript. How can I run a shellscript from my C++ application ( =the HQ9+-ABC interpreter) and when it's done, get the error code (0 = succeded, all others = failed)? So something like this:
system(".tempshellscript738319939474");
if(errcode != 0) { (rerun code); }
can anyone help me? Thanks
From man system(3):
RETURN VALUE
The value returned is -1 on error (e.g. fork failed), and the return
status of the command otherwise. This latter return status is in the
format specified in wait(2). Thus, the exit code of the command will
be WEXITSTATUS(status). In case /bin/sh could not be executed, the
exit status will be that of a command that does exit(127).
system() returns a code depending on the success or failure of whatever you called.
http://www.cplusplus.com/reference/clibrary/cstdlib/system
I remember execve call working for shell scripts that had #! interpreter in their first line for an assignment at university. If you are using system, consider trying execve as well. wait on the pid of the script could help receiving the exit status.

Checking return value of a C++ executable through shell script

I am running a shell script on windows with cygwin in which I execute a program multiple times with different arguments each time. Sometimes, the program generates segmentation fault for some input arguments. I want to generate a text file in which the shell script can write for which of the inputs, the program failed. Basically I want to check return value of the program each time it runs. Here I am assuming that when program fails, it returns a different value from that when it succeeds. I am not sure about this. The executable is a C++ program.
Is it possible to do this? Please guide. If possible, please provide a code snippet for shell script.
Also, please tell what all values are returned.
My script is .sh file.
The return value of the last program that finished is available in the environment variable $?.
You can test the return value using shell's if command:
if program; then
echo Success
else
echo Fail
fi
or by using "and" or "or" lists to do extra commands only if yours succeeds or failed:
program && echo Success
program || echo Fail
Note that the test succeeds if the program returns 0 for success, which is slightly counterintuitive if you're used to C/C++ conditions succeeding for non-zero values.
if it is bat file you can use %ERRORLEVEL%
Assuming no significant spaces in your command line arguments:
cat <<'EOF' |
-V
-h
-:
-a whatnot peezat
!
while read args
do
if program $args
then : OK
else echo "!! FAIL !! ($?) $args" >> logfile
fi
done
This takes a but more effort (to be polite about it) if you must retain spaces. Well, a bit more effort; you probably use an eval in front of the 'program'.