How do you extract data from gdb - c

How do you extract data from gdb so you can examine it in another program?
I am using gdb to debug a program. To see what is in array udata, I have created a source file called printudata with the following contents:
print udata[0]
print udata[1]
print udata[2]
...
print udata[143]
From within gdb I can execute that using source command and get output like this:
(gdb) source printudata
$399 = 1
$400 = 2.5
$401 = .3-10
...
$542 = <number>
So far, that is the best I can do for examining memory.
The only thing I can think of to do with this is (learn regular expressions and) strip off everything up to the equal sign so I can paste this into a spreadsheet which will tell me whether it's correct.
Is this the really the best way to get output from gdb? I am learning all this on my own and only have the basic, free tools that come with Linux (and am a beginner with all the above listed technologies)

You can print an array if it is really an array like this:
p udata
But, if udata is really a pointer, then you can use a cast to make gdb print it like an array.
p *(double(*)[144])udata
If you really want the line at a time output of your current "script", you can define a function and use a loop:
define print_udata
set $i=0
while ($i < 144)
p udata[$i]
set $i=$i+1
end
end
To log the output to a file, you can enable/disable logging:
set logging on
...gdb commands...
set logging off
The output will be in a file called gdb.txt.

In addition to the above, gdb has the "output" and "printf" commands. These don't enter the value into the value history, and they let you control the output much more precisely.

gdb has built-in scripting in both its own scripting language and in python. You can even script GDB from within a python program. You can use any of those options to write the data to a file.
More information about python & gdb here.

Related

How to check whether large command text answer contains a specific string

This is related to u-boot.
I looked at this link (How to test the return of a command in U-Boot CLI) but it doesn't cover what I need. I also checked some other pages related to the 'test' command in u-boot but I can't figure out how to do what I would like. So there it is.
I have a u-boot command on a SBC which returns a set of information as text printed on the screen, where some part are strings representing versions. What I would like is to check whether the command return contains some specific strings to choose automatically what to do.
I have seen a few 'test' command help, but I couldn't figure out how to do this type of check on the text returned by this command. My goal is to have a set of nested ifs to choose in the different cases, or anything equivalent. If regex can be used, they perhaps could be helpful.
Does anybody know how to do this?
Thank you.
In U-Boot's hush shell there is no support for pipes. There is also no command like grep. So there are no means to succeed via U-Boot's built-in shell commands.
If you have access to the source of the command that you are executing, you could change it and use function env_set() to write the relevant data to environment variables and then use test for your purposes.

Trace and log values of a variable with GDB

I am not an experienced programmer but I recently have to check C code translated from Matlab, in order to ensure that with the same data set, C and Matlab are giving the identical results.
Watches are what I am able to use until now but that requires me to sit in front of the screen and watch the values of a variable change at each loop. Is there a way to trace and log the values of a variable into a .txt file so that I can plot it later to compare with the results from Matlab?
I have already tried to write the values into some .txt file with 'fwrite' but there is not the ideal solution as I have to do that in the C code that I want to check. Embarrassed I am currently reading about tracepoint of gdb and will try to use that but I am still unsure if that is what I need. If you have some tips about what else I try.
I´m using Windows 7 and work with CodeBlocks.
Thanks!
Christina
You can set a breakpoint command to run when your watchpoint hits; have it log and execute a continue command to let the program keep running.

(Asterisk PBX) How to control program written in C from asterisk agi in features.conf

How to control programs written in C from asterisk AGI-application in features.conf?
I want to control my program by pushing keys on the telephone (dtmf-tones). I was reading about using pipes for passing on standard I/O. My first idea was:
$ Asterisk | c_program
then have standard output in AGI-script by printf()
The second idea was to use:
$ printf parameter_a >> file
to write to file and then let my c-program read the file and evaluate the contents as parameter.
Has anyone tried out or has experience with similar tasks/problems?
there are no way do like u show.
posible solutions:
1) Run your program with arguments using system(). you can do that with or without AGI.
2) Use linux pipe(special files)
3) Start your program as AGI/EAGI script, your program must work acordinly, see CAGI
4) Use database table(task) and asterisk realtime for put record in it.
most correct is 3) if ur program is not demon and 2,4 if ur program is demon.
also you can use in dialplan

Set GDB breakpoint in C file

Is it possible to add GDB breakpoints in a C files, before compilation? Currently, I have to specify breakpoints after compilation through GDB.
I'm looking for something similar to JavaScript's debugger; statement.
Not as such, but you can insert some helpful function calls:
One option is to create a function:
void break_here ()
{
/* do nothing */
}
then call it wherever you want, but be careful it doesn't get inlined (put it in a different file, or add a "noinline" attribute).
Then, in GDB, just set a breakpoint on break_here, and you're done. If you find it tedious to set that breakpoint every time, you can create a file named .gdbinit in your home directory or in the current working directory that contains the breakpoint command.
Another option that works on Linux is to use a signal:
raise (SIGUSR1);
You could use any signal you like, but it's better to use one that doesn't kill your program (although you can configure GDB to not pass them onto your program, if you choose).
I'm not aware of a way to directly set a breakpoint, but GDB will catch interrupts, so that is one possible solution.
Something like this should work. You'll need to include signal.h:
raise(SIGABRT);
on linux, which I'm assuming you're on since you're using gdb you could make a script to do it with comments in the code
#!/bin/bash
#debug: Script to run programs in gdb with comments to specify break
points
echo "file ./a.out" > run
grep -nrIH "/\*GDB\*/" |
sed "s/\(^[^:]\+:[^:]\+\):.*$/\1/g" |
awk '{print "b" " " $1 }'|
grep -v $(echo $0| sed "s/.*\///g") >> run
gdb --init-command ./run -ex=r
exit 0
then wherever you need a breakpoint, just add /*GDB*/, the script will use grep to find the line numbers and files with those comments, and set a break point on each line of each file it finds them on, then start gdb

Writing a portable command line wrapper in C

I'm writing a perl module called perl5i. Its aim is to fix a swath of common Perl problems in one module (using lots of other modules).
To invoke it on the command line for one liners you'd write: perl -Mperl5i -e 'say "Hello"' I think that's too wordy so I'd like to supply a perl5i wrapper so you can write perl5i -e 'say "Hello"'. I'd also like people to be able to write scripts with #!/usr/bin/perl5i so it must be a compiled C program.
I figured all I had to do was push "-Mperl5i" onto the front of the argument list and call perl. And that's what I tried.
#include <unistd.h>
#include <stdlib.h>
/*
* Meant to mimic the shell command
* exec perl -Mperl5i "$#"
*
* This is a C program so it works in a #! line.
*/
int main (int argc, char* argv[]) {
int i;
/* This value is set by a program which generates this C file */
const char* perl_cmd = "/usr/local/perl/5.10.0/bin/perl";
char* perl_args[argc+1];
perl_args[0] = argv[0];
perl_args[1] = "-Mperl5i";
for( i = 1; i <= argc; i++ ) {
perl_args[i+1] = argv[i];
}
return execv( perl_cmd, perl_args );
}
Windows complicates this approach. Apparently programs in Windows are not passed an array of arguments, they are passed all the arguments as a single string and then do their own parsing! Thus something like perl5i -e "say 'Hello'" becomes perl -Mperl5i -e say 'Hello' and Windows can't deal with the lack of quoting.
So, how can I handle this? Wrap everything in quotes and escapes on Windows? Is there a library to handle this for me? Is there a better approach? Could I just not generate a C program on Windows and write it as a perl wrapper as it doesn't support #! anyway?
UPDATE: Do be more clear, this is shipped software so solutions that require using a certain shell or tweaking the shell configuration (for example, alias perl5i='perl -Mperl5i') aren't satisfactory.
For Windows, use a batch file.
perl5i.bat
#echo off
perl -Mperl5i %*
%* is all the command line parameters minus %0.
On Unixy systems, a similar shell script will suffice.
Update:
I think this will work, but I'm no shell wizard and I don't have an *nix system handy to test.
perl5i
#!bash
perl -Mperl5i $#
Update Again:
DUH! Now I understood your #! comment correctly. My shell script will work from the CLI but not in a #! line, since #!foo requries that foo is a binary file.
Disregard previous update.
It seems like Windows complicates everything.
I think your best there is to use a batch file.
You could use a file association, associate .p5i with perl -Mperl5i %*. Of course this means mucking about in the registry, which is best avoided IMO. Better to include instructions on how to manually add the association in your docs.
Yet another update
You might want to look at how parl does it.
I can't reproduce the behaviour your describe:
/* main.c */
#include <stdio.h>
int main(int argc, char *argv[]) {
int i;
for (i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
}
return 0;
}
C:\> ShellCmd.exe a b c
ShellCmd.exe
a
b
c
That's with Visual Studio 2005.
Windows is always the odd case. Personally, I wouldn't try to code for the Windows environment exception. Some alternatives are using "bat wrappers" or ftype/assoc Registry hacks for a file extension.
Windows ignores the shebang line when running from a DOS command shell, but ironically uses it when CGI-ing Perl in Apache for Windows. I got tired of coding #!c:/perl/bin/perl.exe directly in my web programs because of portability issues when moving to a *nix environment. Instead I created a c:\usr\bin directory on my workstation and copied the perl.exe binary from its default location, typically c:\perl\bin for AS Perl and c:\strawberry\perl\bin for Strawberry Perl. So in web development mode on Windows my programs wouldn't break when migrated to a Linux/UNIX webhost, and I could use a standard issue shebang line "#!/usr/bin/perl -w" without having to go SED crazy prior to deployment. :)
In the DOS command shell environment I just either set my PATH explicitly or create a ftype pointing to the actual perl.exe binary with embedded switch -Mperl5i. The shebang line is ignored.
ftype p5i=c:\strawberry\perl\bin\perl.exe -Mperl5i %1 %*
assoc .pl=p5i
Then from the DOS command line you can just call "program.pl" by itself instead of "perl -Mperl5i program.pl"
So the "say" statement worked in 5.10 without any additional coaxing just by entering the name of the Perl program itself, and it would accept a variable number of command line arguments as well.
Use CommandLineToArgvW to build your argv, or just pass your command line directly to CreateProcess.
Of couse, this requires a separate Windows-specific solution, but you said you're okay with that, this is relatively simple, and often coding key pieces specifically to the target system helps integration (from the users' POV) significantly. YMMV.
If you want to run the same program both with and without a console, you should read Raymond Chen on the topic.
On Windows, at the system level, the command-line is passed to the launched program as a single UTF-16 string, so any quotes entered in the shell are passed as is. So the double quotes from your example are not removed. This is quite different from the POSIX world where the shell does the job of parsing and the launched program receives an array of strings.
I've described here the behavior at the system level. However, between your C (or your Perl) program there is usually the C standard library that is parsing the system command line string to give it to main() or wmain() as argv[]. This is done inside your process, but you can still access the original command line string with GetCommandLineW() if you really want to control how the parsing is done, or get the string in its full UTF-16 encoding.
To learn more about the Windows command-line parsing quirks, read the following:
http://www.autohotkey.net/~deleyd/parameters/parameters.htm#WIN
http://blogs.msdn.com/b/oldnewthing/archive/2006/05/15/597984.aspx
You may also be interested by the code of the wrapper I wrote for Padre on Win32: this is a GUI program (which means that it will not open a console if launched from the Start menu) called padre.exe that embeds perl to launch the padre Perl script. It also does a small trick: it changes argv[0] to point it to perl.exe so that $^X will be something usable to launch external perl scripts.
The execv you are using in your example code is just an emulation in the C library of the POSIX-like behavior. In particular it will not add quotes around your arguments so that the launched perl works as expected. You have to do that yourself.
Note that due to the fact that the client is responsible for parsing, each client client can do it the way it wants. Many let the libc do it, but not all. So generic command-line generation rules on Windows can not exist: the rule depend on the program launched.
You may still be interested in "best effort" implementation such as Win32::ShellQuote.
If you were able to use C++ then perhaps Boost.Program_options would help:
http://www.boost.org/doc/libs/1_39_0/doc/html/program_options.html

Resources