Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect lldb output to file

I'm using lldb inside Xcode, and one of my variables contains a huge chunk of JSON data. Using po myVar isn't much helpful to analyse this data, as it will output in the tiny Xcode debug console.

Is there a way to redirect lldb output to a file ?

I saw here that such a feature seems to be available on gdb as :

(gdb) set logging on
(gdb) set logging file /tmp/mem.txt
(gdb) x/512bx 0xbffff3c0
(gdb) set logging off

and is "translated" in lldb as :

(lldb) memory read --outfile /tmp/mem.txt --count 512 0xbffff3c0
(lldb) me r -o/tmp/mem.txt -c512 0xbffff3c0
(lldb) x/512bx -o/tmp/mem.txt 0xbffff3c0

However, the memory read command will not help in my case, and apparently, --outfile is not available for the print command.

like image 666
Guillaume Algis Avatar asked Oct 04 '13 08:10

Guillaume Algis


4 Answers

You can use a Python script to do so (and much more), as explained here:

LLDB Python scripting in Xcode

Create a file named po.py in a directory of your choice (for example "~/.lldb"):

import lldb

def print_to_file(debugger, command, result, dict):
  #Change the output file to a path/name of your choice
  f=open("/Users/user/temp.txt","w")
  debugger.SetOutputFileHandle(f,True);
  #Change command to the command you want the output of
  command = "po self"
  debugger.HandleCommand(command)

def __lldb_init_module (debugger, dict):
  debugger.HandleCommand('command script add -f po.print_to_file print_to_file ')

Then in lldb write:

command script import ~/.lldb/po.py
print_to_file
like image 80
vinaut Avatar answered Nov 06 '22 23:11

vinaut


Here is a slight modification incorporating some of the comments from above:

def toFile(debugger, command, result, dict):
    f=open("/Users/user/temp.txt","w")
    debugger.SetOutputFileHandle(f,True);
    debugger.HandleCommand(command)  
    f.close()
    debugger.SetOutputFileHandle(sys.stdout, True)

This allows the command to be supplied as an argument, and reverts the output file handle to stdout after the command is run.

like image 1
Matt Avatar answered Nov 06 '22 23:11

Matt


Assuming that you have a variable named jsonData (which has a Data type) you can save it to a file with this command:

expr jsonData.write(to: URL(fileURLWithPath: "/tmp/datadump.bin"))

Alternatively instead of above command you could dump memory used by this variable to a file as in the example below:

(lldb) po jsonData
▿ Optional<Data>
  ▿ some : 32547 bytes
    - count : 32547
    ▿ pointer : 0x00007fe8b69bb410
      - pointerValue : 140637472797712

(lldb) memory read --force --binary --outfile /tmp/datadump.bin --count 32547 0x00007fe8b69bb410
32547 bytes written to '/tmp/datadump.bin'
like image 1
Leszek Szary Avatar answered Nov 06 '22 23:11

Leszek Szary


I found session save <filename> to be a much better, easier option than those listed here. It's not quite the same as you can't use it (to my knowledge selectively) but for generating logs, it's quite handy.

like image 1
Wyatt Childers Avatar answered Nov 07 '22 01:11

Wyatt Childers