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.
Related
I'm trying out generics in swift an came across something unusual while debugging:
instead of printing out the value assigned to the variable, it just prints something different. Heres the example code:
class GenericExample<T: Comparable>{
var someVar: T
init(myVar: T){
someVar = myVar
}
}
let generics = GenericExample<Int>(myVar: 57)
print(generics.someVar)
the result is fine(57) but when running the program for debugging, as in with breakpoints, the value is presented as something like 4301684792
any tips would be appreciated
Don't examine, in the debugger, the value of a variable whose value is not assigned until the line you're breakpointed in or later. That line has not been executed yet, so you will see a random value! (Namely, whatever happens to be sitting in memory at that address.)
Only examine earlier variable values! And don't even look at the little tooltips that pop up. Look only at the variables pane and the lldb console.
Lets say I have a small program that involves picking a document from a database:
let errorDatabase
= NSError(domain: "dk.myproject.couchbase", code: 0, userInfo: nil)
let rev = database.existingDocumentWithID("_design/" + designDocName)
// in xcode I set a break point here
assert(rev != nil)
if rev == nil {
promise.failure(errorDatabase)
}
Then I insert a breakpoint, run the program and can afterwards do:
(lldb) po rev
0x00007fad21df61c0
{
ObjectiveC.NSObject = {...}
}
(lldb) print rev.properties["views"]
(AnyObject?) $R29 = Some {
...
Perfect lets enter the repl and play with the rev object:
(lldb) repl
6> rev
repl.swift:6:1: error: use of unresolved identifier 'rev'
rev
^
I might have wrong expectations for the swift repl - I'm expecting some kind of python, nodejs or scala repl. behaviour where I can play around with objects etc.
Any hints?
I was hoping the same thing the first time I typed repl within LLDB, but I soon discovered that unfortunately you can't do it.
The repl inside LLDB, it turns out, is running in a module injected at top level. Thus you could, from within the repl here, define top-level objects and functions, which are then visible back in "normal" lldb:
(lldb) repl
1> func pt() -> CGPoint {
2. return CGPointZero
3. }
4> :
(lldb) po pt()
(0.0, 0.0)
... but the converse is not true: you cannot, inside the repl, see local variables at the point you are paused, as they are obviously not in scope from top level.
Do note, however, that you can perform assignments in an expr expression. Thus, you can change the value of a local variable, the properties of an existing object, etc., just by saying expr followed by an assignment - and that this does take place in the context where you are paused.
For example, let's say I'm in the middle of creating a pan edge gesture recognizer, and I pause at a breakpoint at this line:
p.edges = UIRectEdge.Right
Now:
(lldb) th step-over
(lldb) expr p.edges = UIRectEdge.Left
(lldb) continue
And now the app is running, but the gesture recognizer works when swiping from the left instead of the right.
Note, I described the purposes and differences between "expression" and "repl" in this question:
Xcode 6.1 'Swift REPL built into the Xcode debugger can inspect and manipulate your running app' not working
Maybe that will help you understand the similarities & differences you are seeing and then intent behind them.
Problem: In project we have localization functions which are specific to a framework/dynamic library. That is they have identical name but fetch resources from different bundles/folders
I'd want to call a function from a specific library, something similar to:
lldb> p my_audio_engine.framework::GetL10nString( stringId );
lldb> expr --shlib my_audio_engine.framework -- GetL10nString();
lldb> p my_audio_engine`L10N_Utils::GetString(40000)
but all these variants don't work.
Adding gdb in tags hoping the same semantic if exists will work on lldb as well.
lldb's expression parser doesn't currently have the equivalent of gdb's foo.c::function meta-symbol to encode a function from a specific source file.
Please feel free to file a bug requesting this at bugreporter.apple.com. It will get duped to the one I filed a while ago, but dups are votes for features, and we haven't gotten around to this one yet 'cause nobody but me asked for it...
For the nonce, you will have to do this by hand. Here's a silly example for calling printf, which I happen to know is in libsystem_c.dylib on OS X. First, I find the address in the shared library I am interested in:
(lldb) image lookup -vn printf libsystem_c.dylib
1 match found in /usr/lib/system/libsystem_c.dylib:
Address: libsystem_c.dylib[0x0000000000042948] (libsystem_c.dylib.__TEXT.__text + 266856)
Summary: libsystem_c.dylib`printf
Module: file = "/usr/lib/system/libsystem_c.dylib", arch = "x86_64"
Symbol: id = {0x00000653}, range = [0x00007fff91307948-0x00007fff91307a2c), name="printf"
The first address (the one under Address) is the address of the function in the dylib, not where it got loaded in the running program. That's not immediately useful. I could calculate the library's load offset if I wanted to and apply it to the file address, but fortunately the first address in the Symbol's address range is the address in the running program so I don't have to. 0x00007fff91307948 is the address I want.
Now I want to call that address. I do this in two steps because it makes the casting easier, like:
(lldb) expr typedef int (*$printf_type)(const char *, ...)
(lldb) expr $printf_type $printf_function = ($printf_type) 0x00007fff91307948
Now I have a function I can call over and over:
(lldb) expr $printf_function("Hello world %d times.\n", 400)
Hello world 400 times.
(int) $2 = 23
If you are going to do this over and over, you can write a Python function that finds the symbol out of the library of interest, and constructs the expression that calls the right function. The Python API's include calls to get symbols from a particular module (lldb-speak for loadable binary images), get their addresses, evaluate expressions, etc.
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
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 *$