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