[Lldb-commits] [lldb] r158194 - in /lldb/branches/apple/python-GIL: ./ 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/Platform/MacOSX/ source/Plugins/Process/FreeBSD/ source/Plugins/Process/gdb-remote/ source/Plugins/SymbolFile/DWARF/ source/Target/ test/functionalities/watchpoint...

Filipe Cabecinhas me at filcab.net
Fri Jun 8 02:17:19 PDT 2012


Author: filcab
Date: Fri Jun  8 04:17:19 2012
New Revision: 158194

URL: http://llvm.org/viewvc/llvm-project?rev=158194&view=rev
Log:
Merge changes from ToT trunk.

Modified:
    lldb/branches/apple/python-GIL/   (props changed)
    lldb/branches/apple/python-GIL/examples/python/crashlog.py
    lldb/branches/apple/python-GIL/examples/python/gdbremote.py
    lldb/branches/apple/python-GIL/examples/python/symbolication.py
    lldb/branches/apple/python-GIL/include/lldb/API/SBTarget.h
    lldb/branches/apple/python-GIL/include/lldb/API/SBValue.h
    lldb/branches/apple/python-GIL/include/lldb/Breakpoint/Watchpoint.h
    lldb/branches/apple/python-GIL/include/lldb/Core/ModuleList.h
    lldb/branches/apple/python-GIL/include/lldb/Core/RegisterValue.h
    lldb/branches/apple/python-GIL/include/lldb/Core/ValueObject.h
    lldb/branches/apple/python-GIL/include/lldb/Interpreter/OptionGroupWatchpoint.h
    lldb/branches/apple/python-GIL/include/lldb/Target/Process.h
    lldb/branches/apple/python-GIL/include/lldb/Target/Target.h
    lldb/branches/apple/python-GIL/include/lldb/lldb-enumerations.h
    lldb/branches/apple/python-GIL/scripts/Python/interface/SBTarget.i
    lldb/branches/apple/python-GIL/scripts/Python/interface/SBValue.i
    lldb/branches/apple/python-GIL/scripts/Python/interface/SBWatchpoint.i
    lldb/branches/apple/python-GIL/source/API/SBTarget.cpp
    lldb/branches/apple/python-GIL/source/API/SBValue.cpp
    lldb/branches/apple/python-GIL/source/API/SBWatchpoint.cpp
    lldb/branches/apple/python-GIL/source/Commands/CommandObjectProcess.cpp
    lldb/branches/apple/python-GIL/source/Commands/CommandObjectRegister.cpp
    lldb/branches/apple/python-GIL/source/Commands/CommandObjectTarget.cpp
    lldb/branches/apple/python-GIL/source/Commands/CommandObjectThread.cpp
    lldb/branches/apple/python-GIL/source/Commands/CommandObjectWatchpoint.cpp
    lldb/branches/apple/python-GIL/source/Core/RegisterValue.cpp
    lldb/branches/apple/python-GIL/source/Core/ValueObject.cpp
    lldb/branches/apple/python-GIL/source/Expression/ExpressionSourceCode.cpp
    lldb/branches/apple/python-GIL/source/Host/macosx/Host.mm
    lldb/branches/apple/python-GIL/source/Interpreter/CommandInterpreter.cpp
    lldb/branches/apple/python-GIL/source/Interpreter/OptionGroupWatchpoint.cpp
    lldb/branches/apple/python-GIL/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
    lldb/branches/apple/python-GIL/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
    lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/branches/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/branches/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/branches/apple/python-GIL/source/Target/Platform.cpp
    lldb/branches/apple/python-GIL/source/Target/Process.cpp
    lldb/branches/apple/python-GIL/source/Target/Target.cpp
    lldb/branches/apple/python-GIL/source/Target/TargetList.cpp
    lldb/branches/apple/python-GIL/source/Target/ThreadList.cpp
    lldb/branches/apple/python-GIL/source/lldb.cpp
    lldb/branches/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
    lldb/branches/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
    lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_target.py
    lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_value.py
    lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_watchpoint.py
    lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestSetWatchpoint.py
    lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
    lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIter.py
    lldb/branches/apple/python-GIL/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
    lldb/branches/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
    lldb/branches/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
    lldb/branches/apple/python-GIL/tools/debugserver/source/DNBArch.h
    lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.cpp
    lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.h
    lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThreadList.cpp
    lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
    lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
    lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
    lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
    lldb/branches/apple/python-GIL/tools/driver/Driver.cpp
    lldb/branches/apple/python-GIL/tools/driver/IOChannel.cpp
    lldb/branches/apple/python-GIL/tools/driver/IOChannel.h

Propchange: lldb/branches/apple/python-GIL/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jun  8 04:17:19 2012
@@ -1 +1 @@
-/lldb/trunk:156467-157728
+/lldb/trunk:156467-158123

Modified: lldb/branches/apple/python-GIL/examples/python/crashlog.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/examples/python/crashlog.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/examples/python/crashlog.py (original)
+++ lldb/branches/apple/python-GIL/examples/python/crashlog.py Fri Jun  8 04:17:19 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/apple/python-GIL/examples/python/gdbremote.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/examples/python/gdbremote.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/examples/python/gdbremote.py (original)
+++ lldb/branches/apple/python-GIL/examples/python/gdbremote.py Fri Jun  8 04:17:19 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/apple/python-GIL/examples/python/symbolication.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/examples/python/symbolication.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/examples/python/symbolication.py (original)
+++ lldb/branches/apple/python-GIL/examples/python/symbolication.py Fri Jun  8 04:17:19 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/apple/python-GIL/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/API/SBTarget.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/API/SBTarget.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/API/SBTarget.h Fri Jun  8 04:17:19 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/apple/python-GIL/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/API/SBValue.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/API/SBValue.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/API/SBValue.h Fri Jun  8 04:17:19 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/apple/python-GIL/include/lldb/Breakpoint/Watchpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/Breakpoint/Watchpoint.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/Breakpoint/Watchpoint.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/Breakpoint/Watchpoint.h Fri Jun  8 04:17:19 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/apple/python-GIL/include/lldb/Core/ModuleList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/Core/ModuleList.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/Core/ModuleList.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/Core/ModuleList.h Fri Jun  8 04:17:19 2012
@@ -115,8 +115,7 @@
     void
     LogUUIDAndPaths (lldb::LogSP &log_sp, 
                      const char *prefix_cstr);
-
-
+                     
     Mutex &
     GetMutex ()
     {

Modified: lldb/branches/apple/python-GIL/include/lldb/Core/RegisterValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/Core/RegisterValue.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/Core/RegisterValue.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/Core/RegisterValue.h Fri Jun  8 04:17:19 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/apple/python-GIL/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/Core/ValueObject.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/Core/ValueObject.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/Core/ValueObject.h Fri Jun  8 04:17:19 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/apple/python-GIL/include/lldb/Interpreter/OptionGroupWatchpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/Interpreter/OptionGroupWatchpoint.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/Interpreter/OptionGroupWatchpoint.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/Interpreter/OptionGroupWatchpoint.h Fri Jun  8 04:17:19 2012
@@ -26,6 +26,9 @@
     {
     public:
         
+        static bool
+        IsWatchSizeSupported(uint32_t watch_size);
+
         OptionGroupWatchpoint ();
 
         virtual

Modified: lldb/branches/apple/python-GIL/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/Target/Process.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/Target/Process.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/Target/Process.h Fri Jun  8 04:17:19 2012
@@ -719,6 +719,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 ()
@@ -779,6 +795,7 @@
     Host::MonitorChildProcessCallback m_monitor_callback;
     void *m_monitor_callback_baton;
     bool m_monitor_signals;
+
 };
 
 //----------------------------------------------------------------------
@@ -3365,6 +3382,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/apple/python-GIL/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/Target/Target.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/Target/Target.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/Target/Target.h Fri Jun  8 04:17:19 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/apple/python-GIL/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/include/lldb/lldb-enumerations.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/include/lldb/lldb-enumerations.h (original)
+++ lldb/branches/apple/python-GIL/include/lldb/lldb-enumerations.h Fri Jun  8 04:17:19 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/apple/python-GIL/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/scripts/Python/interface/SBTarget.i?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/scripts/Python/interface/SBTarget.i (original)
+++ lldb/branches/apple/python-GIL/scripts/Python/interface/SBTarget.i Fri Jun  8 04:17:19 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/apple/python-GIL/scripts/Python/interface/SBValue.i
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/scripts/Python/interface/SBValue.i?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/scripts/Python/interface/SBValue.i (original)
+++ lldb/branches/apple/python-GIL/scripts/Python/interface/SBValue.i Fri Jun  8 04:17:19 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/apple/python-GIL/scripts/Python/interface/SBWatchpoint.i
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/scripts/Python/interface/SBWatchpoint.i?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/scripts/Python/interface/SBWatchpoint.i (original)
+++ lldb/branches/apple/python-GIL/scripts/Python/interface/SBWatchpoint.i Fri Jun  8 04:17:19 2012
@@ -31,9 +31,6 @@
     bool
     IsValid();
 
-    SBError
-    GetError();
-
     watch_id_t
     GetID ();
 

Modified: lldb/branches/apple/python-GIL/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/API/SBTarget.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/API/SBTarget.cpp (original)
+++ lldb/branches/apple/python-GIL/source/API/SBTarget.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/API/SBValue.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/API/SBValue.cpp (original)
+++ lldb/branches/apple/python-GIL/source/API/SBValue.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/API/SBWatchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/API/SBWatchpoint.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/API/SBWatchpoint.cpp (original)
+++ lldb/branches/apple/python-GIL/source/API/SBWatchpoint.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Commands/CommandObjectProcess.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Commands/CommandObjectProcess.cpp Fri Jun  8 04:17:19 2012
@@ -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/apple/python-GIL/source/Commands/CommandObjectRegister.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Commands/CommandObjectRegister.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Commands/CommandObjectRegister.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Commands/CommandObjectRegister.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Commands/CommandObjectTarget.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Commands/CommandObjectTarget.cpp Fri Jun  8 04:17:19 2012
@@ -1628,8 +1628,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, 
@@ -3227,6 +3277,10 @@
                 case 'v':
                     m_verbose = 1;
                     break;
+                
+                case 'A':
+                    m_print_all = true;
+                    break;
                     
                 case 'r':
                     m_use_regex = true;
@@ -3248,6 +3302,7 @@
             m_use_regex = false;
             m_include_inlines = true;
             m_verbose = false;
+            m_print_all = false;
         }
         
         const OptionDefinition*
@@ -3268,6 +3323,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.
         
     };
     
@@ -3303,6 +3359,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)
@@ -3428,7 +3534,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();
@@ -3436,7 +3559,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++;
@@ -3501,12 +3627,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/apple/python-GIL/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Commands/CommandObjectThread.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Commands/CommandObjectThread.cpp Fri Jun  8 04:17:19 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().FindThreadByIndexID(idx).get();
-                        if (find(resume_thread_indexes.begin(), resume_thread_indexes.end(), idx) != resume_thread_indexes.end())
+                        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

Modified: lldb/branches/apple/python-GIL/source/Commands/CommandObjectWatchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Commands/CommandObjectWatchpoint.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Commands/CommandObjectWatchpoint.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Commands/CommandObjectWatchpoint.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Core/RegisterValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Core/RegisterValue.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Core/RegisterValue.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Core/RegisterValue.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Core/ValueObject.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Core/ValueObject.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Core/ValueObject.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Expression/ExpressionSourceCode.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Expression/ExpressionSourceCode.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Expression/ExpressionSourceCode.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Expression/ExpressionSourceCode.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Host/macosx/Host.mm?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Host/macosx/Host.mm (original)
+++ lldb/branches/apple/python-GIL/source/Host/macosx/Host.mm Fri Jun  8 04:17:19 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/apple/python-GIL/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Interpreter/CommandInterpreter.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Interpreter/CommandInterpreter.cpp Fri Jun  8 04:17:19 2012
@@ -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)
     {

Modified: lldb/branches/apple/python-GIL/source/Interpreter/OptionGroupWatchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Interpreter/OptionGroupWatchpoint.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Interpreter/OptionGroupWatchpoint.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Interpreter/OptionGroupWatchpoint.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp Fri Jun  8 04:17:19 2012
@@ -708,7 +708,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();
@@ -734,7 +734,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/apple/python-GIL/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Fri Jun  8 04:17:19 2012
@@ -237,7 +237,8 @@
             {
                 if (GetAck () != '+')
                 {
-                    printf("get ack failed...");
+                    if (log)
+                        log->Printf("get ack failed...");
                     return 0;
                 }
             }
@@ -264,7 +265,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/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Fri Jun  8 04:17:19 2012
@@ -275,78 +275,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
@@ -382,7 +391,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;
@@ -437,10 +446,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
@@ -652,7 +660,6 @@
     bool &timed_out
 )
 {
-    m_interrupt_sent = false;
     timed_out = false;
     LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
 

Modified: lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/branches/apple/python-GIL/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Fri Jun  8 04:17:19 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/apple/python-GIL/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Target/Platform.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Target/Platform.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Target/Platform.cpp Fri Jun  8 04:17:19 2012
@@ -605,6 +605,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/apple/python-GIL/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Target/Process.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Target/Process.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Target/Process.cpp Fri Jun  8 04:17:19 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();
+                }
             }
         }
     }
@@ -2927,6 +2937,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 +3045,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 +3368,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 +3434,7 @@
                          StateAsCString (GetState ()));
         }
     }
+    m_currently_handling_event.SetValue(false, eBroadcastAlways);
 }
 
 void *

Modified: lldb/branches/apple/python-GIL/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Target/Target.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Target/Target.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Target/Target.cpp Fri Jun  8 04:17:19 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

Modified: lldb/branches/apple/python-GIL/source/Target/TargetList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Target/TargetList.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Target/TargetList.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Target/TargetList.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/Target/ThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/Target/ThreadList.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/Target/ThreadList.cpp (original)
+++ lldb/branches/apple/python-GIL/source/Target/ThreadList.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/source/lldb.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/source/lldb.cpp (original)
+++ lldb/branches/apple/python-GIL/source/lldb.cpp Fri Jun  8 04:17:19 2012
@@ -118,8 +118,8 @@
         AppleObjCRuntimeV1::Initialize();
         ObjectContainerUniversalMachO::Initialize();
         ObjectFileMachO::Initialize();
-        ProcessKDP::Initialize();
         ProcessGDBRemote::Initialize();
+        ProcessKDP::Initialize();
         ProcessMachCore::Initialize();
         SymbolVendorMacOSX::Initialize();
         PlatformRemoteiOS::Initialize();
@@ -193,8 +193,8 @@
     ObjectContainerUniversalMachO::Terminate();
     ObjectFileMachO::Terminate();
     ProcessMachCore::Terminate();
-    ProcessKDP::Terminate();
     ProcessGDBRemote::Terminate();
+    ProcessKDP::Terminate();
     SymbolVendorMacOSX::Terminate();
     PlatformMacOSX::Terminate();
     PlatformRemoteiOS::Terminate();

Modified: lldb/branches/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py (original)
+++ lldb/branches/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py Fri Jun  8 04:17:19 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/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/main.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/main.cpp (original)
+++ lldb/branches/apple/python-GIL/test/functionalities/watchpoint/watchpoint_set_command/main.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/test/python_api/default-constructor/sb_target.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_target.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_target.py (original)
+++ lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_target.py Fri Jun  8 04:17:19 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/apple/python-GIL/test/python_api/default-constructor/sb_value.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_value.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_value.py (original)
+++ lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_value.py Fri Jun  8 04:17:19 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/apple/python-GIL/test/python_api/default-constructor/sb_watchpoint.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_watchpoint.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_watchpoint.py (original)
+++ lldb/branches/apple/python-GIL/test/python_api/default-constructor/sb_watchpoint.py Fri Jun  8 04:17:19 2012
@@ -8,7 +8,6 @@
 def fuzz_obj(obj):
     obj.GetID()
     obj.IsValid()
-    obj.GetError()
     obj.GetHardwareIndex()
     obj.GetWatchAddress()
     obj.GetWatchSize()

Modified: lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestSetWatchpoint.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestSetWatchpoint.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestSetWatchpoint.py (original)
+++ lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestSetWatchpoint.py Fri Jun  8 04:17:19 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/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIgnoreCount.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIgnoreCount.py (original)
+++ lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIgnoreCount.py Fri Jun  8 04:17:19 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/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIter.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIter.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIter.py (original)
+++ lldb/branches/apple/python-GIL/test/python_api/watchpoint/TestWatchpointIter.py Fri Jun  8 04:17:19 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/apple/python-GIL/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py (original)
+++ lldb/branches/apple/python-GIL/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py Fri Jun  8 04:17:19 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/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py (original)
+++ lldb/branches/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py Fri Jun  8 04:17:19 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/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py (original)
+++ lldb/branches/apple/python-GIL/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py Fri Jun  8 04:17:19 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/apple/python-GIL/tools/debugserver/source/DNBArch.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/debugserver/source/DNBArch.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/debugserver/source/DNBArch.h (original)
+++ lldb/branches/apple/python-GIL/tools/debugserver/source/DNBArch.h Fri Jun  8 04:17:19 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/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.cpp (original)
+++ lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.h (original)
+++ lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThread.h Fri Jun  8 04:17:19 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/apple/python-GIL/tools/debugserver/source/MacOSX/MachThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThreadList.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThreadList.cpp (original)
+++ lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/MachThreadList.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original)
+++ lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h (original)
+++ lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h Fri Jun  8 04:17:19 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/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original)
+++ lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h (original)
+++ lldb/branches/apple/python-GIL/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h Fri Jun  8 04:17:19 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/apple/python-GIL/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/driver/Driver.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/driver/Driver.cpp (original)
+++ lldb/branches/apple/python-GIL/tools/driver/Driver.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/tools/driver/IOChannel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/driver/IOChannel.cpp?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/driver/IOChannel.cpp (original)
+++ lldb/branches/apple/python-GIL/tools/driver/IOChannel.cpp Fri Jun  8 04:17:19 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/apple/python-GIL/tools/driver/IOChannel.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/python-GIL/tools/driver/IOChannel.h?rev=158194&r1=158193&r2=158194&view=diff
==============================================================================
--- lldb/branches/apple/python-GIL/tools/driver/IOChannel.h (original)
+++ lldb/branches/apple/python-GIL/tools/driver/IOChannel.h Fri Jun  8 04:17:19 2012
@@ -96,6 +96,9 @@
     const char *
     GetPrompt ();
 
+    bool
+    EditLineHasCharacters ();
+    
     void
     EraseCharsBeforeCursor ();
 





More information about the lldb-commits mailing list