Great! This is exactly what I was looking for and works perfectly. Thanks, Scott Knight
On Thu, Apr 17, 2014 at 2:27 PM, Greg Clayton <[email protected]> wrote: > > SBValue > SBTarget::FindFirstGlobalVariable (const char* name); > > This doesn't support the "GetValueForVariablePath()", so you will need to > do: > > ruby_current_vm = lldb.target.FindFirstGlobalVariable('ruby_current_vm'); > > heaps_used = > ruby_current_vm.GetValueForExpressionPath('->objspace->heap_pages.used').GetValueAsUnsigned(0) > > You can also use a very handy wrapper utility class called lldb.value: > > ruby_current_vm = > lldb.value(lldb.target.FindFirstGlobalVariable('ruby_current_vm')) > > Now "ruby_current_vm" behaves like a C structure would, except you can't > use "->" to refer to a child of a pointer you need to use ".". So you > should be able to do: > > heaps_used = ruby_current_vm.objspace.heap_pages.used > > for i in xrange(heaps_used): > page = ruby_current_vm.objspace.heap_pages.sorted[i] > > You had a derefernce on "page" before, but, you can use page is a > lldb.value, so you can just do "page.foo.bar" if you need anything inside > of it. > > Greg > > On Apr 17, 2014, at 11:09 AM, Scott Knight <[email protected]> wrote: > > > Thanks for the information Greg. I have a quick followup. I'm using the > version of lldb that comes with XCode 5.1.1 > > > > Launching it like this > > > > Scotts-MacBook-Pro:~ scottknight$ > /Applications/Xcode.app/Contents/Developer/usr/bin/lldb -p 13892 > > Attaching to process with: > > process attach -p 13892 > > Process 13892 stopped > > Executable module set to > "/Users/scottknight/.rbenv/versions/2.1.1/bin/ruby". > > Architecture set to: x86_64-apple-macosx. > > > > When I tried using GetValueForVariablePath I got 'No value' back. See > the output below. > > > > (lldb) v > > lldb-310.2.37 > > (lldb) script > > Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or > Ctrl-D. > > >>> print lldb.frame.EvaluateExpression('ruby_current_vm') > > (rb_vm_t *) $1 = 0x00007f9a01003000 > > >>> print lldb.frame.GetValueForVariablePath('ruby_current_vm') > > No value > > > > Since ruby_current_vm is a global variable is there something different > I would need to do to access it? > > > > Thanks, > > Scott Knight > > > > > > On Thu, Apr 17, 2014 at 1:45 PM, Greg Clayton <[email protected]> > wrote: > > Running expressions has all sorts of side effects like storing data in > the inferior program and it also involves running the clang expression > parser which can be expensive. > > > > You can, from a frame, get a SBValue for a variable without using the > expression parser: > > > > lldb::SBValue > > SBFrame.GetValueForVariablePath (const char *var_path); > > > > So you can change your code to this: > > > > heaps_used = > lldb.frame.GetValueForVariablePath('ruby_current_vm->objspace->heap_pages.used').GetValueAsUnsigned(0) > > > > for i in xrange(heaps_used): > > page = > lldb.frame.GetValueForVariablePath('*ruby_current_vm->objspace->heap_pages.sorted[%i]' > % i) > > > > The GetValueForVariablePath() will find the variable and not create a > temporary each time. It also doesn't use the expression parser at all so it > won't call any code. The objects you access must be available in the > hierarchy of the struct or class and the struct or class can't override the > "->" operator. Other than that, the GetValueForVariablePath() knows how to > access members ("ruby_current_vm->objspace->heap_pages.sorted"), > dereference pointers using the array syntax ("my_ptr[12]"), deref a pointer > ("*this->other_ptr"), and take the address of something > ("&ruby_current_vm->objspace->heap_pages.sorted[12]"). > > > > So give the GetValueForVariablePath a try. The SBValue returned is > something that represents the live variable value, not a const result like > you get back from expression. SBValue you get back is tied to the frame > from which you got it, so it will continue to evaluate correctly and its > value will change if you step between calling functions with it. If the > frame it came from goes away (step out), then it won't return any valid > values again as it will detect the frame is gone and stop answering any > questions. So you should always fetch a fresh value from the frame each > time you want to use it. > > > > Greg > > > > > > On Apr 17, 2014, at 7:57 AM, Scott Knight <[email protected]> wrote: > > > > > I was recently using lldb to connect to a debug build of ruby to > inspect the heap. In order to do this I was doing something like this > > > > > > ----------- > > > heaps_used = > lldb.frame.EvaluateExpression('ruby_current_vm->objspace->heap_pages.used').GetValueAsUnsigned(0) > > > > > > for i in xrange(heaps_used): > > > page = > lldb.frame.EvaluateExpression('*ruby_current_vm->objspace->heap_pages.sorted[%i]' > % i) > > > ----------- > > > > > > What I noticed was that for each EvaluateExpression a temporary $0, > $1, $2, etc.. variable is created. If I ended up calling my python code > multiple times more and more variables seemed to pile up and every > EvaluateExpression call seemed to take longer and longer. > > > > > > I tried calling EvaluateExpression how I would call expr from the lldb > command line setting my own variable, so something like > > > > > > lldb.frame.EvaluateExpression('int $test = 5') > > > > > > But that seemed to error out. So is there some other way in the API > that is better for accessing global variables that won't slow down. Is this > something actually wrong with the debugger? I can create an actual test > case similar to the test suite in lldb if that would be helpful. > > > > > > Thanks, > > > Scott Knight > > > > > > _______________________________________________ > > > lldb-dev mailing list > > > [email protected] > > > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev > > > > > >
_______________________________________________ lldb-dev mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
