1#!/usr/bin/python 2 3#---------------------------------------------------------------------- 4# Be sure to add the python path that points to the LLDB shared library. 5# On MacOSX csh, tcsh: 6# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python 7# On MacOSX sh, bash: 8# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python 9#---------------------------------------------------------------------- 10 11import lldb 12import os 13import sys 14 15def disassemble_instructions (insts): 16 for i in insts: 17 print i 18 19def usage(): 20 print "Usage: disasm.py [-n name] executable-image" 21 print " By default, it breaks at and disassembles the 'main' function." 22 sys.exit(0) 23 24if len(sys.argv) == 2: 25 fname = 'main' 26 exe = sys.argv[1] 27elif len(sys.argv) == 4: 28 if sys.argv[1] != '-n': 29 usage() 30 else: 31 fname = sys.argv[2] 32 exe = sys.argv[3] 33else: 34 usage() 35 36# Create a new debugger instance 37debugger = lldb.SBDebugger.Create() 38 39# When we step or continue, don't return from the function until the process 40# stops. We do this by setting the async mode to false. 41debugger.SetAsync (False) 42 43# Create a target from a file and arch 44print "Creating a target for '%s'" % exe 45 46target = debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT) 47 48if target: 49 # If the target is valid set a breakpoint at main 50 main_bp = target.BreakpointCreateByName (fname, target.GetExecutable().GetFilename()); 51 52 print main_bp 53 54 # Launch the process. Since we specified synchronous mode, we won't return 55 # from this function until we hit the breakpoint at main 56 process = target.LaunchSimple (None, None, os.getcwd()) 57 58 # Make sure the launch went ok 59 if process: 60 # Print some simple process info 61 state = process.GetState () 62 print process 63 if state == lldb.eStateStopped: 64 # Get the first thread 65 thread = process.GetThreadAtIndex (0) 66 if thread: 67 # Print some simple thread info 68 print thread 69 # Get the first frame 70 frame = thread.GetFrameAtIndex (0) 71 if frame: 72 # Print some simple frame info 73 print frame 74 function = frame.GetFunction() 75 # See if we have debug info (a function) 76 if function: 77 # We do have a function, print some info for the function 78 print function 79 # Now get all instructions for this function and print them 80 insts = function.GetInstructions(target) 81 disassemble_instructions (insts) 82 else: 83 # See if we have a symbol in the symbol table for where we stopped 84 symbol = frame.GetSymbol(); 85 if symbol: 86 # We do have a symbol, print some info for the symbol 87 print symbol 88 # Now get all instructions for this symbol and print them 89 insts = symbol.GetInstructions(target) 90 disassemble_instructions (insts) 91 92 registerList = frame.GetRegisters() 93 print "Frame registers (size of register set = %d):" % registerList.GetSize() 94 for value in registerList: 95 #print value 96 print "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()) 97 for child in value: 98 print "Name: ", child.GetName(), " Value: ", child.GetValue() 99 100 print "Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program" 101 next = sys.stdin.readline() 102 if not next or next.rstrip('\n') == 'quit': 103 print "Terminating the inferior process..." 104 process.Kill() 105 else: 106 # Now continue to the program exit 107 process.Continue() 108 # When we return from the above function we will hopefully be at the 109 # program exit. Print out some process info 110 print process 111 elif state == lldb.eStateExited: 112 print "Didn't hit the breakpoint at main, program has exited..." 113 else: 114 print "Unexpected process state: %s, killing process..." % debugger.StateAsCString (state) 115 process.Kill() 116 117 118 119lldb.SBDebugger.Terminate() 120