Oops, I forgot to attach the script; here it is.

Will

On Sat, Apr 2, 2011 at 9:05 AM, William Knop
<[email protected]> wrote:
> Hi again,
> I've gotten quite far with this script (attached), however I cannot
> figure out if there is a way invoke the lldb interpreter (i.e. the
> "(lldb)" prompt). It would seem that one could somehow activate the
> debugger's EditLineInputReader, perhaps via PushInputReader.
> Unfortunately, EditLineInputReader doesn't appear to be exposed. At
> this point, I may write a small hackish python function that loops,
> sending input via HandleCommand. If there's another way where I don't
> have to hack out an interpreter loop, I'd be grateful to hear of it.
>
> Will
>
> On Fri, Apr 1, 2011 at 9:41 PM, William Knop
> <[email protected]> wrote:
>> Brilliant! Between this example and Jim's, I think I'll be able to put
>> something nice together.
>>
>> Thank you both,
>> Will
>>
>> On Fri, Apr 1, 2011 at 9:26 PM, Johnny Chen <[email protected]> wrote:
>>> Hi William,
>>> Wonder if:
>>> URL: http://llvm.org/viewvc/llvm-project?rev=128755&view=rev
>>> Log:
>>> Add a Python script which launches a program from within lldb and loop until
>>> the
>>> process stops for some reason.  main.c (compiled into a.out) is used as an
>>> example in
>>> the README-run-until-faulted file.
>>>
>>> Added:
>>>    lldb/trunk/utils/test/README-run-until-faulted
>>>    lldb/trunk/utils/test/main.c
>>>    lldb/trunk/utils/test/run-until-faulted.py   (with props)
>>>
>>> is a good enough start for your need?
>>> Thanks.
>>> On Mar 31, 2011, at 6:15 PM, William Knop wrote:
>>>
>>> Hello all,
>>>
>>> I am attempting to use lldb to debug a segfault in my program that
>>> happens sporadically. For instance, running `for ((i=0;i<1000;i++)) {
>>> ./myprogram; };` at a shell prompt may show one. It seems there is no
>>> way to set lldb to run automatically and exit upon success from the
>>> CLI, so I've been exploring lldb's python scripting.
>>>
>>> The goal of the script is to loop, launching the process until
>>> completion or error; if there's an error, I need the script to dump me
>>> back into the lldb interpreter to investigate the bug. Here's what
>>> I've come up with so far:
>>>
>>> import time
>>>
>>> dbg = lldb.SBDebugger.FindDebuggerWithID(lldb.debugger_unique_id)
>>>
>>> ci = dbg.GetCommandInterpreter()
>>>
>>> res = lldb.SBCommandReturnObject()
>>>
>>> dbg.SetAsync(False)
>>>
>>> for i in range(1, 1000):
>>>
>>>  ci.HandleCommand("process launch", res)
>>>
>>>  while (not res.Succeeded()) : time.sleep(0.1)
>>>
>>>  res.Clear()
>>>
>>> Unfortunately, however, it seems the command does not run to
>>> completion, no matter how long I wait. Then when I call
>>> `HandleCommand` a second time, lldb deadlocks. I intended to
>>> eventually check `res.GetError()` or `res.GetStatus()` and call
>>> `quit()` when the error appeared, but I haven't made it that far. I
>>> also initially explored calling `dbg.GetTargetAtIndex(0).Launch()`
>>> rather than `HandleCommand`, but I wasn't entirely sure how to go
>>> about it. Any help would be much appreciated!
>>>
>>> Will
>>> _______________________________________________
>>> lldb-dev mailing list
>>> [email protected]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>>
>>>
>>
>
#!/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 time


# exception definitions
class TargetError(Exception): pass
class ProcessError(Exception):
  def __init__(self, msg): self.msg = msg
  def __str__(self): return repr(self.msg)


# runs target run_iterations times, or indefinitely if run_iterations is negative
def run_times (target, prog_args, run_iterations):
  while run_iterations != 0:
    if run_iterations > 0: run_iterations = run_iterations - 1
    launch(target, prog_args)


# launch target once
def launch (target, prog_args):
  if not target.IsValid (): raise TargetError
  error = lldb.SBError ()
  print "launching with args: ", prog_args
  #process = target.Launch (debugger.GetListener (), None, None, os.ctermid (), os.ctermid (), os.ctermid (), None, 0, False, error)
  process = target.Launch (prog_args, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error)
  if not process.IsValid (): raise ProcessError (error.GetCString ())
  
  # TODO: a blocking call here would be preferable to looping; check out SBListener
  while True:
    state = process.GetState ()
    print "state:", target.GetDebugger().StateAsCString(state)
    if (state == lldb.eStateStopped) or (state == lldb.eStateCrashed):
      # TODO: figure out how to produce an interactive lldb prompt when the program stops/crashes
      target.GetDebugger().PushInputReader(lldb.SBInputReader())
    elif state == lldb.eStateExited: break
    time.sleep(0.1)


# script was run from a CLI
if __name__ == "__main__":
  import sys
  import optparse
  parser = optparse.OptionParser(description='Runs a program in lldb some number of times, stopping execution at exceptions.')
  parser.disable_interspersed_args ()
  parser.add_option('--num', '-n', action="store", dest="prog_iter", default='-1', type=int, help='Number of program iterations (negative numbers loop indefinitely)')
  #parser.add_option('--', action="store", dest="prog_args", default='', help='Program arguments follow')
  (options, args) = parser.parse_args()
  
  if (len (parser.rargs) < 1): parser.error("no program specified")
  
  debugger = lldb.SBDebugger.Create ()
  debugger.SetAsync (False)
  
  target = debugger.CreateTargetWithFileAndArch (parser.rargs.pop(0), lldb.LLDB_ARCH_DEFAULT)
  
  try: run_times (target, parser.rargs, options.prog_iter)
  except TargetError: print ("Invalid target!")
  except ProcessError as e: print ("Invalid process: ", e.msg)


# script was run from lldb
elif __name__ == "__builtin__":
  # TODO
  debugger = lldb.SBDebugger.FindDebuggerWithID (lldb.debugger_unique_id)
  debugger.SetAsync (False)
  
  target = debugger.GetSelectedTarget ()
  
  try: run_times (target, -1)
  except TargetError: print ("Invalid target!")
  except ProcessError as e: print ("Invalid process: ", e.msg)



_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to