diff --git a/lldb/examples/python/disasm.py b/lldb/examples/python/disasm.py new file mode 100755 index 000000000000..f6868e6e4eaa --- /dev/null +++ b/lldb/examples/python/disasm.py @@ -0,0 +1,79 @@ +#!/usr/bin/python + +#---------------------------------------------------------------------- +# Be sure to add the python path that points to the LLDB shared library. +# On MacOSX csh, tcsh: +# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python +# On MacOSX sh, bash: +# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python +#---------------------------------------------------------------------- + +import lldb +import os +import sys +import time + +def disassemble_instructions (insts): + for i in range(0, insts.GetSize()): + print insts.GetInstructionAtIndex(i) + +# Initialize LLDB so we can use it +lldb.SBDebugger.Initialize() + +# Create a new debugger instance +debugger = lldb.SBDebugger.Create() + +# When we step or continue, don't return from the function until the process +# stops. We do this by setting the async mode to false. +debugger.SetAsync (False) + +# Create a target from a file and arch +target = debugger.CreateTargetWithFileAndArch (sys.argv[1], "x86_64") + +if target.IsValid(): + # If the target is valid set a breakpoint at main + main_bp = target.BreakpointCreateByName ("main", "a.out"); + + # Launch the process. Since we specified synchronous mode, we won't return + # from this function until we hit the breakpoint at main + process = target.LaunchProcess (sys.argv[2:], [''], "dev/stdout", 0, False) + + # Make sure the launch went ok + if process.IsValid(): + # Print some simple process info + print "process:", process, "\n" + # Get the first thread + thread = process.GetThreadAtIndex (0) + if thread.IsValid(): + # Print some simple thread info + print "thread: ", thread + # Get the first frame + frame = thread.GetFrameAtIndex (0) + if frame.IsValid(): + # Print some simple frame info + print "frame: ", frame + function = frame.GetFunction() + # See if we have debug info (a function) + if function.IsValid(): + # We do have a function, print some info for the function + print "function: ", function, "\n" + # Now get all instructions for this function and print them + insts = function.GetInstructions(target) + disassemble_instructions (insts) + else: + # See if we have a symbol in the symbol table for where we stopped + symbol = frame.GetSymbol(); + if symbol.IsValid(): + # We do have a symbol, print some info for the symbol + print "symbol: ", symbol, "\n" + # Now get all instructions for this symbol and print them + insts = symbol.GetInstructions(target) + disassemble_instructions (insts) + # Now continue to the program exit + process.Continue() + # When we return from the above function we will hopefully be at the + # program exit. Print out some process info + print "process:", process, "\n" + + +lldb.SBDebugger.Terminate() diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index 0cde443dd11a..df8ff10e022a 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -52,9 +52,6 @@ public: lldb::SBProcess GetProcess (); - lldb::SBProcess - CreateProcess (); - lldb::SBProcess LaunchProcess (char const **argv, char const **envp, diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index 1a72f589c6a1..a288833e0f0b 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -15,6 +15,7 @@ #include "lldb/Interpreter/Args.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/State.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" @@ -287,7 +288,15 @@ SBProcess::Continue () { SBError sb_error; if (IsValid()) - sb_error.SetError(m_opaque_sp->Resume()); + { + Error error (m_opaque_sp->Resume()); + if (error.Success()) + { + if (m_opaque_sp->GetTarget().GetDebugger().GetAsyncExecution () == false) + m_opaque_sp->WaitForProcessToStop (NULL); + } + sb_error.SetError(error); + } else sb_error.SetErrorString ("SBProcess is invalid"); diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 0ac463de3bf3..39b4e5004ebf 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -105,17 +105,6 @@ SBTarget::GetDebugger () const return debugger; } -SBProcess -SBTarget::CreateProcess () -{ - SBProcess sb_process; - - if (m_opaque_sp) - sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener())); - - return sb_process; -} - SBProcess SBTarget::LaunchProcess ( @@ -126,23 +115,39 @@ SBTarget::LaunchProcess bool stop_at_entry ) { - SBProcess process(GetProcess ()); - if (!process.IsValid()) - process = CreateProcess(); - if (process.IsValid()) + SBProcess sb_process; + if (m_opaque_sp) { - Error error (process->Launch (argv, envp, launch_flags, tty, tty, tty)); - if (error.Success()) + // When launching, we always want to create a new process + sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener())); + + if (sb_process.IsValid()) { - if (!stop_at_entry) + Error error (sb_process->Launch (argv, envp, launch_flags, tty, tty, tty)); + if (error.Success()) { - StateType state = process->WaitForProcessToStop (NULL); + // We we are stopping at the entry point, we can return now! + if (stop_at_entry) + return sb_process; + + // Make sure we are stopped at the entry + StateType state = sb_process->WaitForProcessToStop (NULL); if (state == eStateStopped) - process->Resume(); + { + // resume the process to skip the entry point + error = sb_process->Resume(); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop yet again! + if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false) + sb_process->WaitForProcessToStop (NULL); + } + } } } } - return process; + return sb_process; } SBFileSpec @@ -401,9 +406,9 @@ SBTarget::Disassemble (lldb::addr_t start_addr, lldb::addr_t end_addr, const cha // Make sure the process object is alive if we have one (it might be // created but we might not be launched yet). - Process *process = m_opaque_sp->GetProcessSP().get(); - if (process && !process->IsAlive()) - process = NULL; + Process *sb_process = m_opaque_sp->GetProcessSP().get(); + if (sb_process && !sb_process->IsAlive()) + sb_process = NULL; // If we are given a module, then "start_addr" is a file address in // that module. @@ -430,8 +435,8 @@ SBTarget::Disassemble (lldb::addr_t start_addr, lldb::addr_t end_addr, const cha ExecutionContext exe_ctx; - if (process) - process->CalculateExecutionContext(exe_ctx); + if (sb_process) + sb_process->CalculateExecutionContext(exe_ctx); else m_opaque_sp->CalculateExecutionContext(exe_ctx); @@ -479,12 +484,12 @@ SBTarget::Disassemble (const char *function_name, const char *module_name) // Make sure the process object is alive if we have one (it might be // created but we might not be launched yet). - Process *process = m_opaque_sp->GetProcessSP().get(); - if (process && !process->IsAlive()) - process = NULL; + Process *sb_process = m_opaque_sp->GetProcessSP().get(); + if (sb_process && !sb_process->IsAlive()) + sb_process = NULL; - if (process) - process->CalculateExecutionContext(exe_ctx); + if (sb_process) + sb_process->CalculateExecutionContext(exe_ctx); else m_opaque_sp->CalculateExecutionContext(exe_ctx); diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index 7bf7dd29542c..0489dc5605dc 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -233,25 +233,32 @@ SBThread::StepOver (lldb::RunMode stop_other_threads) { SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans, - eStepTypeOver, - sc.line_entry.range, - sc, - stop_other_threads, - false); + eStepTypeOver, + sc.line_entry.range, + sc, + stop_other_threads, + false); } else { m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true, - abort_other_plans, - stop_other_threads); + abort_other_plans, + stop_other_threads); } } Process &process = m_opaque_sp->GetProcess(); // Why do we need to set the current thread by ID here??? process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); - process.Resume(); + Error error (process.Resume()); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop yet again! + if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) + process.WaitForProcessToStop (NULL); + } } } @@ -269,24 +276,30 @@ SBThread::StepInto (lldb::RunMode stop_other_threads) bool avoid_code_without_debug_info = true; SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans, - eStepTypeInto, - sc.line_entry.range, - sc, - stop_other_threads, - avoid_code_without_debug_info); + eStepTypeInto, + sc.line_entry.range, + sc, + stop_other_threads, + avoid_code_without_debug_info); } else { m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false, - abort_other_plans, - stop_other_threads); + abort_other_plans, + stop_other_threads); } Process &process = m_opaque_sp->GetProcess(); // Why do we need to set the current thread by ID here??? process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); - process.Resume(); - + Error error (process.Resume()); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop yet again! + if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) + process.WaitForProcessToStop (NULL); + } } } @@ -302,7 +315,14 @@ SBThread::StepOut () Process &process = m_opaque_sp->GetProcess(); process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); - process.Resume(); + Error error (process.Resume()); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop yet again! + if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) + process.WaitForProcessToStop (NULL); + } } } @@ -314,7 +334,14 @@ SBThread::StepInstruction (bool step_over) m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true); Process &process = m_opaque_sp->GetProcess(); process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); - process.Resume(); + Error error (process.Resume()); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop yet again! + if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) + process.WaitForProcessToStop (NULL); + } } } @@ -331,7 +358,14 @@ SBThread::RunToAddress (lldb::addr_t addr) m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads); Process &process = m_opaque_sp->GetProcess(); process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); - process.Resume(); + Error error (process.Resume()); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop yet again! + if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) + process.WaitForProcessToStop (NULL); + } } }