GDB: Create local variable? - xcode

I'm using Xcode's debugger. While stopped at a breakpoint, is there a command I can type in the GDB command prompt to create a local variable? If so, how? Please provide an example.
I know I can do it in the code and then recompile the program, but I'm looking for a faster way.

If you don't need to reference the variable in your code but just want to do some ad-hoc investigation, you can use Convenience Variables by using the set command with a variable name starting with $:
(gdb) set $foo = method_that_makes_something()
(gdb) set $bar = 15
(gdb) p $bar
$4 = 15
You'll notice when you print things it's prefixed with a numeric variable - you can use these to refer to that value later as well:
(gdb) p $4
$5 = 15
To reiterate: this doesn't actually affect the program's stack, and it can't, as that would break a lot of things. But it's useful if you just need a local playground, some loop variables, etc.
While you can't modify the stack, you can interact with the program's memory space - you can call functions (including malloc) and construct objects, but these will all live in static memory, not as local variables on the stack.

Since a local variable would require stack space and the (compiled) code is tied to the stack layout, no you can't.
Comparing this with scripting languages is not quite appropriate.

Values printed by the print command are saved in the GDB "value history". This allows you to refer to them in other expressions.
For example, suppose you have just printed a pointer to a structure and want to see the contents of the structure. It suffices to type
p *$

Related

Why does Xcode/lldb display wrong data?

Why does lldb insist on printing the wrong data — the value of the first ivar, no matter which ivar I ask for? This is Xcode 5.1.1. And yes, I am compiling with -O0, symbols not stripped, etc.
(lldb) print *self
(SMTestHarness) $13 = {
NSObject = {
isa = SMTestHarness
}
_dir = 0x00740520 #"/Users/lc/Projects/servermonitor/Test/unit-test"
_ip = 0x007406b0
_domain = 0x007429f0
_sm = 0x00676900
_state = 0x00741980
_dsaSimulators = 0x00741d10 5 key/value pairs
_timers = 0x00741f50 2 objects
_originalWd = 0x007403f0 #"/Users/lc/Projects/servermonitor/Test"
}
(lldb) print _dir
(NSString *) $14 = 0x00740520 #"/Users/lc/Projects/servermonitor/Test/unit-test"
(lldb) print _ip
(IPAddress *) $15 = 0x00740520
(lldb) print _domain
(FirstPointDomain *) $16 = 0x00740520
(lldb) print _sm
(ServerMonitorCrashTestDummy *) $17 = 0x00740520
Interestingly, the variable display in the left-hand pane is correct; it's only print commands in the lldb console that are wrong.
The variables view in Xcode doesn't use the lldb expression parser (i.e. the print command.) Mainly this is because it would be very inefficient to have to parse expressions for each local variable & its subelements every time you step. And even without this, a full-on expression parser is way more fire power than you need for the task of dumping local variable values.
Instead, lldb has another sub-system just for dumping the contents of variables (no calling functions or complex expressions, just printing values.) From command-line lldb, you can get at that subsystem with the frame variable command.
That bit of trivia probably doesn't help you much, but it is why you can get different results from "print" which runs the fully general expression parser and the Xcode locals view...
What you are seeing, however, is that the lldb expression parser isn't getting the value of the offsets of individual ivars within their containing ObjC object right. The expression parser thinks all the ivars are at 0 offset from the object start - which is in fact what your example shows. And more particularly - from the example you included - this happens when debugging a 32 bit app using the 1.0 version of the Objective C Runtime.
That's a long-standing bug in lldb.
There isn't a good workaround if you have to debug ObjectiveC 1.0 32-bit x86 apps. If you have a 32 bit only machine, then you are pretty much stuck here, and have to use frame var. But if you have a 64-bit capable machine, unless there's some very compelling reason to debug the 32 bit fork of the app, you can just switch to debugging the 64 bit version of the app instead, and this problem should go away.
Note, though the iOS simulator runs 32 bit code, it uses the ObjectiveC 2.0 runtime, and doesn't have this bug.
If you are printing objects use the "po" (print object) command.

How do I quickly inspect the value of an arbitrary variable in Xcode 4.6.x?

It seems reasonably widely acknowledged that it is slow to use the po command in Xcode 4.6.x. What are the options for inspecting the values of arbitrary variables unspecified at compile time (which rules out usage of NSLog()) which don't take > 15s?
Just set a breakpoint where you want to learn the variables' value. Once the program is paused, a summary of all the variables' value will appear on the Varibles view on the left-bottom of the screen. Here is a screenshot :
You can use the lldb commands:
p (int) myInt
po myObject
po myObject.memberObject
p (float) myObject.floatMember
Just a note, you could also use p instead of po in the newest version of Xcode. If you run the help -a in llb, it will present you with command aliases, below is a snippet of the commands you could use.
> (lldb) help -a
p -- ('expression --') Evaluate a C/ObjC/C++ expression in the current
program context, using user defined variables and variables
currently in scope.
po -- ('expression -o --') Evaluate a C/ObjC/C++ expression in the
current program context, using user defined variables and
variables currently in scope
print -- ('expression --') Evaluate a C/ObjC/C++ expression in the current
program context, using user defined variables and variables
currently in scope.
Turns out the answer is pretty simple: download Xcode 4.6.2 where LLDB debugging speed has been increased significantly. Note some discussion over here

Lua Debugging - Detect when the value of a variable changes

Is it possible to detect when the value of a variable has changed using the lua debug library.
Something like A callback function which would give details like the function in which the value was changed, previous value, etc.
Is such a thing possible?
I read about hooks, but I'm not sure hooks can be set to variables.
If you don't mind using a debugger, then some debuggers allow you to set Watch expressions, which will be triggered when the condition in the expression is true. I'll show how this can be done in MobDebug (it is using lua debug library, but there is no direct way to detect a variable change as far as I know).
Let say we have a script start.lua like the one below and want to detect where foo gets value 2:
print("Start")
local foo = 0
for i = 1, 3 do
local function bar()
print("In bar")
end
foo = i
print("Loop")
bar()
end
print("End")
Download mobdebug.lua and make it available to your scripts (the simplest way is to put it into the folder with your scripts).
Start the server using lua -e "require('mobdebug').listen()" command.
Start the client using lua -e "require('mobdebug').loop()" command.
You will see the prompt in the server window: '>'. Type load start.lua to load the script.
Type step and then step again. You will see "Paused at file start.lua line 3".
Let's see what the value of foo is. Type eval foo and you should see 0.
Now we can set up our watch. Type setw foo == 2. You can specify any Lua expression after setw command; the execution of your script will be stopped when the condition is evaluated as true.
Continue execution of the script using "run" command.
The watch now fires, which will show you the message like: "Paused at file start.lua line 8 (watch expression 1: [foo == 2])". This means that the previous expression changed the value of foo to 2 and the execution is stopped at line 8. You can then inspect your script and the current values (you can use "eval" and "exec" commands to run any Lua code to be evaluated in your script environment) to find what triggered the change.
The benefit of this approach is that you are not limited to monitoring table values and can specify any expression. The main disadvantage is that your script runs under a debugger and the expression is evaluated after each step, which may get really slow.
You can do this to a certain extent in Lua by using metatables and keeping a "proxy" table, and using the __newindex function call to detect attempts to add a variable.
This is covered here in the Programming in Lua book under the section "Tracking Table Accesses":
http://www.lua.org/pil/13.4.4.html
See Also
http://www.gammon.com.au/forum/?id=10887

How to programmatically unset global bash variables/manage Bash global scope?

Context:
We have several pieces of our infrastructure that are managed by large sets of Bash scripts that interact with each other via the source command, including (and frequently chaining includes) of files that are created compliant with a standard Bash template we use. I know that this is a situation that should probably never have been allowed, but it's what we have.
The template basically looks like this:
set_params() {
#for parameters in a file that need to be accessed by other methods
#in that file and have the same value from initialization of that
#file to its conclusion:
global_param1=value
#left blank for variables that are going to be used by other methods
#in the file, but don't have a static value assigned immediately:
global_param2=
}
main_internals() {
#user-created code goes here.
}
main() {
set_params
#generic setup stuff/traps go here
main_internals arg arg arg
#generic teardown stuff goes here
}
Using this structure, we have files include other files via the source command and then call the included files main methods, which wraps and modularizes most operations well enough.
Problem:
Some of the thorniest problems with this infrastructure arise when a new module is added to the codebase that uses a global variable name that is used somewhere else, unrelatedly, in the same sourced chain/set of files. I.e if file1.sh has a variable called myfile which is uses for certain things, then sources file2.sh, and then does some more stuff with myfile, and the person writing file2.sh doesn't know that (in many cases they can't be expected to--there are a lot of files chained together), they might put a non-local variable called myfile in file2.sh, changing the value in the variable with the same name in file1.sh
Question:
Assuming that global variable name conflicts will arise, and that localing everything can't completely solve the problem, is there some way to programmatically unset all variables that have been set in the global scope during the execution of a particular function or invocations below that? Is there a way to unset them without unsetting other variables with the same names that are held by files that source the script in question?
The answer might very well be "no", but after looking around and not finding much other than "keep track of variable names and unset anything after you're done using it" (which will inevitably lead to a costly mistake), I figured I'd ask.
Phrased another way: is there a way to make/hack something that works like a third scope in Bash? Something between "local to a function" and "visible to everything running in this file and any files sourced by this one"?
The following is untested.
You can save a lot of your variables like this:
unset __var __vars
saveIFS=$IFS
IFS=$'\n'
__vars=($(declare -p))
IFS=$saveIFS
or save them based on a common prefix by changing the next to last line above to:
__vars=($(declare -p "${!foo#}"))
Then you can unset the ones you need to:
unset foo bar baz
or unset them based on a common prefix:
unset "${!foo#}"
To restore the variables:
for __var in "${__vars[#]}"
do
$i
done
Beware that
variables with embedded newlines will do the wrong thing
values with whitespace will do the wrong thing
if the matching prefix parameter expansion returns an empty result, the declare -p command will return all variables.
Another technique that's more selective might be that you know specifically which variables are used in the current function so you can selectively save and restore them:
# save
for var in foo bar baz
do
names+=($var)
values+=("${!var}")
done
# restore
for index in "${!names[#]}"
do
declare "${names[index]}"="${values[index]}"
done
Using variable names instead of "var", "index", "names" and "values" that are unlikely to collide with others. Use export instead of declare inside functions since declare forces variables to be local, but then the variables will be exported which may or may not have undesirable consequences.
Recommendation: replace the mess, use fewer globals or use a different language.
Otherwise, experiment with what I've outlined above and see if you can make any of it work with the code you have.

Setting a watch point in GDB

I am operating a huge code base and want to monitor a value of a particular variable (which is buried deep down inside one of the files)especially when it gets set to zero.
1) Variable does not belong to global scope .Is there a better option than to first set breakpoint into the function where it is defined and then set the watch point?
2) After trying the option in 1 I see that watch point gets deleted after a while saying its out of frame which used this .This way it adds to the tediousness of the procedure since I have to add it again and again?Any workarounds?
3) Is there a way to check ie watch if a particular variable is equal to 0( or any specific constant)?
want to monitor a value of a particular variable
Often this is not the best approach, especially in large codebases.
What you really likely want to do is understand the invariants, and assert that they are true on entry and exit to various parts of the code.
1) Variable does not belong to global scope .Is there a better option than to first set breakpoint into the function where it is defined and then set the watch point?
No. For automatic (stack) variables you have to be in the scope where the variable is "active".
What you can do is set a breakpoint on some line, and attach commands to that breakpoint that will set the watchpoint automatically, e.g.
(gdb) break foo.c:123
(gdb) commands 1
silent
watch some_local
continue
end
3) Is there a way to check ie watch if a particular variable is equal to 0
You can't do that with a watchpoint, but you can with a conditional breakpoint:
(gdb) break foo.c:234 if some_local == 0
I will assume that you are using Linux. You can try this:
The first step is to make the variable static, like:
static int myVar;
Then, after compiling your code using -ggdb, you must discover the address of the variable inside your binary, like so (I have used a real case as example):
readelf -s pdv | grep tmp | c++filt
In my situation, the output is:
47: 081c1474 4 OBJECT LOCAL DEFAULT 25 startProc(int)::tmp
The address in this case is 081c1474. Now you can set a watch point inside GDB:
watch *0x081c1474
Mind the "*0x" before the correct address.
I know this question is old, but I hope it helps anyway.

Resources