In objective-c, function cal is translated to objc_msgSend. e.g.
[foo doSomething:#"keke"]
is translated to
objc_msgSend(foo, "doSomething:", #"keke")
How could I step directly to foo.doSomething: while debugging in lldb?
lldb does provide thread plan which could control the step logic.
class GotoUser:
def __init__ (self, thread_plan, dict):
self.start_time = time.time()
self.thread_plan = thread_plan
target = self.thread_plan.GetThread().GetProcess().GetTarget();
module = target.GetModuleAtIndex(0)
sbaddr = lldb.SBAddress(module.GetObjectFileHeaderAddress())
self.start_address = sbaddr.GetLoadAddress(target)
module = target.GetModuleAtIndex(1)
sbaddr = lldb.SBAddress(module.GetObjectFileHeaderAddress())
self.end_address = sbaddr.GetLoadAddress(target)
print "start addr: ", hex(self.start_address), " end addr: ", hex(self.end_address)
def explains_stop (self, event):
if self.thread_plan.GetThread().GetStopReason()== lldb.eStopReasonTrace:
return True
else:
return False
def should_stop (self, event):
cur_pc = self.thread_plan.GetThread().GetFrameAtIndex(0).GetPC()
if cur_pc >= self.start_address and cur_pc <= self.end_address:
self.thread_plan.SetPlanComplete(True)
print 'time used ', (time.time() - self.start_time)
return True
else:
return False
def should_step (self):
return True
create a python script, load it to lldb.
run thread step-scripted gotouser.GotoUser.
mission completed.
full source code:
https://github.com/Jichao/lldb-scripts/blob/master/gotouser.py
version built into lldb:
https://github.com/Jichao/lldb
Using the Python thread plan is clever! But you should not have to do this for ObjC messages. lldb knows that objc_msgSend & a few others are the dispatch functions for ObjC messages. So if a step in ends up at objc_msgSend, lldb will figure out the method implementation from the object/selector pair passed in, set a breakpoint there, and continue.
For instance:
(lldb) run
Process 55502 launched: '/private/tmp/trivial' (x86_64)
Process 55502 stopped
* thread #1: tid = 0x32619ba, function: main , stop reason = breakpoint 1.1
frame #0: 0x0000000100000f28 trivial`main at trivial.m:18
15 main()
16 {
17 Trivial *my_foo = [[Trivial alloc] init];
-> 18 [my_foo doSomething];
19 return 0;
20 }
(lldb) s
Process 55502 stopped
* thread #1: tid = 0x32619ba, function: -[Trivial doSomething] , stop reason = step in
frame #0: 0x0000000100000ed7 trivial`-[Trivial doSomething] at trivial.m:10
7 #implementation Trivial
8 - (void) doSomething
9 {
-> 10 NSLog(#"%# called doSomething.", self);
11 }
12 #end
13
So the step in stopped at the actual message receiver in this case. If that is not what is happening for you, most likely something is fooling the part of lldb that does the object/selector -> implementation lookup. I'd have to know more about your code to figure out why that might be.
How could I step directly to foo.doSomething: while debugging in lldb?
seems: No possbile
Workaround: add related breakpoint
your here: -[foo doSomething:]
Related
I'm using lldb to debug objc based service. several breakpoints (which is set
have been placed in the code, and I see that one of them is reached unexpectedly according to the stack trace.
The method encapsulating this breakpoint shouldn't have called but I still see it in stack trace (file1.mm:97) although it seems like the code isn't being execute there.
I suspect that objc internal method __Block_byref_object_copy_ is responsible for copying the block of code which involves both caller and callee methods (MyClass from the upper frame in the stack and the method in file1.mm:97).
While copying the debugger probably thinks that it reach this line for execution and stop there, where in fact it's only for copying the code block which involves those 2 methods.
Perhaps anybody can support this claim or provide additional explanation of why am I getting this breakpoint where it shouldn't occur ?
* frame #0: 0x0000000107e03ce0 MyLib`::__Block_byref_object_copy_((null)=0x00007fda19a86b30, (null)=0x00007ffeea7f3bd0) at file1.mm:97:27
frame #1: 0x00007fff7de6bb78 libsystem_blocks.dylib`_Block_object_assign + 325
frame #2: 0x0000000107dd960a MyLib`::__copy_helper_block_ea8_32r((null)=0x00007fda19a86540, (null)=0x00007ffeea7f3ba8) at file2.mm:47:55
frame #3: 0x00007fff7de6b9f3 libsystem_blocks.dylib`_Block_copy + 104
frame #4: 0x00007fff7c64e1e8 libobjc.A.dylib`objc_setProperty_atomic_copy + 53
frame #5: 0x00007fff5411d16b Foundation`-[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:] + 1885
frame #6: 0x00007fff54168508 Foundation`-[NSXPCConnection _sendSelector:withProxy:arg1:arg2:] + 125
frame #7: 0x00007fff54168485 Foundation`_NSXPCDistantObjectSimpleMessageSend2 + 46
frame #8: 0x0000000107e0520e MyLib`::-[MyClass func:withVar0:Var1:Var2:withError:](self=0x00007fda17c2cb50, _cmd="funcWithVar0:Var1:Var2:Var3:withError:", var0="aaa", var1=0x0000000000000000, var2="bbb", var3=0x00007fda17d41dd0, err=0x00007ffeea7f4258) at MyClass.mm:196:5
UPDATE:
thanks to the comments below, it happen that if I set breakpoint according to file and line, it gives me 3 locations (!?)
breakpoint set --file myfile.mm --line 97
now when I list my breakpoints, it give me 2 breakpoints that aren't related to the actual method which wraps the file, besides the expected breakpoint.
3.2: where = my class`::__Block_byref_object_copy_() + 16 at myfile:97:27, address = 0x0000000107e03ce0, unresolved, hit count = 0
3.3: where = myclass `::__Block_byref_object_dispose_() + 16 at myfile:97:27, address = 0x0000000107e03d40, unresolved, hit count = 0
Not really an answer, more an illustration ...
unsigned fn ( void )
{
return 3; // Set bp here and see what happens
}
int main(int argc, const char * argv[])
{
#autoreleasepool
{
// insert code here...
NSLog(#"Hello, World!");
unsigned int x = 0;
x = 1;
x = 2;
x = 3;
if ( x >= 0 )
{
switch ( 5 )
{
case 1 : x = 4; break;
case 2 : x = 4; break; // Set bp here - it will trigger!!!!
case 3 : x = 4; break;
case 4 : x = 4; break;
case 5 : x = 4; break; // Set bp here and see what happens
case 6 : x = 4; break;
case 7 : x = 4; break;
default : x = 4; break;
}
}
__block unsigned y;
void ( ^ b1 )( void ) = ^ {
y = fn();
};
void ( ^ b2 )( void ) = ^ {
b1();
};
if ( YES )
{
b2();
}
NSLog ( #"x = %u y = %u", x, y );
}
return 0;
}
Without going into too much detail, note that most of the code above will be optimised away. The compiler will optimise for loops and switches aggressively and will optimise superfluous assignments and checks (e.g. x >= 0 for unsigned x) away. Above even the blocks gets inlined and you end up with what appears to be very strange behaviour. I think the blocks here are relevant to your specific problem?
If you optimise then the first breakpoint indicated in the code does not get triggered as the blocks all get inlined (I think as I did not look at the disassembly). Likewise the third one does get triggered, but because of optimisation in the strangest of places. Really, a large part of the code gets reduced into a single assignment and the compiler does not really know where to stick it so when that bp is triggered it looks as if it is in the strangest and most disconnected place possible.
Finally, even the second (!!!) one will trigger. That code should never execute but since it all collapse due to optimisation you can even get it to trigger.
So I would not be too perplexed about what triggers your bp ...
I mean, above I just proved that 2 == 5 if I take the bp seriously. And that is not even variable but constant 2 == 5!!! Quite amusing ...
I'm trying to add a "clone" system call to the xv6 os. The call creates a new kernel thread which shares the calling process’s address space. The following is my code in proc.c
int clone(void(*fcn)(void*), void* arg, void* stack)
{
int i, pid;
struct proc *np;
int *myarg;
int *myret;
if((np = allocproc()) == 0)
return -1;
np->pgdir = proc->pgdir; //Here's where it tell's me proc is undefined
np->sz = proc->sz;
np->parent = proc;
*np->tf = *proc->tf;
np->stack = stack;
np->tf->eax = 0;
np->tf->eip = (int)fcn;
myret = stack + 4096 - 2 * sizeof(int *);
*myret = 0xFFFFFFFF;
myarg = stack + 4096 - sizeof(int *);
*myarg = (int)arg;
np->tf->esp = (int)stack + PGSIZE - 2 * sizeof(int *);
np->tf->ebp = np->tf->esp;
np->isthread = 1;
for(i = 0; i < NOFILE; i++)
if(proc->ofile[i])
np->ofile[i] = filedup(proc->ofile[i]);
np->cwd = idup(proc->cwd);
safestrcpy(np->name, proc->name, sizeof(proc->name));
pid = np->pid;
acquire(&ptable.lock);
np->state = RUNNABLE;
release(&ptable.lock);
return pid;
}
Most of the implementations I found look just like this, however, whenever I try to make it tells me that 'proc' is undefined. Most implementations of clone that I've seen look nearly identical, with all of them utilizing proc. I'd be happy to share my sysproc.c code as well if that would help in any way.
Thank you!
This has nothing to do with your system call's implementation because proc global variable is being set by the scheduler right before resuming a selected "runnable" process.
The reason for null would probably be because calling this function from a wrong context.
A system call implementation is expected to be executed from a wrapping function named sys_mysysfunc that syscall function called due to a system call inerrupt initiated by a user application code.
Please share with us your entire implementation flow for additional assistance.
fn main() {
let x = 5;
println!("{}", x);
let x = 3.14;
println!("{}", x);
let x = "Hello";
println!("{}", x);
}
What happens to the previous values? My understanding is that they are not destroyed.
Is there a way to still access these values?
If they are still consuming memory space, is it possible to release that space?
What happens to the previous values?
Nothing.
Is there a way to still access these values?
No.
If they are still consuming memory space, is it possible to release that space?
No.
Now, all of the above should be true from the perspective of the code. They're not necessarily true from the perspective of the optimiser. For example, the optimiser might notice that uses of the first and second x's don't overlap, so it can re-use the stack storage of the first x for the second x.
Or it might not. The language itself, insofar as I am aware, has no opinion on the subject.
The only way I'm aware of that you can guarantee that a local variable will definitely release it's stack storage is to return from the function it's defined in.
... well, until you consider inlining, which could also make that not true.
Short version: don't worry about it, unless you're using so much stack space that it's causing actual, measurable problems.
The value can be moved out before the variable is shadowed, but
ultimately the value can't be accessed from a shadowed variable.
Answer to Q1: The decision is up to the compiler and data type and size and OS and system memory load (usually stack based data types stay to the end of the main, and heap based data types with big memory footprint may need to drop if needed).
Answer to Q2: After shadowing: No, before shadowing: Yes (Values), run this code.
Answer to Q3: After shadowing: No, before shadowing: see: Disposes of a value. and Rust manual memory management
Variable scoping and shadowing:
Advantages:
1. Since data cannot be accessed from outer scope, Data Integrity is preserved.
2. When "we need more alphabets", this is nice way to limit variables scope.
Also this works well when you need more local variables or scope.
A way to still access these values before shadowing (note: move forced the closure to take ownership of 'x'):
use std::{thread, time};
fn main() {
let mut v = vec![];
let d = time::Duration::from_millis(100);
let x = 5;
println!("{}", x);
v.push(thread::spawn(move || {
for _ in 1..10 {
thread::sleep(d);
println!("Thread 1: {}", x);
}
}));
let x = 3.14;
println!("{}", x);
v.push(thread::spawn(move || {
for _ in 1..10 {
thread::sleep(d);
println!("Thread 2: {}", x);
}
}));
let x = "Hello";
println!("{}", x);
v.push(thread::spawn(move || {
for _ in 1..10 {
thread::sleep(d);
println!("Thread 3: {}", x);
}
}));
for child in v {
let _ = child.join();
}
}
output:
5
3.14
Hello
Thread 1: 5
Thread 3: Hello
Thread 2: 3.14
Thread 2: 3.14
Thread 3: Hello
Thread 1: 5
Thread 1: 5
Thread 3: Hello
Thread 2: 3.14
Thread 2: 3.14
Thread 3: Hello
Thread 1: 5
Thread 2: 3.14
Thread 3: Hello
Thread 1: 5
Thread 2: 3.14
Thread 1: 5
Thread 3: Hello
Thread 2: 3.14
Thread 1: 5
Thread 3: Hello
Thread 3: Hello
Thread 2: 3.14
Thread 1: 5
Thread 1: 5
Thread 2: 3.14
Thread 3: Hello
Note: move forces the closure to take ownership of 'x', so the address of local x is not the same as thread x but the value is:
use std::thread;
fn main() {
let mut v = vec![];
let x = 5;
println!("{:p}", &x);
v.push(thread::spawn(move || {
println!("Thread 1: {:p}", &x);
}));
let x = 3.14;
println!("{:p}", &x);
v.push(thread::spawn(move || {
println!("Thread 2: {:p}", &x);
}));
let x = "Hello";
println!("{:p}", &x);
v.push(thread::spawn(move || {
println!("Thread 3: {:p}", &x);
}));
for child in v {
let _ = child.join();
}
}
output:
0x8bf934
0x8bf9b8
0x8bfa40
Thread 1: 0x4a3faec
Thread 2: 0x4c3fae8
Thread 3: 0x4e3fa70
As far as I know there is only one thing to keep in mind with shadowing: when values are heap allocated.
From the book:
Note that shadowing a name does not alter or destroy the value it was bound to, and the value will continue to exist until it goes out of scope, even if it is no longer accessible by any means
the previous value is not more accessible after shadowing and it will be
destroyed at the end of the scope, not when the variable is shadowed.
If value are on the stack there is nothing to worry: stack memory management is completely in the hands of the processor.
Instead, if the value is heap allocated, shadowing can be seen as a temporary memory leak that will be released at the end of the scope.
If this may be an issue we can explicitly free the memory with drop() before shadowing:
struct Foo {
_v: Vec<i32>
}
impl Drop for Foo {
fn drop(&mut self) {
println!("dropping foo");
}
}
fn main() {
println!("start");
let x = Foo {_v: vec![1,2,3]};
drop(x);
let x = 100;
println!("end");
}
During a debug session with XCode 5, how would I display the actual value of an NSDecimal var? I found this question but that doesn't work for me. Entering a summary description like {(int)[$VAR intValue]} just results in a message "Summary Unavailable". I should add that my NSDecimals are in an array (NSDecimal dataPoint[2];).
Using the debug console to either print the var description via the context menu or by using p dataPoint[0] just gives me the raw NSDecimal view:
Printing description of dataPoint[0]:
(NSDecimal) [0] = {
_exponent = -1
_length = 1
_isNegative = 0
_isCompact = 1
_reserved = 0
_mantissa = {
[0] = 85
[1] = 0
[2] = 42703
[3] = 65236
[4] = 65534
[5] = 65535
[6] = 23752
[7] = 29855
}
}
UPDATE
In Xcode 10.0, there was an lldb bug that made this answer print the wrong value if the Decimal is a value in a Dictionary<String: Decimal> (and probably in other cases). See this question and answer and Swift bug report SR-8989. The bug was fixed by Xcode 11 (possibly earlier).
ORIGINAL
You can add lldb support for formatting NSDecimal (and, in Swift, Foundation.Decimal) by installing Python code that converts the raw bits of the NSDecimal to a human-readable string. This is called a type summary script and is documented under “PYTHON SCRIPTING” on this page of the lldb documentation.
One advantage of using a type summary script is that it doesn't involve running code in the target process, which can be important for certain targets.
Another advantage is that the Xcode debugger's variable view seems to work more reliably with a type summary script than with a summary format as seen in hypercrypt's answer. I had trouble with the summary format, but the type summary script works reliably.
Without a type summary script (or other customization), Xcode shows an NSDecimal (or Swift Decimal) like this:
With a type summary script, Xcode shows it like this:
Setting up the type summary script involves two steps:
Save the script (shown below) in a file somewhere. I saved it in ~/.../lldb/Decimal.py.
Add a command to ~/.lldbinit to load the script. The command should look like this:
command script import ~/.../lldb/Decimal.py
Change the path to wherever you stored the script.
Here's the script. I have also saved it in this gist.
# Decimal / NSDecimal support for lldb
#
# Put this file somewhere, e.g. ~/.../lldb/Decimal.py
# Then add this line to ~/.lldbinit:
# command script import ~/.../lldb/Decimal.py
import lldb
def stringForDecimal(sbValue, internal_dict):
from decimal import Decimal, getcontext
sbData = sbValue.GetData()
if not sbData.IsValid():
raise Exception('unable to get data: ' + sbError.GetCString())
if sbData.GetByteSize() != 20:
raise Exception('expected data to be 20 bytes but found ' + repr(sbData.GetByteSize()))
sbError = lldb.SBError()
exponent = sbData.GetSignedInt8(sbError, 0)
if sbError.Fail():
raise Exception('unable to read exponent byte: ' + sbError.GetCString())
flags = sbData.GetUnsignedInt8(sbError, 1)
if sbError.Fail():
raise Exception('unable to read flags byte: ' + sbError.GetCString())
length = flags & 0xf
isNegative = (flags & 0x10) != 0
if length == 0 and isNegative:
return 'NaN'
if length == 0:
return '0'
getcontext().prec = 200
value = Decimal(0)
scale = Decimal(1)
for i in range(length):
digit = sbData.GetUnsignedInt16(sbError, 4 + 2 * i)
if sbError.Fail():
raise Exception('unable to read memory: ' + sbError.GetCString())
value += scale * Decimal(digit)
scale *= 65536
value = value.scaleb(exponent)
if isNegative:
value = -value
return str(value)
def __lldb_init_module(debugger, internal_dict):
print('registering Decimal type summaries')
debugger.HandleCommand('type summary add Foundation.Decimal -F "' + __name__ + '.stringForDecimal"')
debugger.HandleCommand('type summary add NSDecimal -F "' + __name__ + '.stringForDecimal"')
The easiest way is to turn it into an NSDecimalNumber in the debugger, i.e.
po [NSDecimalNumber decimalNumberWithDecimal:dataPoint[0]]
This will create a new NSDecimalNumber which prints a nice description. The NSDecimal in your questions is 8.5.
(lldb) po [NSDecimalNumber decimalNumberWithDecimal:dataPoint[0]]
8.5
If you want to have the number displayed in the Variable View, the Summary Format for it would be:
{[NSDecimalNumber decimalNumberWithDecimal:$VAR]}:s
For background information and context for my question, please read this question.
Notice in the updatePlot() method of my DynamicPlotter code, I kind of "reach into" a DynamicDataset property, as follows:
function updatePlot(obj, propNum)
X = get(obj.LH(propNum), 'XData');
Y = get(obj.LH(propNum), 'YData');
X(end+1) = obj.(dynProps{propNum}).newestData(1);
Y(end+1) = obj.(dynProps{propNum}).newestData(2);
set(obj.LH(propNum), 'XData', X, 'YData', Y);
end
updatePlot is a listener callback. Rather than "reach in" to go get the newestData, I am wondering if it would be more efficient to have the data "presented" to the callback with event.eventData. But I am unsure of (a) how to even use event.eventData (the example provided in the documentation isn't very clear to me), and (b) if this yields better or worse performance.
So I guess my main question is, what's the best way for updatePlot() to access the newestData as depicted in the method above: "reaching in and retrieving it" or using event.eventData to "send" the data point to the function to plot?
I hope this wasn't terribly ambiguous.
You first need to have a class that defines an event (in MyClass.m):
classdef MyClass < handle
events
% Event
MyEvent
end
methods
function obj = MyClass
% Constructor
end
end
end
Then you need to create your own EventData subclass (in MyEventData.m):
classdef MyEventData < event.EventData
properties (Access = public)
% Event data
Data
end
methods
function this = MyEventData(data)
% Constructor
this.Data = data;
end
end
end
Attach your data to an instance of the event data class (in a script file):
X = 1:10;
Y = 1:10;
data = struct('XData', X, 'YData', Y);
eventData = MyEventData(data);
And fire the event from your obj and have a listener listen to it:
obj = MyClass;
l = addlistener(obj, 'MyEvent', #(evtSrc,evtData)disp(evtData.Data));
notify(obj, 'MyEvent', eventData)
Anytime you call notify(...), the evtData argument in your listener callback will have your data in its Data property:
>> notify(obj, 'MyEvent', eventData)
XData: [1 2 3 4 5 6 7 8 9 10]
YData: [1 2 3 4 5 6 7 8 9 10]