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