[Lldb-commits] [lldb] r158217 - in /lldb/branches/lldb-platform-work: ./ docs/ examples/python/ include/lldb/ include/lldb/API/ include/lldb/Breakpoint/ include/lldb/Core/ include/lldb/Interpreter/ include/lldb/Target/ scripts/Python/interface/ source/ source/API/ source/Commands/ source/Core/ source/Expression/ source/Host/macosx/ source/Interpreter/ source/Plugins/ObjectFile/ELF/ source/Plugins/ObjectFile/Mach-O/ source/Plugins/ObjectFile/PECOFF/ source/Plugins/Platform/MacOSX/ source/Plugins/Process/FreeBSD/ source/...
Johnny Chen
johnny.chen at apple.com
Fri Jun 8 11:36:35 PDT 2012
Author: johnny
Date: Fri Jun 8 13:36:34 2012
New Revision: 158217
URL: http://llvm.org/viewvc/llvm-project?rev=158217&view=rev
Log:
Merge from ToT trunk.
Added:
lldb/branches/lldb-platform-work/docs/lldb.1
- copied unchanged from r158207, lldb/trunk/docs/lldb.1
Modified:
lldb/branches/lldb-platform-work/ (props changed)
lldb/branches/lldb-platform-work/examples/python/crashlog.py
lldb/branches/lldb-platform-work/examples/python/gdbremote.py
lldb/branches/lldb-platform-work/examples/python/symbolication.py
lldb/branches/lldb-platform-work/include/lldb/API/SBTarget.h
lldb/branches/lldb-platform-work/include/lldb/API/SBValue.h
lldb/branches/lldb-platform-work/include/lldb/Breakpoint/Watchpoint.h
lldb/branches/lldb-platform-work/include/lldb/Core/ModuleList.h
lldb/branches/lldb-platform-work/include/lldb/Core/RegisterValue.h
lldb/branches/lldb-platform-work/include/lldb/Core/Section.h
lldb/branches/lldb-platform-work/include/lldb/Core/ValueObject.h
lldb/branches/lldb-platform-work/include/lldb/Interpreter/CommandInterpreter.h
lldb/branches/lldb-platform-work/include/lldb/Interpreter/OptionGroupWatchpoint.h
lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreter.h
lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterNone.h
lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterPython.h
lldb/branches/lldb-platform-work/include/lldb/Target/Process.h
lldb/branches/lldb-platform-work/include/lldb/Target/Target.h
lldb/branches/lldb-platform-work/include/lldb/lldb-enumerations.h
lldb/branches/lldb-platform-work/scripts/Python/interface/SBTarget.i
lldb/branches/lldb-platform-work/scripts/Python/interface/SBValue.i
lldb/branches/lldb-platform-work/scripts/Python/interface/SBWatchpoint.i
lldb/branches/lldb-platform-work/source/API/SBCommandInterpreter.cpp
lldb/branches/lldb-platform-work/source/API/SBDebugger.cpp
lldb/branches/lldb-platform-work/source/API/SBTarget.cpp
lldb/branches/lldb-platform-work/source/API/SBValue.cpp
lldb/branches/lldb-platform-work/source/API/SBWatchpoint.cpp
lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpointCommand.cpp
lldb/branches/lldb-platform-work/source/Commands/CommandObjectCommands.cpp
lldb/branches/lldb-platform-work/source/Commands/CommandObjectProcess.cpp
lldb/branches/lldb-platform-work/source/Commands/CommandObjectRegister.cpp
lldb/branches/lldb-platform-work/source/Commands/CommandObjectTarget.cpp
lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp
lldb/branches/lldb-platform-work/source/Commands/CommandObjectWatchpoint.cpp
lldb/branches/lldb-platform-work/source/Core/RegisterValue.cpp
lldb/branches/lldb-platform-work/source/Core/Section.cpp
lldb/branches/lldb-platform-work/source/Core/ValueObject.cpp
lldb/branches/lldb-platform-work/source/Expression/ExpressionSourceCode.cpp
lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm
lldb/branches/lldb-platform-work/source/Interpreter/CommandInterpreter.cpp
lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectRegexCommand.cpp
lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.cpp
lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupWatchpoint.cpp
lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterNone.cpp
lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp
lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
lldb/branches/lldb-platform-work/source/Target/Platform.cpp
lldb/branches/lldb-platform-work/source/Target/Process.cpp
lldb/branches/lldb-platform-work/source/Target/Target.cpp
lldb/branches/lldb-platform-work/source/Target/TargetList.cpp
lldb/branches/lldb-platform-work/source/Target/ThreadList.cpp
lldb/branches/lldb-platform-work/source/lldb.cpp
lldb/branches/lldb-platform-work/test/functionalities/completion/TestCompletion.py
lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_target.py
lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_value.py
lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_watchpoint.py
lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestSetWatchpoint.py
lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIter.py
lldb/branches/lldb-platform-work/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
lldb/branches/lldb-platform-work/tools/debugserver/source/DNBArch.h
lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.cpp
lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.h
lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThreadList.cpp
lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
lldb/branches/lldb-platform-work/tools/driver/Driver.cpp
lldb/branches/lldb-platform-work/tools/driver/IOChannel.cpp
lldb/branches/lldb-platform-work/tools/driver/IOChannel.h
Propchange: lldb/branches/lldb-platform-work/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jun 8 13:36:34 2012
@@ -1 +1 @@
-/lldb/trunk:154223-157712
+/lldb/trunk:154223-158207
Modified: lldb/branches/lldb-platform-work/examples/python/crashlog.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/examples/python/crashlog.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/examples/python/crashlog.py (original)
+++ lldb/branches/lldb-platform-work/examples/python/crashlog.py Fri Jun 8 13:36:34 2012
@@ -118,9 +118,11 @@
self.version = version
def locate_module_and_debug_symbols(self):
- if self.resolved_path:
- # Don't load a module twice...
+ # Don't load a module twice...
+ if self.resolved:
return True
+ # Mark this as resolved so we don't keep trying
+ self.resolved = True
uuid_str = self.get_normalized_uuid_string()
print 'Getting symbols for %s %s...' % (uuid_str, self.path),
if os.path.exists(self.dsymForUUIDBinary):
@@ -150,7 +152,8 @@
self.arch = match.group(2)
break;
if not self.resolved_path:
- print "error: file %s '%s' doesn't match the UUID in the installed file" % (uuid_str, self.path)
+ self.unavailable = True
+ print "error\n error: unable to locate '%s' with UUID %s" % (self.path, uuid_str)
return False
if (self.resolved_path and os.path.exists(self.resolved_path)) or (self.path and os.path.exists(self.path)):
print 'ok'
@@ -159,6 +162,8 @@
# if self.symfile:
# print ' dsym = "%s"' % self.symfile
return True
+ else:
+ self.unavailable = True
return False
@@ -313,7 +318,7 @@
elif parse_mode == PARSE_MODE_SYSTEM:
self.system_profile.append(line)
f.close()
-
+
def dump(self):
print "Crash Log File: %s" % (self.path)
print "\nThreads:"
@@ -351,7 +356,7 @@
print 'crashlog.create_target()...4'
print 'error: unable to locate any executables from the crash log'
return None
-
+
def usage():
print "Usage: lldb-symbolicate.py [-n name] executable-image"
@@ -380,6 +385,24 @@
'''Quit command'''
return True
+ def do_symbolicate(self, line):
+ description='''Symbolicate one or more darwin crash log files by index to provide source file and line information,
+ inlined stack frames back to the concrete functions, and disassemble the location of the crash
+ for the first frame of the crashed thread.'''
+ option_parser = CreateSymbolicateCrashLogOptions ('symbolicate', description, False)
+ command_args = shlex.split(line)
+ try:
+ (options, args) = option_parser.parse_args(command_args)
+ except:
+ return
+
+ for idx_str in args:
+ idx = int(idx_str)
+ if idx < len(self.crash_logs):
+ SymbolicateCrashLog (self.crash_logs[idx], options)
+ else:
+ print 'error: crash log index %u is out of range' % (idx)
+
def do_list(self, line=None):
'''Dump a list of all crash logs that are currently loaded.
@@ -460,12 +483,108 @@
def Symbolicate(debugger, command, result, dict):
try:
- SymbolicateCrashLog (shlex.split(command))
+ SymbolicateCrashLogs (shlex.split(command))
except:
result.PutCString ("error: python exception %s" % sys.exc_info()[0])
+
+def SymbolicateCrashLog(crash_log, options):
+ if crash_log.error:
+ print crash_log.error
+ return
+ if options.verbose:
+ crash_log.dump()
+ if not crash_log.images:
+ print 'error: no images in crash log'
+ return
+
+ target = crash_log.create_target ()
+ if not target:
+ return
+ exe_module = target.GetModuleAtIndex(0)
+ images_to_load = list()
+ loaded_images = list()
+ if options.load_all_images:
+ # --load-all option was specified, load everything up
+ for image in crash_log.images:
+ images_to_load.append(image)
+ else:
+ # Only load the images found in stack frames for the crashed threads
+ for ident in crash_log.idents:
+ images = crash_log.find_images_with_identifier (ident)
+ if images:
+ for image in images:
+ images_to_load.append(image)
+ else:
+ print 'error: can\'t find image for identifier "%s"' % ident
+
+ for image in images_to_load:
+ if image in loaded_images:
+ print "warning: skipping %s loaded at %#16.16x duplicate entry (probably commpage)" % (image.path, image.text_addr_lo)
+ else:
+ err = image.add_module (target)
+ if err:
+ print err
+ else:
+ #print 'loaded %s' % image
+ loaded_images.append(image)
+
+ for thread in crash_log.threads:
+ this_thread_crashed = thread.did_crash()
+ if options.crashed_only and this_thread_crashed == False:
+ continue
+ print "%s" % thread
+ #prev_frame_index = -1
+ for frame_idx, frame in enumerate(thread.frames):
+ disassemble = (this_thread_crashed or options.disassemble_all_threads) and frame_idx < options.disassemble_depth;
+ if frame_idx == 0:
+ symbolicated_frame_addresses = crash_log.symbolicate (frame.pc)
+ else:
+ # Any frame above frame zero and we have to subtract one to get the previous line entry
+ symbolicated_frame_addresses = crash_log.symbolicate (frame.pc - 1)
+
+ if symbolicated_frame_addresses:
+ symbolicated_frame_address_idx = 0
+ for symbolicated_frame_address in symbolicated_frame_addresses:
+ print '[%3u] %s' % (frame_idx, symbolicated_frame_address)
-def SymbolicateCrashLog(command_args):
+ if symbolicated_frame_address_idx == 0:
+ if disassemble:
+ instructions = symbolicated_frame_address.get_instructions()
+ if instructions:
+ print
+ symbolication.disassemble_instructions (target,
+ instructions,
+ frame.pc,
+ options.disassemble_before,
+ options.disassemble_after, frame.index > 0)
+ print
+ symbolicated_frame_address_idx += 1
+ else:
+ print frame
+ print
+
+ if options.dump_image_list:
+ print "Binary Images:"
+ for image in crash_log.images:
+ print image
+
+def CreateSymbolicateCrashLogOptions(command_name, description, add_interactive_options):
usage = "usage: %prog [options] <FILE> [FILE ...]"
+ option_parser = optparse.OptionParser(description=description, prog='crashlog',usage=usage)
+ option_parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
+ option_parser.add_option('-a', '--load-all', action='store_true', dest='load_all_images', help='load all executable images, not just the images found in the crashed stack frames', default=False)
+ option_parser.add_option('--images', action='store_true', dest='dump_image_list', help='show image list', default=False)
+ option_parser.add_option('-g', '--debug-delay', type='int', dest='debug_delay', metavar='NSEC', help='pause for NSEC seconds for debugger', default=0)
+ option_parser.add_option('-c', '--crashed-only', action='store_true', dest='crashed_only', help='only symbolicate the crashed thread', default=False)
+ option_parser.add_option('-d', '--disasm-depth', type='int', dest='disassemble_depth', help='set the depth in stack frames that should be disassembled (default is 1)', default=1)
+ option_parser.add_option('-D', '--disasm-all', action='store_true', dest='disassemble_all_threads', help='enabled disassembly of frames on all threads (not just the crashed thread)', default=False)
+ option_parser.add_option('-B', '--disasm-before', type='int', dest='disassemble_before', help='the number of instructions to disassemble before the frame PC', default=4)
+ option_parser.add_option('-A', '--disasm-after', type='int', dest='disassemble_after', help='the number of instructions to disassemble after the frame PC', default=4)
+ if add_interactive_options:
+ option_parser.add_option('-i', '--interactive', action='store_true', help='parse all crash logs and enter interactive mode', default=False)
+ return option_parser
+
+def SymbolicateCrashLogs(command_args):
description='''Symbolicate one or more darwin crash log files to provide source file and line information,
inlined stack frames back to the concrete functions, and disassemble the location of the crash
for the first frame of the crashed thread.
@@ -474,19 +593,9 @@
created that has all of the shared libraries loaded at the load addresses found in the crash log file. This allows
you to explore the program as if it were stopped at the locations described in the crash log and functions can
be disassembled and lookups can be performed using the addresses found in the crash log.'''
- parser = optparse.OptionParser(description=description, prog='crashlog',usage=usage)
- parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
- parser.add_option('-a', '--load-all', action='store_true', dest='load_all_images', help='load all executable images, not just the images found in the crashed stack frames', default=False)
- parser.add_option('--images', action='store_true', dest='dump_image_list', help='show image list', default=False)
- parser.add_option('-g', '--debug-delay', type='int', dest='debug_delay', metavar='NSEC', help='pause for NSEC seconds for debugger', default=0)
- parser.add_option('-c', '--crashed-only', action='store_true', dest='crashed_only', help='only symbolicate the crashed thread', default=False)
- parser.add_option('-d', '--disasm-depth', type='int', dest='disassemble_depth', help='set the depth in stack frames that should be disassembled (default is 1)', default=1)
- parser.add_option('-D', '--disasm-all', action='store_true', dest='disassemble_all_threads', help='enabled disassembly of frames on all threads (not just the crashed thread)', default=False)
- parser.add_option('-B', '--disasm-before', type='int', dest='disassemble_before', help='the number of instructions to disassemble before the frame PC', default=4)
- parser.add_option('-A', '--disasm-after', type='int', dest='disassemble_after', help='the number of instructions to disassemble after the frame PC', default=4)
- parser.add_option('-i', '--interactive', action='store_true', help='parse all crash logs and enter interactive mode', default=False)
+ option_parser = CreateSymbolicateCrashLogOptions ('crashlog', description, True)
try:
- (options, args) = parser.parse_args(command_args)
+ (options, args) = option_parser.parse_args(command_args)
except:
return
@@ -506,92 +615,12 @@
else:
for crash_log_file in args:
crash_log = CrashLog(crash_log_file)
-
- #pp = pprint.PrettyPrinter(indent=4); pp.pprint(args)
- if crash_log.error:
- print crash_log.error
- return
- if options.verbose:
- crash_log.dump()
- if not crash_log.images:
- print 'error: no images in crash log'
- return
-
- target = crash_log.create_target ()
- if not target:
- return
- exe_module = target.GetModuleAtIndex(0)
- images_to_load = list()
- loaded_images = list()
- if options.load_all_images:
- # --load-all option was specified, load everything up
- for image in crash_log.images:
- images_to_load.append(image)
- else:
- # Only load the images found in stack frames for the crashed threads
- for ident in crash_log.idents:
- images = crash_log.find_images_with_identifier (ident)
- if images:
- for image in images:
- images_to_load.append(image)
- else:
- print 'error: can\'t find image for identifier "%s"' % ident
-
- for image in images_to_load:
- if image in loaded_images:
- print "warning: skipping %s loaded at %#16.16x duplicate entry (probably commpage)" % (image.path, image.text_addr_lo)
- else:
- err = image.add_module (target)
- if err:
- print err
- else:
- #print 'loaded %s' % image
- loaded_images.append(image)
-
- for thread in crash_log.threads:
- this_thread_crashed = thread.did_crash()
- if options.crashed_only and this_thread_crashed == False:
- continue
- print "%s" % thread
- #prev_frame_index = -1
- for frame_idx, frame in enumerate(thread.frames):
- disassemble = (this_thread_crashed or options.disassemble_all_threads) and frame_idx < options.disassemble_depth;
- if frame_idx == 0:
- symbolicated_frame_addresses = crash_log.symbolicate (frame.pc)
- else:
- # Any frame above frame zero and we have to subtract one to get the previous line entry
- symbolicated_frame_addresses = crash_log.symbolicate (frame.pc - 1)
-
- if symbolicated_frame_addresses:
- symbolicated_frame_address_idx = 0
- for symbolicated_frame_address in symbolicated_frame_addresses:
- print '[%3u] %s' % (frame_idx, symbolicated_frame_address)
-
- if symbolicated_frame_address_idx == 0:
- if disassemble:
- instructions = symbolicated_frame_address.get_instructions()
- if instructions:
- print
- symbolication.disassemble_instructions (target,
- instructions,
- frame.pc,
- options.disassemble_before,
- options.disassemble_after, frame.index > 0)
- print
- symbolicated_frame_address_idx += 1
- else:
- print frame
- print
-
- if options.dump_image_list:
- print "Binary Images:"
- for image in crash_log.images:
- print image
-
+ SymbolicateCrashLog (crash_log, options)
if __name__ == '__main__':
# Create a new debugger instance
+ print 'main'
lldb.debugger = lldb.SBDebugger.Create()
- SymbolicateCrashLog (sys.argv[1:])
+ SymbolicateCrashLogs (sys.argv[1:])
elif getattr(lldb, 'debugger', None):
lldb.debugger.HandleCommand('command script add -f lldb.macosx.crashlog.Symbolicate crashlog')
print '"crashlog" command installed, type "crashlog --help" for detailed help'
Modified: lldb/branches/lldb-platform-work/examples/python/gdbremote.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/examples/python/gdbremote.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/examples/python/gdbremote.py (original)
+++ lldb/branches/lldb-platform-work/examples/python/gdbremote.py Fri Jun 8 13:36:34 2012
@@ -19,17 +19,172 @@
import commands
import optparse
import os
-import shlex
import re
+import shlex
+import string
+import sys
import tempfile
-log_file = ''
+#----------------------------------------------------------------------
+# Global variables
+#----------------------------------------------------------------------
+g_log_file = ''
+g_byte_order = 'little'
+
+class TerminalColors:
+ '''Simple terminal colors class'''
+ def __init__(self, enabled = True):
+ # TODO: discover terminal type from "file" and disable if
+ # it can't handle the color codes
+ self.enabled = enabled
+
+ def reset(self):
+ '''Reset all terminal colors and formatting.'''
+ if self.enabled:
+ return "\x1b[0m";
+ return ''
+
+ def bold(self, on = True):
+ '''Enable or disable bold depending on the "on" paramter.'''
+ if self.enabled:
+ if on:
+ return "\x1b[1m";
+ else:
+ return "\x1b[22m";
+ return ''
+
+ def italics(self, on = True):
+ '''Enable or disable italics depending on the "on" paramter.'''
+ if self.enabled:
+ if on:
+ return "\x1b[3m";
+ else:
+ return "\x1b[23m";
+ return ''
+
+ def underline(self, on = True):
+ '''Enable or disable underline depending on the "on" paramter.'''
+ if self.enabled:
+ if on:
+ return "\x1b[4m";
+ else:
+ return "\x1b[24m";
+ return ''
+
+ def inverse(self, on = True):
+ '''Enable or disable inverse depending on the "on" paramter.'''
+ if self.enabled:
+ if on:
+ return "\x1b[7m";
+ else:
+ return "\x1b[27m";
+ return ''
+
+ def strike(self, on = True):
+ '''Enable or disable strike through depending on the "on" paramter.'''
+ if self.enabled:
+ if on:
+ return "\x1b[9m";
+ else:
+ return "\x1b[29m";
+ return ''
+
+ def black(self, fg = True):
+ '''Set the foreground or background color to black.
+ The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
+ if self.enabled:
+ if fg:
+ return "\x1b[30m";
+ else:
+ return "\x1b[40m";
+ return ''
+
+ def red(self, fg = True):
+ '''Set the foreground or background color to red.
+ The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
+ if self.enabled:
+ if fg:
+ return "\x1b[31m";
+ else:
+ return "\x1b[41m";
+ return ''
+
+ def green(self, fg = True):
+ '''Set the foreground or background color to green.
+ The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
+ if self.enabled:
+ if fg:
+ return "\x1b[32m";
+ else:
+ return "\x1b[42m";
+ return ''
+
+ def yellow(self, fg = True):
+ '''Set the foreground or background color to yellow.
+ The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
+ if self.enabled:
+ if fg:
+ return "\x1b[43m";
+ else:
+ return "\x1b[33m";
+ return ''
+
+ def blue(self, fg = True):
+ '''Set the foreground or background color to blue.
+ The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
+ if self.enabled:
+ if fg:
+ return "\x1b[34m";
+ else:
+ return "\x1b[44m";
+ return ''
+
+ def magenta(self, fg = True):
+ '''Set the foreground or background color to magenta.
+ The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
+ if self.enabled:
+ if fg:
+ return "\x1b[35m";
+ else:
+ return "\x1b[45m";
+ return ''
+
+ def cyan(self, fg = True):
+ '''Set the foreground or background color to cyan.
+ The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
+ if self.enabled:
+ if fg:
+ return "\x1b[36m";
+ else:
+ return "\x1b[46m";
+ return ''
+
+ def white(self, fg = True):
+ '''Set the foreground or background color to white.
+ The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
+ if self.enabled:
+ if fg:
+ return "\x1b[37m";
+ else:
+ return "\x1b[47m";
+ return ''
+
+ def default(self, fg = True):
+ '''Set the foreground or background color to the default.
+ The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
+ if self.enabled:
+ if fg:
+ return "\x1b[39m";
+ else:
+ return "\x1b[49m";
+ return ''
+
def start_gdb_log(debugger, command, result, dict):
'''Start logging GDB remote packets by enabling logging with timestamps and
thread safe logging. Follow a call to this function with a call to "stop_gdb_log"
in order to dump out the commands.'''
- global log_file
+ global g_log_file
command_args = shlex.split(command)
usage = "usage: start_gdb_log [options] [<LOGFILEPATH>]"
description='''The command enables GDB remote packet logging with timestamps. The packets will be logged to <LOGFILEPATH> if supplied, or a temporary file will be used. Logging stops when stop_gdb_log is called and the packet times will
@@ -41,18 +196,18 @@
except:
return
- if log_file:
- result.PutCString ('error: logging is already in progress with file "%s"', log_file)
+ if g_log_file:
+ result.PutCString ('error: logging is already in progress with file "%s"', g_log_file)
else:
args_len = len(args)
if args_len == 0:
- log_file = tempfile.mktemp()
+ g_log_file = tempfile.mktemp()
elif len(args) == 1:
- log_file = args[0]
+ g_log_file = args[0]
- if log_file:
- debugger.HandleCommand('log enable --threadsafe --timestamp --file "%s" gdb-remote packets' % log_file);
- result.PutCString ("GDB packet logging enable with log file '%s'\nUse the 'stop_gdb_log' command to stop logging and show packet statistics." % log_file)
+ if g_log_file:
+ debugger.HandleCommand('log enable --threadsafe --timestamp --file "%s" gdb-remote packets' % g_log_file);
+ result.PutCString ("GDB packet logging enable with log file '%s'\nUse the 'stop_gdb_log' command to stop logging and show packet statistics." % g_log_file)
return
result.PutCString ('error: invalid log file path')
@@ -63,7 +218,7 @@
to "start_gdb_log" and normalize the timestamps to be relative to the first
timestamp in the log file. Also print out statistics for how long each
command took to allow performance bottlenecks to be determined.'''
- global log_file
+ global g_log_file
# Any commands whose names might be followed by more valid C identifier
# characters must be listed here
command_args = shlex.split(command)
@@ -72,25 +227,634 @@
parser = optparse.OptionParser(description=description, prog='stop_gdb_log',usage=usage)
parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
parser.add_option('-q', '--quiet', action='store_true', dest='quiet', help='display verbose debug info', default=False)
+ parser.add_option('-C', '--color', action='store_true', dest='color', help='add terminal colors', default=False)
parser.add_option('-c', '--sort-by-count', action='store_true', dest='sort_count', help='display verbose debug info', default=False)
+ parser.add_option('-s', '--symbolicate', action='store_true', dest='symbolicate', help='symbolicate addresses in log using current "lldb.target"', default=False)
try:
(options, args) = parser.parse_args(command_args)
except:
return
+ options.colors = TerminalColors(options.color)
+ options.symbolicator = None
+ if options.symbolicate:
+ if lldb.target:
+ import lldb.utils.symbolication
+ options.symbolicator = lldb.utils.symbolication.Symbolicator()
+ options.symbolicator.target = lldb.target
+ else:
+ print "error: can't symbolicate without a target"
- if not log_file:
+ if not g_log_file:
result.PutCString ('error: logging must have been previously enabled with a call to "stop_gdb_log"')
- elif os.path.exists (log_file):
+ elif os.path.exists (g_log_file):
if len(args) == 0:
debugger.HandleCommand('log disable gdb-remote packets');
- result.PutCString ("GDB packet logging disabled. Logged packets are in '%s'" % log_file)
- parse_gdb_log_file (log_file, options)
- log_file = None
+ result.PutCString ("GDB packet logging disabled. Logged packets are in '%s'" % g_log_file)
+ parse_gdb_log_file (g_log_file, options)
else:
result.PutCString (usage)
else:
- print 'error: the GDB packet log file "%s" does not exist' % log_file
+ print 'error: the GDB packet log file "%s" does not exist' % g_log_file
+
+def is_hex_byte(str):
+ if len(str) == 2:
+ return str[0] in string.hexdigits and str[1] in string.hexdigits;
+ return False
+
+# global register info list
+g_register_infos = list()
+g_max_register_info_name_len = 0
+
+class RegisterInfo:
+ """Class that represents register information"""
+ def __init__(self, kvp):
+ self.info = dict()
+ for kv in kvp:
+ key = kv[0]
+ value = kv[1]
+ self.info[key] = value
+ def name(self):
+ '''Get the name of the register.'''
+ if self.info and 'name' in self.info:
+ return self.info['name']
+ return None
+
+ def bit_size(self):
+ '''Get the size in bits of the register.'''
+ if self.info and 'bitsize' in self.info:
+ return int(self.info['bitsize'])
+ return 0
+
+ def byte_size(self):
+ '''Get the size in bytes of the register.'''
+ return self.bit_size() / 8
+
+ def get_value_from_hex_string(self, hex_str):
+ '''Dump the register value given a native byte order encoded hex ASCII byte string.'''
+ encoding = self.info['encoding']
+ bit_size = self.bit_size()
+ packet = Packet(hex_str)
+ if encoding == 'uint':
+ uval = packet.get_hex_uint(g_byte_order)
+ if bit_size == 8:
+ return '0x%2.2x' % (uval)
+ elif bit_size == 16:
+ return '0x%4.4x' % (uval)
+ elif bit_size == 32:
+ return '0x%8.8x' % (uval)
+ elif bit_size == 64:
+ return '0x%16.16x' % (uval)
+ bytes = list();
+ uval = packet.get_hex_uint8()
+ while uval != None:
+ bytes.append(uval)
+ uval = packet.get_hex_uint8()
+ value_str = '0x'
+ if g_byte_order == 'little':
+ bytes.reverse()
+ for byte in bytes:
+ value_str += '%2.2x' % byte
+ return '%s' % (value_str)
+
+ def __str__(self):
+ '''Dump the register info key/value pairs'''
+ s = ''
+ for key in self.info.keys():
+ if s:
+ s += ', '
+ s += "%s=%s " % (key, self.info[key])
+ return s
+
+class Packet:
+ """Class that represents a packet that contains string data"""
+ def __init__(self, packet_str):
+ self.str = packet_str
+
+ def peek_char(self):
+ ch = 0
+ if self.str:
+ ch = self.str[0]
+ return ch
+
+ def get_char(self):
+ ch = 0
+ if self.str:
+ ch = self.str[0]
+ self.str = self.str[1:]
+ return ch
+
+ def get_hex_uint8(self):
+ if self.str and len(self.str) >= 2 and self.str[0] in string.hexdigits and self.str[1] in string.hexdigits:
+ uval = int(self.str[0:2], 16)
+ self.str = self.str[2:]
+ return uval
+ return None
+
+ def get_hex_uint16(self, byte_order):
+ uval = 0
+ if byte_order == 'big':
+ uval |= self.get_hex_uint8() << 8
+ uval |= self.get_hex_uint8()
+ else:
+ uval |= self.get_hex_uint8()
+ uval |= self.get_hex_uint8() << 8
+ return uval
+
+ def get_hex_uint32(self, byte_order):
+ uval = 0
+ if byte_order == 'big':
+ uval |= self.get_hex_uint8() << 24
+ uval |= self.get_hex_uint8() << 16
+ uval |= self.get_hex_uint8() << 8
+ uval |= self.get_hex_uint8()
+ else:
+ uval |= self.get_hex_uint8()
+ uval |= self.get_hex_uint8() << 8
+ uval |= self.get_hex_uint8() << 16
+ uval |= self.get_hex_uint8() << 24
+ return uval
+
+ def get_hex_uint64(self, byte_order):
+ uval = 0
+ if byte_order == 'big':
+ uval |= self.get_hex_uint8() << 56
+ uval |= self.get_hex_uint8() << 48
+ uval |= self.get_hex_uint8() << 40
+ uval |= self.get_hex_uint8() << 32
+ uval |= self.get_hex_uint8() << 24
+ uval |= self.get_hex_uint8() << 16
+ uval |= self.get_hex_uint8() << 8
+ uval |= self.get_hex_uint8()
+ else:
+ uval |= self.get_hex_uint8()
+ uval |= self.get_hex_uint8() << 8
+ uval |= self.get_hex_uint8() << 16
+ uval |= self.get_hex_uint8() << 24
+ uval |= self.get_hex_uint8() << 32
+ uval |= self.get_hex_uint8() << 40
+ uval |= self.get_hex_uint8() << 48
+ uval |= self.get_hex_uint8() << 56
+ return uval
+
+ def get_hex_chars(self, n = 0):
+ str_len = len(self.str)
+ if n == 0:
+ # n was zero, so we need to determine all hex chars and
+ # stop when we hit the end of the string of a non-hex character
+ while n < str_len and self.str[n] in string.hexdigits:
+ n = n + 1
+ else:
+ if n > str_len:
+ return None # Not enough chars
+ # Verify all chars are hex if a length was specified
+ for i in range(n):
+ if self.str[i] not in string.hexdigits:
+ return None # Not all hex digits
+ if n == 0:
+ return None
+ hex_str = self.str[0:n]
+ self.str = self.str[n:]
+ return hex_str
+
+ def get_hex_uint(self, byte_order, n = 0):
+ if byte_order == 'big':
+ hex_str = self.get_hex_chars(n)
+ if hex_str == None:
+ return None
+ return int(hex_str, 16)
+ else:
+ uval = self.get_hex_uint8()
+ if uval == None:
+ return None
+ uval_result = 0
+ shift = 0
+ while uval != None:
+ uval_result |= (uval << shift)
+ shift += 8
+ uval = self.get_hex_uint8()
+ return uval_result
+
+ def get_key_value_pairs(self):
+ kvp = list()
+ key_value_pairs = string.split(self.str, ';')
+ for key_value_pair in key_value_pairs:
+ if len(key_value_pair):
+ kvp.append(string.split(key_value_pair, ':'))
+ return kvp
+
+ def split(self, ch):
+ return string.split(self.str, ch)
+
+ def split_hex(self, ch, byte_order):
+ hex_values = list()
+ strings = string.split(self.str, ch)
+ for str in strings:
+ hex_values.append(Packet(str).get_hex_uint(byte_order))
+ return hex_values
+
+ def __str__(self):
+ return self.str
+
+ def __len__(self):
+ return len(self.str)
+
+g_thread_suffix_regex = re.compile(';thread:([0-9a-fA-F]+);')
+def get_thread_from_thread_suffix(str):
+ if str:
+ match = g_thread_suffix_regex.match (str)
+ if match:
+ return int(match.group(1), 16)
+ return None
+
+def cmd_stop_reply(options, cmd, args):
+ print "get_last_stop_info()"
+
+def rsp_stop_reply(options, cmd, cmd_args, rsp):
+ global g_byte_order
+ packet = Packet(rsp)
+ stop_type = packet.get_char()
+ if stop_type == 'T' or stop_type == 'S':
+ signo = packet.get_hex_uint8()
+ print ' signal = %i' % signo
+ key_value_pairs = packet.get_key_value_pairs()
+ for key_value_pair in key_value_pairs:
+ key = key_value_pair[0]
+ value = key_value_pair[1]
+ if is_hex_byte(key):
+ reg_num = Packet(key).get_hex_uint8()
+ print ' ' + get_register_name_equal_value (options, reg_num, value)
+ else:
+ print ' %s = %s' % (key, value)
+ elif stop_type == 'W':
+ exit_status = packet.get_hex_uint8()
+ print 'exit (status=%i)' % exit_status
+ elif stop_type == 'O':
+ print 'stdout = %s' % packet.str
+
+
+def cmd_unknown_packet(options, cmd, args):
+ if args:
+ print "cmd: %s, args: %s", cmd, args
+ else:
+ print "cmd: %s", cmd
+
+def cmd_query_packet(options, cmd, args):
+ if args:
+ print "query: %s, args: %s" % (cmd, args)
+ else:
+ print "query: %s" % (cmd)
+
+def rsp_ok_error(rsp):
+ print "rsp: ", rsp
+
+def rsp_ok_means_supported(options, cmd, cmd_args, rsp):
+ if rsp == 'OK':
+ print "%s%s is supported" % (cmd, cmd_args)
+ elif rsp == '':
+ print "%s%s is not supported" % (cmd, cmd_args)
+ else:
+ print "%s%s -> %s" % (cmd, cmd_args, rsp)
+
+def rsp_ok_means_success(options, cmd, cmd_args, rsp):
+ if rsp == 'OK':
+ print "success"
+ elif rsp == '':
+ print "%s%s is not supported" % (cmd, cmd_args)
+ else:
+ print "%s%s -> %s" % (cmd, cmd_args, rsp)
+
+def rsp_dump_key_value_pairs(options, cmd, cmd_args, rsp):
+ if rsp:
+ packet = Packet(rsp)
+ key_value_pairs = packet.get_key_value_pairs()
+ for key_value_pair in key_value_pairs:
+ key = key_value_pair[0]
+ value = key_value_pair[1]
+ print " %s = %s" % (key, value)
+ else:
+ print "not supported"
+def cmd_vCont(options, cmd, args):
+ if args == '?':
+ print "%s: get supported extended continue modes" % (cmd)
+ else:
+ got_other_threads = 0
+ s = ''
+ for thread_action in string.split(args[1:], ';'):
+ (short_action, thread) = string.split(thread_action, ':')
+ tid = int(thread, 16)
+ if short_action == 'c':
+ action = 'continue'
+ elif short_action == 's':
+ action = 'step'
+ elif short_action[0] == 'C':
+ action = 'continue with signal 0x%s' % (short_action[1:])
+ elif short_action == 'S':
+ action = 'step with signal 0x%s' % (short_action[1:])
+ else:
+ action = short_action
+ if s:
+ s += ', '
+ if tid == -1:
+ got_other_threads = 1
+ s += 'other-threads:'
+ else:
+ s += 'thread 0x%4.4x: %s' % (tid, action)
+ if got_other_threads:
+ print "extended_continue (%s)" % (s)
+ else:
+ print "extended_continue (%s, other-threads: suspend)" % (s)
+
+def rsp_vCont(options, cmd, cmd_args, rsp):
+ if cmd_args == '?':
+ # Skip the leading 'vCont;'
+ rsp = rsp[6:]
+ modes = string.split(rsp, ';')
+ s = "%s: supported extended continue modes include: " % (cmd)
+
+ for i, mode in enumerate(modes):
+ if i:
+ s += ', '
+ if mode == 'c':
+ s += 'continue'
+ elif mode == 'C':
+ s += 'continue with signal'
+ elif mode == 's':
+ s += 'step'
+ elif mode == 'S':
+ s += 'step with signal'
+ else:
+ s += 'unrecognized vCont mode: ', mode
+ print s
+ elif rsp:
+ if rsp[0] == 'T' or rsp[0] == 'S' or rsp[0] == 'W' or rsp[0] == 'X':
+ rsp_stop_reply (options, cmd, cmd_args, rsp)
+ return
+ if rsp[0] == 'O':
+ print "stdout: %s" % (rsp)
+ return
+ else:
+ print "not supported (cmd = '%s', args = '%s', rsp = '%s')" % (cmd, cmd_args, rsp)
+
+def cmd_vAttach(options, cmd, args):
+ (extra_command, args) = string.split(args, ';')
+ if extra_command:
+ print "%s%s(%s)" % (cmd, extra_command, args)
+ else:
+ print "attach_pid(%s)" % args
+
+def cmd_qRegisterInfo(options, cmd, args):
+ print 'query_register_info(reg_num=%i)' % (int(args, 16))
+
+def rsp_qRegisterInfo(options, cmd, cmd_args, rsp):
+ global g_max_register_info_name_len
+ print 'query_register_info(reg_num=%i):' % (int(cmd_args, 16)),
+ if len(rsp) == 3 and rsp[0] == 'E':
+ g_max_register_info_name_len = 0
+ for reg_info in g_register_infos:
+ name_len = len(reg_info.name())
+ if g_max_register_info_name_len < name_len:
+ g_max_register_info_name_len = name_len
+ print' DONE'
+ else:
+ packet = Packet(rsp)
+ reg_info = RegisterInfo(packet.get_key_value_pairs())
+ g_register_infos.append(reg_info)
+ print reg_info
+
+
+def cmd_qThreadInfo(options, cmd, args):
+ if cmd == 'qfThreadInfo':
+ query_type = 'first'
+ else:
+ query_type = 'subsequent'
+ print 'get_current_thread_list(type=%s)' % (query_type)
+
+def rsp_qThreadInfo(options, cmd, cmd_args, rsp):
+ packet = Packet(rsp)
+ response_type = packet.get_char()
+ if response_type == 'm':
+ tids = packet.split_hex(';', 'big')
+ for i, tid in enumerate(tids):
+ if i:
+ print ',',
+ print '0x%x' % (tid),
+ print
+ elif response_type == 'l':
+ print 'END'
+
+def rsp_hex_big_endian(options, cmd, cmd_args, rsp):
+ packet = Packet(rsp)
+ uval = packet.get_hex_uint('big')
+ print '%s: 0x%x' % (cmd, uval)
+
+def cmd_read_memory(options, cmd, args):
+ packet = Packet(args)
+ addr = packet.get_hex_uint('big')
+ comma = packet.get_char()
+ size = packet.get_hex_uint('big')
+ print 'read_memory (addr = 0x%x, size = %u)' % (addr, size)
+
+def dump_hex_memory_buffer(addr, hex_byte_str):
+ packet = Packet(hex_byte_str)
+ idx = 0
+ ascii = ''
+ uval = packet.get_hex_uint8()
+ while uval != None:
+ if ((idx % 16) == 0):
+ if ascii:
+ print ' ', ascii
+ ascii = ''
+ print '0x%x:' % (addr + idx),
+ print '%2.2x' % (uval),
+ if 0x20 <= uval and uval < 0x7f:
+ ascii += '%c' % uval
+ else:
+ ascii += '.'
+ uval = packet.get_hex_uint8()
+ idx = idx + 1
+ if ascii:
+ print ' ', ascii
+ ascii = ''
+
+def cmd_write_memory(options, cmd, args):
+ packet = Packet(args)
+ addr = packet.get_hex_uint('big')
+ if packet.get_char() != ',':
+ print 'error: invalid write memory command (missing comma after address)'
+ return
+ size = packet.get_hex_uint('big')
+ if packet.get_char() != ':':
+ print 'error: invalid write memory command (missing colon after size)'
+ return
+ print 'write_memory (addr = 0x%x, size = %u, data:' % (addr, size)
+ dump_hex_memory_buffer (addr, packet.str)
+
+def cmd_alloc_memory(options, cmd, args):
+ packet = Packet(args)
+ byte_size = packet.get_hex_uint('big')
+ if packet.get_char() != ',':
+ print 'error: invalid allocate memory command (missing comma after address)'
+ return
+ print 'allocate_memory (byte-size = %u (0x%x), permissions = %s)' % (byte_size, byte_size, packet.str)
+
+def rsp_alloc_memory(options, cmd, cmd_args, rsp):
+ packet = Packet(rsp)
+ addr = packet.get_hex_uint('big')
+ print 'addr = 0x%x' % addr
+
+def cmd_dealloc_memory(options, cmd, args):
+ packet = Packet(args)
+ addr = packet.get_hex_uint('big')
+ if packet.get_char() != ',':
+ print 'error: invalid allocate memory command (missing comma after address)'
+ return
+ print 'deallocate_memory (addr = 0x%x, permissions = %s)' % (addr, packet.str)
+
+def rsp_memory_bytes(options, cmd, cmd_args, rsp):
+ addr = Packet(cmd_args).get_hex_uint('big')
+ dump_hex_memory_buffer (addr, rsp)
+
+def get_register_name_equal_value(options, reg_num, hex_value_str):
+ if reg_num < len(g_register_infos):
+ reg_info = g_register_infos[reg_num]
+ value_str = reg_info.get_value_from_hex_string (hex_value_str)
+ s = reg_info.name() + ' = '
+ if options.symbolicator:
+ symbolicated_addresses = options.symbolicator.symbolicate (int(value_str, 0))
+ if symbolicated_addresses:
+ s += options.colors.magenta()
+ s += '%s' % symbolicated_addresses[0]
+ s += options.colors.reset()
+ return s
+ s += value_str
+ return s
+ else:
+ reg_value = Packet(hex_value_str).get_hex_uint(g_byte_order)
+ return 'reg(%u) = 0x%x' % (reg_num, reg_value)
+
+def cmd_read_one_reg(options, cmd, args):
+ packet = Packet(args)
+ reg_num = packet.get_hex_uint('big')
+ tid = get_thread_from_thread_suffix (packet.str)
+ name = None
+ if reg_num < len(g_register_infos):
+ name = g_register_infos[reg_num].name ()
+ if packet.str:
+ packet.get_char() # skip ;
+ thread_info = packet.get_key_value_pairs()
+ tid = int(thread_info[0][1], 16)
+ s = 'read_register (reg_num=%u' % reg_num
+ if name:
+ s += ' (%s)' % (name)
+ if tid != None:
+ s += ', tid = 0x%4.4x' % (tid)
+ s += ')'
+ print s
+
+def rsp_read_one_reg(options, cmd, cmd_args, rsp):
+ packet = Packet(cmd_args)
+ reg_num = packet.get_hex_uint('big')
+ print get_register_name_equal_value (options, reg_num, rsp)
+
+def cmd_write_one_reg(options, cmd, args):
+ packet = Packet(args)
+ reg_num = packet.get_hex_uint('big')
+ if packet.get_char() != '=':
+ print 'error: invalid register write packet'
+ else:
+ name = None
+ hex_value_str = packet.get_hex_chars()
+ tid = get_thread_from_thread_suffix (packet.str)
+ s = 'write_register (reg_num=%u' % reg_num
+ if name:
+ s += ' (%s)' % (name)
+ s += ', value = '
+ s += get_register_name_equal_value(options, reg_num, hex_value_str)
+ if tid != None:
+ s += ', tid = 0x%4.4x' % (tid)
+ s += ')'
+ print s
+
+def dump_all_regs(packet):
+ for reg_info in g_register_infos:
+ nibble_size = reg_info.bit_size() / 4
+ hex_value_str = packet.get_hex_chars(nibble_size)
+ if hex_value_str != None:
+ value = reg_info.get_value_from_hex_string (hex_value_str)
+ print '%*s = %s' % (g_max_register_info_name_len, reg_info.name(), value)
+ else:
+ return
+
+def cmd_read_all_regs(cmd, cmd_args):
+ packet = Packet(cmd_args)
+ packet.get_char() # toss the 'g' command character
+ tid = get_thread_from_thread_suffix (packet.str)
+ if tid != None:
+ print 'read_all_register(thread = 0x%4.4x)' % tid
+ else:
+ print 'read_all_register()'
+
+def rsp_read_all_regs(options, cmd, cmd_args, rsp):
+ packet = Packet(rsp)
+ dump_all_regs (packet)
+
+def cmd_write_all_regs(options, cmd, args):
+ packet = Packet(args)
+ print 'write_all_registers()'
+ dump_all_regs (packet)
+
+g_bp_types = [ "software_bp", "hardware_bp", "write_wp", "read_wp", "access_wp" ]
+
+def cmd_bp(options, cmd, args):
+ if cmd == 'Z':
+ s = 'set_'
+ else:
+ s = 'clear_'
+ packet = Packet (args)
+ bp_type = packet.get_hex_uint('big')
+ packet.get_char() # Skip ,
+ bp_addr = packet.get_hex_uint('big')
+ packet.get_char() # Skip ,
+ bp_size = packet.get_hex_uint('big')
+ s += g_bp_types[bp_type]
+ s += " (addr = 0x%x, size = %u)" % (bp_addr, bp_size)
+ print s
+
+def cmd_mem_rgn_info(options, cmd, args):
+ packet = Packet(args)
+ packet.get_char() # skip ':' character
+ addr = packet.get_hex_uint('big')
+ print 'get_memory_region_info (addr=0x%x)' % (addr)
+
+def cmd_kill(options, cmd, args):
+ print 'kill_process()'
+
+gdb_remote_commands = {
+ '\\?' : { 'cmd' : cmd_stop_reply , 'rsp' : rsp_stop_reply , 'name' : "stop reply pacpket"},
+ 'QStartNoAckMode' : { 'cmd' : cmd_query_packet , 'rsp' : rsp_ok_means_supported , 'name' : "query if no ack mode is supported"},
+ 'QThreadSuffixSupported' : { 'cmd' : cmd_query_packet , 'rsp' : rsp_ok_means_supported , 'name' : "query if thread suffix is supported" },
+ 'QListThreadsInStopReply' : { 'cmd' : cmd_query_packet , 'rsp' : rsp_ok_means_supported , 'name' : "query if threads in stop reply packets are supported" },
+ 'qHostInfo' : { 'cmd' : cmd_query_packet , 'rsp' : rsp_dump_key_value_pairs, 'name' : "get host information" },
+ 'vCont' : { 'cmd' : cmd_vCont , 'rsp' : rsp_vCont , 'name' : "extended continue command" },
+ 'vAttach' : { 'cmd' : cmd_vAttach , 'rsp' : rsp_stop_reply , 'name' : "attach to process" },
+ 'qRegisterInfo' : { 'cmd' : cmd_qRegisterInfo , 'rsp' : rsp_qRegisterInfo , 'name' : "query register info" },
+ 'qfThreadInfo' : { 'cmd' : cmd_qThreadInfo , 'rsp' : rsp_qThreadInfo , 'name' : "get current thread list" },
+ 'qsThreadInfo' : { 'cmd' : cmd_qThreadInfo , 'rsp' : rsp_qThreadInfo , 'name' : "get current thread list" },
+ 'qShlibInfoAddr' : { 'cmd' : cmd_query_packet , 'rsp' : rsp_hex_big_endian , 'name' : "get shared library info address" },
+ 'qMemoryRegionInfo' : { 'cmd' : cmd_mem_rgn_info , 'rsp' : rsp_dump_key_value_pairs, 'name' : "get memory region information" },
+ 'm' : { 'cmd' : cmd_read_memory , 'rsp' : rsp_memory_bytes , 'name' : "read memory" },
+ 'M' : { 'cmd' : cmd_write_memory , 'rsp' : rsp_ok_means_success , 'name' : "write memory" },
+ '_M' : { 'cmd' : cmd_alloc_memory , 'rsp' : rsp_alloc_memory , 'name' : "allocate memory" },
+ '_m' : { 'cmd' : cmd_dealloc_memory, 'rsp' : rsp_ok_means_success , 'name' : "deallocate memory" },
+ 'p' : { 'cmd' : cmd_read_one_reg , 'rsp' : rsp_read_one_reg , 'name' : "read single register" },
+ 'P' : { 'cmd' : cmd_write_one_reg , 'rsp' : rsp_ok_means_success , 'name' : "write single register" },
+ 'g' : { 'cmd' : cmd_read_all_regs , 'rsp' : rsp_read_all_regs , 'name' : "read all registers" },
+ 'G' : { 'cmd' : cmd_write_all_regs, 'rsp' : rsp_ok_means_success , 'name' : "write all registers" },
+ 'z' : { 'cmd' : cmd_bp , 'rsp' : rsp_ok_means_success , 'name' : "clear breakpoint or watchpoint" },
+ 'Z' : { 'cmd' : cmd_bp , 'rsp' : rsp_ok_means_success , 'name' : "set breakpoint or watchpoint" },
+ 'k' : { 'cmd' : cmd_kill , 'rsp' : rsp_stop_reply , 'name' : "kill process" },
+}
def parse_gdb_log_file(file, options):
'''Parse a GDB log file that was generated by enabling logging with:
(lldb) log enable --threadsafe --timestamp --file <FILE> gdb-remote packets
@@ -104,15 +868,77 @@
tricky_commands = [ 'qRegisterInfo' ]
timestamp_regex = re.compile('(\s*)([1-9][0-9]+\.[0-9]+)([^0-9].*)$')
packet_name_regex = re.compile('([A-Za-z_]+)[^a-z]')
+ packet_transmit_name_regex = re.compile('(?P<direction>send|read) packet: (?P<packet>.*)')
+ packet_contents_name_regex = re.compile('\$([^#]+)#[0-9a-fA-F]{2}')
+ packet_names_regex_str = '(' + '|'.join(gdb_remote_commands.keys()) + ')(.*)';
+ packet_names_regex = re.compile(packet_names_regex_str);
+
base_time = 0.0
last_time = 0.0
packet_send_time = 0.0
- packet_name = None
packet_total_times = {}
packet_count = {}
file = open(file)
lines = file.read().splitlines()
+ last_command = None
+ last_command_args = None
+ last_command_packet = None
for line in lines:
+ packet_name = None
+ m = packet_transmit_name_regex.search(line)
+ is_command = False
+ if m:
+ direction = m.group('direction')
+ is_command = direction == 'send'
+ packet = m.group('packet')
+ sys.stdout.write(options.colors.green())
+ if options.quiet:
+ if is_command:
+ print '-->', packet
+ else:
+ print '<--', packet
+ else:
+ print '# ', line
+ sys.stdout.write(options.colors.reset())
+
+ #print 'direction = "%s", packet = "%s"' % (direction, packet)
+
+ if packet[0] == '+':
+ print 'ACK'
+ elif packet[0] == '-':
+ print 'NACK'
+ elif packet[0] == '$':
+ m = packet_contents_name_regex.match(packet)
+ if m:
+ contents = m.group(1)
+ if is_command:
+ m = packet_names_regex.match (contents)
+ if m:
+ last_command = m.group(1)
+ packet_name = last_command
+ last_command_args = m.group(2)
+ last_command_packet = contents
+ gdb_remote_commands[last_command]['cmd'](options, last_command, last_command_args)
+ else:
+ packet_match = packet_name_regex.match (line[idx+14:])
+ if packet_match:
+ packet_name = packet_match.group(1)
+ for tricky_cmd in tricky_commands:
+ if packet_name.find (tricky_cmd) == 0:
+ packet_name = tricky_cmd
+ else:
+ packet_name = contents
+ last_command = None
+ last_command_args = None
+ last_command_packet = None
+ elif last_command:
+ gdb_remote_commands[last_command]['rsp'](options, last_command, last_command_args, contents)
+ else:
+ print 'error: invalid packet: "', packet, '"'
+ else:
+ print '???'
+ else:
+ print '## ', line
match = timestamp_regex.match (line)
if match:
curr_time = float (match.group(2))
@@ -121,15 +947,9 @@
delta = curr_time - last_time
else:
base_time = curr_time
- idx = line.find('send packet: $')
- if idx >= 0:
+
+ if is_command:
packet_send_time = curr_time
- packet_match = packet_name_regex.match (line[idx+14:])
- if packet_match:
- packet_name = packet_match.group(1)
- for tricky_cmd in tricky_commands:
- if packet_name.find (tricky_cmd) == 0:
- packet_name = tricky_cmd
elif line.find('read packet: $') >= 0 and packet_name:
if packet_name in packet_total_times:
packet_total_times[packet_name] += delta
@@ -142,8 +962,8 @@
if not options or not options.quiet:
print '%s%.6f %+.6f%s' % (match.group(1), curr_time - base_time, delta, match.group(3))
last_time = curr_time
- else:
- print line
+ # else:
+ # print line
if packet_total_times:
total_packet_time = 0.0
total_packet_count = 0
@@ -178,15 +998,39 @@
if __name__ == '__main__':
- import sys
+ usage = "usage: gdbremote [options]"
+ description='''The command disassembles a GDB remote packet log.'''
+ parser = optparse.OptionParser(description=description, prog='gdbremote',usage=usage)
+ parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
+ parser.add_option('-q', '--quiet', action='store_true', dest='quiet', help='display verbose debug info', default=False)
+ parser.add_option('-C', '--color', action='store_true', dest='color', help='add terminal colors', default=False)
+ parser.add_option('-c', '--sort-by-count', action='store_true', dest='sort_count', help='display verbose debug info', default=False)
+ parser.add_option('--crashlog', type='string', dest='crashlog', help='symbolicate using a darwin crash log file', default=False)
+ try:
+ (options, args) = parser.parse_args(sys.argv[1:])
+ except:
+ print 'error: argument error'
+ sys.exit(1)
+
+ options.colors = TerminalColors(options.color)
+ options.symbolicator = None
+ if options.crashlog:
+ import lldb
+ lldb.debugger = lldb.SBDebugger.Create()
+ import lldb.macosx.crashlog
+ options.symbolicator = lldb.macosx.crashlog.CrashLog(options.crashlog)
+ print '%s' % (options.symbolicator)
+
# This script is being run from the command line, create a debugger in case we are
# going to use any debugger functions in our function.
- for file in sys.argv[1:]:
+ for file in args:
print '#----------------------------------------------------------------------'
print "# GDB remote log file: '%s'" % file
print '#----------------------------------------------------------------------'
- parse_gdb_log_file (file, None)
-
+ parse_gdb_log_file (file, options)
+ if options.symbolicator:
+ print '%s' % (options.symbolicator)
+
else:
import lldb
if lldb.debugger:
Modified: lldb/branches/lldb-platform-work/examples/python/symbolication.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/examples/python/symbolication.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/examples/python/symbolication.py (original)
+++ lldb/branches/lldb-platform-work/examples/python/symbolication.py Fri Jun 8 13:36:34 2012
@@ -193,6 +193,8 @@
def __init__(self, path, uuid = None):
self.path = path
self.resolved_path = None
+ self.resolved = False
+ self.unavailable = False
self.uuid = uuid
self.section_infos = list()
self.identifier = None
@@ -245,6 +247,8 @@
return self.section_infos or self.slide != None
def load_module(self, target):
+ if self.unavailable:
+ return None # We already warned that we couldn't find this module, so don't return an error string
# Load this module into "target" using the section infos to
# set the section load addresses
if self.has_section_load_info():
@@ -288,6 +292,8 @@
self.module = target.AddModule (None, None, uuid_str)
if not self.module:
self.locate_module_and_debug_symbols ()
+ if self.unavailable:
+ return None
resolved_path = self.get_resolved_path()
self.module = target.AddModule (resolved_path, self.arch, uuid_str, self.symfile)
if not self.module:
@@ -306,6 +312,7 @@
# self.module
# self.symfile
# Subclasses can inherit from this class and override this function
+ self.resolved = True
return True
def get_uuid(self):
@@ -320,6 +327,9 @@
def create_target(self):
'''Create a target using the information in this Image object.'''
+ if self.unavailable:
+ return None
+
if self.locate_module_and_debug_symbols ():
resolved_path = self.get_resolved_path();
path_spec = lldb.SBFileSpec (resolved_path)
@@ -368,7 +378,7 @@
def find_image_containing_load_addr(self, load_addr):
for image in self.images:
- if image.contains_addr (load_addr):
+ if image.get_section_containing_load_addr (load_addr):
return image
return None
@@ -384,32 +394,39 @@
return None
def symbolicate(self, load_addr):
+ if not self.target:
+ self.create_target()
if self.target:
- symbolicated_address = Address(self.target, load_addr)
- if symbolicated_address.symbolicate ():
+ image = self.find_image_containing_load_addr (load_addr)
+ if image:
+ image.add_module (self.target)
+ symbolicated_address = Address(self.target, load_addr)
+ if symbolicated_address.symbolicate ():
- if symbolicated_address.so_addr:
- symbolicated_addresses = list()
- symbolicated_addresses.append(symbolicated_address)
- # See if we were able to reconstruct anything?
- while 1:
- inlined_parent_so_addr = lldb.SBAddress()
- inlined_parent_sym_ctx = symbolicated_address.sym_ctx.GetParentOfInlinedScope (symbolicated_address.so_addr, inlined_parent_so_addr)
- if not inlined_parent_sym_ctx:
- break
- if not inlined_parent_so_addr:
- break
-
- symbolicated_address = Address(self.target, inlined_parent_so_addr.GetLoadAddress(self.target))
- symbolicated_address.sym_ctx = inlined_parent_sym_ctx
- symbolicated_address.so_addr = inlined_parent_so_addr
- symbolicated_address.symbolicate ()
+ if symbolicated_address.so_addr:
+ symbolicated_addresses = list()
+ symbolicated_addresses.append(symbolicated_address)
+ # See if we were able to reconstruct anything?
+ while 1:
+ inlined_parent_so_addr = lldb.SBAddress()
+ inlined_parent_sym_ctx = symbolicated_address.sym_ctx.GetParentOfInlinedScope (symbolicated_address.so_addr, inlined_parent_so_addr)
+ if not inlined_parent_sym_ctx:
+ break
+ if not inlined_parent_so_addr:
+ break
+
+ symbolicated_address = Address(self.target, inlined_parent_so_addr.GetLoadAddress(self.target))
+ symbolicated_address.sym_ctx = inlined_parent_sym_ctx
+ symbolicated_address.so_addr = inlined_parent_so_addr
+ symbolicated_address.symbolicate ()
- # push the new frame onto the new frame stack
- symbolicated_addresses.append (symbolicated_address)
+ # push the new frame onto the new frame stack
+ symbolicated_addresses.append (symbolicated_address)
- if symbolicated_addresses:
- return symbolicated_addresses
+ if symbolicated_addresses:
+ return symbolicated_addresses
+ else:
+ print 'error: no target in Symbolicator'
return None
Modified: lldb/branches/lldb-platform-work/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/API/SBTarget.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/API/SBTarget.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/API/SBTarget.h Fri Jun 8 13:36:34 2012
@@ -692,7 +692,7 @@
FindWatchpointByID (lldb::watch_id_t watch_id);
lldb::SBWatchpoint
- WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write);
+ WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError& error);
bool
EnableAllWatchpoints ();
Modified: lldb/branches/lldb-platform-work/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/API/SBValue.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/API/SBValue.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/API/SBValue.h Fri Jun 8 13:36:34 2012
@@ -325,6 +325,9 @@
/// @param[in] write
/// Stop when this value is modified
///
+ /// @param[out]
+ /// An error object. Contains the reason if there is some failure.
+ ///
/// @return
/// An SBWatchpoint object. This object might not be valid upon
/// return due to a value not being contained in memory, too
@@ -332,6 +335,10 @@
/// use.
//------------------------------------------------------------------
lldb::SBWatchpoint
+ Watch (bool resolve_location, bool read, bool write, SBError &error);
+
+ // Backward compatibility fix in the interim.
+ lldb::SBWatchpoint
Watch (bool resolve_location, bool read, bool write);
//------------------------------------------------------------------
@@ -351,6 +358,9 @@
/// @param[in] write
/// Stop when this value is modified
///
+ /// @param[out]
+ /// An error object. Contains the reason if there is some failure.
+ ///
/// @return
/// An SBWatchpoint object. This object might not be valid upon
/// return due to a value not being contained in memory, too
@@ -358,7 +368,7 @@
/// use.
//------------------------------------------------------------------
lldb::SBWatchpoint
- WatchPointee (bool resolve_location, bool read, bool write);
+ WatchPointee (bool resolve_location, bool read, bool write, SBError &error);
// this must be defined in the .h file because synthetic children as implemented in the core
// currently rely on being able to extract the SharedPointer out of an SBValue. if the implementation
Modified: lldb/branches/lldb-platform-work/include/lldb/Breakpoint/Watchpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Breakpoint/Watchpoint.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Breakpoint/Watchpoint.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Breakpoint/Watchpoint.h Fri Jun 8 13:36:34 2012
@@ -115,7 +115,7 @@
void * m_callback_baton; // Callback user data to pass to callback
std::string m_decl_str; // Declaration information, if any.
std::string m_watch_spec_str; // Spec for the watchpoint (for future use).
- Error m_error; // An error object describing errors creating watchpoint.
+ Error m_error; // An error object describing errors associated with this watchpoint.
std::auto_ptr<ClangUserExpression> m_condition_ap; // The condition to test.
Modified: lldb/branches/lldb-platform-work/include/lldb/Core/ModuleList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Core/ModuleList.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Core/ModuleList.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Core/ModuleList.h Fri Jun 8 13:36:34 2012
@@ -115,8 +115,7 @@
void
LogUUIDAndPaths (lldb::LogSP &log_sp,
const char *prefix_cstr);
-
-
+
Mutex &
GetMutex ()
{
Modified: lldb/branches/lldb-platform-work/include/lldb/Core/RegisterValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Core/RegisterValue.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Core/RegisterValue.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Core/RegisterValue.h Fri Jun 8 13:36:34 2012
@@ -348,12 +348,14 @@
uint32_t offset,
bool partial_data_ok);
+ // The default value of 0 for reg_name_right_align_at means no alignment at all.
bool
Dump (Stream *s,
const RegisterInfo *reg_info,
bool prefix_with_name,
bool prefix_with_alt_name,
- lldb::Format format) const;
+ lldb::Format format,
+ uint32_t reg_name_right_align_at = 0) const;
void *
GetBytes ();
Modified: lldb/branches/lldb-platform-work/include/lldb/Core/Section.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Core/Section.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Core/Section.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Core/Section.h Fri Jun 8 13:36:34 2012
@@ -15,6 +15,7 @@
#include "lldb/Core/Flags.h"
#include "lldb/Core/ModuleChild.h"
#include "lldb/Core/ConstString.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UserID.h"
#include "lldb/Core/VMRange.h"
#include <limits.h>
@@ -85,9 +86,23 @@
size_t
Slide (lldb::addr_t slide_amount, bool slide_children);
+
+ // Update all section lookup caches
+ void
+ Finalize ();
protected:
collection m_sections;
+
+ typedef RangeDataArray<uint64_t, uint64_t, collection::size_type, 1> SectionRangeCache;
+ mutable SectionRangeCache m_range_cache;
+#ifdef LLDB_CONFIGURATION_DEBUG
+ mutable bool m_finalized;
+#endif
+
+ void BuildRangeCache() const;
+
+ void InvalidateRangeCache() const;
};
@@ -273,6 +288,13 @@
{
m_thread_specific = b;
}
+
+ // Update all section lookup caches
+ void
+ Finalize ()
+ {
+ m_children.Finalize();
+ }
protected:
Modified: lldb/branches/lldb-platform-work/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Core/ValueObject.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Core/ValueObject.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Core/ValueObject.h Fri Jun 8 13:36:34 2012
@@ -690,7 +690,7 @@
std::string& destination);
virtual uint64_t
- GetValueAsUnsigned (uint64_t fail_value);
+ GetValueAsUnsigned (uint64_t fail_value, bool *success = NULL);
virtual bool
SetValueFromCString (const char *value_str, Error& error);
Modified: lldb/branches/lldb-platform-work/include/lldb/Interpreter/CommandInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Interpreter/CommandInterpreter.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Interpreter/CommandInterpreter.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Interpreter/CommandInterpreter.h Fri Jun 8 13:36:34 2012
@@ -146,7 +146,7 @@
bool
HandleCommand (const char *command_line,
- bool add_to_history,
+ LazyBool add_to_history,
CommandReturnObject &result,
ExecutionContext *override_context = NULL,
bool repeat_on_empty_command = true,
@@ -179,7 +179,8 @@
bool stop_on_continue,
bool stop_on_error,
bool echo_commands,
- bool print_results,
+ bool print_results,
+ LazyBool add_to_history,
CommandReturnObject &result);
//------------------------------------------------------------------
@@ -209,7 +210,8 @@
bool stop_on_continue,
bool stop_on_error,
bool echo_commands,
- bool print_results,
+ bool print_results,
+ LazyBool add_to_history,
CommandReturnObject &result);
CommandObject *
@@ -477,6 +479,7 @@
char m_repeat_char;
bool m_batch_command_mode;
ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated children and whether the user has been told
+ uint32_t m_command_source_depth;
};
Modified: lldb/branches/lldb-platform-work/include/lldb/Interpreter/OptionGroupWatchpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Interpreter/OptionGroupWatchpoint.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Interpreter/OptionGroupWatchpoint.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Interpreter/OptionGroupWatchpoint.h Fri Jun 8 13:36:34 2012
@@ -26,6 +26,9 @@
{
public:
+ static bool
+ IsWatchSizeSupported(uint32_t watch_size);
+
OptionGroupWatchpoint ();
virtual
Modified: lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreter.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreter.h Fri Jun 8 13:36:34 2012
@@ -118,19 +118,19 @@
virtual ~ScriptInterpreter ();
virtual bool
- ExecuteOneLine (const char *command, CommandReturnObject *result) = 0;
+ ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io) = 0;
virtual void
ExecuteInterpreterLoop () = 0;
virtual bool
- ExecuteOneLineWithReturn (const char *in_string, ScriptReturnType return_type, void *ret_value)
+ ExecuteOneLineWithReturn (const char *in_string, ScriptReturnType return_type, void *ret_value, bool enable_io)
{
return true;
}
virtual bool
- ExecuteMultipleLines (const char *in_string)
+ ExecuteMultipleLines (const char *in_string, bool enable_io)
{
return true;
}
Modified: lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterNone.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterNone.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterNone.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterNone.h Fri Jun 8 13:36:34 2012
@@ -23,7 +23,7 @@
~ScriptInterpreterNone ();
bool
- ExecuteOneLine (const char *command, CommandReturnObject *result);
+ ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io);
void
ExecuteInterpreterLoop ();
Modified: lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Interpreter/ScriptInterpreterPython.h Fri Jun 8 13:36:34 2012
@@ -39,7 +39,7 @@
~ScriptInterpreterPython ();
bool
- ExecuteOneLine (const char *command, CommandReturnObject *result);
+ ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io);
void
ExecuteInterpreterLoop ();
@@ -47,10 +47,11 @@
bool
ExecuteOneLineWithReturn (const char *in_string,
ScriptInterpreter::ScriptReturnType return_type,
- void *ret_value);
+ void *ret_value,
+ bool enable_io);
bool
- ExecuteMultipleLines (const char *in_string);
+ ExecuteMultipleLines (const char *in_string, bool enable_io);
bool
ExportFunctionDefinitionToInterpreter (StringList &function_def);
@@ -257,6 +258,36 @@
ScriptInterpreterPython *m_python_interpreter;
FILE* m_tmp_fh;
};
+
+ class PythonInputReaderManager
+ {
+ public:
+ PythonInputReaderManager (ScriptInterpreterPython *interpreter);
+
+ operator bool()
+ {
+ return m_error;
+ }
+
+ ~PythonInputReaderManager();
+
+ private:
+
+ static size_t
+ InputReaderCallback (void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+ static lldb::thread_result_t
+ RunPythonInputReader (lldb::thread_arg_t baton);
+
+ ScriptInterpreterPython *m_interpreter;
+ lldb::DebuggerSP m_debugger_sp;
+ lldb::InputReaderSP m_reader_sp;
+ bool m_error;
+ };
static size_t
InputReaderCallback (void *baton,
Modified: lldb/branches/lldb-platform-work/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/Process.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/Process.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/Process.h Fri Jun 8 13:36:34 2012
@@ -82,15 +82,23 @@
StringList &value,
Error *err);
-
+ bool GetDisableMemoryCache() const
+ {
+ return m_disable_memory_cache;
+ }
+
protected:
-
+ const ConstString &
+ GetDisableMemoryCacheVarName () const;
+
void
CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
bool pending);
const ConstString
CreateInstanceName ();
+
+ bool m_disable_memory_cache;
};
//----------------------------------------------------------------------
@@ -725,6 +733,22 @@
{
m_resume_count = c;
}
+
+ bool
+ GetLaunchInSeparateProcessGroup ()
+ {
+ return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
+ }
+
+ void
+ SetLaunchInSeparateProcessGroup (bool separate)
+ {
+ if (separate)
+ m_flags.Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
+ else
+ m_flags.Clear (lldb::eLaunchFlagLaunchInSeparateProcessGroup);
+
+ }
void
Clear ()
@@ -785,6 +809,7 @@
Host::MonitorChildProcessCallback m_monitor_callback;
void *m_monitor_callback_baton;
bool m_monitor_signals;
+
};
//----------------------------------------------------------------------
@@ -3371,6 +3396,7 @@
std::auto_ptr<NextEventAction> m_next_event_action_ap;
std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions;
ReadWriteLock m_run_lock;
+ Predicate<bool> m_currently_handling_event;
enum {
eCanJITDontKnow= 0,
Modified: lldb/branches/lldb-platform-work/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/Target.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/Target.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/Target.h Fri Jun 8 13:36:34 2012
@@ -523,7 +523,8 @@
lldb::WatchpointSP
CreateWatchpoint (lldb::addr_t addr,
size_t size,
- uint32_t type);
+ uint32_t type,
+ Error &error);
lldb::WatchpointSP
GetLastCreatedWatchpoint ()
Modified: lldb/branches/lldb-platform-work/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/lldb-enumerations.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/lldb-enumerations.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/lldb-enumerations.h Fri Jun 8 13:36:34 2012
@@ -45,7 +45,8 @@
eLaunchFlagDisableASLR = (1u << 3), ///< Disable Address Space Layout Randomization
eLaunchFlagDisableSTDIO = (1u << 4), ///< Disable stdio for inferior process (e.g. for a GUI app)
eLaunchFlagLaunchInTTY = (1u << 5), ///< Launch the process in a new TTY if supported by the host
- eLaunchFlagLaunchInShell= (1u << 6) ///< Launch the process inside a shell to get shell expansion
+ eLaunchFlagLaunchInShell= (1u << 6), ///< Launch the process inside a shell to get shell expansion
+ eLaunchFlagLaunchInSeparateProcessGroup = (1u << 7) ///< Launch the process in a separate process group
} LaunchFlags;
//----------------------------------------------------------------------
Modified: lldb/branches/lldb-platform-work/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/scripts/Python/interface/SBTarget.i?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/scripts/Python/interface/SBTarget.i (original)
+++ lldb/branches/lldb-platform-work/scripts/Python/interface/SBTarget.i Fri Jun 8 13:36:34 2012
@@ -668,7 +668,8 @@
WatchAddress (lldb::addr_t addr,
size_t size,
bool read,
- bool write);
+ bool write,
+ SBError &error);
lldb::SBBroadcaster
Modified: lldb/branches/lldb-platform-work/scripts/Python/interface/SBValue.i
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/scripts/Python/interface/SBValue.i?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/scripts/Python/interface/SBValue.i (original)
+++ lldb/branches/lldb-platform-work/scripts/Python/interface/SBValue.i Fri Jun 8 13:36:34 2012
@@ -313,14 +313,14 @@
/// It returns an SBWatchpoint, which may be invalid.
") Watch;
lldb::SBWatchpoint
- Watch (bool resolve_location, bool read, bool write);
+ Watch (bool resolve_location, bool read, bool write, SBError &error);
%feature("docstring", "
/// Find and watch the location pointed to by a variable.
/// It returns an SBWatchpoint, which may be invalid.
") WatchPointee;
lldb::SBWatchpoint
- WatchPointee (bool resolve_location, bool read, bool write);
+ WatchPointee (bool resolve_location, bool read, bool write, SBError &error);
bool
GetDescription (lldb::SBStream &description);
Modified: lldb/branches/lldb-platform-work/scripts/Python/interface/SBWatchpoint.i
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/scripts/Python/interface/SBWatchpoint.i?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/scripts/Python/interface/SBWatchpoint.i (original)
+++ lldb/branches/lldb-platform-work/scripts/Python/interface/SBWatchpoint.i Fri Jun 8 13:36:34 2012
@@ -31,9 +31,6 @@
bool
IsValid();
- SBError
- GetError();
-
watch_id_t
GetID ();
Modified: lldb/branches/lldb-platform-work/source/API/SBCommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/API/SBCommandInterpreter.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/branches/lldb-platform-work/source/API/SBCommandInterpreter.cpp Fri Jun 8 13:36:34 2012
@@ -94,7 +94,7 @@
Mutex::Locker api_locker;
if (target_sp)
api_locker.Lock(target_sp->GetAPIMutex());
- m_opaque_ptr->HandleCommand (command_line, add_to_history, result.ref());
+ m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref());
}
else
{
Modified: lldb/branches/lldb-platform-work/source/API/SBDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/API/SBDebugger.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/API/SBDebugger.cpp (original)
+++ lldb/branches/lldb-platform-work/source/API/SBDebugger.cpp Fri Jun 8 13:36:34 2012
@@ -147,7 +147,14 @@
// non-mandatory. We have seen deadlocks with this function when called
// so we need to safeguard against this until we can determine what is
// causing the deadlocks.
+ LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
const bool mandatory = false;
+ if (log)
+ {
+ log->Printf ("SBDebugger::MemoryPressureDetected (), mandatory = %d", mandatory);
+ }
+
ModuleList::RemoveOrphanSharedModules(mandatory);
}
Modified: lldb/branches/lldb-platform-work/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/API/SBTarget.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/API/SBTarget.cpp (original)
+++ lldb/branches/lldb-platform-work/source/API/SBTarget.cpp Fri Jun 8 13:36:34 2012
@@ -1634,6 +1634,8 @@
if (target_sp)
{
Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ Mutex::Locker locker;
+ target_sp->GetWatchpointList().GetListMutex(locker);
result = target_sp->RemoveWatchpointByID (wp_id);
}
@@ -1656,6 +1658,8 @@
if (target_sp && wp_id != LLDB_INVALID_WATCH_ID)
{
Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ Mutex::Locker locker;
+ target_sp->GetWatchpointList().GetListMutex(locker);
watchpoint_sp = target_sp->GetWatchpointList().FindByID(wp_id);
sb_watchpoint.SetSP (watchpoint_sp);
}
@@ -1670,7 +1674,7 @@
}
lldb::SBWatchpoint
-SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write)
+SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError &error)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@@ -1685,7 +1689,10 @@
watch_type |= LLDB_WATCH_TYPE_READ;
if (write)
watch_type |= LLDB_WATCH_TYPE_WRITE;
- watchpoint_sp = target_sp->CreateWatchpoint(addr, size, watch_type);
+ // Target::CreateWatchpoint() is thread safe.
+ Error cw_error;
+ watchpoint_sp = target_sp->CreateWatchpoint(addr, size, watch_type, cw_error);
+ error.SetError(cw_error);
sb_watchpoint.SetSP (watchpoint_sp);
}
@@ -1705,6 +1712,8 @@
if (target_sp)
{
Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ Mutex::Locker locker;
+ target_sp->GetWatchpointList().GetListMutex(locker);
target_sp->EnableAllWatchpoints ();
return true;
}
@@ -1718,6 +1727,8 @@
if (target_sp)
{
Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ Mutex::Locker locker;
+ target_sp->GetWatchpointList().GetListMutex(locker);
target_sp->DisableAllWatchpoints ();
return true;
}
@@ -1731,6 +1742,8 @@
if (target_sp)
{
Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ Mutex::Locker locker;
+ target_sp->GetWatchpointList().GetListMutex(locker);
target_sp->RemoveAllWatchpoints ();
return true;
}
Modified: lldb/branches/lldb-platform-work/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/API/SBValue.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/API/SBValue.cpp (original)
+++ lldb/branches/lldb-platform-work/source/API/SBValue.cpp Fri Jun 8 13:36:34 2012
@@ -304,7 +304,7 @@
if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock()))
{
if (log)
- log->Printf ("SBValue(%p)::GetValueDidChange() => error: process is running", value_sp.get());
+ log->Printf ("SBValue(%p)::GetType() => error: process is running", value_sp.get());
}
else
{
@@ -482,7 +482,7 @@
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBValue(%p)::GetTypeSummary() => error: process is running", value_sp.get());
+ log->Printf ("SBValue(%p)::GetTypeFormat() => error: process is running", value_sp.get());
}
else
{
@@ -627,7 +627,7 @@
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBValue(%p)::GetTypeSynthetic() => error: process is running", value_sp.get());
+ log->Printf ("SBValue(%p)::CreateChildAtOffset() => error: process is running", value_sp.get());
}
else
{
@@ -650,9 +650,9 @@
if (log)
{
if (new_value_sp)
- log->Printf ("SBValue(%p)::GetChildAtOffset => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString());
+ log->Printf ("SBValue(%p)::CreateChildAtOffset => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString());
else
- log->Printf ("SBValue(%p)::GetChildAtOffset => NULL", value_sp.get());
+ log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL", value_sp.get());
}
return sb_value;
}
@@ -709,13 +709,13 @@
if (log)
{
if (new_value_sp)
- log->Printf ("SBValue(%p)::GetChildFromExpression(name=\"%s\", expression=\"%s\") => SBValue (%p)",
+ log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => SBValue (%p)",
value_sp.get(),
name,
expression,
new_value_sp.get());
else
- log->Printf ("SBValue(%p)::GetChildFromExpression(name=\"%s\", expression=\"%s\") => NULL",
+ log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => NULL",
value_sp.get(),
name,
expression);
@@ -793,9 +793,9 @@
if (log)
{
if (new_value_sp)
- log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString());
+ log->Printf ("SBValue(%p)::CreateValueFromData => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString());
else
- log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", value_sp.get());
+ log->Printf ("SBValue(%p)::CreateValueFromData => NULL", value_sp.get());
}
return sb_value;
}
@@ -1501,7 +1501,7 @@
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBValue(%p)::GetPointerToObject () => SBValue(%p)", value_sp.get(), value_sp.get());
+ log->Printf ("SBValue(%p)::AddressOf () => SBValue(%p)", value_sp.get(), value_sp.get());
return sb_value;
}
@@ -1655,7 +1655,7 @@
}
lldb::SBWatchpoint
-SBValue::Watch (bool resolve_location, bool read, bool write)
+SBValue::Watch (bool resolve_location, bool read, bool write, SBError &error)
{
SBWatchpoint sb_watchpoint;
@@ -1696,7 +1696,9 @@
if (write)
watch_type |= LLDB_WATCH_TYPE_WRITE;
- WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, watch_type);
+ Error rc;
+ WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, watch_type, rc);
+ error.SetError(rc);
if (watchpoint_sp)
{
@@ -1717,12 +1719,21 @@
return sb_watchpoint;
}
+// FIXME: Remove this method impl (as well as the decl in .h) once it is no longer needed.
+// Backward compatibility fix in the interim.
+lldb::SBWatchpoint
+SBValue::Watch (bool resolve_location, bool read, bool write)
+{
+ SBError error;
+ return Watch(resolve_location, read, write, error);
+}
+
lldb::SBWatchpoint
-SBValue::WatchPointee (bool resolve_location, bool read, bool write)
+SBValue::WatchPointee (bool resolve_location, bool read, bool write, SBError &error)
{
SBWatchpoint sb_watchpoint;
if (IsInScope() && GetType().IsPointerType())
- sb_watchpoint = Dereference().Watch (resolve_location, read, write);
+ sb_watchpoint = Dereference().Watch (resolve_location, read, write, error);
return sb_watchpoint;
}
Modified: lldb/branches/lldb-platform-work/source/API/SBWatchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/API/SBWatchpoint.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/API/SBWatchpoint.cpp (original)
+++ lldb/branches/lldb-platform-work/source/API/SBWatchpoint.cpp Fri Jun 8 13:36:34 2012
@@ -87,10 +87,7 @@
bool
SBWatchpoint::IsValid() const
{
- lldb::WatchpointSP watchpoint_sp(GetSP());
- if (watchpoint_sp && watchpoint_sp->GetError().Success())
- return true;
- return false;
+ return m_opaque_sp;
}
SBError
Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpointCommand.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpointCommand.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpointCommand.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpointCommand.cpp Fri Jun 8 13:36:34 2012
@@ -866,7 +866,8 @@
stop_on_continue,
data->stop_on_error,
echo_commands,
- print_results,
+ print_results,
+ eLazyBoolNo,
result);
result.GetImmediateOutputStream()->Flush();
result.GetImmediateErrorStream()->Flush();
Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectCommands.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectCommands.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectCommands.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectCommands.cpp Fri Jun 8 13:36:34 2012
@@ -284,7 +284,8 @@
m_options.m_stop_on_continue,
m_options.m_stop_on_error,
echo_commands,
- print_results,
+ print_results,
+ eLazyBoolCalculate,
result);
}
else
@@ -295,6 +296,36 @@
return result.Succeeded();
}
+
+ virtual const char*
+ GetRepeatCommand (Args ¤t_command_args, uint32_t index)
+ {
+ return "";
+ }
+
+ int
+ HandleArgumentCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
+ {
+ std::string completion_str (input.GetArgumentAtIndex(cursor_index));
+ completion_str.erase (cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
+ CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ NULL,
+ word_complete,
+ matches);
+ return matches.GetSize();
+ }
};
OptionDefinition
Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectProcess.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectProcess.cpp Fri Jun 8 13:36:34 2012
@@ -598,7 +598,7 @@
// This supports the use-case scenario of immediately continuing the process once attached.
if (m_options.attach_info.GetContinueOnceAttached())
- m_interpreter.HandleCommand("process continue", false, result);
+ m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
}
return result.Succeeded();
}
@@ -622,7 +622,7 @@
{ LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
{ LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."},
{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."},
-{ LLDB_OPT_SET_2, false, "waitfor", 'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."},
+{ LLDB_OPT_SET_2, false, "waitfor", 'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectRegister.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectRegister.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectRegister.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectRegister.cpp Fri Jun 8 13:36:34 2012
@@ -95,7 +95,7 @@
bool prefix_with_altname = m_command_options.alternate_name;
bool prefix_with_name = !prefix_with_altname;
- reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat());
+ reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat(), 8);
if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))
{
Process *process = exe_ctx.GetProcessPtr();
Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectTarget.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectTarget.cpp Fri Jun 8 13:36:34 2012
@@ -1692,8 +1692,58 @@
}
static uint32_t
+LookupTypeHere (CommandInterpreter &interpreter,
+ Stream &strm,
+ const SymbolContext &sym_ctx,
+ const char *name_cstr,
+ bool name_is_regex)
+{
+ if (!sym_ctx.module_sp)
+ return 0;
+
+ TypeList type_list;
+ const uint32_t max_num_matches = UINT32_MAX;
+ uint32_t num_matches = 1;
+ bool name_is_fully_qualified = false;
+
+ ConstString name(name_cstr);
+ num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list);
+
+ if (num_matches)
+ {
+ strm.Indent ();
+ strm.PutCString("Best match found in ");
+ DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0);
+ strm.PutCString(":\n");
+
+ TypeSP type_sp (type_list.GetTypeAtIndex(0));
+ if (type_sp)
+ {
+ // Resolve the clang type so that any forward references
+ // to types that haven't yet been parsed will get parsed.
+ type_sp->GetClangFullType ();
+ type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
+ // Print all typedef chains
+ TypeSP typedef_type_sp (type_sp);
+ TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
+ while (typedefed_type_sp)
+ {
+ strm.EOL();
+ strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString());
+ typedefed_type_sp->GetClangFullType ();
+ typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
+ typedef_type_sp = typedefed_type_sp;
+ typedefed_type_sp = typedef_type_sp->GetTypedefType();
+ }
+ }
+ strm.EOL();
+ }
+ return num_matches;
+}
+
+static uint32_t
LookupFileAndLineInModule (CommandInterpreter &interpreter,
- Stream &strm,
+ Stream &strm,
Module *module,
const FileSpec &file_spec,
uint32_t line,
@@ -3291,6 +3341,10 @@
case 'v':
m_verbose = 1;
break;
+
+ case 'A':
+ m_print_all = true;
+ break;
case 'r':
m_use_regex = true;
@@ -3312,6 +3366,7 @@
m_use_regex = false;
m_include_inlines = true;
m_verbose = false;
+ m_print_all = false;
}
const OptionDefinition*
@@ -3332,6 +3387,7 @@
bool m_use_regex; // Name lookups in m_str are regular expressions.
bool m_include_inlines;// Check for inline entries when looking up by file/line.
bool m_verbose; // Enable verbose lookup info
+ bool m_print_all; // Print all matches, even in cases where there's a best match.
};
@@ -3367,6 +3423,56 @@
return &m_options;
}
+ bool
+ LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
+ {
+ switch (m_options.m_type)
+ {
+ case eLookupTypeAddress:
+ case eLookupTypeFileLine:
+ case eLookupTypeFunction:
+ case eLookupTypeFunctionOrSymbol:
+ case eLookupTypeSymbol:
+ default:
+ return false;
+ case eLookupTypeType:
+ break;
+ }
+
+ ExecutionContext exe_ctx = interpreter.GetDebugger().GetSelectedExecutionContext();
+
+ StackFrameSP frame = exe_ctx.GetFrameSP();
+
+ if (!frame)
+ return false;
+
+ const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
+
+ if (!sym_ctx.module_sp)
+ return false;
+
+ switch (m_options.m_type)
+ {
+ default:
+ return false;
+ case eLookupTypeType:
+ if (!m_options.m_str.empty())
+ {
+ if (LookupTypeHere (m_interpreter,
+ result.GetOutputStream(),
+ sym_ctx,
+ m_options.m_str.c_str(),
+ m_options.m_use_regex))
+ {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ }
+ break;
+ }
+
+ return true;
+ }
bool
LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
@@ -3492,7 +3598,24 @@
if (command.GetArgumentCount() == 0)
{
- // Dump all sections for all modules images
+ ModuleSP current_module;
+
+ // Where it is possible to look in the current symbol context
+ // first, try that. If this search was successful and --all
+ // was not passed, don't print anything else.
+ if (LookupHere (m_interpreter, result, syntax_error))
+ {
+ result.GetOutputStream().EOL();
+ num_successful_lookups++;
+ if (!m_options.m_print_all)
+ {
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
+ }
+
+ // Dump all sections for all other modules
+
ModuleList &target_modules = target->GetImages();
Mutex::Locker modules_locker(target_modules.GetMutex());
const uint32_t num_modules = target_modules.GetSize();
@@ -3500,7 +3623,10 @@
{
for (i = 0; i<num_modules && syntax_error == false; ++i)
{
- if (LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
+ Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
+
+ if (module_pointer != current_module.get() &&
+ LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
{
result.GetOutputStream().EOL();
num_successful_lookups++;
@@ -3565,12 +3691,13 @@
{ LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules."},
{ LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."},
{ LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."},
- { LLDB_OPT_SET_3|
- LLDB_OPT_SET_4, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."},
+ { LLDB_OPT_SET_FROM_TO(3,5),
+ false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."},
{ LLDB_OPT_SET_4, true, "function", 'F', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."},
{ LLDB_OPT_SET_5, true, "name", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function or symbol by name in one or more target modules."},
{ LLDB_OPT_SET_6, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."},
{ LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
+ { LLDB_OPT_SET_ALL, false, "all", 'A', no_argument, NULL, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp Fri Jun 8 13:36:34 2012
@@ -660,11 +660,26 @@
std::vector<uint32_t> resume_thread_indexes;
for (uint32_t i=0; i<argc; ++i)
{
- idx = Args::StringToUInt32 (command.GetArgumentAtIndex(0), LLDB_INVALID_INDEX32);
- if (idx < num_threads)
- resume_thread_indexes.push_back(idx);
+ bool success;
+ const int base = 0;
+ idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
+ if (!success)
+ {
+ result.AppendErrorWithFormat ("invalid value for thread index: %s.", command.GetArgumentAtIndex(i));
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ else if (process->GetThreadList().FindThreadByIndexID(idx))
+ {
+ if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) == resume_thread_indexes.end())
+ resume_thread_indexes.push_back(idx);
+ }
else
- result.AppendWarningWithFormat("Thread index %u out of range.\n", idx);
+ {
+ result.AppendErrorWithFormat("thread index %u out of range.\n", idx);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
}
if (resume_thread_indexes.empty())
@@ -675,13 +690,24 @@
}
else
{
- result.AppendMessage ("Resuming thread ");
+ if (resume_thread_indexes.size() == 1)
+ result.AppendMessageWithFormat ("Resuming thread: ");
+ else
+ result.AppendMessageWithFormat ("Resuming threads: ");
+
for (idx=0; idx<num_threads; ++idx)
{
- Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
- if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end())
+ Thread *thread = process->GetThreadList().FindThreadByIndexID(idx).get();
+ std::vector<uint32_t>::iterator this_thread_pos = find(resume_thread_indexes.begin(), resume_thread_indexes.end(), thread->GetIndexID());
+
+ if (this_thread_pos != resume_thread_indexes.end())
{
- result.AppendMessageWithFormat ("%u ", idx);
+ resume_thread_indexes.erase(this_thread_pos);
+ if (resume_thread_indexes.size() > 0)
+ result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
+ else
+ result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
+
thread->SetResumeState (eStateRunning);
}
else
@@ -704,7 +730,7 @@
// Set the actions that the threads should each take when resuming
for (idx=0; idx<num_threads; ++idx)
{
- Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
+ Thread *thread = process->GetThreadList().FindThreadByIndexID(idx).get();
if (thread == current_thread)
{
result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID());
@@ -937,7 +963,7 @@
}
else
{
- thread = process->GetThreadList().GetThreadAtIndex(m_options.m_thread_idx).get();
+ thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
}
if (thread == NULL)
Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectWatchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectWatchpoint.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectWatchpoint.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectWatchpoint.cpp Fri Jun 8 13:36:34 2012
@@ -943,6 +943,7 @@
CommandReturnObject &result
)
{
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame == NULL)
@@ -1011,7 +1012,8 @@
// Now it's time to create the watchpoint.
uint32_t watch_type = m_option_watchpoint.watch_type;
- Watchpoint *wp = exe_ctx.GetTargetRef().CreateWatchpoint(addr, size, watch_type).get();
+ error.Clear();
+ Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type, error).get();
if (wp) {
if (var_sp && var_sp->GetDeclaration().GetFile()) {
StreamString ss;
@@ -1027,6 +1029,8 @@
} else {
result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n",
addr, size);
+ if (error.AsCString(NULL))
+ result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
}
@@ -1192,8 +1196,9 @@
}
// Get the address to watch.
- addr = valobj_sp->GetValueAsUnsigned(0);
- if (!addr) {
+ bool success = false;
+ addr = valobj_sp->GetValueAsUnsigned(0, &success);
+ if (!success) {
result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
result.SetStatus(eReturnStatusFailed);
return false;
@@ -1203,7 +1208,8 @@
// Now it's time to create the watchpoint.
uint32_t watch_type = m_option_watchpoint.watch_type;
- Watchpoint *wp = exe_ctx.GetTargetRef().CreateWatchpoint(addr, size, watch_type).get();
+ Error error;
+ Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type, error).get();
if (wp) {
if (var_sp && var_sp->GetDeclaration().GetFile()) {
StreamString ss;
@@ -1219,6 +1225,8 @@
} else {
result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n",
addr, size);
+ if (error.AsCString(NULL))
+ result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
}
Modified: lldb/branches/lldb-platform-work/source/Core/RegisterValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Core/RegisterValue.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Core/RegisterValue.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Core/RegisterValue.cpp Fri Jun 8 13:36:34 2012
@@ -17,6 +17,7 @@
#include "lldb/Core/Error.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
#include "lldb/Interpreter/Args.h"
using namespace lldb;
@@ -28,22 +29,34 @@
const RegisterInfo *reg_info,
bool prefix_with_name,
bool prefix_with_alt_name,
- Format format) const
+ Format format,
+ uint32_t reg_name_right_align_at) const
{
DataExtractor data;
if (GetData (data))
{
bool name_printed = false;
+ // For simplicity, alignment of the register name printing applies only
+ // in the most common case where:
+ //
+ // prefix_with_name^prefix_with_alt_name is true
+ //
+ StreamString format_string;
+ if (reg_name_right_align_at && (prefix_with_name^prefix_with_alt_name))
+ format_string.Printf("%%%us", reg_name_right_align_at);
+ else
+ format_string.Printf("%%s");
+ const char *fmt = format_string.GetData();
if (prefix_with_name)
{
if (reg_info->name)
{
- s->Printf ("%s", reg_info->name);
+ s->Printf (fmt, reg_info->name);
name_printed = true;
}
else if (reg_info->alt_name)
{
- s->Printf ("%s", reg_info->alt_name);
+ s->Printf (fmt, reg_info->alt_name);
prefix_with_alt_name = false;
name_printed = true;
}
@@ -54,13 +67,13 @@
s->PutChar ('/');
if (reg_info->alt_name)
{
- s->Printf ("%s", reg_info->alt_name);
+ s->Printf (fmt, reg_info->alt_name);
name_printed = true;
}
else if (!name_printed)
{
// No alternate name but we were asked to display a name, so show the main name
- s->Printf ("%s", reg_info->name);
+ s->Printf (fmt, reg_info->name);
name_printed = true;
}
}
Modified: lldb/branches/lldb-platform-work/source/Core/Section.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Core/Section.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Core/Section.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Core/Section.cpp Fri Jun 8 13:36:34 2012
@@ -379,6 +379,9 @@
SectionList::SectionList () :
m_sections()
+#ifdef LLDB_CONFIGURATION_DEBUG
+ , m_finalized(false)
+#endif
{
}
@@ -393,6 +396,7 @@
assert (section_sp.get());
uint32_t section_index = m_sections.size();
m_sections.push_back(section_sp);
+ InvalidateRangeCache();
return section_index;
}
@@ -432,6 +436,7 @@
if ((*sect_iter)->GetID() == sect_id)
{
*sect_iter = sect_sp;
+ InvalidateRangeCache();
return true;
}
else if (depth > 0)
@@ -565,26 +570,69 @@
return sect_sp;
}
+void
+SectionList::BuildRangeCache() const
+{
+ m_range_cache.Clear();
+
+ for (collection::size_type idx = 0, last_idx = m_sections.size();
+ idx < last_idx;
+ ++idx)
+ {
+ Section *sect = m_sections[idx].get();
+
+ addr_t linked_file_address = sect->GetLinkedFileAddress();
+
+ if (linked_file_address != LLDB_INVALID_ADDRESS)
+ m_range_cache.Append(SectionRangeCache::Entry(linked_file_address, sect->GetByteSize(), idx));
+ }
+
+ m_range_cache.Sort();
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ m_finalized = true;
+#endif
+}
+
+void
+SectionList::InvalidateRangeCache() const
+{
+#ifdef LLDB_CONFIGURATION_DEBUG
+ assert(!m_finalized);
+#endif
+ m_range_cache.Clear();
+}
SectionSP
SectionList::FindSectionContainingLinkedFileAddress (addr_t vm_addr, uint32_t depth) const
{
- SectionSP sect_sp;
- const_iterator sect_iter;
- const_iterator end = m_sections.end();
- for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
- {
- Section *sect = sect_iter->get();
- if (sect->ContainsLinkedFileAddress (vm_addr))
- {
- sect_sp = *sect_iter;
- }
- else if (depth > 0)
- {
- sect_sp = sect->GetChildren().FindSectionContainingLinkedFileAddress (vm_addr, depth - 1);
- }
+ //if (m_range_cache.IsEmpty())
+ // BuildRangeCache();
+#ifdef LLDB_CONFIGURATION_DEBUG
+ assert(m_finalized);
+#endif
+
+ SectionRangeCache::Entry *entry = m_range_cache.FindEntryThatContains(vm_addr);
+
+ if (entry)
+ return m_sections[entry->data];
+
+ if (depth == 0)
+ return SectionSP();
+
+ for (const_iterator si = m_sections.begin(), se = m_sections.end();
+ si != se;
+ ++si)
+ {
+ Section *sect = si->get();
+
+ SectionSP sect_sp = sect->GetChildren().FindSectionContainingLinkedFileAddress(vm_addr, depth - 1);
+
+ if (sect_sp)
+ return sect_sp;
}
- return sect_sp;
+
+ return SectionSP();
}
bool
@@ -628,6 +676,22 @@
if ((*pos)->Slide(slide_amount, slide_children))
++count;
}
+ InvalidateRangeCache();
return count;
}
+void
+SectionList::Finalize ()
+{
+ BuildRangeCache();
+
+ for (const_iterator si = m_sections.begin(), se = m_sections.end();
+ si != se;
+ ++si)
+ {
+ Section *sect = si->get();
+
+ sect->GetChildren().Finalize();
+ }
+}
+
Modified: lldb/branches/lldb-platform-work/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Core/ValueObject.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Core/ValueObject.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Core/ValueObject.cpp Fri Jun 8 13:36:34 2012
@@ -1246,15 +1246,23 @@
// if > 8bytes, 0 is returned. this method should mostly be used
// to read address values out of pointers
uint64_t
-ValueObject::GetValueAsUnsigned (uint64_t fail_value)
+ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success)
{
// If our byte size is zero this is an aggregate type that has children
if (ClangASTContext::IsAggregateType (GetClangType()) == false)
{
Scalar scalar;
if (ResolveValue (scalar))
+ {
+ if (success)
+ *success = true;
return scalar.GetRawBits64(fail_value);
+ }
+ // fallthrough, otherwise...
}
+
+ if (success)
+ *success = false;
return fail_value;
}
Modified: lldb/branches/lldb-platform-work/source/Expression/ExpressionSourceCode.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Expression/ExpressionSourceCode.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Expression/ExpressionSourceCode.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Expression/ExpressionSourceCode.cpp Fri Jun 8 13:36:34 2012
@@ -37,6 +37,8 @@
wrap_stream.Printf("%s \n"
"#undef NULL \n"
"#define NULL 0 \n"
+ "#undef nil \n"
+ "#define nil (id)0 \n"
"typedef unsigned short unichar;\n"
"void \n"
"%s(void *$__lldb_arg) \n"
@@ -51,6 +53,8 @@
wrap_stream.Printf("%s \n"
"#undef NULL \n"
"#define NULL 0 \n"
+ "#undef nil \n"
+ "#define nil (id)0 \n"
"typedef unsigned short unichar; \n"
"void \n"
"$__lldb_class::%s(void *$__lldb_arg) %s\n"
@@ -68,6 +72,8 @@
wrap_stream.Printf("%s \n"
"#undef NULL \n"
"#define NULL 0 \n"
+ "#undef nil \n"
+ "#define nil (id)0 \n"
"typedef unsigned short unichar; \n"
"@interface $__lldb_objc_class ($__lldb_category) \n"
"+(void)%s:(void *)$__lldb_arg; \n"
@@ -88,6 +94,8 @@
wrap_stream.Printf("%s \n"
"#undef NULL \n"
"#define NULL 0 \n"
+ "#undef nil \n"
+ "#define nil (id)0 \n"
"typedef unsigned short unichar; \n"
"@interface $__lldb_objc_class ($__lldb_category) \n"
"-(void)%s:(void *)$__lldb_arg; \n"
Modified: lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm Fri Jun 8 13:36:34 2012
@@ -1240,6 +1240,9 @@
if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR))
flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag
+
+ if (launch_info.GetLaunchInSeparateProcessGroup())
+ flags |= POSIX_SPAWN_SETPGROUP;
//#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
// // Close all files exception those with file actions if this is supported.
Modified: lldb/branches/lldb-platform-work/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/CommandInterpreter.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/CommandInterpreter.cpp Fri Jun 8 13:36:34 2012
@@ -80,8 +80,8 @@
m_script_interpreter_ap (),
m_comment_char ('#'),
m_repeat_char ('!'),
- m_batch_command_mode (false),
- m_truncation_warning(eNoTruncation)
+ m_truncation_warning(eNoTruncation),
+ m_command_source_depth (0)
{
const char *dbg_name = debugger.GetInstanceName().AsCString();
std::string lang_name = ScriptInterpreter::LanguageToString (script_language);
@@ -240,6 +240,10 @@
AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp);
}
+ cmd_obj_sp = GetCommandSPExact ("process kill", false);
+ if (cmd_obj_sp)
+ AddAlias ("kill", cmd_obj_sp);
+
cmd_obj_sp = GetCommandSPExact ("process launch", false);
if (cmd_obj_sp)
{
@@ -1218,7 +1222,7 @@
bool
CommandInterpreter::HandleCommand (const char *command_line,
- bool add_to_history,
+ LazyBool lazy_add_to_history,
CommandReturnObject &result,
ExecutionContext *override_context,
bool repeat_on_empty_command,
@@ -1246,7 +1250,14 @@
if (!no_context_switching)
UpdateExecutionContext (override_context);
-
+
+ // <rdar://problem/11328896>
+ bool add_to_history;
+ if (lazy_add_to_history == eLazyBoolCalculate)
+ add_to_history = (m_command_source_depth == 0);
+ else
+ add_to_history = (lazy_add_to_history == eLazyBoolYes);
+
bool empty_command = false;
bool comment_command = false;
if (command_string.empty())
@@ -2226,7 +2237,7 @@
bool echo_commands = false;
bool print_results = false;
- HandleCommandsFromFile (init_file, exe_ctx, stop_on_continue, stop_on_error, echo_commands, print_results, result);
+ HandleCommandsFromFile (init_file, exe_ctx, stop_on_continue, stop_on_error, echo_commands, print_results, eLazyBoolNo, result);
}
else
{
@@ -2258,6 +2269,7 @@
bool stop_on_error,
bool echo_commands,
bool print_results,
+ LazyBool add_to_history,
CommandReturnObject &result)
{
size_t num_lines = commands.GetSize();
@@ -2294,7 +2306,7 @@
CommandReturnObject tmp_result;
// If override_context is not NULL, pass no_context_switching = true for
// HandleCommand() since we updated our context already.
- bool success = HandleCommand(cmd, false, tmp_result,
+ bool success = HandleCommand(cmd, add_to_history, tmp_result,
NULL, /* override_context */
true, /* repeat_on_empty_command */
override_context != NULL /* no_context_switching */);
@@ -2372,6 +2384,7 @@
bool stop_on_error,
bool echo_command,
bool print_result,
+ LazyBool add_to_history,
CommandReturnObject &result)
{
if (cmd_file.Exists())
@@ -2385,7 +2398,9 @@
result.SetStatus (eReturnStatusFailed);
return;
}
- HandleCommands (commands, context, stop_on_continue, stop_on_error, echo_command, print_result, result);
+ m_command_source_depth++;
+ HandleCommands (commands, context, stop_on_continue, stop_on_error, echo_command, print_result, add_to_history, result);
+ m_command_source_depth--;
}
else
{
Modified: lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectRegexCommand.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectRegexCommand.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectRegexCommand.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectRegexCommand.cpp Fri Jun 8 13:36:34 2012
@@ -88,7 +88,7 @@
}
// Interpret the new command and return this as the result!
result.GetOutputStream().Printf("%s\n", new_command.c_str());
- return m_interpreter.HandleCommand(new_command.c_str(), true, result);
+ return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result);
}
}
result.SetStatus(eReturnStatusFailed);
Modified: lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.cpp Fri Jun 8 13:36:34 2012
@@ -67,7 +67,7 @@
}
// We can do better when reporting the status of one-liner script execution.
- if (script_interpreter->ExecuteOneLine (command, &result))
+ if (script_interpreter->ExecuteOneLine (command, &result, true))
result.SetStatus(eReturnStatusSuccessFinishNoResult);
else
result.SetStatus(eReturnStatusFailed);
Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupWatchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupWatchpoint.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupWatchpoint.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupWatchpoint.cpp Fri Jun 8 13:36:34 2012
@@ -45,6 +45,19 @@
};
+bool
+OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size)
+{
+ for (uint32_t i = 0; i < llvm::array_lengthof(g_watch_size); ++i)
+ {
+ if (g_watch_size[i].value == 0)
+ break;
+ if (watch_size == g_watch_size[i].value)
+ return true;
+ }
+ return false;
+}
+
OptionGroupWatchpoint::OptionGroupWatchpoint () :
OptionGroup()
{
Modified: lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterNone.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterNone.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterNone.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterNone.cpp Fri Jun 8 13:36:34 2012
@@ -26,7 +26,7 @@
}
bool
-ScriptInterpreterNone::ExecuteOneLine (const char *command, CommandReturnObject *)
+ScriptInterpreterNone::ExecuteOneLine (const char *command, CommandReturnObject *, bool enable_io)
{
m_interpreter.GetDebugger().GetErrorStream().PutCString ("error: there is no embedded script interpreter in this mode.\n");
return false;
Modified: lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp Fri Jun 8 13:36:34 2012
@@ -252,6 +252,253 @@
bool m_old_value;
};
+ScriptInterpreterPython::PythonInputReaderManager::PythonInputReaderManager (ScriptInterpreterPython *interpreter) :
+m_interpreter(interpreter),
+m_debugger_sp(),
+m_reader_sp(),
+m_error(false)
+{
+ if (m_interpreter == NULL)
+ {
+ m_error = true;
+ return;
+ }
+
+ m_debugger_sp = m_interpreter->GetCommandInterpreter().GetDebugger().shared_from_this();
+
+ if (!m_debugger_sp)
+ {
+ m_error = true;
+ return;
+ }
+
+ m_reader_sp = InputReaderSP(new InputReader(*m_debugger_sp.get()));
+
+ if (!m_reader_sp)
+ {
+ m_error = true;
+ return;
+ }
+
+ Error error (m_reader_sp->Initialize (ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback,
+ m_interpreter, // baton
+ eInputReaderGranularityLine, // token size, to pass to callback function
+ NULL, // end token
+ NULL, // prompt
+ true)); // echo input
+ if (error.Fail())
+ m_error = true;
+ else
+ {
+ m_debugger_sp->PushInputReader (m_reader_sp);
+ m_interpreter->m_embedded_thread_input_reader_sp = m_reader_sp;
+ }
+}
+
+ScriptInterpreterPython::PythonInputReaderManager::~PythonInputReaderManager()
+{
+ if (m_interpreter)
+ {
+ if (m_interpreter->m_embedded_thread_input_reader_sp)
+ m_interpreter->m_embedded_thread_input_reader_sp->SetIsDone (true);
+ m_interpreter->m_embedded_python_pty.CloseSlaveFileDescriptor();
+ }
+
+
+ if (m_reader_sp)
+ {
+ m_reader_sp->SetIsDone (true);
+ if (m_debugger_sp)
+ m_debugger_sp->PopInputReader(m_reader_sp);
+ }
+
+ if (m_interpreter)
+ m_interpreter->m_embedded_thread_input_reader_sp.reset();
+}
+
+size_t
+ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback
+(
+ void *baton,
+ InputReader &reader,
+ InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len
+ )
+{
+ lldb::thread_t embedded_interpreter_thread;
+ LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+
+ if (baton == NULL)
+ return 0;
+
+ ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
+
+ if (script_interpreter->m_script_lang != eScriptLanguagePython)
+ return 0;
+
+ StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
+
+ switch (notification)
+ {
+ case eInputReaderActivate:
+ {
+ // Save terminal settings if we can
+ int input_fd = reader.GetDebugger().GetInputFile().GetDescriptor();
+ if (input_fd == File::kInvalidDescriptor)
+ input_fd = STDIN_FILENO;
+
+ script_interpreter->SaveTerminalState(input_fd);
+
+ {
+ ScriptInterpreterPython::Locker locker(script_interpreter,
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock);
+ }
+
+ char error_str[1024];
+ if (script_interpreter->m_embedded_python_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str,
+ sizeof(error_str)))
+ {
+ if (log)
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Activate, succeeded in opening master pty (fd = %d).",
+ script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor());
+ {
+ StreamString run_string;
+ char error_str[1024];
+ const char *pty_slave_name = script_interpreter->m_embedded_python_pty.GetSlaveName (error_str, sizeof (error_str));
+ if (pty_slave_name != NULL)
+ {
+ run_string.Printf ("run_one_line (%s, 'save_stderr = sys.stderr')", script_interpreter->m_dictionary_name.c_str());
+ PyRun_SimpleString (run_string.GetData());
+ run_string.Clear ();
+
+ run_string.Printf ("run_one_line (%s, 'sys.stderr = sys.stdout')", script_interpreter->m_dictionary_name.c_str());
+ PyRun_SimpleString (run_string.GetData());
+ run_string.Clear ();
+
+ run_string.Printf ("run_one_line (%s, 'save_stdin = sys.stdin')", script_interpreter->m_dictionary_name.c_str());
+ PyRun_SimpleString (run_string.GetData());
+ run_string.Clear ();
+
+ run_string.Printf ("run_one_line (%s, \"sys.stdin = open ('%s', 'r')\")", script_interpreter->m_dictionary_name.c_str(),
+ pty_slave_name);
+ PyRun_SimpleString (run_string.GetData());
+ run_string.Clear ();
+ }
+ }
+ embedded_interpreter_thread = Host::ThreadCreate ("<lldb.script-interpreter.noninteractive-python>",
+ ScriptInterpreterPython::PythonInputReaderManager::RunPythonInputReader,
+ script_interpreter, NULL);
+ if (IS_VALID_LLDB_HOST_THREAD(embedded_interpreter_thread))
+ {
+ if (log)
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Activate, succeeded in creating thread (thread_t = %p)", embedded_interpreter_thread);
+ Error detach_error;
+ Host::ThreadDetach (embedded_interpreter_thread, &detach_error);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Activate, failed in creating thread");
+ reader.SetIsDone (true);
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Activate, failed to open master pty ");
+ reader.SetIsDone (true);
+ }
+ }
+ break;
+
+ case eInputReaderDeactivate:
+ // When another input reader is pushed, don't leave the session...
+ //script_interpreter->LeaveSession ();
+ break;
+
+ case eInputReaderReactivate:
+ {
+ // Don't try and acquire the interpreter lock here because code like
+ // this:
+ //
+ // (lldb) script
+ // >>> v = lldb.frame.EvaluateExpression("collection->get_at_index(12)")
+ //
+ // This will cause the process to run. The interpreter lock is taken
+ // by the input reader for the "script" command. If we try and acquire
+ // the lock here, when the process runs it might deactivate this input
+ // reader (if STDIN is hooked up to the inferior process) and
+ // reactivate it when the process stops which will deadlock.
+ //ScriptInterpreterPython::Locker locker(script_interpreter,
+ // ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+ // ScriptInterpreterPython::Locker::FreeAcquiredLock);
+ }
+ break;
+
+ case eInputReaderAsynchronousOutputWritten:
+ break;
+
+ case eInputReaderInterrupt:
+ reader.SetIsDone(true);
+ break;
+
+ case eInputReaderEndOfFile:
+ reader.SetIsDone(true);
+ break;
+
+ case eInputReaderGotToken:
+ if (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor() != -1)
+ {
+ if (log)
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, GotToken, bytes='%s', byte_len = %lu", bytes,
+ bytes_len);
+ if (bytes && bytes_len)
+ ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), bytes, bytes_len);
+ ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), "\n", 1);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, GotToken, bytes='%s', byte_len = %lu, Master File Descriptor is bad.",
+ bytes,
+ bytes_len);
+ reader.SetIsDone (true);
+ }
+
+ break;
+
+ case eInputReaderDone:
+ {
+ StreamString run_string;
+ char error_str[1024];
+ const char *pty_slave_name = script_interpreter->m_embedded_python_pty.GetSlaveName (error_str, sizeof (error_str));
+ if (pty_slave_name != NULL)
+ {
+ run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin')", script_interpreter->m_dictionary_name.c_str());
+ PyRun_SimpleString (run_string.GetData());
+ run_string.Clear();
+
+ run_string.Printf ("run_one_line (%s, 'sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str());
+ PyRun_SimpleString (run_string.GetData());
+ run_string.Clear();
+ }
+ }
+
+ // Restore terminal settings if they were validly saved
+ if (log)
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Done, closing down input reader.");
+
+ script_interpreter->RestoreTerminalState ();
+
+ script_interpreter->m_embedded_python_pty.CloseMasterFileDescriptor();
+ break;
+ }
+
+ return bytes_len;
+}
+
ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
ScriptInterpreter (interpreter, eScriptLanguagePython),
m_embedded_python_pty (),
@@ -514,7 +761,7 @@
}
bool
-ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result)
+ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io)
{
if (!m_valid_session)
return false;
@@ -567,7 +814,11 @@
PyObject *pargs = Py_BuildValue("(Os)",script_interpreter_dict,command);
if (pargs != NULL)
{
- PyObject *pvalue = PyObject_CallObject (pfunc, pargs);
+ PyObject *pvalue = NULL;
+ { // scope for PythonInputReaderManager
+ PythonInputReaderManager py_input(enable_io ? this : NULL);
+ pvalue = PyObject_CallObject (pfunc, pargs);
+ }
Py_DECREF (pargs);
if (pvalue != NULL)
{
@@ -794,7 +1045,8 @@
bool
ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
ScriptInterpreter::ScriptReturnType return_type,
- void *ret_value)
+ void *ret_value,
+ bool enable_io)
{
Locker locker(this,
@@ -830,14 +1082,17 @@
if (in_string != NULL)
{
- py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
- if (py_return == NULL)
- {
- py_error = PyErr_Occurred ();
- if (py_error != NULL)
- PyErr_Clear ();
+ { // scope for PythonInputReaderManager
+ PythonInputReaderManager py_input(enable_io ? this : NULL);
+ py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
+ if (py_return == NULL)
+ {
+ py_error = PyErr_Occurred ();
+ if (py_error != NULL)
+ PyErr_Clear ();
- py_return = PyRun_String (in_string, Py_single_input, globals, locals);
+ py_return = PyRun_String (in_string, Py_single_input, globals, locals);
+ }
}
if (locals != NULL
@@ -956,7 +1211,7 @@
}
bool
-ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string)
+ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, bool enable_io)
{
@@ -998,7 +1253,10 @@
PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
if (compiled_code)
{
- py_return = PyEval_EvalCode (compiled_code, globals, locals);
+ { // scope for PythonInputReaderManager
+ PythonInputReaderManager py_input(enable_io ? this : NULL);
+ py_return = PyEval_EvalCode (compiled_code, globals, locals);
+ }
if (py_return != NULL)
{
success = true;
@@ -1191,7 +1449,7 @@
// Convert StringList to one long, newline delimited, const char *.
std::string function_def_string(function_def.CopyList());
- return ExecuteMultipleLines (function_def_string.c_str());
+ return ExecuteMultipleLines (function_def_string.c_str(), false);
}
bool
@@ -1597,6 +1855,19 @@
return NULL;
}
+lldb::thread_result_t
+ScriptInterpreterPython::PythonInputReaderManager::RunPythonInputReader (lldb::thread_arg_t baton)
+{
+ ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
+
+ const InputReaderSP reader_sp = script_interpreter->m_embedded_thread_input_reader_sp;
+
+ if (reader_sp)
+ reader_sp->WaitOnReaderIsDone();
+
+ return NULL;
+}
+
uint32_t
ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor_sp)
{
@@ -1751,7 +2022,7 @@
command_stream.Printf("if not (sys.path.__contains__('%s')):\n sys.path.append('%s');\n\n",
directory,
directory);
- bool syspath_retval = ExecuteMultipleLines(command_stream.GetData());
+ bool syspath_retval = ExecuteMultipleLines(command_stream.GetData(), false);
if (!syspath_retval)
{
error.SetErrorString("Python sys.path handling failed");
@@ -1772,7 +2043,7 @@
// this call will fail if the module does not exist (because the parameter to it is not a string
// but an actual Python module object, which is non-existant if the module was not imported before)
bool was_imported = (ExecuteOneLineWithReturn(command_stream.GetData(),
- ScriptInterpreterPython::eScriptReturnTypeInt, &refcount) && refcount > 0);
+ ScriptInterpreterPython::eScriptReturnTypeInt, &refcount, false) && refcount > 0);
if (was_imported == true && can_reload == false)
{
error.SetErrorString("module already imported");
@@ -1782,7 +2053,7 @@
// now actually do the import
command_stream.Clear();
command_stream.Printf("import %s",basename.c_str());
- bool import_retval = ExecuteOneLine(command_stream.GetData(), NULL);
+ bool import_retval = ExecuteOneLine(command_stream.GetData(), NULL, false);
if (!import_retval)
{
error.SetErrorString("Python import statement failed");
@@ -1861,6 +2132,8 @@
SynchronicityHandler synch_handler(debugger_sp,
synchronicity);
+ PythonInputReaderManager py_input(this);
+
ret_val = g_swig_call_command (impl_function,
m_dictionary_name.c_str(),
debugger_sp,
@@ -1890,7 +2163,7 @@
if (ExecuteOneLineWithReturn (command.c_str(),
ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
- &result_ptr) && result_ptr)
+ &result_ptr, false) && result_ptr)
{
return std::string(result_ptr);
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Fri Jun 8 13:36:34 2012
@@ -682,6 +682,8 @@
section_sp->SetIsThreadSpecific (is_thread_specific);
m_sections_ap->AddSection(section_sp);
}
+
+ m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
}
return m_sections_ap.get();
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Fri Jun 8 13:36:34 2012
@@ -889,7 +889,7 @@
// adjust the child section offsets for all existing children.
const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr;
segment->Slide(slide_amount, false);
- segment->GetChildren().Slide (-slide_amount, false);
+ segment->GetChildren().Slide(-slide_amount, false);
segment->SetByteSize (curr_seg_max_addr - sect64_min_addr);
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp Fri Jun 8 13:36:34 2012
@@ -648,6 +648,8 @@
m_sections_ap->AddSection(section_sp);
}
+
+ m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
}
}
return m_sections_ap.get();
Modified: lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp Fri Jun 8 13:36:34 2012
@@ -624,7 +624,7 @@
module_spec.GetArchitecture(),
module_sp,
NULL);
- if (module_sp && module_sp->GetUUID() == *module_uuid_ptr)
+ if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
{
//printf ("sdk[%u] last found\n", m_last_module_sdk_idx);
error.Clear();
@@ -650,7 +650,7 @@
module_spec.GetArchitecture(),
module_sp,
NULL);
- if (module_sp && module_sp->GetUUID() == *module_uuid_ptr)
+ if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
{
// Remember the index of the last SDK that we found a file
// in in case the wrong SDK was selected.
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Fri Jun 8 13:36:34 2012
@@ -942,7 +942,7 @@
// XXX - Release the master terminal descriptor and pass it off to the
// XXX - ProcessMonitor instance. Similarly stash the inferior pid.
// For now just use stdin fd
- monitor->m_terminal_fd = STDIN_FILENO;
+ monitor->m_terminal_fd = ::dup(STDIN_FILENO);
monitor->m_pid = pid;
// Set the terminal fd to be in non blocking mode (it simplifies the
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Fri Jun 8 13:36:34 2012
@@ -241,7 +241,8 @@
{
if (GetAck () != '+')
{
- printf("get ack failed...");
+ if (log)
+ log->Printf("get ack failed...");
return 0;
}
}
@@ -268,7 +269,11 @@
bool
GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker)
{
- return locker.TryLock (m_sequence_mutex);
+ if (IsRunning())
+ return locker.TryLock (m_sequence_mutex);
+
+ locker.Lock (m_sequence_mutex);
+ return true;
}
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Fri Jun 8 13:36:34 2012
@@ -276,78 +276,87 @@
{
if (send_async)
{
- Mutex::Locker async_locker (m_async_mutex);
- m_async_packet.assign(payload, payload_length);
- m_async_packet_predicate.SetValue (true, eBroadcastNever);
-
- if (log)
- log->Printf ("async: async packet = %s", m_async_packet.c_str());
-
- bool timed_out = false;
- if (SendInterrupt(locker, 2, timed_out))
+ if (IsRunning())
{
- if (m_interrupt_sent)
- {
- TimeValue timeout_time;
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds (m_packet_timeout);
-
- if (log)
- log->Printf ("async: sent interrupt");
+ Mutex::Locker async_locker (m_async_mutex);
+ m_async_packet.assign(payload, payload_length);
+ m_async_packet_predicate.SetValue (true, eBroadcastNever);
+
+ if (log)
+ log->Printf ("async: async packet = %s", m_async_packet.c_str());
- if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
+ bool timed_out = false;
+ if (SendInterrupt(locker, 2, timed_out))
+ {
+ if (m_interrupt_sent)
{
- if (log)
- log->Printf ("async: got response");
+ m_interrupt_sent = false;
+ TimeValue timeout_time;
+ timeout_time = TimeValue::Now();
+ timeout_time.OffsetWithSeconds (m_packet_timeout);
- // Swap the response buffer to avoid malloc and string copy
- response.GetStringRef().swap (m_async_response.GetStringRef());
- response_len = response.GetStringRef().size();
- }
- else
- {
if (log)
- log->Printf ("async: timed out waiting for response");
- }
-
- // Make sure we wait until the continue packet has been sent again...
- if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
- {
- if (log)
+ log->Printf ("async: sent interrupt");
+
+ if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
{
- if (timed_out)
- log->Printf ("async: timed out waiting for process to resume, but process was resumed");
- else
- log->Printf ("async: async packet sent");
+ if (log)
+ log->Printf ("async: got response");
+
+ // Swap the response buffer to avoid malloc and string copy
+ response.GetStringRef().swap (m_async_response.GetStringRef());
+ response_len = response.GetStringRef().size();
+ }
+ else
+ {
+ if (log)
+ log->Printf ("async: timed out waiting for response");
+ }
+
+ // Make sure we wait until the continue packet has been sent again...
+ if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
+ {
+ if (log)
+ {
+ if (timed_out)
+ log->Printf ("async: timed out waiting for process to resume, but process was resumed");
+ else
+ log->Printf ("async: async packet sent");
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("async: timed out waiting for process to resume");
}
}
else
{
+ // We had a racy condition where we went to send the interrupt
+ // yet we were able to get the lock, so the process must have
+ // just stopped?
if (log)
- log->Printf ("async: timed out waiting for process to resume");
+ log->Printf ("async: got lock without sending interrupt");
+ // Send the packet normally since we got the lock
+ if (SendPacketNoLock (payload, payload_length))
+ response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
+ else
+ {
+ if (log)
+ log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
+ }
}
}
else
{
- // We had a racy condition where we went to send the interrupt
- // yet we were able to get the lock, so the process must have
- // just stopped?
if (log)
- log->Printf ("async: got lock without sending interrupt");
- // Send the packet normally since we got the lock
- if (SendPacketNoLock (payload, payload_length))
- response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
- else
- {
- if (log)
- log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
- }
+ log->Printf ("async: failed to interrupt");
}
}
else
{
if (log)
- log->Printf ("async: failed to interrupt");
+ log->Printf ("async: not running, async is ignored");
}
}
else
@@ -383,7 +392,7 @@
BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
m_public_is_running.SetValue (true, eBroadcastNever);
// Set the starting continue packet into "continue_packet". This packet
- // make change if we are interrupted and we continue after an async packet...
+ // may change if we are interrupted and we continue after an async packet...
std::string continue_packet(payload, packet_length);
bool got_stdout = false;
@@ -438,10 +447,9 @@
const uint8_t signo = response.GetHexU8 (UINT8_MAX);
- bool continue_after_async = false;
- if (m_async_signal != -1 || m_async_packet_predicate.GetValue())
+ bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue();
+ if (continue_after_async || m_interrupt_sent)
{
- continue_after_async = true;
// We sent an interrupt packet to stop the inferior process
// for an async signal or to send an async packet while running
// but we might have been single stepping and received the
@@ -653,7 +661,6 @@
bool &timed_out
)
{
- m_interrupt_sent = false;
timed_out = false;
LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
Modified: lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Jun 8 13:36:34 2012
@@ -1646,6 +1646,10 @@
bool discard_thread_plans = true;
bool catch_stop_event = true;
EventSP event_sp;
+
+ // FIXME: InterruptIfRunning should be done in the Process base class, or better still make Halt do what is
+ // needed. This shouldn't be a feature of a particular plugin.
+
return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
}
@@ -1688,6 +1692,9 @@
log->Printf ("ProcessGDBRemote::DoDestroy()");
// Interrupt if our inferior is running...
+ int exit_status = SIGABRT;
+ std::string exit_string;
+
if (m_gdb_comm.IsConnected())
{
if (m_public_state.GetValue() != eStateAttaching)
@@ -1703,16 +1710,39 @@
{
SetLastStopPacket (response);
ClearThreadIDList ();
- SetExitStatus(response.GetHexU8(), NULL);
+ exit_status = response.GetHexU8();
+ }
+ else
+ {
+ if (log)
+ log->Printf ("ProcessGDBRemote::DoDestroy - got unexpected response to k packet: %s", response.GetStringRef().c_str());
+ exit_string.assign("got unexpected response to k packet: ");
+ exit_string.append(response.GetStringRef());
}
}
else
{
- SetExitStatus(SIGABRT, NULL);
- //error.SetErrorString("kill packet failed");
+ if (log)
+ log->Printf ("ProcessGDBRemote::DoDestroy - failed to send k packet");
+ exit_string.assign("failed to send the k packet");
}
}
+ else
+ {
+ if (log)
+ log->Printf ("ProcessGDBRemote::DoDestroy - failed to send k packet");
+ exit_string.assign ("killing while attaching.");
+ }
+ }
+ else
+ {
+ // If we missed setting the exit status on the way out, do it here.
+ // NB set exit status can be called multiple times, the first one sets the status.
+ exit_string.assign("destroying when not connected to debugserver");
}
+
+ SetExitStatus(exit_status, exit_string.c_str());
+
StopAsyncThread ();
KillDebugserverProcess ();
return error;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Jun 8 13:36:34 2012
@@ -1457,6 +1457,57 @@
return NULL;
}
+class SymbolFileDWARF::DelayedAddObjCClassProperty
+{
+public:
+ DelayedAddObjCClassProperty
+ (
+ clang::ASTContext *ast,
+ lldb::clang_type_t class_opaque_type,
+ const char *property_name,
+ lldb::clang_type_t property_opaque_type, // The property type is only required if you don't have an ivar decl
+ clang::ObjCIvarDecl *ivar_decl,
+ const char *property_setter_name,
+ const char *property_getter_name,
+ uint32_t property_attributes,
+ uint64_t metadata = 0
+ ) :
+ m_ast (ast),
+ m_class_opaque_type (class_opaque_type),
+ m_property_name (property_name),
+ m_property_opaque_type (property_opaque_type),
+ m_ivar_decl (ivar_decl),
+ m_property_setter_name (property_setter_name),
+ m_property_getter_name (property_getter_name),
+ m_property_attributes (property_attributes),
+ m_metadata (metadata)
+ {
+ }
+
+ bool Finalize() const
+ {
+ return ClangASTContext::AddObjCClassProperty(m_ast,
+ m_class_opaque_type,
+ m_property_name,
+ m_property_opaque_type,
+ m_ivar_decl,
+ m_property_setter_name,
+ m_property_getter_name,
+ m_property_attributes,
+ m_metadata);
+ }
+private:
+ clang::ASTContext *m_ast;
+ lldb::clang_type_t m_class_opaque_type;
+ const char *m_property_name;
+ lldb::clang_type_t m_property_opaque_type;
+ clang::ObjCIvarDecl *m_ivar_decl;
+ const char *m_property_setter_name;
+ const char *m_property_getter_name;
+ uint32_t m_property_attributes;
+ uint64_t m_metadata;
+};
+
size_t
SymbolFileDWARF::ParseChildMembers
(
@@ -1468,6 +1519,7 @@
std::vector<clang::CXXBaseSpecifier *>& base_classes,
std::vector<int>& member_accessibilities,
DWARFDIECollection& member_function_dies,
+ DelayedPropertyList& delayed_properties,
AccessType& default_accessibility,
bool &is_a_class,
LayoutInfo &layout_info
@@ -1739,14 +1791,15 @@
assert (ivar_decl != NULL);
}
- GetClangASTContext().AddObjCClassProperty (class_clang_type,
- prop_name,
- member_type->GetClangLayoutType(),
- ivar_decl,
- prop_setter_name,
- prop_getter_name,
- prop_attributes,
- MakeUserID(die->GetOffset()));
+ delayed_properties.push_back(DelayedAddObjCClassProperty(GetClangASTContext().getASTContext(),
+ class_clang_type,
+ prop_name,
+ member_type->GetClangLayoutType(),
+ ivar_decl,
+ prop_setter_name,
+ prop_getter_name,
+ prop_attributes,
+ MakeUserID(die->GetOffset())));
if (ivar_decl)
GetClangASTContext().SetMetadata((uintptr_t)ivar_decl, MakeUserID(die->GetOffset()));
@@ -1857,6 +1910,7 @@
break;
}
}
+
return count;
}
@@ -2061,6 +2115,8 @@
bool is_a_class = false;
// Parse members and base classes first
DWARFDIECollection member_function_dies;
+
+ DelayedPropertyList delayed_properties;
ParseChildMembers (sc,
dwarf_cu,
@@ -2070,6 +2126,7 @@
base_classes,
member_accessibilities,
member_function_dies,
+ delayed_properties,
default_accessibility,
is_a_class,
layout_info);
@@ -2128,6 +2185,11 @@
}
}
}
+
+ for (DelayedPropertyList::const_iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
+ pi != pe;
+ ++pi)
+ pi->Finalize();
}
}
@@ -5922,7 +5984,7 @@
decl_ctx_die))
{
type_ptr = m_die_to_type[die];
- if (type_ptr)
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
{
type_sp = type_ptr->shared_from_this();
break;
@@ -6047,7 +6109,7 @@
// The type for this DIE should have been filled in the function call above
type_ptr = m_die_to_type[die];
- if (type_ptr)
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
{
type_sp = type_ptr->shared_from_this();
break;
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Fri Jun 8 13:36:34 2012
@@ -331,6 +331,9 @@
bool parse_children,
lldb_private::VariableList* cc_variable_list = NULL);
+ class DelayedAddObjCClassProperty;
+ typedef std::vector <DelayedAddObjCClassProperty> DelayedPropertyList;
+
size_t ParseChildMembers(
const lldb_private::SymbolContext& sc,
DWARFCompileUnit* dwarf_cu,
@@ -340,6 +343,7 @@
std::vector<clang::CXXBaseSpecifier *>& base_classes,
std::vector<int>& member_accessibilities,
DWARFDIECollection& member_function_dies,
+ DelayedPropertyList& delayed_properties,
lldb::AccessType &default_accessibility,
bool &is_a_class,
LayoutInfo &layout_info);
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Fri Jun 8 13:36:34 2012
@@ -426,6 +426,8 @@
}
}
}
+ oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
+ comp_unit_info->debug_map_sections_sp->Finalize();
#if defined(DEBUG_OSO_DMAP)
s << "OSO sections after:\n";
oso_objfile->GetSectionList()->Dump(&s, NULL, true);
Modified: lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp Fri Jun 8 13:36:34 2012
@@ -78,6 +78,8 @@
dsym_section_list->AddSection(exec_sect_sp);
}
}
+
+ dsym_section_list->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
}
}
Modified: lldb/branches/lldb-platform-work/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Platform.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Platform.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Platform.cpp Fri Jun 8 13:36:34 2012
@@ -620,6 +620,11 @@
ProcessSP process_sp;
// Make sure we stop at the entry point
launch_info.GetFlags ().Set (eLaunchFlagDebug);
+ // We always launch the process we are going to debug in a separate process
+ // group, since then we can handle ^C interrupts ourselves w/o having to worry
+ // about the target getting them as well.
+ launch_info.SetLaunchInSeparateProcessGroup(true);
+
error = LaunchProcess (launch_info);
if (error.Success())
{
Modified: lldb/branches/lldb-platform-work/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Process.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Process.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Process.cpp Fri Jun 8 13:36:34 2012
@@ -812,6 +812,7 @@
m_should_detach (false),
m_next_event_action_ap(),
m_run_lock (),
+ m_currently_handling_event(false),
m_can_jit(eCanJITDontKnow)
{
UpdateInstanceName();
@@ -1299,15 +1300,24 @@
// to tell the program to run.
if (!IsHijackedForEvent(eBroadcastBitStateChanged))
{
- const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
- const bool new_state_is_stopped = StateIsStoppedState(new_state, false);
- if (old_state_is_stopped != new_state_is_stopped)
+ if (new_state == eStateDetached)
{
- if (new_state_is_stopped)
+ if (log)
+ log->Printf("Process::SetPublicState (%s) -- unlocking run lock for detach", StateAsCString(new_state));
+ m_run_lock.WriteUnlock();
+ }
+ else
+ {
+ const bool old_state_is_stopped = StateIsStoppedState(old_state, false);
+ const bool new_state_is_stopped = StateIsStoppedState(new_state, false);
+ if (old_state_is_stopped != new_state_is_stopped)
{
- if (log)
- log->Printf("Process::SetPublicState (%s) -- unlocking run lock", StateAsCString(new_state));
- m_run_lock.WriteUnlock();
+ if (new_state_is_stopped)
+ {
+ if (log)
+ log->Printf("Process::SetPublicState (%s) -- unlocking run lock", StateAsCString(new_state));
+ m_run_lock.WriteUnlock();
+ }
}
}
}
@@ -1923,64 +1933,55 @@
}
-// Comment out line below to disable memory caching
+// Comment out line below to disable memory caching, overriding the process setting
+// target.process.disable-memory-cache
#define ENABLE_MEMORY_CACHING
// Uncomment to verify memory caching works after making changes to caching code
//#define VERIFY_MEMORY_READS
-#if defined (ENABLE_MEMORY_CACHING)
-
-#if defined (VERIFY_MEMORY_READS)
-
size_t
Process::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
{
- // Memory caching is enabled, with debug verification
- if (buf && size)
+ if (!GetDisableMemoryCache())
+ {
+#if defined (VERIFY_MEMORY_READS)
+ // Memory caching is enabled, with debug verification
+
+ if (buf && size)
+ {
+ // Uncomment the line below to make sure memory caching is working.
+ // I ran this through the test suite and got no assertions, so I am
+ // pretty confident this is working well. If any changes are made to
+ // memory caching, uncomment the line below and test your changes!
+
+ // Verify all memory reads by using the cache first, then redundantly
+ // reading the same memory from the inferior and comparing to make sure
+ // everything is exactly the same.
+ std::string verify_buf (size, '\0');
+ assert (verify_buf.size() == size);
+ const size_t cache_bytes_read = m_memory_cache.Read (this, addr, buf, size, error);
+ Error verify_error;
+ const size_t verify_bytes_read = ReadMemoryFromInferior (addr, const_cast<char *>(verify_buf.data()), verify_buf.size(), verify_error);
+ assert (cache_bytes_read == verify_bytes_read);
+ assert (memcmp(buf, verify_buf.data(), verify_buf.size()) == 0);
+ assert (verify_error.Success() == error.Success());
+ return cache_bytes_read;
+ }
+ return 0;
+#else // !defined(VERIFY_MEMORY_READS)
+ // Memory caching is enabled, without debug verification
+
+ return m_memory_cache.Read (addr, buf, size, error);
+#endif // defined (VERIFY_MEMORY_READS)
+ }
+ else
{
- // Uncomment the line below to make sure memory caching is working.
- // I ran this through the test suite and got no assertions, so I am
- // pretty confident this is working well. If any changes are made to
- // memory caching, uncomment the line below and test your changes!
-
- // Verify all memory reads by using the cache first, then redundantly
- // reading the same memory from the inferior and comparing to make sure
- // everything is exactly the same.
- std::string verify_buf (size, '\0');
- assert (verify_buf.size() == size);
- const size_t cache_bytes_read = m_memory_cache.Read (this, addr, buf, size, error);
- Error verify_error;
- const size_t verify_bytes_read = ReadMemoryFromInferior (addr, const_cast<char *>(verify_buf.data()), verify_buf.size(), verify_error);
- assert (cache_bytes_read == verify_bytes_read);
- assert (memcmp(buf, verify_buf.data(), verify_buf.size()) == 0);
- assert (verify_error.Success() == error.Success());
- return cache_bytes_read;
+ // Memory caching is disabled
+
+ return ReadMemoryFromInferior (addr, buf, size, error);
}
- return 0;
-}
-
-#else // #if defined (VERIFY_MEMORY_READS)
-
-size_t
-Process::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- // Memory caching enabled, no verification
- return m_memory_cache.Read (addr, buf, size, error);
}
-
-#endif // #else for #if defined (VERIFY_MEMORY_READS)
-#else // #if defined (ENABLE_MEMORY_CACHING)
-
-size_t
-Process::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
- // Memory caching is disabled
- return ReadMemoryFromInferior (addr, buf, size, error);
-}
-
-#endif // #else for #if defined (ENABLE_MEMORY_CACHING)
-
size_t
Process::ReadCStringFromMemory (addr_t addr, std::string &out_str, Error &error)
{
@@ -2927,6 +2928,11 @@
Error
Process::Halt ()
{
+ // First make sure we aren't in the middle of handling an event, or we might restart. This is pretty weak, since
+ // we could just straightaway get another event. It just narrows the window...
+ m_currently_handling_event.WaitForValueEqualTo(false);
+
+
// Pause our private state thread so we can ensure no one else eats
// the stop event out from under us.
Listener halt_listener ("lldb.process.halt_listener");
@@ -3030,31 +3036,51 @@
Error error (WillDestroy());
if (error.Success())
{
- DisableAllBreakpointSites();
if (m_public_state.GetValue() == eStateRunning)
{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TEMPORARY));
+ if (log)
+ log->Printf("Process::Destroy() About to halt.");
error = Halt();
if (error.Success())
{
// Consume the halt event.
EventSP stop_event;
TimeValue timeout (TimeValue::Now());
- timeout.OffsetWithMicroSeconds(1000);
+ timeout.OffsetWithSeconds(1);
StateType state = WaitForProcessToStop (&timeout);
if (state != eStateStopped)
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TEMPORARY));
if (log)
log->Printf("Process::Destroy() Halt failed to stop, state is: %s", StateAsCString(state));
+ // If we really couldn't stop the process then we should just error out here, but if the
+ // lower levels just bobbled sending the event and we really are stopped, then continue on.
+ StateType private_state = m_private_state.GetValue();
+ if (private_state != eStateStopped && private_state != eStateExited)
+ {
+ return error;
+ }
}
}
else
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TEMPORARY));
if (log)
log->Printf("Process::Destroy() Halt got error: %s", error.AsCString());
+ return error;
}
}
+
+ if (m_public_state.GetValue() != eStateRunning)
+ {
+ // Ditch all thread plans, and remove all our breakpoints: in case we have to restart the target to
+ // kill it, we don't want it hitting a breakpoint...
+ // Only do this if we've stopped, however, since if we didn't manage to halt it above, then
+ // we're not going to have much luck doing this now.
+ m_thread_list.DiscardThreadPlans();
+ DisableAllBreakpointSites();
+ }
error = DoDestroy();
if (error.Success())
@@ -3333,6 +3359,7 @@
Process::HandlePrivateEvent (EventSP &event_sp)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ m_currently_handling_event.SetValue(true, eBroadcastNever);
const StateType new_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
@@ -3398,6 +3425,7 @@
StateAsCString (GetState ()));
}
}
+ m_currently_handling_event.SetValue(false, eBroadcastAlways);
}
void *
@@ -3956,7 +3984,6 @@
}
}
UserSettingsControllerSP &usc = GetSettingsController();
- usc.reset (new SettingsController);
UserSettingsController::InitializeSettingsController (usc,
SettingsController::global_settings_table,
SettingsController::instance_settings_table);
@@ -4877,16 +4904,36 @@
Error &err,
bool pending)
{
+ if (var_name == GetDisableMemoryCacheVarName())
+ {
+ bool success;
+ bool result = Args::StringToBoolean(value, false, &success);
+
+ if (success)
+ {
+ m_disable_memory_cache = result;
+ }
+ else
+ {
+ err.SetErrorStringWithFormat ("Bad value \"%s\" for %s, should be Boolean.", value, GetDisableMemoryCacheVarName().AsCString());
+ }
+
+ }
}
void
ProcessInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
bool pending)
{
-// if (new_settings.get() == NULL)
-// return;
-//
-// ProcessInstanceSettings *new_process_settings = (ProcessInstanceSettings *) new_settings.get();
+ if (new_settings.get() == NULL)
+ return;
+
+ ProcessInstanceSettings *new_settings_ptr = static_cast <ProcessInstanceSettings *> (new_settings.get());
+
+ if (!new_settings_ptr)
+ return;
+
+ *this = *new_settings_ptr;
}
bool
@@ -4895,9 +4942,17 @@
StringList &value,
Error *err)
{
- if (err)
- err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
- return false;
+ if (var_name == GetDisableMemoryCacheVarName())
+ {
+ value.AppendString(m_disable_memory_cache ? "true" : "false");
+ return true;
+ }
+ else
+ {
+ if (err)
+ err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
+ return false;
+ }
}
const ConstString
@@ -4913,6 +4968,14 @@
return ret_val;
}
+const ConstString &
+ProcessInstanceSettings::GetDisableMemoryCacheVarName () const
+{
+ static ConstString disable_memory_cache_var_name ("disable-memory-cache");
+
+ return disable_memory_cache_var_name;
+}
+
//--------------------------------------------------
// SettingsController Variable Tables
//--------------------------------------------------
@@ -4929,6 +4992,13 @@
Process::SettingsController::instance_settings_table[] =
{
//{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"},
+ { "disable-memory-cache", eSetVarTypeBoolean,
+#ifdef ENABLE_MEMORY_CACHING
+ "false",
+#else
+ "true",
+#endif
+ NULL, false, false, "Disable reading and caching of memory in fixed-size units." },
{ NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL }
};
Modified: lldb/branches/lldb-platform-work/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Target.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Target.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Target.cpp Fri Jun 8 13:36:34 2012
@@ -30,6 +30,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionGroupWatchpoint.h"
#include "lldb/lldb-private-log.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
@@ -465,10 +466,25 @@
return (m_process_sp && m_process_sp->IsAlive());
}
+static bool
+CheckIfWatchpointsExhausted(Target *target, Error &error)
+{
+ uint32_t num_supported_hardware_watchpoints;
+ Error rc = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints);
+ if (rc.Success())
+ {
+ uint32_t num_current_watchpoints = target->GetWatchpointList().GetSize();
+ if (num_current_watchpoints >= num_supported_hardware_watchpoints)
+ error.SetErrorStringWithFormat("number of supported hardware watchpoints (%u) has been reached",
+ num_supported_hardware_watchpoints);
+ }
+ return false;
+}
+
// See also Watchpoint::SetWatchpointType(uint32_t type) and
// the OptionGroupWatchpoint::WatchType enum type.
WatchpointSP
-Target::CreateWatchpoint(lldb::addr_t addr, size_t size, uint32_t type)
+Target::CreateWatchpoint(lldb::addr_t addr, size_t size, uint32_t type, Error &error)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
if (log)
@@ -477,12 +493,25 @@
WatchpointSP wp_sp;
if (!ProcessIsValid())
+ {
+ error.SetErrorString("process is not alive");
return wp_sp;
+ }
if (addr == LLDB_INVALID_ADDRESS || size == 0)
+ {
+ if (size == 0)
+ error.SetErrorString("cannot set a watchpoint with watch_size of 0");
+ else
+ error.SetErrorStringWithFormat("invalid watch address: %llu", addr);
return wp_sp;
+ }
// Currently we only support one watchpoint per address, with total number
// of watchpoints limited by the hardware which the inferior is running on.
+
+ // Grab the list mutex while doing operations.
+ Mutex::Locker locker;
+ this->GetWatchpointList().GetListMutex(locker);
WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);
if (matched_sp)
{
@@ -513,17 +542,23 @@
m_watchpoint_list.Add(wp_sp);
}
- Error rc = m_process_sp->EnableWatchpoint(wp_sp.get());
+ error = m_process_sp->EnableWatchpoint(wp_sp.get());
if (log)
log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n",
__FUNCTION__,
- rc.Success() ? "succeeded" : "failed",
+ error.Success() ? "succeeded" : "failed",
wp_sp->GetID());
- if (rc.Fail()) {
+ if (error.Fail()) {
// Enabling the watchpoint on the device side failed.
// Remove the said watchpoint from the list maintained by the target instance.
m_watchpoint_list.Remove(wp_sp->GetID());
+ // See if we could provide more helpful error message.
+ if (!CheckIfWatchpointsExhausted(this, error))
+ {
+ if (!OptionGroupWatchpoint::IsWatchSizeSupported(size))
+ error.SetErrorStringWithFormat("watch size of %lu is not supported", size);
+ }
wp_sp.reset();
}
else
@@ -2001,7 +2036,8 @@
stop_on_continue,
stop_on_error,
echo_commands,
- print_results,
+ print_results,
+ eLazyBoolNo,
result);
// If the command started the target going again, we should bag out of
Modified: lldb/branches/lldb-platform-work/source/Target/TargetList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/TargetList.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/TargetList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/TargetList.cpp Fri Jun 8 13:36:34 2012
@@ -165,6 +165,10 @@
if (!platform_sp)
platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
+ if (!arch.IsValid())
+ arch = specified_arch;
+
+
if (file)
{
ModuleSP exe_module_sp;
Modified: lldb/branches/lldb-platform-work/source/Target/ThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadList.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadList.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadList.cpp Fri Jun 8 13:36:34 2012
@@ -466,7 +466,12 @@
for (pos = m_threads.begin(); pos != end; ++pos)
{
ThreadSP thread_sp(*pos);
- thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
+ StateType run_state;
+ if (thread_sp->GetResumeState() != eStateSuspended)
+ run_state = thread_sp->GetCurrentPlan()->RunState();
+ else
+ run_state = eStateSuspended;
+ thread_sp->WillResume(run_state);
}
}
else
Modified: lldb/branches/lldb-platform-work/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/lldb.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/lldb.cpp (original)
+++ lldb/branches/lldb-platform-work/source/lldb.cpp Fri Jun 8 13:36:34 2012
@@ -119,8 +119,8 @@
AppleObjCRuntimeV1::Initialize();
ObjectContainerUniversalMachO::Initialize();
ObjectFileMachO::Initialize();
- ProcessKDP::Initialize();
ProcessGDBRemote::Initialize();
+ ProcessKDP::Initialize();
ProcessMachCore::Initialize();
SymbolVendorMacOSX::Initialize();
PlatformRemoteiOS::Initialize();
@@ -194,8 +194,8 @@
ObjectContainerUniversalMachO::Terminate();
ObjectFileMachO::Terminate();
ProcessMachCore::Terminate();
- ProcessKDP::Terminate();
ProcessGDBRemote::Terminate();
+ ProcessKDP::Terminate();
SymbolVendorMacOSX::Terminate();
PlatformMacOSX::Terminate();
PlatformRemoteiOS::Terminate();
Modified: lldb/branches/lldb-platform-work/test/functionalities/completion/TestCompletion.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/completion/TestCompletion.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/completion/TestCompletion.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/completion/TestCompletion.py Fri Jun 8 13:36:34 2012
@@ -109,8 +109,8 @@
self.complete_from_to('settings set target.process', 'settings set target.process.')
def test_settings_set_target_process_dot(self):
- """Test that 'settings set target.process.' completes to 'settings set target.process.thread.'."""
- self.complete_from_to('settings set target.process.', 'settings set target.process.thread.')
+ """Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'."""
+ self.complete_from_to('settings set target.process.t', 'settings set target.process.thread.')
def test_settings_set_target_process_thread_dot(self):
"""Test that 'settings set target.process.thread.' completes to ['Available completions:',
Modified: lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py Fri Jun 8 13:36:34 2012
@@ -61,6 +61,10 @@
self.expect("watchpoint set expression -w write --", error=True,
startstr = 'error: required argument missing; specify an expression to evaulate into the addres to watch for')
+ # It's an error if the expression did not evaluate to an address.
+ self.expect("watchpoint set expression MyAggregateDataType", error=True,
+ startstr = 'error: expression did not evaluate to an address')
+
# Check for missing option terminator '--'.
self.expect("watchpoint set expression -w write -x 1 g_char_ptr", error=True,
startstr = 'error: did you forget to enter the option terminator string "--"?')
Modified: lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/main.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/main.cpp (original)
+++ lldb/branches/lldb-platform-work/test/functionalities/watchpoint/watchpoint_set_command/main.cpp Fri Jun 8 13:36:34 2012
@@ -98,6 +98,12 @@
err = ::pthread_create (&g_thread_2, NULL, thread_func, &thread_index_2);
err = ::pthread_create (&g_thread_3, NULL, thread_func, &thread_index_3);
+ struct {
+ int a;
+ int b;
+ int c;
+ } MyAggregateDataType;
+
printf ("Before turning all three threads loose...\n"); // Set break point at this line.
// Join all of our threads
Modified: lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_target.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_target.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_target.py (original)
+++ lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_target.py Fri Jun 8 13:36:34 2012
@@ -52,7 +52,8 @@
obj.GetAddressByteSize()
obj.GetByteOrder()
obj.GetTriple()
- obj.WatchAddress(123, 8, True, True)
+ error = lldb.SBError()
+ obj.WatchAddress(123, 8, True, True, error)
obj.GetBroadcaster()
obj.GetDescription(lldb.SBStream(), lldb.eDescriptionLevelBrief)
obj.Clear()
Modified: lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_value.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_value.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_value.py (original)
+++ lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_value.py Fri Jun 8 13:36:34 2012
@@ -34,8 +34,9 @@
obj.GetDescription(stream)
obj.GetExpressionPath(stream)
obj.GetExpressionPath(stream, True)
- obj.Watch(True, True, False)
- obj.WatchPointee(True, False, True)
+ error = lldb.SBError()
+ obj.Watch(True, True, False, error)
+ obj.WatchPointee(True, False, True, error)
for child_val in obj:
print child_val
error = lldb.SBError()
Modified: lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_watchpoint.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_watchpoint.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_watchpoint.py (original)
+++ lldb/branches/lldb-platform-work/test/python_api/default-constructor/sb_watchpoint.py Fri Jun 8 13:36:34 2012
@@ -8,7 +8,6 @@
def fuzz_obj(obj):
obj.GetID()
obj.IsValid()
- obj.GetError()
obj.GetHardwareIndex()
obj.GetWatchAddress()
obj.GetWatchSize()
Modified: lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestSetWatchpoint.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestSetWatchpoint.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestSetWatchpoint.py (original)
+++ lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestSetWatchpoint.py Fri Jun 8 13:36:34 2012
@@ -61,7 +61,8 @@
# Watch 'global' for read and write.
value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal)
- watchpoint = value.Watch(True, True, True)
+ error = lldb.SBError();
+ watchpoint = value.Watch(True, True, True, error)
self.assertTrue(value and watchpoint,
"Successfully found the variable and set a watchpoint")
self.DebugSBValue(value)
Modified: lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIgnoreCount.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIgnoreCount.py (original)
+++ lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIgnoreCount.py Fri Jun 8 13:36:34 2012
@@ -61,7 +61,8 @@
# Watch 'global' for read and write.
value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal)
- watchpoint = value.Watch(True, True, True)
+ error = lldb.SBError();
+ watchpoint = value.Watch(True, True, True, error)
self.assertTrue(value and watchpoint,
"Successfully found the variable and set a watchpoint")
self.DebugSBValue(value)
Modified: lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIter.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIter.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIter.py (original)
+++ lldb/branches/lldb-platform-work/test/python_api/watchpoint/TestWatchpointIter.py Fri Jun 8 13:36:34 2012
@@ -61,7 +61,8 @@
# Watch 'global' for read and write.
value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal)
- watchpoint = value.Watch(True, True, True)
+ error = lldb.SBError();
+ watchpoint = value.Watch(True, True, True, error)
self.assertTrue(value and watchpoint,
"Successfully found the variable and set a watchpoint")
self.DebugSBValue(value)
Modified: lldb/branches/lldb-platform-work/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py (original)
+++ lldb/branches/lldb-platform-work/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py Fri Jun 8 13:36:34 2012
@@ -66,7 +66,8 @@
# Watch 'global' for write.
value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal)
- watchpoint = value.Watch(True, False, True)
+ error = lldb.SBError();
+ watchpoint = value.Watch(True, False, True, error)
self.assertTrue(value and watchpoint,
"Successfully found the variable and set a watchpoint")
self.DebugSBValue(value)
Modified: lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py (original)
+++ lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py Fri Jun 8 13:36:34 2012
@@ -67,7 +67,8 @@
value.GetValueAsUnsigned(0),
value.GetType().GetPointeeType())
# Watch for write to *g_char_ptr.
- watchpoint = value.WatchPointee(True, False, True)
+ error = lldb.SBError();
+ watchpoint = value.WatchPointee(True, False, True, error)
self.assertTrue(value and watchpoint,
"Successfully found the pointer and set a watchpoint")
self.DebugSBValue(value)
Modified: lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py (original)
+++ lldb/branches/lldb-platform-work/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py Fri Jun 8 13:36:34 2012
@@ -37,6 +37,21 @@
self.buildDwarf()
self.do_set_watchaddress()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_watch_address_with_invalid_watch_size_with_dsym(self):
+ """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size."""
+ self.buildDsym()
+ self.do_set_watchaddress_with_invalid_watch_size()
+
+ @python_api_test
+ @dwarf_test
+ def test_watch_address_with_invalid_watch_size_with_dwarf(self):
+ """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size."""
+ self.buildDwarf()
+ self.do_set_watchaddress_with_invalid_watch_size()
+
def do_set_watchaddress(self):
"""Use SBTarget.WatchAddress() to set a watchpoint and verify that the program stops later due to the watchpoint."""
exe = os.path.join(os.getcwd(), "a.out")
@@ -67,7 +82,8 @@
value.GetValueAsUnsigned(0),
value.GetType().GetPointeeType())
# Watch for write to *g_char_ptr.
- watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 1, False, True)
+ error = lldb.SBError();
+ watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 1, False, True, error)
self.assertTrue(value and watchpoint,
"Successfully found the pointer and set a watchpoint")
self.DebugSBValue(value)
@@ -95,6 +111,42 @@
# This finishes our test.
+ def do_set_watchaddress_with_invalid_watch_size(self):
+ """Use SBTarget.WatchAddress() to set a watchpoint with invalid watch_size and verify we get a meaningful error message."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now create a breakpoint on main.c.
+ breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() == 1,
+ VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at the entry point.
+ process = target.LaunchSimple(None, None, os.getcwd())
+
+ # We should be stopped due to the breakpoint. Get frame #0.
+ process = target.GetProcess()
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ PROCESS_STOPPED)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ frame0 = thread.GetFrameAtIndex(0)
+
+ value = frame0.FindValue('g_char_ptr',
+ lldb.eValueTypeVariableGlobal)
+ pointee = value.CreateValueFromAddress("pointee",
+ value.GetValueAsUnsigned(0),
+ value.GetType().GetPointeeType())
+ # Watch for write to *g_char_ptr.
+ error = lldb.SBError();
+ watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 365, False, True, error)
+ self.assertFalse(watchpoint)
+ self.expect(error.GetCString(), exe=False,
+ substrs = ['watch size of %d is not supported' % 365])
+
if __name__ == '__main__':
import atexit
Modified: lldb/branches/lldb-platform-work/tools/debugserver/source/DNBArch.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/source/DNBArch.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/source/DNBArch.h (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/source/DNBArch.h Fri Jun 8 13:36:34 2012
@@ -82,6 +82,19 @@
virtual bool DisableHardwareWatchpoint (uint32_t hw_index) { return false; }
virtual uint32_t GetHardwareWatchpointHit() { return INVALID_NUB_HW_INDEX; }
virtual bool StepNotComplete () { return false; }
+
+protected:
+ friend class MachThread;
+
+ enum
+ {
+ Trans_Pending = 0, // Transaction is pending, and checkpoint state has been snapshotted.
+ Trans_Done = 1, // Transaction is done, the current state is committed, and checkpoint state is irrelevant.
+ Trans_Rolled_Back = 2 // Transaction is done, the current state has been rolled back to the checkpoint state.
+ };
+ virtual bool StartTransForHWP() { return true; }
+ virtual bool RollbackTransForHWP() { return true; }
+ virtual bool FinishTransForHWP() { return true; }
};
Modified: lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.cpp (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.cpp Fri Jun 8 13:36:34 2012
@@ -700,6 +700,18 @@
}
bool
+MachThread::RollbackTransForHWP()
+{
+ return m_arch_ap->RollbackTransForHWP();
+}
+
+bool
+MachThread::FinishTransForHWP()
+{
+ return m_arch_ap->FinishTransForHWP();
+}
+
+bool
MachThread::DisableHardwareBreakpoint (const DNBBreakpoint *bp)
{
if (bp != NULL && bp->IsHardware())
Modified: lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.h (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThread.h Fri Jun 8 13:36:34 2012
@@ -66,6 +66,8 @@
bool DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
bool DisableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
uint32_t NumSupportedHardwareWatchpoints () const;
+ bool RollbackTransForHWP();
+ bool FinishTransForHWP();
nub_state_t GetState();
void SetState(nub_state_t state);
Modified: lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThreadList.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThreadList.cpp (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/MachThreadList.cpp Fri Jun 8 13:36:34 2012
@@ -478,8 +478,17 @@
for (uint32_t idx = 0; idx < num_threads; ++idx)
{
if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp)) == INVALID_NUB_HW_INDEX)
+ {
+ // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ for (uint32_t i = 0; i < idx; ++i)
+ m_threads[i]->RollbackTransForHWP();
return INVALID_NUB_HW_INDEX;
+ }
}
+ // Notify each thread to commit the pending transaction.
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->FinishTransForHWP();
+
// Use an arbitrary thread to signal the completion of our transaction.
if (num_threads)
m_threads[0]->HardwareWatchpointStateChanged();
@@ -498,8 +507,17 @@
for (uint32_t idx = 0; idx < num_threads; ++idx)
{
if (!m_threads[idx]->DisableHardwareWatchpoint(wp))
+ {
+ // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ for (uint32_t i = 0; i < idx; ++i)
+ m_threads[i]->RollbackTransForHWP();
return false;
+ }
}
+ // Notify each thread to commit the pending transaction.
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->FinishTransForHWP();
+
// Use an arbitrary thread to signal the completion of our transaction.
if (num_threads)
m_threads[0]->HardwareWatchpointStateChanged();
Modified: lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Fri Jun 8 13:36:34 2012
@@ -818,6 +818,42 @@
}
}
+bool
+DNBArchImplI386::StartTransForHWP()
+{
+ if (m_2pc_trans_state != Trans_Done || m_2pc_trans_state != Trans_Rolled_Back)
+ DNBLogError ("%s inconsistent state detected, expected %d or %d, got: %d", __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
+ m_2pc_dbg_checkpoint = m_state.context.dbg;
+ m_2pc_trans_state = Trans_Pending;
+ return true;
+}
+bool
+DNBArchImplI386::RollbackTransForHWP()
+{
+ m_state.context.dbg = m_2pc_dbg_checkpoint;
+ if (m_2pc_trans_state != Trans_Pending)
+ DNBLogError ("%s inconsistent state detected, expected %d, got: %d", __FUNCTION__, Trans_Pending, m_2pc_trans_state);
+ m_2pc_trans_state = Trans_Rolled_Back;
+ kern_return_t kret = SetDBGState();
+ DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::RollbackTransForHWP() SetDBGState() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return true;
+ else
+ return false;
+}
+bool
+DNBArchImplI386::FinishTransForHWP()
+{
+ m_2pc_trans_state = Trans_Done;
+ return true;
+}
+DNBArchImplI386::DBG
+DNBArchImplI386::GetDBGCheckpoint()
+{
+ return m_2pc_dbg_checkpoint;
+}
+
uint32_t
DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write)
{
@@ -851,6 +887,8 @@
// See if we found an available hw breakpoint slot above
if (i < num_hw_watchpoints)
{
+ StartTransForHWP();
+
// Modify our local copy of the debug state, first.
SetWatchpoint(debug_state, i, addr, size, read, write);
// Now set the watch point in the inferior.
@@ -859,6 +897,8 @@
if (kret == KERN_SUCCESS)
return i;
+ else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed.
+ m_state.context.dbg = GetDBGCheckpoint();
}
else
{
@@ -879,6 +919,8 @@
DBG &debug_state = m_state.context.dbg;
if (hw_index < num_hw_points && !IsWatchpointVacant(debug_state, hw_index))
{
+ StartTransForHWP();
+
// Modify our local copy of the debug state, first.
ClearWatchpoint(debug_state, hw_index);
// Now disable the watch point in the inferior.
@@ -888,6 +930,8 @@
if (kret == KERN_SUCCESS)
return true;
+ else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed.
+ m_state.context.dbg = GetDBGCheckpoint();
}
}
return false;
@@ -911,7 +955,7 @@
DNBArchImplI386::GetHardwareWatchpointHit(nub_addr_t &addr)
{
// Read the debug state
- kern_return_t kret = GetDBGState(false);
+ kern_return_t kret = GetDBGState(true);
DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret);
if (kret == KERN_SUCCESS)
{
Modified: lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h Fri Jun 8 13:36:34 2012
@@ -27,7 +27,9 @@
public:
DNBArchImplI386(MachThread *thread) :
m_thread(thread),
- m_state()
+ m_state(),
+ m_2pc_dbg_checkpoint(),
+ m_2pc_trans_state(Trans_Done)
{
}
virtual ~DNBArchImplI386()
@@ -231,8 +233,15 @@
static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
+ virtual bool StartTransForHWP();
+ virtual bool RollbackTransForHWP();
+ virtual bool FinishTransForHWP();
+ DBG GetDBGCheckpoint();
+
MachThread *m_thread;
State m_state;
+ DBG m_2pc_dbg_checkpoint;
+ uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning (0), Done (1), or Rolled Back (2)?
};
#endif // #if defined (__i386__) || defined (__x86_64__)
Modified: lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Fri Jun 8 13:36:34 2012
@@ -795,6 +795,42 @@
}
}
+bool
+DNBArchImplX86_64::StartTransForHWP()
+{
+ if (m_2pc_trans_state != Trans_Done || m_2pc_trans_state != Trans_Rolled_Back)
+ DNBLogError ("%s inconsistent state detected, expected %d or %d, got: %d", __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
+ m_2pc_dbg_checkpoint = m_state.context.dbg;
+ m_2pc_trans_state = Trans_Pending;
+ return true;
+}
+bool
+DNBArchImplX86_64::RollbackTransForHWP()
+{
+ m_state.context.dbg = m_2pc_dbg_checkpoint;
+ if (m_2pc_trans_state != Trans_Pending)
+ DNBLogError ("%s inconsistent state detected, expected %d, got: %d", __FUNCTION__, Trans_Pending, m_2pc_trans_state);
+ m_2pc_trans_state = Trans_Rolled_Back;
+ kern_return_t kret = SetDBGState();
+ DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::RollbackTransForHWP() SetDBGState() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return true;
+ else
+ return false;
+}
+bool
+DNBArchImplX86_64::FinishTransForHWP()
+{
+ m_2pc_trans_state = Trans_Done;
+ return true;
+}
+DNBArchImplX86_64::DBG
+DNBArchImplX86_64::GetDBGCheckpoint()
+{
+ return m_2pc_dbg_checkpoint;
+}
+
uint32_t
DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write)
{
@@ -828,6 +864,8 @@
// See if we found an available hw breakpoint slot above
if (i < num_hw_watchpoints)
{
+ StartTransForHWP();
+
// Modify our local copy of the debug state, first.
SetWatchpoint(debug_state, i, addr, size, read, write);
// Now set the watch point in the inferior.
@@ -836,6 +874,8 @@
if (kret == KERN_SUCCESS)
return i;
+ else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed.
+ m_state.context.dbg = GetDBGCheckpoint();
}
else
{
@@ -856,6 +896,8 @@
DBG &debug_state = m_state.context.dbg;
if (hw_index < num_hw_points && !IsWatchpointVacant(debug_state, hw_index))
{
+ StartTransForHWP();
+
// Modify our local copy of the debug state, first.
ClearWatchpoint(debug_state, hw_index);
// Now disable the watch point in the inferior.
@@ -865,6 +907,8 @@
if (kret == KERN_SUCCESS)
return true;
+ else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed.
+ m_state.context.dbg = GetDBGCheckpoint();
}
}
return false;
Modified: lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h Fri Jun 8 13:36:34 2012
@@ -26,7 +26,9 @@
public:
DNBArchImplX86_64(MachThread *thread) :
m_thread(thread),
- m_state()
+ m_state(),
+ m_2pc_dbg_checkpoint(),
+ m_2pc_trans_state(Trans_Done)
{
}
virtual ~DNBArchImplX86_64()
@@ -238,8 +240,15 @@
static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
+ virtual bool StartTransForHWP();
+ virtual bool RollbackTransForHWP();
+ virtual bool FinishTransForHWP();
+ DBG GetDBGCheckpoint();
+
MachThread *m_thread;
- State m_state;
+ State m_state;
+ DBG m_2pc_dbg_checkpoint;
+ uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning (0), Done (1), or Rolled Back (2)?
};
#endif // #if defined (__i386__) || defined (__x86_64__)
Modified: lldb/branches/lldb-platform-work/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/driver/Driver.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/driver/Driver.cpp (original)
+++ lldb/branches/lldb-platform-work/tools/driver/Driver.cpp Fri Jun 8 13:36:34 2012
@@ -1080,10 +1080,19 @@
case eInputReaderInterrupt:
if (driver->m_io_channel_ap.get() != NULL)
{
- driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
- // I wish I could erase the entire input line, but there's no public API for that.
- driver->m_io_channel_ap->EraseCharsBeforeCursor();
- driver->m_io_channel_ap->RefreshPrompt();
+ SBProcess process = driver->GetDebugger().GetSelectedTarget().GetProcess();
+ if (!driver->m_io_channel_ap->EditLineHasCharacters()
+ && process.IsValid() && process.GetState() == lldb::eStateRunning)
+ {
+ process.Stop();
+ }
+ else
+ {
+ driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
+ // I wish I could erase the entire input line, but there's no public API for that.
+ driver->m_io_channel_ap->EraseCharsBeforeCursor();
+ driver->m_io_channel_ap->RefreshPrompt();
+ }
}
break;
Modified: lldb/branches/lldb-platform-work/tools/driver/IOChannel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/driver/IOChannel.cpp?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/driver/IOChannel.cpp (original)
+++ lldb/branches/lldb-platform-work/tools/driver/IOChannel.cpp Fri Jun 8 13:36:34 2012
@@ -50,6 +50,17 @@
return pos->second.c_str();
}
+bool
+IOChannel::EditLineHasCharacters ()
+{
+ const LineInfo *line_info = el_line(m_edit_line);
+ if (line_info)
+ return line_info->cursor != line_info->buffer;
+ else
+ return false;
+}
+
+
void
IOChannel::EraseCharsBeforeCursor ()
{
Modified: lldb/branches/lldb-platform-work/tools/driver/IOChannel.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/driver/IOChannel.h?rev=158217&r1=158216&r2=158217&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/driver/IOChannel.h (original)
+++ lldb/branches/lldb-platform-work/tools/driver/IOChannel.h Fri Jun 8 13:36:34 2012
@@ -96,6 +96,9 @@
const char *
GetPrompt ();
+ bool
+ EditLineHasCharacters ();
+
void
EraseCharsBeforeCursor ();
More information about the lldb-commits
mailing list