I'm trying to write a GDB script (legacy, not Python) that will print information on members of a local variable (a C or C++ struct), but only if that local variable exists. Something like:
# 'magic' should be evaluate to "if 'info locals' has a variable named foo, then
# evaluate to true, otherwise evaluate to false.
if (magic)
print foo->member
end
I know this is somewhat contrived, because the locals are dependent on the stack frame (so I'm probably better off making it conditional on the frame), but I'd still like to know if something along these lines is possible.
First -- Python is just far superior for this kind of thing. That's why we added it to gdb!
However, this can still be done with an older gdb. However, it's awful, and after doing it I think you'll appreciate the Python approach even more. What you do is: first, use the various "set logging" commands to redirect the output to a temporary file . Then use gdb commands to print the information you need, in this case something like "info local". Then, use the "shell" command to shell out to rewrite the temporary file into a file that is itself a gdb script. For example, use "sed" to detect that the variable exists in your output, and then emit "set $var_exists=1". Finally, "source" the result of this scripting and test the convenience variable that was set.
Eww. But it works.
Related
I would like to write a bat script which call gdb. I want to use script variables in debugging session (like paths, variable names etc.) For example name and location of the config, address ranges to dump or even command.
Is there easy way to do that? I know that there are gdb scripts but I'm not sure how to do that in easy way.
I see that I can access to script variables with "environment" specifier but I can't use it in other way than show and modify this data.
Without considering the sense of this example I would like to have behavior like below.
Bat script:
SET MY_COMMAND=run
SET MY_COMMAND2=quit
SET MY_FUNCTION=main
:: GDB CALL ??
And expected gdb behavior:
break MY_FUNCTION
MY_COMMAND
MY_COMMAND2
Maybe this will be solution for you:
~/.gdbinit
You can put gdb commands there, and whenever gdb is started it will execute them.
Well, in fact, in your case it would be easier to use another approach:
--command=FILE
I would like to assign the "info sharedlibrary" value to a variable in user define function.
Such as,
define customFunction
set $i = info sharedlibrary
end
But it seems impossible in gdb
And also i cannot use python script too...
Is there any way to do this??
Thank you
ps. I trying to do this because i want to print only selected library's instructions.
You don't mention why you can't use a Python function. That's by far the simplest way to program gdb.
However, if you really must do it, and really must avoid Python, there is a way. It's gross! But it does work. It's like this:
Use the various set logging commands to redirect output to a temporary file.
Invoke the command you want.
Use set logging again to disable logging.
Use the shell command to run sed or perl or what-have-you on this temporary file to turn it into a sequence of gdb commands, say commands to set a variable, or commands to print exactly the output you want.
source the resulting file
I would like to know if it is possible to build tcl scripts debugger using Tcl Library API and/or Tcl internal interfaces (I mean if they contain sufficient data to do so). I've noticed that existing tcl debuggers instrument tcl scripts and work with this additional layer. My idea was to use Tcl_CreateObjTrace to trace every evaluated command and use it as a point to retrive callstack, locals etc. Problem is that it seems that not every information is accessible from API at a time of evaluation. For example I would like to know which line is currently evaluated but Interp has such info only for top evaluations (iPtr->cmdFramePtr->line is empty for procedures' bodies). Anyone has tried such approach? Does it make any sense? Maybe should I look into hashed entries in Interp? Any clues and opinions would be appreciated (the best for Tcl 8.5).
Your best bet for a non-intrusive debugging system might be to try using an execution step trace (called for each command called during the execution of the command to which the trace is attached) with info frame to actually get the information. Here's a simple version, attaching to source so that you can watch an entire script:
proc traceinfo args {
puts [dict get [info frame -2] cmd]
}
trace add execution source enterstep traceinfo
source yourscript.tcl
Be prepared for plenty of output. The dictionary out of info frame can have all sorts of relevant entries, such as information about what the line number of the command is and what the source file is; the cmd entry is the unsubstituted source for the command called (if you want the substituted version, see the relevant arguments to the trace callback, traceinfo above).
I am writing a drop-down console for my app. Suppose I want to output the value of variable myvar by using the following command:
]/get myvar
Is there a better way than to create a map so that the output is
return mymap[argv[0]]; ?
In other words, can I associate the input char array "myvar" to the variable named myvar without doing it manually for all the variables in the program.
Short answer:
No.
Long answer:
Pfff, no way! After your piece of code is build as a binary, there is no such thing as a variable name. Just some pointers, values on the stack, and so on...
If you want to implement something like this, I would recommend you to go for a scripting library (Lua, for example), and manually map some variables so you can read/change those variables via scripts. In this case the console input is basically what you are feeding to the script engine.
This might be a good reference.
UPDATE:
In fact, just found the project called Lua Console.
Seems like it's not maintained anymore, but it doesn't mean it will not work.
How do you pass options to an executable? Is there an easier way than making the options boolean arguments?
EDIT: The last two answers have suggested using arguments. I know I can code a workable solution like that, but I'd rather have them be options.
EDIT2: Per requests for clarification, I'll use this simple example:
It's fairly easy to handle arguments because they automatically get parsed into an array.
./printfile file.txt 1000
If I want to know what the name of the file the user wants to print, I access it via argv[1].
Now about how this situation:
./printfile file.txt 1000 --nolinebreaks
The user wants to print the file with no line breaks. This is not required for the program to be able to run (as the filename and number of lines to print are), but the user has the option of using if if s/he would like. Now I could do this using:
./printfile file.txt 1000 true
The usage prompt would inform the user that the third argument is used to determine whether to print the file with line breaks or not. However, this seems rather clumsy.
Command-line arguments is the way to go. You may want to consider using Boost.ProgramOptions to simplify this task.
You seem to think that there is some fundamental difference between "options" that start with "--" and "arguments" that don't. The only difference is in how you parse them.
It might be worth your time to look at GNU's getopt()/getopt_long() option parser. It supports passing arguments with options such as --number-of-line-breaks 47.
I use two methods for passing information:
1/ The use of command line arguments, which are made easier to handle with specific libraries such as getargs.
2/ As environment variables, using getenv.
Pax has the right idea here.
If you need more thorough two-way communication, open the process with pipes and send stuff to stdin/listen on stdout.
You can also use Window's PostMessage() function. This is very handy if the executable you want to send the options to is already running. I can post some example code if you are interested in this technique.
The question isn't blazingly clear as to the context and just what you are trying to do - you mean running an executable from within a C++ program? There are several standard C library functions with names like execl(), execv(), execve(), ... that take the options as strings or pointer to an array of strings. There's also system() which takes a string containing whatever you'd be typing at a bash prompt, options and all.
I like the popt library. It is C, but works fine from C++ as well.
It doesn't appear to be cross-platform though. I found that out when I had to hack out my own API-compatible version of it for a Windows port of some Linux software.
You can put options in a .ini file and use the GetPrivateProfileXXX API's to create a class that can read the type of program options you're looking for from the .ini.
You can also create an interactive shell for your app to change certain settings real-time.
EDIT:
From your edits, can't you just parse each option looking for special keywords associated with that option that are "optional"?