From johnny.chen at apple.com Mon Jun 27 13:17:24 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 18:17:24 -0000 Subject: [Lldb-commits] [lldb] r133918 - in /lldb/trunk/test: embedded_interpreter/ functionalities/breakpoint/inlined_breakpoints/ functionalities/breakpoint/inlined_breakpoints/Makefile functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py functionalities/embedded_interpreter/ functionalities/embedded_interpreter/Makefile functionalities/embedded_interpreter/TestConvenienceVariables.py functionalities/load_unload/ functionalities/load_unload/TestLoadUnload.py inlined_breakpoints/ load_unload/ Message-ID: <20110627181724.EBB5C2A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 13:17:24 2011 New Revision: 133918 URL: http://llvm.org/viewvc/llvm-project?rev=133918&view=rev Log: Move top level test dirs inlined_breakpoints, load_unload, and embedded_interpreter to reside under functionalities. Added: lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/ - copied from r133916, lldb/trunk/test/inlined_breakpoints/ lldb/trunk/test/functionalities/embedded_interpreter/ - copied from r133916, lldb/trunk/test/embedded_interpreter/ lldb/trunk/test/functionalities/load_unload/ - copied from r133916, lldb/trunk/test/load_unload/ Removed: lldb/trunk/test/embedded_interpreter/ lldb/trunk/test/inlined_breakpoints/ lldb/trunk/test/load_unload/ Modified: lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/Makefile lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py lldb/trunk/test/functionalities/embedded_interpreter/Makefile lldb/trunk/test/functionalities/embedded_interpreter/TestConvenienceVariables.py lldb/trunk/test/functionalities/load_unload/TestLoadUnload.py Modified: lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/Makefile?rev=133918&r1=133916&r2=133918&view=diff ============================================================================== --- lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/Makefile (original) +++ lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/Makefile Mon Jun 27 13:17:24 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../../make CXX_SOURCES := int.cpp Modified: lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py?rev=133918&r1=133916&r2=133918&view=diff ============================================================================== --- lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py (original) +++ lldb/trunk/test/functionalities/breakpoint/inlined_breakpoints/TestInlinedBreakpoints.py Mon Jun 27 13:17:24 2011 @@ -11,7 +11,7 @@ class InlinedBreakpointsTestCase(TestBase): """Bug fixed: rdar://problem/8464339""" - mydir = "inlined_breakpoints" + mydir = os.path.join("functionalities", "breakpoint", "inlined_breakpoints") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym_and_run_command(self): Modified: lldb/trunk/test/functionalities/embedded_interpreter/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/embedded_interpreter/Makefile?rev=133918&r1=133916&r2=133918&view=diff ============================================================================== --- lldb/trunk/test/functionalities/embedded_interpreter/Makefile (original) +++ lldb/trunk/test/functionalities/embedded_interpreter/Makefile Mon Jun 27 13:17:24 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../make C_SOURCES := main.c Modified: lldb/trunk/test/functionalities/embedded_interpreter/TestConvenienceVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/embedded_interpreter/TestConvenienceVariables.py?rev=133918&r1=133916&r2=133918&view=diff ============================================================================== --- lldb/trunk/test/functionalities/embedded_interpreter/TestConvenienceVariables.py (original) +++ lldb/trunk/test/functionalities/embedded_interpreter/TestConvenienceVariables.py Mon Jun 27 13:17:24 2011 @@ -8,7 +8,7 @@ class ConvenienceVariablesCase(TestBase): - mydir = "embedded_interpreter" + mydir = os.path.join("functionalities", "embedded_interpreter") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym_and_run_command(self): Modified: lldb/trunk/test/functionalities/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/load_unload/TestLoadUnload.py?rev=133918&r1=133916&r2=133918&view=diff ============================================================================== --- lldb/trunk/test/functionalities/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/functionalities/load_unload/TestLoadUnload.py Mon Jun 27 13:17:24 2011 @@ -10,7 +10,7 @@ class LoadUnloadTestCase(TestBase): - mydir = "load_unload" + mydir = os.path.join("functionalities", "load_unload") def setUp(self): # Call super's setUp(). From johnny.chen at apple.com Mon Jun 27 13:25:00 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 18:25:00 -0000 Subject: [Lldb-commits] [lldb] r133919 - in /lldb/trunk/test: functionalities/inferior-crashing/ functionalities/inferior-crashing/Makefile functionalities/inferior-crashing/TestInferiorCrashing.py functionalities/platform/ functionalities/platform/TestPlatformCommand.py inferior-crashing/ macosx/order/ macosx/order/Makefile macosx/order/TestOrderFile.py order/ platform/ Message-ID: <20110627182500.EBF032A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 13:25:00 2011 New Revision: 133919 URL: http://llvm.org/viewvc/llvm-project?rev=133919&view=rev Log: Move top level test dirs platform and inferior-crashing to reside under functionalities and order to reside under macosx. Added: lldb/trunk/test/functionalities/inferior-crashing/ - copied from r133916, lldb/trunk/test/inferior-crashing/ lldb/trunk/test/functionalities/platform/ - copied from r133916, lldb/trunk/test/platform/ lldb/trunk/test/macosx/order/ - copied from r133916, lldb/trunk/test/order/ Removed: lldb/trunk/test/inferior-crashing/ lldb/trunk/test/order/ lldb/trunk/test/platform/ Modified: lldb/trunk/test/functionalities/inferior-crashing/Makefile lldb/trunk/test/functionalities/inferior-crashing/TestInferiorCrashing.py lldb/trunk/test/functionalities/platform/TestPlatformCommand.py lldb/trunk/test/macosx/order/Makefile lldb/trunk/test/macosx/order/TestOrderFile.py Modified: lldb/trunk/test/functionalities/inferior-crashing/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/inferior-crashing/Makefile?rev=133919&r1=133916&r2=133919&view=diff ============================================================================== --- lldb/trunk/test/functionalities/inferior-crashing/Makefile (original) +++ lldb/trunk/test/functionalities/inferior-crashing/Makefile Mon Jun 27 13:25:00 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../make C_SOURCES := main.c Modified: lldb/trunk/test/functionalities/inferior-crashing/TestInferiorCrashing.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/inferior-crashing/TestInferiorCrashing.py?rev=133919&r1=133916&r2=133919&view=diff ============================================================================== --- lldb/trunk/test/functionalities/inferior-crashing/TestInferiorCrashing.py (original) +++ lldb/trunk/test/functionalities/inferior-crashing/TestInferiorCrashing.py Mon Jun 27 13:25:00 2011 @@ -7,7 +7,7 @@ class CrashingInferiorTestCase(TestBase): - mydir = "inferior-crashing" + mydir = os.path.join("functionalities", "inferior-crashing") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_inferior_crashing_dsym(self): Modified: lldb/trunk/test/functionalities/platform/TestPlatformCommand.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/platform/TestPlatformCommand.py?rev=133919&r1=133916&r2=133919&view=diff ============================================================================== --- lldb/trunk/test/functionalities/platform/TestPlatformCommand.py (original) +++ lldb/trunk/test/functionalities/platform/TestPlatformCommand.py Mon Jun 27 13:25:00 2011 @@ -9,7 +9,7 @@ class PlatformCommandTestCase(TestBase): - mydir = "platform" + mydir = os.path.join("functionalities", "platform") def test_help_platform(self): self.runCmd("help platform") Modified: lldb/trunk/test/macosx/order/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/order/Makefile?rev=133919&r1=133916&r2=133919&view=diff ============================================================================== --- lldb/trunk/test/macosx/order/Makefile (original) +++ lldb/trunk/test/macosx/order/Makefile Mon Jun 27 13:25:00 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../make C_SOURCES := main.c LDFLAGS = $(CFLAGS) -Xlinker -order_file ./order-file Modified: lldb/trunk/test/macosx/order/TestOrderFile.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/order/TestOrderFile.py?rev=133919&r1=133916&r2=133919&view=diff ============================================================================== --- lldb/trunk/test/macosx/order/TestOrderFile.py (original) +++ lldb/trunk/test/macosx/order/TestOrderFile.py Mon Jun 27 13:25:00 2011 @@ -10,7 +10,7 @@ class OrderFileTestCase(TestBase): - mydir = "order" + mydir = os.path.join("macosx", "order") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym(self): From johnny.chen at apple.com Mon Jun 27 13:30:03 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 18:30:03 -0000 Subject: [Lldb-commits] [lldb] r133920 - in /lldb/trunk/test: lang/objc/print-obj/ print-obj/ Message-ID: <20110627183003.A653C2A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 13:30:03 2011 New Revision: 133920 URL: http://llvm.org/viewvc/llvm-project?rev=133920&view=rev Log: Move sample objc program to reside under lang/objc. Added: lldb/trunk/test/lang/objc/print-obj/ - copied from r133916, lldb/trunk/test/print-obj/ Removed: lldb/trunk/test/print-obj/ From johnny.chen at apple.com Mon Jun 27 13:32:19 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 18:32:19 -0000 Subject: [Lldb-commits] [lldb] r133921 - /lldb/trunk/test/lang/objc/print-obj/Makefile Message-ID: <20110627183219.AF3092A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 13:32:19 2011 New Revision: 133921 URL: http://llvm.org/viewvc/llvm-project?rev=133921&view=rev Log: Simplified Makefile. Modified: lldb/trunk/test/lang/objc/print-obj/Makefile Modified: lldb/trunk/test/lang/objc/print-obj/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/print-obj/Makefile?rev=133921&r1=133920&r2=133921&view=diff ============================================================================== --- lldb/trunk/test/lang/objc/print-obj/Makefile (original) +++ lldb/trunk/test/lang/objc/print-obj/Makefile Mon Jun 27 13:32:19 2011 @@ -1,125 +1,6 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES := -CXX_SOURCES := -OBJC_SOURCES := blocked.m -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -framework Foundation -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../../../make +OBJC_SOURCES := blocked.m +LDFLAGS = $(CFLAGS) -lobjc -framework Foundation +include $(LEVEL)/Makefile.rules From johnny.chen at apple.com Mon Jun 27 15:05:23 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 20:05:23 -0000 Subject: [Lldb-commits] [lldb] r133933 - in /lldb/trunk/test: lang/objc/print-obj/TestPrintObj.py lang/objc/print-obj/blocked.m lldbtest.py Message-ID: <20110627200523.BD3DF2A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 15:05:23 2011 New Revision: 133933 URL: http://llvm.org/viewvc/llvm-project?rev=133933&view=rev Log: Add TestPrintObj.py to go with lang/objc/print-objc, which: Test "print object" where another thread blocks the print object from making progress. Set a breakpoint on the line in my_pthread_routine. Then switch threads to the main thread, and do print the lock_me object. Since that will try to get the lock already gotten by my_pthread_routime thread, it will have to switch to running all threads, and that should then succeed. Added: lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py Modified: lldb/trunk/test/lang/objc/print-obj/blocked.m lldb/trunk/test/lldbtest.py Added: lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py?rev=133933&view=auto ============================================================================== --- lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py (added) +++ lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py Mon Jun 27 15:05:23 2011 @@ -0,0 +1,100 @@ +""" +Test "print object" where another thread blocks the print object from making progress. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + + at unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") +class PrintObjTestCase(TestBase): + + mydir = os.path.join("lang", "objc", "print-obj") + + def test_print_obj_with_dsym(self): + """Test "print object" where another thread blocks the print object from making progress.""" + d = {'EXE': 'a.out'} + self.buildDsym(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.print_obj('a.out') + + def test_print_obj_with_dwarf(self): + """Test "print object" where another thread blocks the print object from making progress.""" + d = {'EXE': 'b.out'} + self.buildDwarf(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.print_obj('b.out') + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # My source program. + self.source = "blocked.m" + # Find the line numbers to break at. + self.line = line_number(self.source, '// Set a breakpoint here.') + + def print_obj(self, exe_name): + """ + Test "print object" where another thread blocks the print object from making progress. + + Set a breakpoint on the line in my_pthread_routine. Then switch threads + to the main thread, and do print the lock_me object. Since that will + try to get the lock already gotten by my_pthread_routime thread, it will + have to switch to running all threads, and that should then succeed. + """ + exe = os.path.join(os.getcwd(), exe_name) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + self.runCmd("breakpoint list") + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple(None, None, os.getcwd()) + + self.runCmd("thread backtrace all") + + # Let's get the current stopped thread. We'd like to switch to the + # other thread to issue our 'po lock_me' command. + import lldbutil + this_thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) + self.assertTrue(this_thread) + + # Find the other thread. The iteration protocol of SBProcess and the + # rich comparison method (equality) comes in handy. + other_thread = None + for t in process: + if t != this_thread: + other_thread = t + break + + # Set the other thread as the selected thread to issue our 'po' command.other + self.assertTrue(other_thread) + process.SetSelectedThread(other_thread) + self.runCmd("thread backtrace") + + # We want to traverse the frame to the one corresponding to blocked.m to + # issue our 'po lock_me' command. + + depth = other_thread.GetNumFrames() + for i in range(depth): + frame = other_thread.GetFrameAtIndex(i) + name = frame.GetFunctionName() + if name == 'main': + other_thread.SetSelectedFrame(i) + if self.TraceOn(): + print "selected frame:" + str(frame) + break + + self.expect("po lock_me", OBJECT_PRINTED_CORRECTLY, + substrs = ['LockMe *', 'I am pretty special.']) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Modified: lldb/trunk/test/lang/objc/print-obj/blocked.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/print-obj/blocked.m?rev=133933&r1=133932&r2=133933&view=diff ============================================================================== --- lldb/trunk/test/lang/objc/print-obj/blocked.m (original) +++ lldb/trunk/test/lang/objc/print-obj/blocked.m Mon Jun 27 15:05:23 2011 @@ -50,7 +50,7 @@ { printf ("my_pthread_routine about to enter.\n"); pthread_mutex_lock(&test_mutex); - printf ("Releasing Lock.\n"); /// Set a breakpoint here. + printf ("Releasing Lock.\n"); // Set a breakpoint here. pthread_mutex_unlock(&test_mutex); return NULL; } Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=133933&r1=133932&r2=133933&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Jun 27 15:05:23 2011 @@ -155,6 +155,8 @@ BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3" +OBJECT_PRINTED_CORRECTLY = "Object printed correctly" + SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly" STEP_OUT_SUCCEEDED = "Thread step-out succeeded" @@ -360,7 +362,7 @@ - create/get a debugger set with synchronous mode (self.dbg) - get the command interpreter from with the debugger (self.ci) - create a result object for use with the command interpreter - (self.result) + (self.res) - plus other stuffs - The tearDown method tries to perform some necessary cleanup on behalf From johnny.chen at apple.com Mon Jun 27 16:52:46 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 21:52:46 -0000 Subject: [Lldb-commits] [lldb] r133947 - /lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py Message-ID: <20110627215246.BE67C2A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 16:52:46 2011 New Revision: 133947 URL: http://llvm.org/viewvc/llvm-project?rev=133947&view=rev Log: Add comments and print output for selected thread under trace mode. Modified: lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py Modified: lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py?rev=133947&r1=133946&r2=133947&view=diff ============================================================================== --- lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py (original) +++ lldb/trunk/test/lang/objc/print-obj/TestPrintObj.py Mon Jun 27 16:52:46 2011 @@ -64,7 +64,7 @@ self.assertTrue(this_thread) # Find the other thread. The iteration protocol of SBProcess and the - # rich comparison method (equality) comes in handy. + # rich comparison methods (__eq__/__ne__) of SBThread come in handy. other_thread = None for t in process: if t != this_thread: @@ -74,6 +74,8 @@ # Set the other thread as the selected thread to issue our 'po' command.other self.assertTrue(other_thread) process.SetSelectedThread(other_thread) + if self.TraceOn(): + print "selected thread:" + lldbutil.get_description(other_thread) self.runCmd("thread backtrace") # We want to traverse the frame to the one corresponding to blocked.m to @@ -86,7 +88,7 @@ if name == 'main': other_thread.SetSelectedFrame(i) if self.TraceOn(): - print "selected frame:" + str(frame) + print "selected frame:" + lldbutil.get_description(frame) break self.expect("po lock_me", OBJECT_PRINTED_CORRECTLY, From johnny.chen at apple.com Mon Jun 27 16:55:59 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 21:55:59 -0000 Subject: [Lldb-commits] [lldb] r133949 - in /lldb/trunk/test: inlines/ lang/c/inlines/ lang/c/inlines/Makefile Message-ID: <20110627215559.9284D2A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 16:55:59 2011 New Revision: 133949 URL: http://llvm.org/viewvc/llvm-project?rev=133949&view=rev Log: Move top level inlines dir to reside under lang/c. Added: lldb/trunk/test/lang/c/inlines/ - copied from r133916, lldb/trunk/test/inlines/ Removed: lldb/trunk/test/inlines/ Modified: lldb/trunk/test/lang/c/inlines/Makefile Modified: lldb/trunk/test/lang/c/inlines/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/inlines/Makefile?rev=133949&r1=133916&r2=133949&view=diff ============================================================================== --- lldb/trunk/test/lang/c/inlines/Makefile (original) +++ lldb/trunk/test/lang/c/inlines/Makefile Mon Jun 27 16:55:59 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../../make C_SOURCES := inlines.c From johnny.chen at apple.com Mon Jun 27 16:57:58 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 21:57:58 -0000 Subject: [Lldb-commits] [lldb] r133950 - in /lldb/trunk/test: lang/c/recurse/ lang/c/recurse/Makefile recurse/ Message-ID: <20110627215758.E17032A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 16:57:58 2011 New Revision: 133950 URL: http://llvm.org/viewvc/llvm-project?rev=133950&view=rev Log: Move top level recurse dir to reside under lang/c. Added: lldb/trunk/test/lang/c/recurse/ - copied from r133916, lldb/trunk/test/recurse/ Removed: lldb/trunk/test/recurse/ Modified: lldb/trunk/test/lang/c/recurse/Makefile Modified: lldb/trunk/test/lang/c/recurse/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/recurse/Makefile?rev=133950&r1=133916&r2=133950&view=diff ============================================================================== --- lldb/trunk/test/lang/c/recurse/Makefile (original) +++ lldb/trunk/test/lang/c/recurse/Makefile Mon Jun 27 16:57:58 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../../make C_SOURCES := main.c From johnny.chen at apple.com Mon Jun 27 17:10:42 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 22:10:42 -0000 Subject: [Lldb-commits] [lldb] r133951 - in /lldb/trunk/test: functionalities/process_launch/ functionalities/signal/ functionalities/stop-hook/ functionalities/target_command/ process_launch/ signal/ stop-hook/ target/ Message-ID: <20110627221042.DB1552A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 17:10:42 2011 New Revision: 133951 URL: http://llvm.org/viewvc/llvm-project?rev=133951&view=rev Log: Move to plevel dirs stop-hook, target, process_launch, and signal to reside under functionalities. Rename target dir to target_command. Added: lldb/trunk/test/functionalities/process_launch/ - copied from r133916, lldb/trunk/test/process_launch/ lldb/trunk/test/functionalities/signal/ - copied from r133916, lldb/trunk/test/signal/ lldb/trunk/test/functionalities/stop-hook/ - copied from r133916, lldb/trunk/test/stop-hook/ lldb/trunk/test/functionalities/target_command/ - copied from r133916, lldb/trunk/test/target/ Removed: lldb/trunk/test/process_launch/ lldb/trunk/test/signal/ lldb/trunk/test/stop-hook/ lldb/trunk/test/target/ Modified: lldb/trunk/test/functionalities/process_launch/Makefile lldb/trunk/test/functionalities/process_launch/TestProcessLaunch.py lldb/trunk/test/functionalities/signal/Makefile lldb/trunk/test/functionalities/signal/TestSendSignal.py lldb/trunk/test/functionalities/stop-hook/Makefile lldb/trunk/test/functionalities/stop-hook/TestStopHookCmd.py lldb/trunk/test/functionalities/stop-hook/TestStopHookMechanism.py lldb/trunk/test/functionalities/target_command/Makefile lldb/trunk/test/functionalities/target_command/TestTargetCommand.py Modified: lldb/trunk/test/functionalities/process_launch/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/process_launch/Makefile?rev=133951&r1=133916&r2=133951&view=diff ============================================================================== --- lldb/trunk/test/functionalities/process_launch/Makefile (original) +++ lldb/trunk/test/functionalities/process_launch/Makefile Mon Jun 27 17:10:42 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../make CXX_SOURCES := main.cpp #CXX_SOURCES := print-cwd.cpp Modified: lldb/trunk/test/functionalities/process_launch/TestProcessLaunch.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/process_launch/TestProcessLaunch.py?rev=133951&r1=133916&r2=133951&view=diff ============================================================================== --- lldb/trunk/test/functionalities/process_launch/TestProcessLaunch.py (original) +++ lldb/trunk/test/functionalities/process_launch/TestProcessLaunch.py Mon Jun 27 17:10:42 2011 @@ -9,7 +9,7 @@ class ProcessLaunchTestCase(TestBase): - mydir = "process_launch" + mydir = os.path.join("functionalities", "process_launch") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_io_with_dsym (self): Modified: lldb/trunk/test/functionalities/signal/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/signal/Makefile?rev=133951&r1=133916&r2=133951&view=diff ============================================================================== --- lldb/trunk/test/functionalities/signal/Makefile (original) +++ lldb/trunk/test/functionalities/signal/Makefile Mon Jun 27 17:10:42 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../make C_SOURCES := main.c Modified: lldb/trunk/test/functionalities/signal/TestSendSignal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/signal/TestSendSignal.py?rev=133951&r1=133916&r2=133951&view=diff ============================================================================== --- lldb/trunk/test/functionalities/signal/TestSendSignal.py (original) +++ lldb/trunk/test/functionalities/signal/TestSendSignal.py Mon Jun 27 17:10:42 2011 @@ -7,7 +7,7 @@ class SendSignalTestCase(TestBase): - mydir = "signal" + mydir = os.path.join("functionalities", "signal") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym_and_run_command(self): Modified: lldb/trunk/test/functionalities/stop-hook/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/stop-hook/Makefile?rev=133951&r1=133916&r2=133951&view=diff ============================================================================== --- lldb/trunk/test/functionalities/stop-hook/Makefile (original) +++ lldb/trunk/test/functionalities/stop-hook/Makefile Mon Jun 27 17:10:42 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../make CXX_SOURCES := main.cpp Modified: lldb/trunk/test/functionalities/stop-hook/TestStopHookCmd.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/stop-hook/TestStopHookCmd.py?rev=133951&r1=133916&r2=133951&view=diff ============================================================================== --- lldb/trunk/test/functionalities/stop-hook/TestStopHookCmd.py (original) +++ lldb/trunk/test/functionalities/stop-hook/TestStopHookCmd.py Mon Jun 27 17:10:42 2011 @@ -10,7 +10,7 @@ class StopHookCmdTestCase(TestBase): - mydir = "stop-hook" + mydir = os.path.join("functionalities", "stop-hook") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym(self): Modified: lldb/trunk/test/functionalities/stop-hook/TestStopHookMechanism.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/stop-hook/TestStopHookMechanism.py?rev=133951&r1=133916&r2=133951&view=diff ============================================================================== --- lldb/trunk/test/functionalities/stop-hook/TestStopHookMechanism.py (original) +++ lldb/trunk/test/functionalities/stop-hook/TestStopHookMechanism.py Mon Jun 27 17:10:42 2011 @@ -10,7 +10,7 @@ class StopHookMechanismTestCase(TestBase): - mydir = "stop-hook" + mydir = os.path.join("functionalities", "stop-hook") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym(self): Modified: lldb/trunk/test/functionalities/target_command/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/target_command/Makefile?rev=133951&r1=133916&r2=133951&view=diff ============================================================================== --- lldb/trunk/test/functionalities/target_command/Makefile (original) +++ lldb/trunk/test/functionalities/target_command/Makefile Mon Jun 27 17:10:42 2011 @@ -1,4 +1,4 @@ -LEVEL = ../make +LEVEL = ../../make # Example: # Modified: lldb/trunk/test/functionalities/target_command/TestTargetCommand.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/target_command/TestTargetCommand.py?rev=133951&r1=133916&r2=133951&view=diff ============================================================================== --- lldb/trunk/test/functionalities/target_command/TestTargetCommand.py (original) +++ lldb/trunk/test/functionalities/target_command/TestTargetCommand.py Mon Jun 27 17:10:42 2011 @@ -9,7 +9,7 @@ class targetCommandTestCase(TestBase): - mydir = "target" + mydir = os.path.join("functionalities", "target_command") def setUp(self): # Call super's setUp(). From johnny.chen at apple.com Mon Jun 27 17:38:57 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 22:38:57 -0000 Subject: [Lldb-commits] [lldb] r133954 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_event.py Message-ID: <20110627223857.CADF72A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 17:38:57 2011 New Revision: 133954 URL: http://llvm.org/viewvc/llvm-project?rev=133954&view=rev Log: Add fuzz calls for SBEvent. Added: lldb/trunk/test/python_api/default-constructor/sb_event.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=133954&r1=133953&r2=133954&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Mon Jun 27 17:38:57 2011 @@ -121,6 +121,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_event + sb_event.fuzz_obj(obj) @python_api_test def test_SBFileSpec(self): Added: lldb/trunk/test/python_api/default-constructor/sb_event.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_event.py?rev=133954&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_event.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_event.py Mon Jun 27 17:38:57 2011 @@ -0,0 +1,17 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetDataFlavor() + obj.GetType() + broadcaster = obj.GetBroadcaster() + # Do fuzz testing on the broadcaster obj, it should not crash lldb. + import sb_broadcaster + sb_broadcaster.fuzz_obj(broadcaster) + obj.BroadcasterMatchesPtr(None) + obj.BroadcasterMatchesRef(broadcaster) + obj.GetDescription(lldb.SBStream()) From johnny.chen at apple.com Mon Jun 27 17:55:51 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 22:55:51 -0000 Subject: [Lldb-commits] [lldb] r133956 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_filespec.py Message-ID: <20110627225551.E10A92A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 17:55:51 2011 New Revision: 133956 URL: http://llvm.org/viewvc/llvm-project?rev=133956&view=rev Log: Add fuzz calls for SBFileSpec. Added: lldb/trunk/test/python_api/default-constructor/sb_filespec.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=133956&r1=133955&r2=133956&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Mon Jun 27 17:55:51 2011 @@ -131,6 +131,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_filespec + sb_filespec.fuzz_obj(obj) @python_api_test def test_SBFrame(self): Added: lldb/trunk/test/python_api/default-constructor/sb_filespec.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_filespec.py?rev=133956&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_filespec.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_filespec.py Mon Jun 27 17:55:51 2011 @@ -0,0 +1,14 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.Exists() + obj.ResolveExecutableLocation() + obj.GetFilename() + obj.GetDirectory() + obj.GetPath(None, 0) + obj.GetDescription(lldb.SBStream()) From johnny.chen at apple.com Mon Jun 27 18:53:55 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 27 Jun 2011 23:53:55 -0000 Subject: [Lldb-commits] [lldb] r133965 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_frame.py sb_function.py Message-ID: <20110627235355.91B432A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 18:53:55 2011 New Revision: 133965 URL: http://llvm.org/viewvc/llvm-project?rev=133965&view=rev Log: Add fuzz calls for SBFrame and SBFunction. Added: lldb/trunk/test/python_api/default-constructor/sb_frame.py lldb/trunk/test/python_api/default-constructor/sb_function.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=133965&r1=133964&r2=133965&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Mon Jun 27 18:53:55 2011 @@ -141,6 +141,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_frame + sb_frame.fuzz_obj(obj) @python_api_test def test_SBFunction(self): @@ -148,6 +151,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_function + sb_function.fuzz_obj(obj) @python_api_test def test_SBInputReader(self): Added: lldb/trunk/test/python_api/default-constructor/sb_frame.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_frame.py?rev=133965&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_frame.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_frame.py Mon Jun 27 18:53:55 2011 @@ -0,0 +1,34 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetFrameID() + obj.GetPC() + obj.SetPC(0xffffffff) + obj.GetSP() + obj.GetFP() + obj.GetPCAddress() + obj.GetSymbolContext(0) + obj.GetModule() + obj.GetCompileUnit() + obj.GetFunction() + obj.GetSymbol() + obj.GetBlock() + obj.GetFunctionName() + obj.IsInlined() + obj.EvaluateExpression("x + y") + obj.EvaluateExpression("x + y", lldb.eDynamicCanRunTarget) + obj.GetFrameBlock() + obj.GetLineEntry() + obj.GetThread() + obj.Disassemble() + obj.GetVariables(True, True, True, True) + obj.GetVariables(True, True, True, False, lldb.eDynamicCanRunTarget) + obj.GetRegisters() + obj.FindVariable("my_var") + obj.FindVariable("my_var", lldb.eDynamicCanRunTarget) + obj.GetDescription(lldb.SBStream()) Added: lldb/trunk/test/python_api/default-constructor/sb_function.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_function.py?rev=133965&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_function.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_function.py Mon Jun 27 18:53:55 2011 @@ -0,0 +1,19 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetName() + obj.GetMangledName() + obj.GetInstructions(lldb.SBTarget()) + sa = obj.GetStartAddress() + ea = obj.GetEndAddress() + # Do fuzz testing on the address obj, it should not crash lldb. + import sb_address + sb_address.fuzz_obj(sa) + sb_address.fuzz_obj(ea) + obj.GetPrologueByteSize + obj.GetDescription(lldb.SBStream()) From johnny.chen at apple.com Mon Jun 27 19:12:06 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 28 Jun 2011 00:12:06 -0000 Subject: [Lldb-commits] [lldb] r133972 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_inputreader.py Message-ID: <20110628001206.919D72A6C12C@llvm.org> Author: johnny Date: Mon Jun 27 19:12:06 2011 New Revision: 133972 URL: http://llvm.org/viewvc/llvm-project?rev=133972&view=rev Log: Add fuzz calls for SBInputReader. Added: lldb/trunk/test/python_api/default-constructor/sb_inputreader.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=133972&r1=133971&r2=133972&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Mon Jun 27 19:12:06 2011 @@ -161,6 +161,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_inputreader + sb_inputreader.fuzz_obj(obj) @python_api_test def test_SBInstruction(self): Added: lldb/trunk/test/python_api/default-constructor/sb_inputreader.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_inputreader.py?rev=133972&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_inputreader.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_inputreader.py Mon Jun 27 19:12:06 2011 @@ -0,0 +1,13 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.Initialize(lldb.SBDebugger.Create(), None, None, 0, "$", "^", True) + obj.IsActive() + obj.IsDone() + obj.SetIsDone(True) + obj.GetGranularity() From gclayton at apple.com Tue Jun 28 14:01:40 2011 From: gclayton at apple.com (Greg Clayton) Date: Tue, 28 Jun 2011 19:01:40 -0000 Subject: [Lldb-commits] [lldb] r134019 - in /lldb/trunk: include/lldb/Core/Disassembler.h source/Commands/CommandObjectDisassemble.cpp source/Core/Disassembler.cpp Message-ID: <20110628190140.5C2312A6C12C@llvm.org> Author: gclayton Date: Tue Jun 28 14:01:40 2011 New Revision: 134019 URL: http://llvm.org/viewvc/llvm-project?rev=134019&view=rev Log: Remove the disassembly option: "eOptionShowCurrentLine" and replaced it with two: eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains the current PC (mixed mode only) eOptionMarkPCAddress = (1u << 3) // Mark the disassembly line the contains the PC This allows mixed mode to show the line that contains the current PC, and it allows us to mark the PC address in the disassembly if desired. Having these be separate gives more control on the disassembly output. SBFrame::Disassemble() doesn't enable any of these options. Modified: lldb/trunk/include/lldb/Core/Disassembler.h lldb/trunk/source/Commands/CommandObjectDisassemble.cpp lldb/trunk/source/Core/Disassembler.cpp Modified: lldb/trunk/include/lldb/Core/Disassembler.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Disassembler.h?rev=134019&r1=134018&r2=134019&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Disassembler.h (original) +++ lldb/trunk/include/lldb/Core/Disassembler.h Tue Jun 28 14:01:40 2011 @@ -189,7 +189,8 @@ eOptionNone = 0u, eOptionShowBytes = (1u << 0), eOptionRawOuput = (1u << 1), - eOptionShowCurrentLine = (1u << 2) + eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains the current PC (mixed mode only) + eOptionMarkPCAddress = (1u << 3) // Mark the disassembly line the contains the PC }; static Disassembler* Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=134019&r1=134018&r2=134019&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Tue Jun 28 14:01:40 2011 @@ -258,10 +258,12 @@ m_options.num_lines_context = 1; ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - uint32_t options = 0; + // Always show the PC in the disassembly + uint32_t options = Disassembler::eOptionMarkPCAddress; - if (!m_options.show_mixed) - options |= Disassembler::eOptionShowCurrentLine; + // Mark the source line for the current PC only if we are doing mixed source and assembly + if (m_options.show_mixed) + options |= Disassembler::eOptionMarkPCSourceLine; if (m_options.show_bytes) options |= Disassembler::eOptionShowBytes; Modified: lldb/trunk/source/Core/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=134019&r1=134018&r2=134019&view=diff ============================================================================== --- lldb/trunk/source/Core/Disassembler.cpp (original) +++ lldb/trunk/source/Core/Disassembler.cpp Tue Jun 28 14:01:40 2011 @@ -337,7 +337,6 @@ pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress(); const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; const bool use_inline_block_range = false; - for (size_t i=0; iGetInstructionList().GetInstructionAtIndex (i).get(); @@ -375,7 +374,7 @@ sc.line_entry.line, num_mixed_context_lines, num_mixed_context_lines, - ((options & eOptionShowCurrentLine) ? "->" : ""), + ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), &strm); } } @@ -405,12 +404,9 @@ } } - if (pc_addr_ptr) + if ((options & eOptionMarkPCAddress) && pc_addr_ptr) { - if (inst_is_at_pc) - strm.PutCString("-> "); - else - strm.PutCString(" "); + strm.PutCString(inst_is_at_pc ? "-> " : " "); } const bool show_bytes = (options & eOptionShowBytes) != 0; const bool raw = (options & eOptionRawOuput) != 0; From johnny.chen at apple.com Tue Jun 28 14:07:02 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 28 Jun 2011 19:07:02 -0000 Subject: [Lldb-commits] [lldb] r134020 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_instruction.py sb_instructionlist.py Message-ID: <20110628190702.9675B2A6C12C@llvm.org> Author: johnny Date: Tue Jun 28 14:07:02 2011 New Revision: 134020 URL: http://llvm.org/viewvc/llvm-project?rev=134020&view=rev Log: Add fuzz calls for SBInstruction and SBInstructionList. Added: lldb/trunk/test/python_api/default-constructor/sb_instruction.py lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=134020&r1=134019&r2=134020&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Tue Jun 28 14:07:02 2011 @@ -171,6 +171,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_instruction + sb_instruction.fuzz_obj(obj) @python_api_test def test_SBInstructionList(self): @@ -178,6 +181,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_instructionlist + sb_instructionlist.fuzz_obj(obj) @python_api_test def test_SBLineEntry(self): Added: lldb/trunk/test/python_api/default-constructor/sb_instruction.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_instruction.py?rev=134020&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_instruction.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_instruction.py Tue Jun 28 14:07:02 2011 @@ -0,0 +1,16 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetAddress() + obj.GetByteSize + obj.DoesBranch() + obj.Print(None) + obj.GetDescription(lldb.SBStream()) + obj.EmulateWithFrame(lldb.SBFrame(), 0) + obj.DumpEmulation("armv7") + obj.TestEmulation(lldb.SBStream(), "my-file") Added: lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py?rev=134020&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py Tue Jun 28 14:07:02 2011 @@ -0,0 +1,14 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetSize() + obj.GetInstructionAtIndex(0xffffffff) + obj.AppendInstruction(lldb.SBInstruction()) + obj.Print(None) + obj.GetDescription(lldb.SBStream()) + obj.DumpEmulationForAllInstructions("armv7") From johnny.chen at apple.com Tue Jun 28 14:39:19 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 28 Jun 2011 19:39:19 -0000 Subject: [Lldb-commits] [lldb] r134022 - in /lldb/trunk/test: expression_command/call-function/TestCallStdStringFunction.py lang/objc/foundation/TestObjCMethods.py Message-ID: <20110628193919.593A02A6C12C@llvm.org> Author: johnny Date: Tue Jun 28 14:39:19 2011 New Revision: 134022 URL: http://llvm.org/viewvc/llvm-project?rev=134022&view=rev Log: Add @expectedFailure for TestCallStdStringFunction.py (radar was filed) and remove @expectedFailure from TestObjCMethods.py's print_ivars_correctly() function (it has been passing for a while). Modified: lldb/trunk/test/expression_command/call-function/TestCallStdStringFunction.py lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py Modified: lldb/trunk/test/expression_command/call-function/TestCallStdStringFunction.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/call-function/TestCallStdStringFunction.py?rev=134022&r1=134021&r2=134022&view=diff ============================================================================== --- lldb/trunk/test/expression_command/call-function/TestCallStdStringFunction.py (original) +++ lldb/trunk/test/expression_command/call-function/TestCallStdStringFunction.py Tue Jun 28 14:39:19 2011 @@ -18,14 +18,16 @@ self.line = line_number('main.cpp', '// Please test these expressions while stopped at this line:') + # rdar://problem/9471744 test failure: ./dotest.py -C clang -v -w -t -p CallStdString + @unittest2.expectedFailure @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") def test_with_dsym(self): """Test calling std::String member function.""" self.buildDsym() self.call_function() - @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") - @python_api_test + # rdar://problem/9471744 test failure: ./dotest.py -C clang -v -w -t -p CallStdString + @unittest2.expectedFailure def test_with_dwarf_(self): """Test calling std::String member function.""" self.buildDsym() Modified: lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py?rev=134022&r1=134021&r2=134022&view=diff ============================================================================== --- lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py (original) +++ lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py Tue Jun 28 14:39:19 2011 @@ -199,7 +199,6 @@ self.expect("expression -o -- my", "Object description displayed correctly", patterns = ["Hello from.*a.out.*with timestamp: "]) - @unittest2.expectedFailure # See: lldb needs to use the ObjC runtime symbols for ivar offsets # Only fails for the ObjC 2.0 runtime. def print_ivars_correctly(self) : From johnny.chen at apple.com Tue Jun 28 15:46:03 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 28 Jun 2011 20:46:03 -0000 Subject: [Lldb-commits] [lldb] r134028 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_instruction.py sb_lineentry.py Message-ID: <20110628204603.74C6D2A6C12C@llvm.org> Author: johnny Date: Tue Jun 28 15:46:03 2011 New Revision: 134028 URL: http://llvm.org/viewvc/llvm-project?rev=134028&view=rev Log: Add fuzz calls for SBLineEntry. Added: lldb/trunk/test/python_api/default-constructor/sb_lineentry.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py lldb/trunk/test/python_api/default-constructor/sb_instruction.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=134028&r1=134027&r2=134028&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Tue Jun 28 15:46:03 2011 @@ -191,6 +191,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_lineentry + sb_lineentry.fuzz_obj(obj) @python_api_test def test_SBListener(self): Modified: lldb/trunk/test/python_api/default-constructor/sb_instruction.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_instruction.py?rev=134028&r1=134027&r2=134028&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_instruction.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_instruction.py Tue Jun 28 15:46:03 2011 @@ -7,7 +7,7 @@ def fuzz_obj(obj): obj.GetAddress() - obj.GetByteSize + obj.GetByteSize() obj.DoesBranch() obj.Print(None) obj.GetDescription(lldb.SBStream()) Added: lldb/trunk/test/python_api/default-constructor/sb_lineentry.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_lineentry.py?rev=134028&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_lineentry.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_lineentry.py Tue Jun 28 15:46:03 2011 @@ -0,0 +1,14 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetStartAddress() + obj.GetEndAddress() + obj.GetFileSpec() + obj.GetLine() + obj.GetColumn() + obj.GetDescription(lldb.SBStream()) From johnny.chen at apple.com Tue Jun 28 15:57:22 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 28 Jun 2011 20:57:22 -0000 Subject: [Lldb-commits] [lldb] r134029 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_listener.py Message-ID: <20110628205722.307662A6C12C@llvm.org> Author: johnny Date: Tue Jun 28 15:57:22 2011 New Revision: 134029 URL: http://llvm.org/viewvc/llvm-project?rev=134029&view=rev Log: Add fuzz calls for SBListener. Added: lldb/trunk/test/python_api/default-constructor/sb_listener.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=134029&r1=134028&r2=134029&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Tue Jun 28 15:57:22 2011 @@ -201,6 +201,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_listener + sb_listener.fuzz_obj(obj) @python_api_test def test_SBModule(self): Added: lldb/trunk/test/python_api/default-constructor/sb_listener.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_listener.py?rev=134029&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_listener.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_listener.py Tue Jun 28 15:57:22 2011 @@ -0,0 +1,23 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.AddEvent(lldb.SBEvent()) + obj.StartListeningForEvents(lldb.SBBroadcaster(), 0xffffffff) + obj.StopListeningForEvents(lldb.SBBroadcaster(), 0xffffffff) + event = lldb.SBEvent() + broadcaster = lldb.SBBroadcaster() + obj.WaitForEvent(5, event) + obj.WaitForEventForBroadcaster(5, broadcaster, event) + obj.WaitForEventForBroadcasterWithType(5, broadcaster, 0xffffffff, event) + obj.PeekAtNextEvent(event) + obj.PeekAtNextEventForBroadcaster(broadcaster, event) + obj.PeekAtNextEventForBroadcasterWithType(broadcaster, 0xffffffff, event) + obj.GetNextEvent(event) + obj.GetNextEventForBroadcaster(broadcaster, event) + obj.GetNextEventForBroadcasterWithType(broadcaster, 0xffffffff, event) + obj.HandleBroadcastEvent(event) From johnny.chen at apple.com Tue Jun 28 17:32:15 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 28 Jun 2011 22:32:15 -0000 Subject: [Lldb-commits] [lldb] r134037 - in /lldb/trunk: source/API/SBModule.cpp test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py test/python_api/default-constructor/sb_module.py test/python_api/default-constructor/sb_process.py Message-ID: <20110628223215.8CC322A6C12C@llvm.org> Author: johnny Date: Tue Jun 28 17:32:15 2011 New Revision: 134037 URL: http://llvm.org/viewvc/llvm-project?rev=134037&view=rev Log: Add fuzz calls for SBModule and SBProcess. Added: lldb/trunk/test/python_api/default-constructor/sb_module.py lldb/trunk/test/python_api/default-constructor/sb_process.py Modified: lldb/trunk/source/API/SBModule.cpp lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/source/API/SBModule.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBModule.cpp?rev=134037&r1=134036&r2=134037&view=diff ============================================================================== --- lldb/trunk/source/API/SBModule.cpp (original) +++ lldb/trunk/source/API/SBModule.cpp Tue Jun 28 17:32:15 2011 @@ -223,10 +223,11 @@ bool SBModule::ResolveFileAddress (lldb::addr_t vm_addr, SBAddress& addr) { - if (m_opaque_sp) + if (m_opaque_sp && addr.IsValid()) return m_opaque_sp->ResolveFileAddress (vm_addr, *addr); - addr->Clear(); + if (addr.IsValid()) + addr->Clear(); return false; } Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=134037&r1=134036&r2=134037&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Tue Jun 28 17:32:15 2011 @@ -211,6 +211,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_module + sb_module.fuzz_obj(obj) @python_api_test def test_SBProcess(self): @@ -218,6 +221,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_process + sb_process.fuzz_obj(obj) @python_api_test def test_SBStream(self): Added: lldb/trunk/test/python_api/default-constructor/sb_module.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_module.py?rev=134037&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_module.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_module.py Tue Jun 28 17:32:15 2011 @@ -0,0 +1,19 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetFileSpec() + obj.GetPlatformFileSpec() + obj.SetPlatformFileSpec(lldb.SBFileSpec()) + obj.GetUUIDBytes() + obj.GetUUIDString() + obj.ResolveFileAddress(sys.maxint, lldb.SBAddress()) + obj.ResolveSymbolContextForAddress(lldb.SBAddress(), 0) + obj.GetDescription(lldb.SBStream()) + obj.GetNumSymbols() + obj.GetSymbolAtIndex(sys.maxint) + obj.FindFunctions("my_func", 0xffffffff, True, lldb.SBSymbolContextList()) Added: lldb/trunk/test/python_api/default-constructor/sb_process.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_process.py?rev=134037&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_process.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_process.py Tue Jun 28 17:32:15 2011 @@ -0,0 +1,42 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetTarget() + obj.GetByteOrder() + obj.PutSTDIN("my data", 7) + obj.GetSTDOUT(6) + obj.GetSTDERR(6) + event = lldb.SBEvent() + obj.ReportEventState(event, None) + obj.AppendEventStateReport(event, lldb.SBCommandReturnObject()) + error = lldb.SBError() + obj.RemoteAttachToProcessWithID(123, error) + obj.RemoteLaunch(None, None, None, None, None, None, 0, False, error) + obj.GetNumThreads() + obj.GetThreadAtIndex(0) + obj.GetThreadByID(0) + obj.GetSelectedThread() + obj.SetSelectedThread(lldb.SBThread()) + obj.SetSelectedThreadByID(0) + obj.GetState() + obj.GetExitStatus() + obj.GetExitDescription() + obj.GetProcessID() + obj.GetAddressByteSize() + obj.Destroy() + obj.Continue() + obj.Stop() + obj.Kill() + obj.Detach() + obj.Signal(7) + obj.ReadMemory(0x0000ffff, 10, error) + obj.WriteMemory(0x0000ffff, "hi data", error) + obj.GetBroadcaster() + obj.GetDescription(lldb.SBStream()) + obj.LoadImage(lldb.SBFileSpec(), error) + obj.UnloadImage(0) From johnny.chen at apple.com Tue Jun 28 18:29:14 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 28 Jun 2011 23:29:14 -0000 Subject: [Lldb-commits] [lldb] r134040 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_address.py sb_broadcaster.py sb_debugger.py sb_error.py sb_event.py sb_frame.py sb_instructionlist.py sb_process.py sb_stringlist.py Message-ID: <20110628232914.4E8442A6C12C@llvm.org> Author: johnny Date: Tue Jun 28 18:29:14 2011 New Revision: 134040 URL: http://llvm.org/viewvc/llvm-project?rev=134040&view=rev Log: Add fuzz calls for SBStringList and add obj.Clear() calls for some files. Added: lldb/trunk/test/python_api/default-constructor/sb_stringlist.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py lldb/trunk/test/python_api/default-constructor/sb_address.py lldb/trunk/test/python_api/default-constructor/sb_broadcaster.py lldb/trunk/test/python_api/default-constructor/sb_debugger.py lldb/trunk/test/python_api/default-constructor/sb_error.py lldb/trunk/test/python_api/default-constructor/sb_event.py lldb/trunk/test/python_api/default-constructor/sb_frame.py lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py lldb/trunk/test/python_api/default-constructor/sb_process.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=134040&r1=134039&r2=134040&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Tue Jun 28 18:29:14 2011 @@ -239,6 +239,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_stringlist + sb_stringlist.fuzz_obj(obj) @python_api_test def test_SBSymbol(self): Modified: lldb/trunk/test/python_api/default-constructor/sb_address.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_address.py?rev=134040&r1=134039&r2=134040&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_address.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_address.py Tue Jun 28 18:29:14 2011 @@ -10,3 +10,4 @@ obj.GetLoadAddress(lldb.SBTarget()) obj.OffsetAddress(sys.maxint) obj.GetDescription(lldb.SBStream()) + obj.Clear() Modified: lldb/trunk/test/python_api/default-constructor/sb_broadcaster.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_broadcaster.py?rev=134040&r1=134039&r2=134040&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_broadcaster.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_broadcaster.py Tue Jun 28 18:29:14 2011 @@ -17,3 +17,4 @@ obj.EventTypeHasListeners(0) obj.RemoveListener(listener, 0xffffffff) obj.RemoveListener(listener, 0) + obj.Clear() Modified: lldb/trunk/test/python_api/default-constructor/sb_debugger.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_debugger.py?rev=134040&r1=134039&r2=134040&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_debugger.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_debugger.py Tue Jun 28 18:29:14 2011 @@ -49,3 +49,4 @@ obj.GetCloseInputOnEOF() obj.SetCloseInputOnEOF(True) obj.SetCloseInputOnEOF(False) + obj.Clear() Modified: lldb/trunk/test/python_api/default-constructor/sb_error.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_error.py?rev=134040&r1=134039&r2=134040&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_error.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_error.py Tue Jun 28 18:29:14 2011 @@ -17,3 +17,4 @@ obj.SetErrorString("xyz") obj.SetErrorStringWithFormat("%s!", "error") obj.GetDescription(lldb.SBStream()) + obj.Clear() Modified: lldb/trunk/test/python_api/default-constructor/sb_event.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_event.py?rev=134040&r1=134039&r2=134040&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_event.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_event.py Tue Jun 28 18:29:14 2011 @@ -15,3 +15,4 @@ obj.BroadcasterMatchesPtr(None) obj.BroadcasterMatchesRef(broadcaster) obj.GetDescription(lldb.SBStream()) + obj.Clear() Modified: lldb/trunk/test/python_api/default-constructor/sb_frame.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_frame.py?rev=134040&r1=134039&r2=134040&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_frame.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_frame.py Tue Jun 28 18:29:14 2011 @@ -32,3 +32,4 @@ obj.FindVariable("my_var") obj.FindVariable("my_var", lldb.eDynamicCanRunTarget) obj.GetDescription(lldb.SBStream()) + obj.Clear() Modified: lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py?rev=134040&r1=134039&r2=134040&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_instructionlist.py Tue Jun 28 18:29:14 2011 @@ -12,3 +12,4 @@ obj.Print(None) obj.GetDescription(lldb.SBStream()) obj.DumpEmulationForAllInstructions("armv7") + obj.Clear() Modified: lldb/trunk/test/python_api/default-constructor/sb_process.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_process.py?rev=134040&r1=134039&r2=134040&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_process.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_process.py Tue Jun 28 18:29:14 2011 @@ -40,3 +40,4 @@ obj.GetDescription(lldb.SBStream()) obj.LoadImage(lldb.SBFileSpec(), error) obj.UnloadImage(0) + obj.Clear() Added: lldb/trunk/test/python_api/default-constructor/sb_stringlist.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_stringlist.py?rev=134040&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_stringlist.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_stringlist.py Tue Jun 28 18:29:14 2011 @@ -0,0 +1,14 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.AppendString("another string") + obj.AppendList(None, 0) + obj.AppendList(lldb.SBStringList()) + obj.GetSize() + obj.GetStringAtIndex(0xffffffff) + obj.Clear() From johnny.chen at apple.com Tue Jun 28 18:38:38 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 28 Jun 2011 23:38:38 -0000 Subject: [Lldb-commits] [lldb] r134042 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_symbol.py sb_symbolcontext.py Message-ID: <20110628233838.C6ACC2A6C12C@llvm.org> Author: johnny Date: Tue Jun 28 18:38:38 2011 New Revision: 134042 URL: http://llvm.org/viewvc/llvm-project?rev=134042&view=rev Log: Add fuzz calls for SBSymbol and SBSymbolContext. Added: lldb/trunk/test/python_api/default-constructor/sb_symbol.py lldb/trunk/test/python_api/default-constructor/sb_symbolcontext.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=134042&r1=134041&r2=134042&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Tue Jun 28 18:38:38 2011 @@ -249,6 +249,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_symbol + sb_symbol.fuzz_obj(obj) @python_api_test def test_SBSymbolContext(self): @@ -256,6 +259,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_symbolcontext + sb_symbolcontext.fuzz_obj(obj) @python_api_test def test_SBSymbolContextList(self): Added: lldb/trunk/test/python_api/default-constructor/sb_symbol.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_symbol.py?rev=134042&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_symbol.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_symbol.py Tue Jun 28 18:38:38 2011 @@ -0,0 +1,16 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetName() + obj.GetMangledName() + obj.GetInstructions(lldb.SBTarget()) + obj.GetStartAddress() + obj.GetEndAddress() + obj.GetPrologueByteSize() + obj.GetType() + obj.GetDescription(lldb.SBStream()) Added: lldb/trunk/test/python_api/default-constructor/sb_symbolcontext.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_symbolcontext.py?rev=134042&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_symbolcontext.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_symbolcontext.py Tue Jun 28 18:38:38 2011 @@ -0,0 +1,15 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetModule() + obj.GetCompileUnit() + obj.GetFunction() + obj.GetBlock() + obj.GetLineEntry() + obj.GetSymbol() + obj.GetDescription(lldb.SBStream()) From johnny.chen at apple.com Tue Jun 28 19:05:40 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 29 Jun 2011 00:05:40 -0000 Subject: [Lldb-commits] [lldb] r134046 - in /lldb/trunk: source/API/SBTarget.cpp test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py test/python_api/default-constructor/sb_target.py test/python_api/default-constructor/sb_thread.py Message-ID: <20110629000540.5D37C2A6C12C@llvm.org> Author: johnny Date: Tue Jun 28 19:05:40 2011 New Revision: 134046 URL: http://llvm.org/viewvc/llvm-project?rev=134046&view=rev Log: Add fuzz calls for SBTarget and SBThread. Added: lldb/trunk/test/python_api/default-constructor/sb_target.py lldb/trunk/test/python_api/default-constructor/sb_thread.py Modified: lldb/trunk/source/API/SBTarget.cpp lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/source/API/SBTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=134046&r1=134045&r2=134046&view=diff ============================================================================== --- lldb/trunk/source/API/SBTarget.cpp (original) +++ lldb/trunk/source/API/SBTarget.cpp Tue Jun 28 19:05:40 2011 @@ -504,13 +504,14 @@ SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr, lldb::SBAddress& addr) { - if (m_opaque_sp) + if (m_opaque_sp && addr.IsValid()) { Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex()); return m_opaque_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, *addr); } - addr->Clear(); + if (addr.IsValid()) + addr->Clear(); return false; } @@ -518,7 +519,7 @@ SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope) { SBSymbolContext sc; - if (m_opaque_sp) + if (m_opaque_sp && addr.IsValid()) m_opaque_sp->GetImages().ResolveSymbolContextForAddress (*addr, resolve_scope, sc.ref()); return sc; } Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=134046&r1=134045&r2=134046&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Tue Jun 28 19:05:40 2011 @@ -277,6 +277,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_target + sb_target.fuzz_obj(obj) @python_api_test def test_SBThread(self): @@ -284,6 +287,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_thread + sb_thread.fuzz_obj(obj) @python_api_test def test_SBType(self): Added: lldb/trunk/test/python_api/default-constructor/sb_target.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_target.py?rev=134046&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_target.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_target.py Tue Jun 28 19:05:40 2011 @@ -0,0 +1,42 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetProcess() + listener = lldb.SBListener() + error = lldb.SBError() + obj.Launch(listener, None, None, None, None, None, None, 0, True, error) + obj.LaunchSimple(None, None, None) + obj.AttachToProcessWithID(listener, 123, error) + obj.AttachToProcessWithName(listener, 'lldb', False, error) + obj.ConnectRemote(listener, "connect://to/here", None, error) + obj.GetExecutable() + obj.GetNumModules() + obj.GetModuleAtIndex(0xffffffff) + obj.GetDebugger() + filespec = lldb.SBFileSpec() + obj.FindModule(filespec) + contextlist = lldb.SBSymbolContextList() + obj.FindFunctions("the_func", 0xff, True, contextlist) + address = lldb.SBAddress() + obj.ResolveLoadAddress(0xffff, address) + obj.ResolveSymbolContextForAddress(address, 0) + obj.BreakpointCreateByLocation("filename", 20) + obj.BreakpointCreateByLocation(filespec, 20) + obj.BreakpointCreateByName("func", None) + obj.BreakpointCreateByRegex("func.", None) + obj.BreakpointCreateByAddress(0xf0f0) + obj.GetNumBreakpoints() + obj.GetBreakpointAtIndex(0) + obj.BreakpointDelete(0) + obj.FindBreakpointByID(0) + obj.EnableAllBreakpoints() + obj.DisableAllBreakpoints() + obj.DeleteAllBreakpoints() + obj.GetBroadcaster() + obj.GetDescription(lldb.SBStream(), lldb.eDescriptionLevelBrief) + obj.Clear() Added: lldb/trunk/test/python_api/default-constructor/sb_thread.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_thread.py?rev=134046&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_thread.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_thread.py Tue Jun 28 19:05:40 2011 @@ -0,0 +1,35 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetStopReason() + obj.GetStopReasonDataCount() + obj.GetStopReasonDataAtIndex(100) + obj.GetStopDescription(256) + obj.GetThreadID() + obj.GetIndexID() + obj.GetName() + obj.GetQueueName() + obj.StepOver(lldb.eOnlyDuringStepping) + obj.StepInto(lldb.eOnlyDuringStepping) + obj.StepOut() + frame = lldb.SBFrame() + obj.StepOutOfFrame(frame) + obj.StepInstruction(True) + filespec = lldb.SBFileSpec() + obj.StepOverUntil(frame, filespec, 1234) + obj.RunToAddress(0xabcd) + obj.Suspend() + obj.Resume() + obj.IsSuspended() + obj.GetNumFrames() + obj.GetFrameAtIndex(200) + obj.GetSelectedFrame() + obj.SetSelectedFrame(999) + obj.GetProcess() + obj.GetDescription(lldb.SBStream()) + obj.Clear() From granata.enrico at gmail.com Tue Jun 28 23:18:11 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Wed, 29 Jun 2011 04:18:11 -0000 Subject: [Lldb-commits] [lldb] r134056 - /lldb/trunk/docs/try.me Message-ID: <20110629041811.CBEC72A6C12C@llvm.org> Author: enrico Date: Tue Jun 28 23:18:11 2011 New Revision: 134056 URL: http://llvm.org/viewvc/llvm-project?rev=134056&view=rev Log: just a test for commit access - ignore this Added: lldb/trunk/docs/try.me Added: lldb/trunk/docs/try.me URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/docs/try.me?rev=134056&view=auto ============================================================================== (empty) From gclayton at apple.com Wed Jun 29 13:28:50 2011 From: gclayton at apple.com (Greg Clayton) Date: Wed, 29 Jun 2011 18:28:50 -0000 Subject: [Lldb-commits] [lldb] r134081 - /lldb/trunk/source/API/SBValue.cpp Message-ID: <20110629182850.A415E2A6C12C@llvm.org> Author: gclayton Date: Wed Jun 29 13:28:50 2011 New Revision: 134081 URL: http://llvm.org/viewvc/llvm-project?rev=134081&view=rev Log: Fixed an issue that was checked in with the dynamic types and update point changes that caused all SBValue objects to completely ignore the target lock due to bad C++ scoping of the target Mutex::Locker variables. Modified: lldb/trunk/source/API/SBValue.cpp Modified: lldb/trunk/source/API/SBValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=134081&r1=134080&r2=134081&view=diff ============================================================================== --- lldb/trunk/source/API/SBValue.cpp (original) +++ lldb/trunk/source/API/SBValue.cpp Wed Jun 29 13:28:50 2011 @@ -149,8 +149,10 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - result = m_opaque_sp->IsInScope (); + result = m_opaque_sp->IsInScope (); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -173,8 +175,10 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - cstr = m_opaque_sp->GetValueAsCString (); + cstr = m_opaque_sp->GetValueAsCString (); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -226,8 +230,10 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - cstr = m_opaque_sp->GetObjectDescription (); + cstr = m_opaque_sp->GetObjectDescription (); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -253,8 +259,10 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - result = m_opaque_sp->GetValueDidChange (); + result = m_opaque_sp->GetValueDidChange (); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -276,8 +284,10 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - cstr = m_opaque_sp->GetSummaryAsCString(); + cstr = m_opaque_sp->GetSummaryAsCString(); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -303,8 +313,10 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - cstr = m_opaque_sp->GetLocationAsCString(); + cstr = m_opaque_sp->GetLocationAsCString(); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -330,8 +342,10 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - success = m_opaque_sp->SetValueFromCString (value_str); + success = m_opaque_sp->SetValueFromCString (value_str); + } } return success; } @@ -351,16 +365,18 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - child_sp = m_opaque_sp->GetChildAtIndex (idx, true); - if (use_dynamic != lldb::eNoDynamicValues) - { - if (child_sp) + child_sp = m_opaque_sp->GetChildAtIndex (idx, true); + if (use_dynamic != lldb::eNoDynamicValues) { - lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic); - if (dynamic_sp) - child_sp = dynamic_sp; + if (child_sp) + { + lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic); + if (dynamic_sp) + child_sp = dynamic_sp; + } } } } @@ -380,9 +396,11 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name)); + idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name)); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -412,15 +430,17 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) - Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); - if (use_dynamic_value != lldb::eNoDynamicValues) { - if (child_sp) + Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); + child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); + if (use_dynamic_value != lldb::eNoDynamicValues) { - lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value); - if (dynamic_sp) - child_sp = dynamic_sp; + if (child_sp) + { + lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value); + if (dynamic_sp) + child_sp = dynamic_sp; + } } } } @@ -443,9 +463,11 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - num_children = m_opaque_sp->GetNumChildren(); + num_children = m_opaque_sp->GetNumChildren(); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -463,10 +485,12 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - Error error; - sb_value = m_opaque_sp->Dereference (error); + Error error; + sb_value = m_opaque_sp->Dereference (error); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) @@ -483,9 +507,11 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - is_ptr_type = m_opaque_sp->IsPointerType(); + is_ptr_type = m_opaque_sp->IsPointerType(); + } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -502,9 +528,11 @@ if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTarget()) + { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); - return m_opaque_sp->GetClangType(); + return m_opaque_sp->GetClangType(); + } } return NULL; } From jingham at apple.com Wed Jun 29 14:42:28 2011 From: jingham at apple.com (Jim Ingham) Date: Wed, 29 Jun 2011 19:42:28 -0000 Subject: [Lldb-commits] [lldb] r134090 - in /lldb/trunk: include/lldb/Breakpoint/BreakpointSiteList.h source/Breakpoint/BreakpointSiteList.cpp source/Target/Process.cpp Message-ID: <20110629194228.92E642A6C12C@llvm.org> Author: jingham Date: Wed Jun 29 14:42:28 2011 New Revision: 134090 URL: http://llvm.org/viewvc/llvm-project?rev=134090&view=rev Log: Remove a few more places where we were iterating linearly over the Breakpoint Site's rather than looking up what we needed by address, which is much faster. Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp lldb/trunk/source/Target/Process.cpp Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h?rev=134090&r1=134089&r2=134090&view=diff ============================================================================== --- lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h (original) +++ lldb/trunk/include/lldb/Breakpoint/BreakpointSiteList.h Wed Jun 29 14:42:28 2011 @@ -165,6 +165,9 @@ void SetEnabledForAll(const bool enable, const lldb::break_id_t except_id = LLDB_INVALID_BREAK_ID); + + bool + FindInRange (lldb::addr_t lower_bound, lldb::addr_t upper_bound, BreakpointSiteList &bp_site_list) const; typedef void (*BreakpointSiteSPMapFunc) (lldb::BreakpointSiteSP &bp, void *baton); Modified: lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp?rev=134090&r1=134089&r2=134090&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp (original) +++ lldb/trunk/source/Breakpoint/BreakpointSiteList.cpp Wed Jun 29 14:42:28 2011 @@ -209,6 +209,41 @@ return stop_sp; } +bool +BreakpointSiteList::FindInRange (lldb::addr_t lower_bound, lldb::addr_t upper_bound, BreakpointSiteList &bp_site_list) const +{ + + if (lower_bound > upper_bound) + return false; + + collection::const_iterator lower, upper, pos; + lower = m_bp_site_list.lower_bound(lower_bound); + if (lower == m_bp_site_list.end() + || (*lower).first >= upper_bound) + return false; + + // This is one tricky bit. The breakpoint might overlap the bottom end of the range. So we grab the + // breakpoint prior to the lower bound, and check that that + its byte size isn't in our range. + if (lower != m_bp_site_list.begin()) + { + collection::const_iterator prev_pos = lower; + prev_pos--; + const BreakpointSiteSP &prev_bp = (*prev_pos).second; + if (prev_bp->GetLoadAddress() + prev_bp->GetByteSize() > lower_bound) + bp_site_list.Add (prev_bp); + + } + + upper = m_bp_site_list.upper_bound(upper_bound); + + for (pos = lower; pos != upper; pos++) + { + bp_site_list.Add ((*pos).second); + } + return true; +} + + void BreakpointSiteList::SetEnabledForAll (const bool enabled, const lldb::break_id_t except_id) { Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=134090&r1=134089&r2=134090&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Wed Jun 29 14:42:28 2011 @@ -1378,18 +1378,22 @@ size_t opcode_offset; size_t idx; BreakpointSiteSP bp; + BreakpointSiteList bp_sites_in_range; - for (idx = 0; (bp = m_breakpoint_site_list.GetByIndex(idx)) != NULL; ++idx) + if (m_breakpoint_site_list.FindInRange (bp_addr, bp_addr + size, bp_sites_in_range)) { - if (bp->GetType() == BreakpointSite::eSoftware) + for (idx = 0; (bp = bp_sites_in_range.GetByIndex(idx)) != NULL; ++idx) { - if (bp->IntersectsRange(bp_addr, size, &intersect_addr, &intersect_size, &opcode_offset)) + if (bp->GetType() == BreakpointSite::eSoftware) { - assert(bp_addr <= intersect_addr && intersect_addr < bp_addr + size); - assert(bp_addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= bp_addr + size); - assert(opcode_offset + intersect_size <= bp->GetByteSize()); - size_t buf_offset = intersect_addr - bp_addr; - ::memcpy(buf + buf_offset, bp->GetSavedOpcodeBytes() + opcode_offset, intersect_size); + if (bp->IntersectsRange(bp_addr, size, &intersect_addr, &intersect_size, &opcode_offset)) + { + assert(bp_addr <= intersect_addr && intersect_addr < bp_addr + size); + assert(bp_addr < intersect_addr + intersect_size && intersect_addr + intersect_size <= bp_addr + size); + assert(opcode_offset + intersect_size <= bp->GetByteSize()); + size_t buf_offset = intersect_addr - bp_addr; + ::memcpy(buf + buf_offset, bp->GetSavedOpcodeBytes() + opcode_offset, intersect_size); + } } } } From johnny.chen at apple.com Wed Jun 29 16:19:39 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 29 Jun 2011 21:19:39 -0000 Subject: [Lldb-commits] [lldb] r134096 - in /lldb/trunk: include/lldb/API/SBType.h source/API/SBType.cpp source/API/SBValue.cpp test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py test/python_api/default-constructor/sb_type.py test/python_api/default-constructor/sb_value.py test/python_api/default-constructor/sb_valuelist.py Message-ID: <20110629211940.03B0C2A6C12C@llvm.org> Author: johnny Date: Wed Jun 29 16:19:39 2011 New Revision: 134096 URL: http://llvm.org/viewvc/llvm-project?rev=134096&view=rev Log: Add fuzz calls to SBType, SBValue, and SBValueList. Fixed crashes for SBValue fuzz calls. And change 'bool SBType::IsPointerType(void)' to 'bool SBType::IsAPointerType(void)' to avoid name collision with the static 'bool SBType::IsPointerType(void *)' function, which SWIG cannot handle. Added: lldb/trunk/test/python_api/default-constructor/sb_type.py lldb/trunk/test/python_api/default-constructor/sb_value.py lldb/trunk/test/python_api/default-constructor/sb_valuelist.py Modified: lldb/trunk/include/lldb/API/SBType.h lldb/trunk/source/API/SBType.cpp lldb/trunk/source/API/SBValue.cpp lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/include/lldb/API/SBType.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBType.h?rev=134096&r1=134095&r2=134096&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBType.h (original) +++ lldb/trunk/include/lldb/API/SBType.h Wed Jun 29 16:19:39 2011 @@ -53,7 +53,7 @@ GetChildIndexForName (bool omit_empty_base_classes, const char *name); bool - IsPointerType (); + IsAPointerType (); SBType GetPointeeType (); Modified: lldb/trunk/source/API/SBType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBType.cpp?rev=134096&r1=134095&r2=134096&view=diff ============================================================================== --- lldb/trunk/source/API/SBType.cpp (original) +++ lldb/trunk/source/API/SBType.cpp Wed Jun 29 16:19:39 2011 @@ -165,7 +165,7 @@ } bool -SBType::IsPointerType () +SBType::IsAPointerType () { return ClangASTContext::IsPointerType (m_type); } @@ -174,7 +174,7 @@ SBType::GetPointeeType () { void *pointee_type = NULL; - if (IsPointerType ()) + if (IsAPointerType ()) { pointee_type = ClangASTType::GetPointeeType (m_type); } @@ -187,7 +187,7 @@ const char *name = GetName(); uint64_t byte_size = GetByteSize(); uint64_t num_children = GetNumberChildren (true); - bool is_ptr = IsPointerType (); + bool is_ptr = IsAPointerType (); description.Printf ("type_name: %s, size: %d bytes", (name != NULL ? name : ""), byte_size); if (is_ptr) Modified: lldb/trunk/source/API/SBValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=134096&r1=134095&r2=134096&view=diff ============================================================================== --- lldb/trunk/source/API/SBValue.cpp (original) +++ lldb/trunk/source/API/SBValue.cpp Wed Jun 29 16:19:39 2011 @@ -353,8 +353,13 @@ SBValue SBValue::GetChildAtIndex (uint32_t idx) { - lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); - return GetChildAtIndex (idx, use_dynamic_value); + if (m_opaque_sp) + { + lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); + return GetChildAtIndex (idx, use_dynamic_value); + } + else + return GetChildAtIndex (idx, eNoDynamicValues); } SBValue @@ -416,8 +421,13 @@ SBValue SBValue::GetChildMemberWithName (const char *name) { - lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); - return GetChildMemberWithName (name, use_dynamic_value); + if (m_opaque_sp) + { + lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); + return GetChildMemberWithName (name, use_dynamic_value); + } + else + return GetChildMemberWithName (name, eNoDynamicValues); } SBValue Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=134096&r1=134095&r2=134096&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Wed Jun 29 16:19:39 2011 @@ -297,6 +297,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_type + sb_type.fuzz_obj(obj) @python_api_test def test_SBValue(self): @@ -304,6 +307,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_value + sb_value.fuzz_obj(obj) @python_api_test def test_SBValueList(self): @@ -311,6 +317,9 @@ if self.TraceOn(): print obj self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_valuelist + sb_valuelist.fuzz_obj(obj) if __name__ == '__main__': Added: lldb/trunk/test/python_api/default-constructor/sb_type.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_type.py?rev=134096&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_type.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_type.py Wed Jun 29 16:19:39 2011 @@ -0,0 +1,19 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetName() + obj.GetByteSize() + #obj.GetEncoding(5) + obj.GetNumberChildren(True) + member = lldb.SBTypeMember() + obj.GetChildAtIndex(True, 0, member) + obj.GetChildIndexForName(True, "_member_field") + obj.IsAPointerType() + obj.GetPointeeType() + obj.GetDescription(lldb.SBStream()) + Added: lldb/trunk/test/python_api/default-constructor/sb_value.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_value.py?rev=134096&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_value.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_value.py Wed Jun 29 16:19:39 2011 @@ -0,0 +1,35 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.GetError() + obj.GetName() + obj.GetTypeName() + obj.GetByteSize() + obj.IsInScope() + obj.GetFormat() + obj.SetFormat(lldb.eFormatBoolean) + obj.GetValue() + obj.GetValueType() + obj.GetValueDidChange() + obj.GetSummary() + obj.GetObjectDescription() + obj.GetLocation() + obj.SetValueFromCString("my_new_value") + obj.GetChildAtIndex(1) + obj.GetChildAtIndex(2, lldb.eNoDynamicValues) + obj.GetIndexOfChildWithName("my_first_child") + obj.GetChildMemberWithName("my_first_child") + obj.GetChildMemberWithName("my_first_child", lldb.eNoDynamicValues) + obj.GetNumChildren() + obj.GetOpaqueType() + obj.Dereference() + obj.TypeIsPointerType() + stream = lldb.SBStream() + obj.GetDescription(stream) + obj.GetExpressionPath(stream) + obj.GetExpressionPath(stream, True) Added: lldb/trunk/test/python_api/default-constructor/sb_valuelist.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_valuelist.py?rev=134096&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_valuelist.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_valuelist.py Wed Jun 29 16:19:39 2011 @@ -0,0 +1,12 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.Append(lldb.SBValue()) + obj.GetSize() + obj.GetValueAtIndex(100) + obj.FindValueObjectByUID(200) From johnny.chen at apple.com Wed Jun 29 16:42:46 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 29 Jun 2011 21:42:46 -0000 Subject: [Lldb-commits] [lldb] r134098 - in /lldb/trunk/test/python_api/default-constructor: TestDefaultConstructorForAPIObjects.py sb_typemember.py Message-ID: <20110629214246.B6F922A6C12C@llvm.org> Author: johnny Date: Wed Jun 29 16:42:46 2011 New Revision: 134098 URL: http://llvm.org/viewvc/llvm-project?rev=134098&view=rev Log: Add fuzz calls for SBTypeMember. Added: lldb/trunk/test/python_api/default-constructor/sb_typemember.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Modified: lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=134098&r1=134097&r2=134098&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original) +++ lldb/trunk/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Wed Jun 29 16:42:46 2011 @@ -302,6 +302,16 @@ sb_type.fuzz_obj(obj) @python_api_test + def test_SBTypeMember(self): + obj = lldb.SBTypeMember() + if self.TraceOn(): + print obj + self.assertFalse(obj) + # Do fuzz testing on the invalid obj, it should not crash lldb. + import sb_typemember + sb_typemember.fuzz_obj(obj) + + @python_api_test def test_SBValue(self): obj = lldb.SBValue() if self.TraceOn(): Added: lldb/trunk/test/python_api/default-constructor/sb_typemember.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_typemember.py?rev=134098&view=auto ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_typemember.py (added) +++ lldb/trunk/test/python_api/default-constructor/sb_typemember.py Wed Jun 29 16:42:46 2011 @@ -0,0 +1,18 @@ +""" +Fuzz tests an object after the default construction to make sure it does not crash lldb. +""" + +import sys +import lldb + +def fuzz_obj(obj): + obj.IsBaseClass() + obj.IsBitfield() + obj.GetBitfieldWidth() + obj.GetBitfieldOffset() + obj.GetOffset() + obj.GetName() + obj.GetType() + obj.GetParentType() + obj.SetName("my_type_member_name") + obj.Clear() From gclayton at apple.com Wed Jun 29 17:09:02 2011 From: gclayton at apple.com (Greg Clayton) Date: Wed, 29 Jun 2011 22:09:02 -0000 Subject: [Lldb-commits] [lldb] r134102 - in /lldb/trunk: include/lldb/API/SBDefines.h include/lldb/API/SBModule.h include/lldb/API/SBTarget.h include/lldb/API/SBValueList.h include/lldb/Core/ValueObject.h include/lldb/Core/ValueObjectList.h include/lldb/Symbol/ClangASTContext.h source/API/SBModule.cpp source/API/SBTarget.cpp source/API/SBValueList.cpp source/Core/Value.cpp source/Core/ValueObject.cpp source/Core/ValueObjectList.cpp source/Core/ValueObjectVariable.cpp source/Symbol/ClangASTContext.cpp Message-ID: <20110629220902.D89C32A6C12C@llvm.org> Author: gclayton Date: Wed Jun 29 17:09:02 2011 New Revision: 134102 URL: http://llvm.org/viewvc/llvm-project?rev=134102&view=rev Log: Added support for finding and global variables in the SBTarget and SBModule level in the public API. Also modified the ValueObject values to be able to display global variables without having a valid running process. The globals will read themselves from the object file section data if there is no process, and from the process if there is one. Also fixed an issue where modifications for dynamic types could cause child values of ValueObjects to not show up if the value was unable to evaluate itself (children of NULL pointer objects). Modified: lldb/trunk/include/lldb/API/SBDefines.h lldb/trunk/include/lldb/API/SBModule.h lldb/trunk/include/lldb/API/SBTarget.h lldb/trunk/include/lldb/API/SBValueList.h lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/include/lldb/Core/ValueObjectList.h lldb/trunk/include/lldb/Symbol/ClangASTContext.h lldb/trunk/source/API/SBModule.cpp lldb/trunk/source/API/SBTarget.cpp lldb/trunk/source/API/SBValueList.cpp lldb/trunk/source/Core/Value.cpp lldb/trunk/source/Core/ValueObject.cpp lldb/trunk/source/Core/ValueObjectList.cpp lldb/trunk/source/Core/ValueObjectVariable.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/include/lldb/API/SBDefines.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDefines.h?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBDefines.h (original) +++ lldb/trunk/include/lldb/API/SBDefines.h Wed Jun 29 17:09:02 2011 @@ -57,6 +57,7 @@ class SBTarget; class SBThread; class SBValue; +class SBValueList; } Modified: lldb/trunk/include/lldb/API/SBModule.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBModule.h?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBModule.h (original) +++ lldb/trunk/include/lldb/API/SBModule.h Wed Jun 29 17:09:02 2011 @@ -12,6 +12,7 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBSymbolContext.h" +#include "lldb/API/SBValueList.h" namespace lldb { @@ -80,6 +81,12 @@ bool append, lldb::SBSymbolContextList& sc_list); + lldb::SBValueList + FindGlobalVariables (lldb::SBTarget &target, + const char *name, + uint32_t max_matches); + + private: friend class SBAddress; friend class SBFrame; Modified: lldb/trunk/include/lldb/API/SBTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBTarget.h (original) +++ lldb/trunk/include/lldb/API/SBTarget.h Wed Jun 29 17:09:02 2011 @@ -189,6 +189,10 @@ bool append, lldb::SBSymbolContextList& sc_list); + lldb::SBValueList + FindGlobalVariables (const char *name, + uint32_t max_matches); + void Clear (); @@ -260,6 +264,7 @@ friend class SBFunction; friend class SBProcess; friend class SBSymbol; + friend class SBModule; //------------------------------------------------------------------ // Constructors are private, use static Target::Create function to Modified: lldb/trunk/include/lldb/API/SBValueList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValueList.h?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBValueList.h (original) +++ lldb/trunk/include/lldb/API/SBValueList.h Wed Jun 29 17:09:02 2011 @@ -30,6 +30,9 @@ void Append (const lldb::SBValue &val_obj); + void + Append (const lldb::SBValueList& value_list); + uint32_t GetSize() const; @@ -58,7 +61,10 @@ lldb_private::ValueObjectList * get (); - + + lldb_private::ValueObjectList & + ref (); + #endif private: Modified: lldb/trunk/include/lldb/Core/ValueObject.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObject.h (original) +++ lldb/trunk/include/lldb/Core/ValueObject.h Wed Jun 29 17:09:02 2011 @@ -239,6 +239,9 @@ virtual bool IsPossibleCPlusPlusDynamicType (); + + virtual bool + IsPossibleDynamicType (); virtual bool IsBaseClass () Modified: lldb/trunk/include/lldb/Core/ValueObjectList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectList.h?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectList.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectList.h Wed Jun 29 17:09:02 2011 @@ -44,6 +44,9 @@ void Append (const lldb::ValueObjectSP &val_obj_sp); + void + Append (const ValueObjectList &valobj_list); + lldb::ValueObjectSP FindValueObjectByPointer (ValueObject *valobj); Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Wed Jun 29 17:09:02 2011 @@ -635,6 +635,11 @@ lldb::clang_type_t *target_type = NULL); static bool + IsPossibleDynamicType (clang::ASTContext *ast, + lldb::clang_type_t clang_type, + lldb::clang_type_t *dynamic_pointee_type = NULL); + + static bool IsCStringType (lldb::clang_type_t clang_type, uint32_t &length); static bool Modified: lldb/trunk/source/API/SBModule.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBModule.cpp?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/source/API/SBModule.cpp (original) +++ lldb/trunk/source/API/SBModule.cpp Wed Jun 29 17:09:02 2011 @@ -15,6 +15,10 @@ #include "lldb/Core/Module.h" #include "lldb/Core/Log.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/ValueObjectList.h" +#include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/Target.h" using namespace lldb; using namespace lldb_private; @@ -307,3 +311,34 @@ return 0; } + +SBValueList +SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches) +{ + SBValueList sb_value_list; + if (m_opaque_sp) + { + VariableList variable_list; + const uint32_t match_count = m_opaque_sp->FindGlobalVariables (ConstString (name), + false, + max_matches, + variable_list); + + if (match_count > 0) + { + ValueObjectList &value_object_list = sb_value_list.ref(); + for (uint32_t i=0; iGetImages().FindGlobalVariables (ConstString (name), + append, + max_matches, + variable_list); + + if (match_count > 0) + { + ExecutionContextScope *exe_scope = m_opaque_sp->GetProcessSP().get(); + if (exe_scope == NULL) + exe_scope = m_opaque_sp.get(); + ValueObjectList &value_object_list = sb_value_list.ref(); + for (uint32_t i=0; i() { return m_opaque_ap.get(); } -lldb_private::ValueObjectList & +ValueObjectList & SBValueList::operator*() { return *m_opaque_ap; } -const lldb_private::ValueObjectList * +const ValueObjectList * SBValueList::operator->() const { return m_opaque_ap.get(); } -const lldb_private::ValueObjectList & +const ValueObjectList & SBValueList::operator*() const { return *m_opaque_ap; @@ -121,11 +121,21 @@ } } +void +SBValueList::Append (const lldb::SBValueList& value_list) +{ + if (value_list.IsValid()) + { + CreateIfNeeded (); + m_opaque_ap->Append (*value_list); + } +} + SBValue SBValueList::GetValueAtIndex (uint32_t idx) const { - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); //if (log) // log->Printf ("SBValueList::GetValueAtIndex (uint32_t idx) idx = %d", idx); @@ -148,7 +158,7 @@ uint32_t SBValueList::GetSize () const { - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); //if (log) // log->Printf ("SBValueList::GetSize ()"); @@ -180,9 +190,17 @@ return sb_value; } -lldb_private::ValueObjectList * +ValueObjectList * SBValueList::get () { return m_opaque_ap.get(); } +ValueObjectList & +SBValueList::ref () +{ + CreateIfNeeded(); + return *m_opaque_ap.get(); +} + + Modified: lldb/trunk/source/Core/Value.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Value.cpp?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/source/Core/Value.cpp (original) +++ lldb/trunk/source/Core/Value.cpp Wed Jun 29 17:09:02 2011 @@ -516,6 +516,7 @@ Error error; lldb::addr_t address = LLDB_INVALID_ADDRESS; AddressType address_type = eAddressTypeFile; + Address file_so_addr; switch (m_value_type) { default: @@ -541,11 +542,11 @@ case eValueTypeLoadAddress: if (exe_ctx == NULL) { - error.SetErrorString ("can't read memory (no execution context)"); + error.SetErrorString ("can't read load address (no execution context)"); } else if (exe_ctx->process == NULL) { - error.SetErrorString ("can't read memory (invalid process)"); + error.SetErrorString ("can't read load address (invalid process)"); } else { @@ -557,6 +558,15 @@ break; case eValueTypeFileAddress: + if (exe_ctx == NULL) + { + error.SetErrorString ("can't read file address (no execution context)"); + } + else if (exe_ctx->target == NULL) + { + error.SetErrorString ("can't read file address (invalid target)"); + } + else { // The only thing we can currently lock down to a module so that // we can resolve a file address, is a variable. @@ -564,9 +574,10 @@ if (GetVariable()) { - lldb::addr_t file_addr = m_value.ULongLong(LLDB_INVALID_ADDRESS); - if (file_addr != LLDB_INVALID_ADDRESS) + address = m_value.ULongLong(LLDB_INVALID_ADDRESS); + if (address != LLDB_INVALID_ADDRESS) { + bool resolved = false; SymbolContext var_sc; variable->CalculateSymbolContext(&var_sc); if (var_sc.module_sp) @@ -574,31 +585,46 @@ ObjectFile *objfile = var_sc.module_sp->GetObjectFile(); if (objfile) { - Address so_addr(file_addr, objfile->GetSectionList()); - address = so_addr.GetLoadAddress (exe_ctx->target); - if (address != LLDB_INVALID_ADDRESS) + Address so_addr(address, objfile->GetSectionList()); + addr_t load_address = so_addr.GetLoadAddress (exe_ctx->target); + if (load_address != LLDB_INVALID_ADDRESS) { + resolved = true; + address = load_address; address_type = eAddressTypeLoad; data.SetByteOrder(exe_ctx->target->GetArchitecture().GetByteOrder()); data.SetAddressByteSize(exe_ctx->target->GetArchitecture().GetAddressByteSize()); } else { - data.SetByteOrder(objfile->GetByteOrder()); - data.SetAddressByteSize(objfile->GetAddressByteSize()); + if (so_addr.IsSectionOffset()) + { + resolved = true; + file_so_addr = so_addr; + data.SetByteOrder(objfile->GetByteOrder()); + data.SetAddressByteSize(objfile->GetAddressByteSize()); + } } } - if (address_type == eAddressTypeFile) - error.SetErrorStringWithFormat ("%s is not loaded.\n", var_sc.module_sp->GetFileSpec().GetFilename().AsCString()); } - else + if (!resolved) { - error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'", file_addr, variable->GetName().AsCString("")); + if (var_sc.module_sp) + error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s", + address, + variable->GetName().AsCString(""), + var_sc.module_sp->GetFileSpec().GetDirectory().GetCString(), + var_sc.module_sp->GetFileSpec().GetDirectory() ? "/" : "", + var_sc.module_sp->GetFileSpec().GetFilename().GetCString()); + else + error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'", + address, + variable->GetName().AsCString("")); } } else { - error.SetErrorString ("Invalid file address."); + error.SetErrorString ("invalid file address"); } } else @@ -651,14 +677,28 @@ // The address is an address in this process, so just copy it memcpy (dst, (uint8_t*)NULL + address, byte_size); } - else if (address_type == eAddressTypeLoad) + else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile)) { - if (exe_ctx->process->ReadMemory(address, dst, byte_size, error) != byte_size) + if (file_so_addr.IsValid()) { - if (error.Success()) - error.SetErrorStringWithFormat("read %u bytes of memory from 0x%llx failed", (uint64_t)address, byte_size); - else + // We have a file address that we were able to translate into a + // section offset address so we might be able to read this from + // the object files if we don't have a live process. Lets always + // try and read from the process if we have one though since we + // want to read the actual value by setting "prefer_file_cache" + // to false. + const bool prefer_file_cache = false; + if (exe_ctx->target->ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size) + { + error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address); + } + } + else + { + if (exe_ctx->process->ReadMemory(address, dst, byte_size, error) != byte_size) + { error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address); + } } } else Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Wed Jun 29 17:09:02 2011 @@ -285,21 +285,21 @@ ValueObject::GetChildAtIndex (uint32_t idx, bool can_create) { ValueObjectSP child_sp; - if (UpdateValueIfNeeded()) + // We may need to update our value if we are dynamic + if (IsPossibleDynamicType ()) + UpdateValueIfNeeded(); + if (idx < GetNumChildren()) { - if (idx < GetNumChildren()) + // Check if we have already made the child value object? + if (can_create && m_children[idx] == NULL) { - // Check if we have already made the child value object? - if (can_create && m_children[idx] == NULL) - { - // No we haven't created the child at this index, so lets have our - // subclass do it and cache the result for quick future access. - m_children[idx] = CreateChildAtIndex (idx, false, 0); - } - - if (m_children[idx] != NULL) - return m_children[idx]->GetSP(); + // No we haven't created the child at this index, so lets have our + // subclass do it and cache the result for quick future access. + m_children[idx] = CreateChildAtIndex (idx, false, 0); } + + if (m_children[idx] != NULL) + return m_children[idx]->GetSP(); } return child_sp; } @@ -322,36 +322,37 @@ // need a vector of indexes that can get us down to the correct child ValueObjectSP child_sp; - if (UpdateValueIfNeeded()) - { - std::vector child_indexes; - clang::ASTContext *clang_ast = GetClangAST(); - void *clang_type = GetClangType(); - bool omit_empty_base_classes = true; - const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast, - clang_type, - name.GetCString(), - omit_empty_base_classes, - child_indexes); - if (num_child_indexes > 0) - { - std::vector::const_iterator pos = child_indexes.begin (); - std::vector::const_iterator end = child_indexes.end (); + // We may need to update our value if we are dynamic + if (IsPossibleDynamicType ()) + UpdateValueIfNeeded(); + + std::vector child_indexes; + clang::ASTContext *clang_ast = GetClangAST(); + void *clang_type = GetClangType(); + bool omit_empty_base_classes = true; + const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast, + clang_type, + name.GetCString(), + omit_empty_base_classes, + child_indexes); + if (num_child_indexes > 0) + { + std::vector::const_iterator pos = child_indexes.begin (); + std::vector::const_iterator end = child_indexes.end (); - child_sp = GetChildAtIndex(*pos, can_create); - for (++pos; pos != end; ++pos) + child_sp = GetChildAtIndex(*pos, can_create); + for (++pos; pos != end; ++pos) + { + if (child_sp) { - if (child_sp) - { - ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create)); - child_sp = new_child_sp; - } - else - { - child_sp.reset(); - } - + ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create)); + child_sp = new_child_sp; } + else + { + child_sp.reset(); + } + } } return child_sp; @@ -391,62 +392,59 @@ { ValueObject *valobj = NULL; - if (UpdateValueIfNeeded()) - { - bool omit_empty_base_classes = true; - - std::string child_name_str; - uint32_t child_byte_size = 0; - int32_t child_byte_offset = 0; - uint32_t child_bitfield_bit_size = 0; - uint32_t child_bitfield_bit_offset = 0; - bool child_is_base_class = false; - bool child_is_deref_of_parent = false; - - const bool transparent_pointers = synthetic_array_member == false; - clang::ASTContext *clang_ast = GetClangAST(); - clang_type_t clang_type = GetClangType(); - clang_type_t child_clang_type; - - ExecutionContext exe_ctx; - GetExecutionContextScope()->CalculateExecutionContext (exe_ctx); - - child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, - clang_ast, - GetName().GetCString(), - clang_type, - idx, - transparent_pointers, - omit_empty_base_classes, - child_name_str, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - if (child_clang_type && child_byte_size) - { - if (synthetic_index) - child_byte_offset += child_byte_size * synthetic_index; - - ConstString child_name; - if (!child_name_str.empty()) - child_name.SetCString (child_name_str.c_str()); + bool omit_empty_base_classes = true; - valobj = new ValueObjectChild (*this, - clang_ast, - child_clang_type, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - if (m_pointers_point_to_load_addrs) - valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs); - } + std::string child_name_str; + uint32_t child_byte_size = 0; + int32_t child_byte_offset = 0; + uint32_t child_bitfield_bit_size = 0; + uint32_t child_bitfield_bit_offset = 0; + bool child_is_base_class = false; + bool child_is_deref_of_parent = false; + + const bool transparent_pointers = synthetic_array_member == false; + clang::ASTContext *clang_ast = GetClangAST(); + clang_type_t clang_type = GetClangType(); + clang_type_t child_clang_type; + + ExecutionContext exe_ctx; + GetExecutionContextScope()->CalculateExecutionContext (exe_ctx); + + child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, + clang_ast, + GetName().GetCString(), + clang_type, + idx, + transparent_pointers, + omit_empty_base_classes, + child_name_str, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); + if (child_clang_type && child_byte_size) + { + if (synthetic_index) + child_byte_offset += child_byte_size * synthetic_index; + + ConstString child_name; + if (!child_name_str.empty()) + child_name.SetCString (child_name_str.c_str()); + + valobj = new ValueObjectChild (*this, + clang_ast, + child_clang_type, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); + if (m_pointers_point_to_load_addrs) + valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs); } return valobj; @@ -994,6 +992,12 @@ return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType()); } +bool +ValueObject::IsPossibleDynamicType () +{ + return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType()); +} + ValueObjectSP ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create) { Modified: lldb/trunk/source/Core/ValueObjectList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectList.cpp?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectList.cpp (original) +++ lldb/trunk/source/Core/ValueObjectList.cpp Wed Jun 29 17:09:02 2011 @@ -51,6 +51,16 @@ m_value_objects.push_back(val_obj_sp); } +void +ValueObjectList::Append (const ValueObjectList &valobj_list) +{ + std::copy(valobj_list.m_value_objects.begin(), // source begin + valobj_list.m_value_objects.end(), // source end + back_inserter(m_value_objects)); // destination + +} + + uint32_t ValueObjectList::GetSize() const { Modified: lldb/trunk/source/Core/ValueObjectVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectVariable.cpp?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectVariable.cpp (original) +++ lldb/trunk/source/Core/ValueObjectVariable.cpp Wed Jun 29 17:09:02 2011 @@ -169,7 +169,7 @@ // Make sure this type has a value before we try and read it // If we have a file address, convert it to a load address if we can. - if (value_type == Value::eValueTypeFileAddress && exe_ctx.process) + if (value_type == Value::eValueTypeFileAddress && exe_ctx.process && exe_ctx.process->IsAlive()) { lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); if (file_addr != LLDB_INVALID_ADDRESS) Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=134102&r1=134101&r2=134102&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Wed Jun 29 17:09:02 2011 @@ -4046,6 +4046,150 @@ } bool +ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type) +{ + QualType pointee_qual_type; + if (clang_type) + { + QualType qual_type (QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + bool success = false; + switch (type_class) + { + case clang::Type::Builtin: + if (cast(qual_type)->getKind() == clang::BuiltinType::ObjCId) + { + if (dynamic_pointee_type) + *dynamic_pointee_type = clang_type; + return true; + } + break; + + case clang::Type::ObjCObjectPointer: + if (dynamic_pointee_type) + *dynamic_pointee_type = cast(qual_type)->getPointeeType().getAsOpaquePtr(); + return true; + + case clang::Type::Pointer: + pointee_qual_type = cast(qual_type)->getPointeeType(); + success = true; + break; + + case clang::Type::LValueReference: + case clang::Type::RValueReference: + pointee_qual_type = cast(qual_type)->getPointeeType(); + success = true; + break; + + case clang::Type::Typedef: + return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type); + + default: + break; + } + + if (success) + { + // Check to make sure what we are pointing too is a possible dynamic C++ type + // We currently accept any "void *" (in case we have a class that has been + // watered down to an opaque pointer) and virtual C++ classes. + const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass(); + switch (pointee_type_class) + { + case clang::Type::Builtin: + switch (cast(pointee_qual_type)->getKind()) + { + case clang::BuiltinType::UnknownAny: + case clang::BuiltinType::Void: + if (dynamic_pointee_type) + *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr(); + return true; + + case clang::BuiltinType::NullPtr: + case clang::BuiltinType::Bool: + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + case clang::BuiltinType::WChar_U: + case clang::BuiltinType::Char16: + case clang::BuiltinType::Char32: + case clang::BuiltinType::UShort: + case clang::BuiltinType::UInt: + case clang::BuiltinType::ULong: + case clang::BuiltinType::ULongLong: + case clang::BuiltinType::UInt128: + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + case clang::BuiltinType::WChar_S: + case clang::BuiltinType::Short: + case clang::BuiltinType::Int: + case clang::BuiltinType::Long: + case clang::BuiltinType::LongLong: + case clang::BuiltinType::Int128: + case clang::BuiltinType::Float: + case clang::BuiltinType::Double: + case clang::BuiltinType::LongDouble: + case clang::BuiltinType::Dependent: + case clang::BuiltinType::Overload: + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCClass: + case clang::BuiltinType::ObjCSel: + case clang::BuiltinType::BoundMember: + break; + } + break; + + case clang::Type::Record: + { + CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + if (GetCompleteQualType (ast, pointee_qual_type)) + { + success = cxx_record_decl->isDynamicClass(); + } + else + { + // We failed to get the complete type, so we have to + // treat this as a void * which we might possibly be + // able to complete + success = true; + } + if (success) + { + if (dynamic_pointee_type) + *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr(); + return true; + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + { + const clang::ObjCObjectType *objc_class_type = pointee_qual_type->getAsObjCQualifiedInterfaceType(); + if (objc_class_type) + { + GetCompleteQualType (ast, pointee_qual_type); + if (dynamic_pointee_type) + *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr(); + return true; + } + } + break; + + default: + break; + } + } + } + if (dynamic_pointee_type) + *dynamic_pointee_type = NULL; + return false; +} + + +bool ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type) { QualType pointee_qual_type; From johnny.chen at apple.com Wed Jun 29 17:26:59 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 29 Jun 2011 22:26:59 -0000 Subject: [Lldb-commits] [lldb] r134107 - in /lldb/trunk/test/python_api/default-constructor: sb_module.py sb_target.py Message-ID: <20110629222659.B2B592A6C12C@llvm.org> Author: johnny Date: Wed Jun 29 17:26:59 2011 New Revision: 134107 URL: http://llvm.org/viewvc/llvm-project?rev=134107&view=rev Log: Add fuzz calls for SBModule/SBTarget.FindGlobalVariables(...). Modified: lldb/trunk/test/python_api/default-constructor/sb_module.py lldb/trunk/test/python_api/default-constructor/sb_target.py Modified: lldb/trunk/test/python_api/default-constructor/sb_module.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_module.py?rev=134107&r1=134106&r2=134107&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_module.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_module.py Wed Jun 29 17:26:59 2011 @@ -17,3 +17,4 @@ obj.GetNumSymbols() obj.GetSymbolAtIndex(sys.maxint) obj.FindFunctions("my_func", 0xffffffff, True, lldb.SBSymbolContextList()) + obj.FindGlobalVariables(lldb.SBTarget(), "my_global_var", 1) Modified: lldb/trunk/test/python_api/default-constructor/sb_target.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_target.py?rev=134107&r1=134106&r2=134107&view=diff ============================================================================== --- lldb/trunk/test/python_api/default-constructor/sb_target.py (original) +++ lldb/trunk/test/python_api/default-constructor/sb_target.py Wed Jun 29 17:26:59 2011 @@ -22,6 +22,7 @@ obj.FindModule(filespec) contextlist = lldb.SBSymbolContextList() obj.FindFunctions("the_func", 0xff, True, contextlist) + obj.FindGlobalVariables("my_global_var", 1) address = lldb.SBAddress() obj.ResolveLoadAddress(0xffff, address) obj.ResolveSymbolContextForAddress(address, 0) From granata.enrico at gmail.com Wed Jun 29 17:27:15 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Wed, 29 Jun 2011 22:27:15 -0000 Subject: [Lldb-commits] [lldb] r134108 - in /lldb/trunk: include/lldb/ include/lldb/Core/ include/lldb/Symbol/ lldb.xcodeproj/ lldb.xcodeproj/xcshareddata/xcschemes/ source/Commands/ source/Core/ source/Symbol/ test/functionalities/data-formatter/ Message-ID: <20110629222715.E35632A6C12C@llvm.org> Author: enrico Date: Wed Jun 29 17:27:15 2011 New Revision: 134108 URL: http://llvm.org/viewvc/llvm-project?rev=134108&view=rev Log: This commit adds a new top subcommand "summary" to command type named "type". Currently this command implements three commands: type summary add [ ...] type summary delete [ ...] type summary list [ [] ...] type summary clear This allows you to specify the default format that will be used to display summaries for variables, shown when you use "frame variable" or "expression", or the SBValue classes. Examples: type summary add "x = ${var.x}" Point type summary list type summary add --one-liner SimpleType Modified: lldb/trunk/include/lldb/Core/Debugger.h lldb/trunk/include/lldb/Core/FormatManager.h lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/include/lldb/Symbol/ClangASTType.h lldb/trunk/include/lldb/lldb-forward-rtti.h lldb/trunk/include/lldb/lldb-forward.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme lldb/trunk/source/Commands/CommandObjectType.cpp lldb/trunk/source/Core/Debugger.cpp lldb/trunk/source/Core/FormatManager.cpp lldb/trunk/source/Core/ValueObject.cpp lldb/trunk/source/Symbol/ClangASTType.cpp lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py lldb/trunk/test/functionalities/data-formatter/main.cpp Modified: lldb/trunk/include/lldb/Core/Debugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Debugger.h (original) +++ lldb/trunk/include/lldb/Core/Debugger.h Wed Jun 29 17:27:15 2011 @@ -415,7 +415,8 @@ const ExecutionContext *exe_ctx, const Address *addr, Stream &s, - const char **end); + const char **end, + ValueObject* vobj = NULL); void @@ -473,18 +474,50 @@ public: - static bool - GetFormatForType (const ConstString &type, lldb::Format& format, bool& cascade); - - static void - AddFormatForType (const ConstString &type, lldb::Format format, bool cascade); + class ValueFormats + { + public: + static bool + Get(ValueObject& vobj, ValueFormat::SharedPointer &entry); + + static void + Add(const ConstString &type, const ValueFormat::SharedPointer &entry); + + static bool + Delete(const ConstString &type); + + static void + Clear(); + + static void + LoopThrough(FormatManager::ValueCallback callback, void* callback_baton); + + static uint32_t GetCurrentRevision(); + }; - static bool - DeleteFormatForType (const ConstString &type); + class SummaryFormats + { + public: + + static bool + Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry); + + static void + Add(const ConstString &type, const SummaryFormat::SharedPointer &entry); + + static bool + Delete(const ConstString &type); + + static void + Clear(); + + static void + LoopThrough(FormatManager::SummaryCallback callback, void* callback_baton); + + static uint32_t + GetCurrentRevision(); + }; - static void - LoopThroughFormatList (FormatManager::Callback callback, - void* callback_baton); }; } // namespace lldb_private Modified: lldb/trunk/include/lldb/Core/FormatManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/FormatManager.h (original) +++ lldb/trunk/include/lldb/Core/FormatManager.h Wed Jun 29 17:27:15 2011 @@ -40,42 +40,288 @@ #include "lldb/Core/Communication.h" #include "lldb/Core/InputReaderStack.h" #include "lldb/Core/Listener.h" -#include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/SourceManager.h" #include "lldb/Core/UserID.h" #include "lldb/Core/UserSettingsController.h" +#include "lldb/Core/ValueObject.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" #include "lldb/Target/TargetList.h" -namespace lldb_private { +#include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" +namespace lldb_private { -class FormatManager +class IFormatChangeListener { public: + virtual void + Changed() = 0; + + virtual + ~IFormatChangeListener() {} + +}; - typedef bool(*Callback)(void*, const char*, lldb::Format, bool); +struct SummaryFormat +{ + std::string m_format; + bool m_dont_show_children; + bool m_dont_show_value; + bool m_show_members_oneliner; + bool m_cascades; + SummaryFormat(std::string f = "", bool c = false, bool nochildren = true, bool novalue = true, bool oneliner = false) : + m_format(f), + m_dont_show_children(nochildren), + m_dont_show_value(novalue), + m_show_members_oneliner(oneliner), + m_cascades(c) + { + } + + bool + DoesPrintChildren() const + { + return !m_dont_show_children; + } + + bool + DoesPrintValue() const + { + return !m_dont_show_value; + } + + bool + IsOneliner() const + { + return m_show_members_oneliner; + } + + typedef lldb::SharedPtr::Type SharedPointer; + +}; - FormatManager() : - m_format_map(FormatMap()), - m_format_map_mutex(Mutex::eMutexTypeRecursive) +struct ValueFormat +{ + lldb::Format m_format; + bool m_cascades; + ValueFormat (lldb::Format f = lldb::eFormatInvalid, bool c = false) : + m_format (f), + m_cascades (c) + { + } + + typedef lldb::SharedPtr::Type SharedPointer; + + ~ValueFormat() { } + +}; + +template +class FormatNavigator +{ +public: + typedef typename MapType::iterator MapIterator; + typedef typename MapType::key_type MapKeyType; + typedef typename MapType::mapped_type MapValueType; + + FormatNavigator(IFormatChangeListener* lst = NULL) : + m_map_mutex(Mutex::eMutexTypeRecursive), + m_map(MapType()), + listener(lst) + { + } + bool - GetFormatForType (const ConstString &type, lldb::Format& format, bool& cascade); - + Get(ValueObject& vobj, MapValueType& entry) + { + Mutex::Locker(m_map_mutex); + clang::QualType type = clang::QualType::getFromOpaquePtr(vobj.GetClangType()); + bool ret = Get(vobj, type, entry); + if(ret) + entry = MapValueType(entry); + else + entry = MapValueType(); + return ret; + } + void - AddFormatForType (const ConstString &type, lldb::Format format, bool cascade); - + Add(const MapKeyType &type, const MapValueType& entry) + { + Mutex::Locker(m_map_mutex); + m_map[type] = MapValueType(entry); + if(listener) + listener->Changed(); + } + bool - DeleteFormatForType (const ConstString &type); - + Delete(const MapKeyType& type) + { + Mutex::Locker(m_map_mutex); + MapIterator iter = m_map.find(type); + if (iter == m_map.end()) + return false; + m_map.erase(type); + if(listener) + listener->Changed(); + return true; + } + + void + Clear() + { + Mutex::Locker(m_map_mutex); + m_map.clear(); + if(listener) + listener->Changed(); + } + void - LoopThroughFormatList (Callback cback, void* param); + LoopThrough(CallbackType callback, void* param) + { + if (callback) + { + Mutex::Locker(m_map_mutex); + MapIterator pos, end = m_map.end(); + for (pos = m_map.begin(); pos != end; pos++) + { + MapKeyType type = pos->first; + if(!callback(param, type, MapValueType(pos->second))) + break; + } + } + } + + ~FormatNavigator() + { + } + +private: + + Mutex m_map_mutex; + MapType m_map; + IFormatChangeListener* listener; + + DISALLOW_COPY_AND_ASSIGN(FormatNavigator); + + bool + Get(const MapKeyType &type, MapValueType& entry) + { + Mutex::Locker(m_map_mutex); + MapIterator iter = m_map.find(type); + if (iter == m_map.end()) + return false; + entry = iter->second; + return true; + } + + bool Get(ValueObject& vobj, + const clang::QualType& q_type, + MapValueType& entry) + { + if (q_type.isNull()) + return false; + clang::QualType type = q_type.getUnqualifiedType(); + type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict(); + ConstString name(type.getAsString().c_str()); + //printf("trying to get format for VO name %s of type %s\n",vobj.GetName().AsCString(),name.AsCString()); + if (Get(name.GetCString(), entry)) + return true; + // look for a "base type", whatever that means + const clang::Type* typePtr = type.getTypePtrOrNull(); + if (!typePtr) + return false; + if (typePtr->isReferenceType()) + return Get(vobj,type.getNonReferenceType(),entry); + // for C++ classes, navigate up the hierarchy + if (typePtr->isRecordType()) + { + clang::CXXRecordDecl* record = typePtr->getAsCXXRecordDecl(); + if (record) + { + if (!record->hasDefinition()) + // dummy call to do the complete + ClangASTContext::GetNumChildren(vobj.GetClangAST(), vobj.GetClangType(), false); + clang::IdentifierInfo *info = record->getIdentifier(); + if (info) { + // this is the class name, plain and simple + ConstString id_info(info->getName().str().c_str()); + if (Get(id_info.GetCString(), entry)) + return true; + } + if (record->hasDefinition()) + { + clang::CXXRecordDecl::base_class_iterator pos,end; + if( record->getNumBases() > 0) + { + end = record->bases_end(); + for (pos = record->bases_begin(); pos != end; pos++) + { + if((Get(vobj, pos->getType(), entry)) && entry->m_cascades) + return true; // if it does not cascade, just move on to other base classes which might + } + } + if (record->getNumVBases() > 0) + { + end = record->vbases_end(); + for (pos = record->vbases_begin(); pos != end; pos++) + { + if((Get(vobj, pos->getType(), entry)) && entry->m_cascades) + return true; + } + } + } + } + } + // try to strip typedef chains + const clang::TypedefType* type_tdef = type->getAs(); + if (type_tdef) + if ((Get(vobj, type_tdef->getDecl()->getUnderlyingType(), entry)) && entry->m_cascades) + return true; + return false; + } + +}; + +class FormatManager : public IFormatChangeListener +{ + +public: + + typedef bool(*ValueCallback)(void*, const char*, const ValueFormat::SharedPointer&); + typedef bool(*SummaryCallback)(void*, const char*, const SummaryFormat::SharedPointer&); + +private: + + typedef std::map ValueMap; + typedef std::map SummaryMap; + + typedef FormatNavigator ValueNavigator; + typedef FormatNavigator SummaryNavigator; + + ValueNavigator m_value_nav; + SummaryNavigator m_summary_nav; + + uint32_t m_last_revision; + +public: + + FormatManager() : + m_value_nav(this), + m_summary_nav(this), + m_last_revision(0) + { + } + + ValueNavigator& Value() { return m_value_nav; } + SummaryNavigator& Summary() { return m_summary_nav; } + static bool GetFormatFromCString (const char *format_cstr, bool partial_match_ok, @@ -86,24 +332,23 @@ static const char * GetFormatAsCString (lldb::Format format); - -private: - struct Entry + + void + Changed() { - lldb::Format format; - bool cascades; - Entry (lldb::Format f = lldb::eFormatInvalid, bool c = false) : - format (f), - cascades (c) - { - } - }; + __sync_add_and_fetch(&m_last_revision, +1); + } + + uint32_t + GetCurrentRevision() const + { + return m_last_revision; + } - typedef std::map FormatMap; - typedef FormatMap::iterator FormatIterator; + ~FormatManager() + { + } - FormatMap m_format_map; - Mutex m_format_map_mutex; }; } // namespace lldb_private Modified: lldb/trunk/include/lldb/Core/ValueObject.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObject.h (original) +++ lldb/trunk/include/lldb/Core/ValueObject.h Wed Jun 29 17:27:15 2011 @@ -64,6 +64,12 @@ class ValueObject : public UserID { public: + + enum GetExpressionPathFormat + { + eDereferencePointers = 1, + eHonorPointers, + }; class EvaluationPoint { @@ -262,8 +268,8 @@ GetBaseClassPath (Stream &s); virtual void - GetExpressionPath (Stream &s, bool qualify_cxx_base_classes); - + GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat = eDereferencePointers); + virtual bool IsInScope () { @@ -347,6 +353,9 @@ bool UpdateValueIfNeeded (); + + void + UpdateFormatsIfNeeded(); DataExtractor & GetDataExtractor (); @@ -508,7 +517,9 @@ ValueObject *m_deref_valobj; lldb::Format m_format; - lldb::Format m_last_format; + uint32_t m_last_format_mgr_revision; + lldb::SummaryFormatSP m_last_summary_format; + lldb::ValueFormatSP m_last_value_format; bool m_value_is_valid:1, m_value_did_change:1, m_children_count_valid:1, Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Wed Jun 29 17:27:15 2011 @@ -182,6 +182,13 @@ static lldb::Format GetFormat (lldb::clang_type_t opaque_clang_qual_type); + + uint32_t + GetTypeByteSize(); + + static uint32_t + GetTypeByteSize(clang::ASTContext *ast_context, + lldb::clang_type_t opaque_clang_qual_type); bool GetValueAsScalar (const DataExtractor &data, Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward-rtti.h (original) +++ lldb/trunk/include/lldb/lldb-forward-rtti.h Wed Jun 29 17:27:15 2011 @@ -60,6 +60,7 @@ typedef SharedPtr::Type StopInfoSP; typedef SharedPtr::Type StoppointLocationSP; typedef SharedPtr::Type StreamSP; + typedef SharedPtr::Type SummaryFormatSP; typedef SharedPtr::Type SymbolFileSP; typedef SharedPtr::Type SymbolContextSpecifierSP; typedef SharedPtr::Type TargetSP; @@ -72,6 +73,7 @@ typedef SharedPtr::Type UnwindPlanSP; typedef SharedPtr::Type ValueObjectSP; typedef SharedPtr::Type ValueSP; + typedef SharedPtr::Type ValueFormatSP; typedef SharedPtr::Type ValueListSP; typedef SharedPtr::Type VariableSP; typedef SharedPtr::Type VariableListSP; Modified: lldb/trunk/include/lldb/lldb-forward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward.h (original) +++ lldb/trunk/include/lldb/lldb-forward.h Wed Jun 29 17:27:15 2011 @@ -76,6 +76,7 @@ class FileSpec; class FileSpecList; class Flags; +class FormatManager; class FuncUnwinders; class Function; class FunctionInfo; @@ -130,6 +131,7 @@ class StreamFile; class StreamString; class StringList; +class SummaryFormat; class Symbol; class SymbolContext; class SymbolContextList; @@ -164,6 +166,7 @@ class UserSettingsController; class VMRange; class Value; +class ValueFormat; class ValueList; class ValueObject; class ValueObjectList; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed Jun 29 17:27:15 2011 @@ -924,7 +924,7 @@ 26BC7E9610F1B85900F91463 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Timer.cpp; path = source/Core/Timer.cpp; sourceTree = ""; }; 26BC7E9810F1B85900F91463 /* UserID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UserID.cpp; path = source/Core/UserID.cpp; sourceTree = ""; }; 26BC7E9910F1B85900F91463 /* Value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Value.cpp; path = source/Core/Value.cpp; sourceTree = ""; }; - 26BC7E9A10F1B85900F91463 /* ValueObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObject.cpp; path = source/Core/ValueObject.cpp; sourceTree = ""; }; + 26BC7E9A10F1B85900F91463 /* ValueObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; name = ValueObject.cpp; path = source/Core/ValueObject.cpp; sourceTree = ""; }; 26BC7E9B10F1B85900F91463 /* ValueObjectChild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectChild.cpp; path = source/Core/ValueObjectChild.cpp; sourceTree = ""; }; 26BC7E9C10F1B85900F91463 /* ValueObjectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectList.cpp; path = source/Core/ValueObjectList.cpp; sourceTree = ""; }; 26BC7E9D10F1B85900F91463 /* ValueObjectVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectVariable.cpp; path = source/Core/ValueObjectVariable.cpp; sourceTree = ""; }; Modified: lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme (original) +++ lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme Wed Jun 29 17:27:15 2011 @@ -1,6 +1,6 @@ + version = "1.8"> @@ -77,7 +77,7 @@ launchStyle = "0" useCustomWorkingDirectory = "NO" customWorkingDirectory = "/Volumes/work/gclayton/Documents/devb/attach" - buildConfiguration = "Release" + buildConfiguration = "Debug" ignoresPersistentStateOnLaunch = "YES" enablesOpenGLESFrameCapture = "YES"> Modified: lldb/trunk/source/Commands/CommandObjectType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectType.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectType.cpp Wed Jun 29 17:27:15 2011 @@ -25,10 +25,10 @@ using namespace lldb_private; //------------------------------------------------------------------------- -// CommandObjectTypeAdd +// CommandObjectTypeFormatAdd //------------------------------------------------------------------------- -class CommandObjectTypeAdd : public CommandObject +class CommandObjectTypeFormatAdd : public CommandObject { private: @@ -97,7 +97,7 @@ } public: - CommandObjectTypeAdd (CommandInterpreter &interpreter) : + CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) : CommandObject (interpreter, "type format add", "Add a new formatting style for a type.", @@ -121,7 +121,7 @@ m_arguments.push_back (type_arg); } - ~CommandObjectTypeAdd () + ~CommandObjectTypeFormatAdd () { } @@ -138,9 +138,22 @@ } const char* format_cstr = command.GetArgumentAtIndex(0); + + if (!format_cstr || !format_cstr[0]) + { + result.AppendError("empty format strings not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + lldb::Format format; - Error error = Args::StringToFormat(format_cstr, format, NULL); + Error error; + error = Args::StringToFormat(format_cstr, format, NULL); + ValueFormat::SharedPointer entry; + + entry.reset(new ValueFormat(format,m_options.m_cascade)); + if (error.Fail()) { result.AppendError(error.AsCString()); @@ -153,7 +166,14 @@ for(int i = 1; i < argc; i++) { const char* typeA = command.GetArgumentAtIndex(i); ConstString typeCS(typeA); - Debugger::AddFormatForType(typeCS, format, m_options.m_cascade); + if (typeCS) + Debugger::ValueFormats::Add(typeCS, entry); + else + { + result.AppendError("empty typenames not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } } result.SetStatus(eReturnStatusSuccessFinishNoResult); @@ -163,7 +183,7 @@ }; OptionDefinition -CommandObjectTypeAdd::CommandOptions::g_option_table[] = +CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] = { { LLDB_OPT_SET_ALL, false, "cascade", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } @@ -171,13 +191,13 @@ //------------------------------------------------------------------------- -// CommandObjectTypeDelete +// CommandObjectTypeFormatDelete //------------------------------------------------------------------------- -class CommandObjectTypeDelete : public CommandObject +class CommandObjectTypeFormatDelete : public CommandObject { public: - CommandObjectTypeDelete (CommandInterpreter &interpreter) : + CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) : CommandObject (interpreter, "type format delete", "Delete an existing formatting style for a type.", @@ -185,17 +205,17 @@ { CommandArgumentEntry type_arg; CommandArgumentData type_style_arg; - + type_style_arg.arg_type = eArgTypeName; type_style_arg.arg_repetition = eArgRepeatPlain; type_arg.push_back (type_style_arg); m_arguments.push_back (type_arg); - + } - ~CommandObjectTypeDelete () + ~CommandObjectTypeFormatDelete () { } @@ -214,7 +234,15 @@ const char* typeA = command.GetArgumentAtIndex(0); ConstString typeCS(typeA); - if (Debugger::DeleteFormatForType(typeCS)) + if(!typeCS) + { + result.AppendError("empty typenames not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + + if (Debugger::ValueFormats::Delete(typeCS)) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); @@ -225,31 +253,60 @@ result.SetStatus(eReturnStatusFailed); return false; } + + } + +}; + +//------------------------------------------------------------------------- +// CommandObjectTypeFormatClear +//------------------------------------------------------------------------- +class CommandObjectTypeFormatClear : public CommandObject +{ +public: + CommandObjectTypeFormatClear (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type format clear", + "Delete all existing format styles.", + NULL) + { + } + + ~CommandObjectTypeFormatClear () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + Debugger::ValueFormats::Clear(); + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); } }; //------------------------------------------------------------------------- -// CommandObjectTypeList +// CommandObjectTypeFormatList //------------------------------------------------------------------------- -bool CommandObjectTypeList_LoopCallback(void* pt2self, const char* type, lldb::Format format, bool cascade); +bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, const char* type, const ValueFormat::SharedPointer& entry); -class CommandObjectTypeList; +class CommandObjectTypeFormatList; -struct CommandObjectTypeList_LoopCallbackParam { - CommandObjectTypeList* self; +struct CommandObjectTypeFormatList_LoopCallbackParam { + CommandObjectTypeFormatList* self; CommandReturnObject* result; RegularExpression* regex; - CommandObjectTypeList_LoopCallbackParam(CommandObjectTypeList* S, CommandReturnObject* R, + CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R, RegularExpression* X = NULL) : self(S), result(R), regex(X) {} }; -class CommandObjectTypeList : public CommandObject +class CommandObjectTypeFormatList : public CommandObject { public: - CommandObjectTypeList (CommandInterpreter &interpreter) : + CommandObjectTypeFormatList (CommandInterpreter &interpreter) : CommandObject (interpreter, "type format list", "Show a list of current formatting styles.", @@ -266,7 +323,7 @@ m_arguments.push_back (type_arg); } - ~CommandObjectTypeList () + ~CommandObjectTypeFormatList () { } @@ -275,16 +332,16 @@ { const size_t argc = command.GetArgumentCount(); - CommandObjectTypeList_LoopCallbackParam *param; + CommandObjectTypeFormatList_LoopCallbackParam *param; if (argc == 1) { RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); regex->Compile(command.GetArgumentAtIndex(0)); - param = new CommandObjectTypeList_LoopCallbackParam(this,&result,regex); + param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex); } else - param = new CommandObjectTypeList_LoopCallbackParam(this,&result); - Debugger::LoopThroughFormatList(CommandObjectTypeList_LoopCallback, param); + param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result); + Debugger::ValueFormats::LoopThrough(CommandObjectTypeFormatList_LoopCallback, param); delete param; result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); @@ -294,45 +351,438 @@ bool LoopCallback (const char* type, - lldb::Format format, - bool cascade, + const ValueFormat::SharedPointer& entry, RegularExpression* regex, CommandReturnObject *result) { if (regex == NULL || regex->Execute(type)) { - result->GetOutputStream().Printf ("%s: %s\n", type, FormatManager::GetFormatAsCString (format)); + result->GetOutputStream().Printf ("%s: %s%s\n", type, + FormatManager::GetFormatAsCString (entry->m_format), + entry->m_cascades ? "" : " (not cascading)"); } return true; } - friend bool CommandObjectTypeList_LoopCallback(void* pt2self, const char* type, lldb::Format format, bool cascade); + friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, const char* type, const ValueFormat::SharedPointer& entry); }; bool -CommandObjectTypeList_LoopCallback ( +CommandObjectTypeFormatList_LoopCallback ( void* pt2self, const char* type, - lldb::Format format, - bool cascade) + const ValueFormat::SharedPointer& entry) { - CommandObjectTypeList_LoopCallbackParam* param = (CommandObjectTypeList_LoopCallbackParam*)pt2self; - return param->self->LoopCallback(type, format, cascade, param->regex, param->result); + CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self; + return param->self->LoopCallback(type, entry, param->regex, param->result); } + + + +//------------------------------------------------------------------------- +// CommandObjectTypeSummaryAdd +//------------------------------------------------------------------------- + +class CommandObjectTypeSummaryAdd : public CommandObject +{ + +private: + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter) + { + } + + virtual + ~CommandOptions (){} + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + bool success; + + switch (short_option) + { + case 'c': + m_cascade = Args::StringToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); + break; + case 'h': + m_no_children = !Args::StringToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid value for nochildren: %s.\n", option_arg); + break; + case 'v': + m_no_value = !Args::StringToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid value for novalue: %s.\n", option_arg); + break; + case 'o': + m_one_liner = Args::StringToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid value for oneliner: %s.\n", option_arg); + break; + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_cascade = true; + m_no_children = true; + m_no_value = false; + m_one_liner = false; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + + bool m_cascade; + bool m_no_children; + bool m_no_value; + bool m_one_liner; + }; + + CommandOptions m_options; + + virtual Options * + GetOptions () + { + return &m_options; + } + +public: + CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type summary add", + "Add a new summary style for a type.", + NULL), m_options (interpreter) + { + CommandArgumentEntry format_arg; + CommandArgumentData format_style_arg; + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + format_style_arg.arg_type = eArgTypeFormat; + format_style_arg.arg_repetition = eArgRepeatPlain; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatPlus; + + format_arg.push_back (format_style_arg); + type_arg.push_back (type_style_arg); + + m_arguments.push_back (format_arg); + m_arguments.push_back (type_arg); + } + + ~CommandObjectTypeSummaryAdd () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + + // we support just one custom syntax: type summary add -o yes typeName + // anything else, must take the usual route + // e.g. type summary add -o yes "" type1 type2 ... typeN + + bool isValidShortcut = m_options.m_one_liner && (argc == 1); + bool isValid = (argc >= 2); + + if (!isValidShortcut && !isValid) + { + result.AppendErrorWithFormat ("%s takes two or more args.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + const char* format_cstr = (isValidShortcut ? "" : command.GetArgumentAtIndex(0)); + + if ( (!format_cstr || !format_cstr[0]) && !m_options.m_one_liner ) + { + result.AppendError("empty summary strings not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + Error error; + + SummaryFormat::SharedPointer entry(new SummaryFormat(format_cstr,m_options.m_cascade, + m_options.m_no_children,m_options.m_no_value, + m_options.m_one_liner)); + + if (error.Fail()) + { + result.AppendError(error.AsCString()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + // now I have a valid format, let's add it to every type + + for(int i = (isValidShortcut ? 0 : 1); i < argc; i++) { + const char* typeA = command.GetArgumentAtIndex(i); + ConstString typeCS(typeA); + if (typeCS) + Debugger::SummaryFormats::Add(typeCS, entry); + else + { + result.AppendError("empty typenames not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); + } + +}; + +OptionDefinition +CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_ALL, false, "cascade", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, + { LLDB_OPT_SET_ALL, false, "show-children", 'h', required_argument, NULL, 0, eArgTypeBoolean, "If true, print children."}, + { LLDB_OPT_SET_ALL, false, "show-value", 'v', required_argument, NULL, 0, eArgTypeBoolean, "If true, print value."}, + { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, 0, eArgTypeBoolean, "If true, just print a one-line preformatted summary."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + + +//------------------------------------------------------------------------- +// CommandObjectTypeSummaryDelete +//------------------------------------------------------------------------- + +class CommandObjectTypeSummaryDelete : public CommandObject +{ +public: + CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type summary delete", + "Delete an existing summary style for a type.", + NULL) + { + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatPlain; + + type_arg.push_back (type_style_arg); + + m_arguments.push_back (type_arg); + + } + + ~CommandObjectTypeSummaryDelete () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + + if (argc != 1) + { + result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + const char* typeA = command.GetArgumentAtIndex(0); + ConstString typeCS(typeA); + + if(!typeCS) + { + result.AppendError("empty typenames not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + + if (Debugger::SummaryFormats::Delete(typeCS)) + { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); + } + else + { + result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA); + result.SetStatus(eReturnStatusFailed); + return false; + } + + } + +}; + +//------------------------------------------------------------------------- +// CommandObjectTypeSummaryClear +//------------------------------------------------------------------------- + +class CommandObjectTypeSummaryClear : public CommandObject +{ +public: + CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type summary clear", + "Delete all existing summary styles.", + NULL) + { + } + + ~CommandObjectTypeSummaryClear () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + Debugger::SummaryFormats::Clear(); + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } + +}; + +//------------------------------------------------------------------------- +// CommandObjectTypeSummaryList +//------------------------------------------------------------------------- + +bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry); + +class CommandObjectTypeSummaryList; + +struct CommandObjectTypeSummaryList_LoopCallbackParam { + CommandObjectTypeSummaryList* self; + CommandReturnObject* result; + RegularExpression* regex; + CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R, + RegularExpression* X = NULL) : self(S), result(R), regex(X) {} +}; + +class CommandObjectTypeSummaryList : public CommandObject +{ +public: + CommandObjectTypeSummaryList (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type summary list", + "Show a list of current summary styles.", + NULL) + { + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatOptional; + + type_arg.push_back (type_style_arg); + + m_arguments.push_back (type_arg); + } + + ~CommandObjectTypeSummaryList () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + + CommandObjectTypeSummaryList_LoopCallbackParam *param; + + if (argc == 1) { + RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); + regex->Compile(command.GetArgumentAtIndex(0)); + param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex); + } + else + param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result); + Debugger::SummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param); + delete param; + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } + +private: + + bool + LoopCallback (const char* type, + const SummaryFormat::SharedPointer& entry, + RegularExpression* regex, + CommandReturnObject *result) + { + if (regex == NULL || regex->Execute(type)) + { + result->GetOutputStream().Printf ("%s: `%s`%s%s%s%s\n", type, + entry->m_format.c_str(), + entry->m_cascades ? "" : " (not cascading)", + entry->m_dont_show_children ? "" : " (show children)", + entry->m_dont_show_value ? "" : " (show value)", + entry->m_show_members_oneliner ? " (one-line printout)" : ""); + } + return true; + } + + friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry); + +}; + +bool +CommandObjectTypeSummaryList_LoopCallback ( + void* pt2self, + const char* type, + const SummaryFormat::SharedPointer& entry) +{ + CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; + return param->self->LoopCallback(type, entry, param->regex, param->result); +} + + + + + class CommandObjectTypeFormat : public CommandObjectMultiword { public: CommandObjectTypeFormat (CommandInterpreter &interpreter) : CommandObjectMultiword (interpreter, "type format", - "A set of commands for editing variable display options", + "A set of commands for editing variable value display options", "type format [] ") { - LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeAdd (interpreter))); - LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeDelete (interpreter))); - LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeList (interpreter))); + LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter))); + LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter))); + LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter))); + LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter))); } @@ -341,6 +791,27 @@ } }; +class CommandObjectTypeSummary : public CommandObjectMultiword +{ +public: + CommandObjectTypeSummary (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "type format", + "A set of commands for editing variable summary display options", + "type summary [] ") + { + LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter))); + LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter))); + LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter))); + LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter))); + } + + + ~CommandObjectTypeSummary () + { + } +}; + //------------------------------------------------------------------------- // CommandObjectType //------------------------------------------------------------------------- @@ -352,6 +823,7 @@ "type []") { LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter))); + LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter))); } Modified: lldb/trunk/source/Core/Debugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/source/Core/Debugger.cpp (original) +++ lldb/trunk/source/Core/Debugger.cpp Wed Jun 29 17:27:15 2011 @@ -11,6 +11,9 @@ #include +#include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" + #include "lldb/lldb-private.h" #include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Core/FormatManager.h" @@ -20,6 +23,7 @@ #include "lldb/Core/StreamAsynchronousIO.h" #include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" +#include "lldb/Core/ValueObject.h" #include "lldb/Host/Terminal.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Target/TargetList.h" @@ -698,13 +702,20 @@ const ExecutionContext *exe_ctx, const Address *addr, Stream &s, - const char **end + const char **end, + ValueObject* vobj ) { + ValueObject* realvobj = NULL; // makes it super-easy to parse pointers bool success = true; const char *p; for (p = format; *p != '\0'; ++p) { + if(realvobj) + { + vobj = realvobj; + realvobj = NULL; + } size_t non_special_chars = ::strcspn (p, "${}\\"); if (non_special_chars > 0) { @@ -732,7 +743,7 @@ ++p; // Skip the '{' - if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p)) + if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p, vobj)) { // The stream had all it needed s.Write(sub_strm.GetData(), sub_strm.GetSize()); @@ -777,6 +788,284 @@ bool var_success = false; switch (var_name_begin[0]) { + case '*': + { + if (!vobj) break; + var_name_begin++; + lldb::clang_type_t pointer_clang_type = vobj->GetClangType(); + clang_type_t elem_or_pointee_clang_type; + const Flags type_flags (ClangASTContext::GetTypeInfo (pointer_clang_type, + vobj->GetClangAST(), + &elem_or_pointee_clang_type)); + if (type_flags.Test (ClangASTContext::eTypeIsPointer)) + { + if (ClangASTContext::IsCharType (elem_or_pointee_clang_type)) + { + StreamString sstr; + ExecutionContextScope *exe_scope = vobj->GetExecutionContextScope(); + Process *process = exe_scope->CalculateProcess(); + if(!process) break; + lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS; + AddressType cstr_address_type = eAddressTypeInvalid; + DataExtractor data; + size_t bytes_read = 0; + std::vector data_buffer; + Error error; + cstr_address = vobj->GetPointerValue (cstr_address_type, true); + { + const size_t k_max_buf_size = 256; + data_buffer.resize (k_max_buf_size + 1); + // NULL terminate in case we don't get the entire C string + data_buffer.back() = '\0'; + + sstr << '"'; + + data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder()); + while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0) + { + size_t len = strlen(&data_buffer.front()); + if (len == 0) + break; + if (len > bytes_read) + len = bytes_read; + + data.Dump (&sstr, + 0, // Start offset in "data" + eFormatCharArray, // Print as characters + 1, // Size of item (1 byte for a char!) + len, // How many bytes to print? + UINT32_MAX, // num per line + LLDB_INVALID_ADDRESS,// base address + 0, // bitfield bit size + 0); // bitfield bit offset + + if (len < k_max_buf_size) + break; + cstr_address += k_max_buf_size; + } + sstr << '"'; + s.PutCString(sstr.GetData()); + var_success = true; + break; + } + } + else /*if (ClangASTContext::IsAggregateType (elem_or_pointee_clang_type)) or this is some other pointer type*/ + { + Error error; + realvobj = vobj; + vobj = vobj->Dereference(error).get(); + if(!vobj || error.Fail()) + break; + } + } + else + break; + } + case 'v': + { + const char* targetvalue; + bool use_summary = false; + ValueObject* target; + lldb::Format custom_format = eFormatInvalid; + int bitfield_lower = -1; + int bitfield_higher = -1; + if (!vobj) break; + // simplest case ${var}, just print vobj's value + if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) + target = vobj; + else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) + { + // this is a variable with some custom format applied to it + const char* var_name_final; + target = vobj; + { + const char* percent_position = ::strchr(var_name_begin,'%'); // TODO: make this a constant + //if(!percent_position || percent_position > var_name_end) + // var_name_final = var_name_end; + //else + //{ + var_name_final = percent_position; + char* format_name = new char[var_name_end-var_name_final]; format_name[var_name_end-var_name_final-1] = '\0'; + memcpy(format_name, var_name_final+1, var_name_end-var_name_final-1); + FormatManager::GetFormatFromCString(format_name, + true, + custom_format); // if this fails, custom_format is reset to invalid + delete format_name; + //} + } + } + else if (::strncmp(var_name_begin,"var[",strlen("var[")) == 0) + { + // this is a bitfield variable + const char *var_name_final; + target = vobj; + + { + const char* percent_position = ::strchr(var_name_begin,'%'); + if(!percent_position || percent_position > var_name_end) + var_name_final = var_name_end; + else + { + var_name_final = percent_position; + char* format_name = new char[var_name_end-var_name_final]; format_name[var_name_end-var_name_final-1] = '\0'; + memcpy(format_name, var_name_final+1, var_name_end-var_name_final-1); + FormatManager::GetFormatFromCString(format_name, + true, + custom_format); // if this fails, custom_format is reset to invalid + delete format_name; + } + } + + { + // code here might be simpler than in the case below + const char* open_bracket_position = ::strchr(var_name_begin,'['); + if(open_bracket_position && open_bracket_position < var_name_final) + { + char* separator_position = ::strchr(open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield + char* close_bracket_position = ::strchr(open_bracket_position,']'); + // as usual, we assume that [] will come before % + //printf("trying to expand a []\n"); + var_name_final = open_bracket_position; + if (separator_position == NULL || separator_position > var_name_end) + { + char *end = NULL; + bitfield_lower = ::strtoul (open_bracket_position+1, &end, 0); + bitfield_higher = bitfield_lower; + //printf("got to read low=%d high same\n",bitfield_lower); + } + else if(close_bracket_position && close_bracket_position < var_name_end) + { + char *end = NULL; + bitfield_lower = ::strtoul (open_bracket_position+1, &end, 0); + bitfield_higher = ::strtoul (separator_position+1, &end, 0); + //printf("got to read low=%d high=%d\n",bitfield_lower,bitfield_higher); + } + else + break; + if(bitfield_lower > bitfield_higher) + break; + } + } + } + // this is ${var.something} or multiple .something nested + else if (::strncmp (var_name_begin, "var", strlen("var")) == 0) + { + // check for custom format string + + // we need this because we might have ${var.something%format}. in this case var_name_end + // still points to the closing }, but we must extract the variable name only up to + // before the %. var_name_final will point to that % sign position + const char* var_name_final; + + { + const char* percent_position = ::strchr(var_name_begin,'%'); + if(!percent_position || percent_position > var_name_end) + var_name_final = var_name_end; + else + { + var_name_final = percent_position; + char* format_name = new char[var_name_end-var_name_final]; format_name[var_name_end-var_name_final-1] = '\0'; + memcpy(format_name, var_name_final+1, var_name_end-var_name_final-1); + FormatManager::GetFormatFromCString(format_name, + true, + custom_format); // if this fails, custom_format is reset to invalid + delete format_name; + } + } + + { + const char* open_bracket_position = ::strchr(var_name_begin,'['); + if(open_bracket_position && open_bracket_position < var_name_final) + { + char* separator_position = ::strchr(open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield + char* close_bracket_position = ::strchr(open_bracket_position,']'); + // as usual, we assume that [] will come before % + //printf("trying to expand a []\n"); + var_name_final = open_bracket_position; + if (separator_position == NULL || separator_position > var_name_end) + { + char *end = NULL; + bitfield_lower = ::strtoul (open_bracket_position+1, &end, 0); + bitfield_higher = bitfield_lower; + //printf("got to read low=%d high same\n",bitfield_lower); + } + else if(close_bracket_position && close_bracket_position < var_name_end) + { + char *end = NULL; + bitfield_lower = ::strtoul (open_bracket_position+1, &end, 0); + bitfield_higher = ::strtoul (separator_position+1, &end, 0); + //printf("got to read low=%d high=%d\n",bitfield_lower,bitfield_higher); + } + else + break; + if(bitfield_lower > bitfield_higher) + break; + //*((char*)open_bracket_position) = '\0'; + //printf("variable name is %s\n",var_name_begin); + //*((char*)open_bracket_position) = '['; + } + } + + Error error; + lldb::VariableSP var_sp; + StreamString sstring; + vobj->GetExpressionPath(sstring, true, ValueObject::eHonorPointers); + //printf("name to expand in phase 0: %s\n",sstring.GetData()); + sstring.PutRawBytes(var_name_begin+3, var_name_final-var_name_begin-3); + //printf("name to expand in phase 1: %s\n",sstring.GetData()); + std::string name = std::string(sstring.GetData()); + target = exe_ctx->frame->GetValueForVariableExpressionPath (name.c_str(), + eNoDynamicValues, + 0, + var_sp, + error).get(); + if (error.Fail()) + { + //printf("ERROR: %s\n",error.AsCString("unknown")); + break; + } + } + else + break; + if(*(var_name_end+1)=='s') + { + use_summary = true; + var_name_end++; + } + if (bitfield_lower >= 0) + { + //printf("trying to print a []\n"); + // format this as a bitfield + DataExtractor extractor = target->GetDataExtractor(); + uint32_t item_byte_size = ClangASTType::GetTypeByteSize(target->GetClangAST(), target->GetClangType()); + if(custom_format == eFormatInvalid) + custom_format = eFormatHex; + var_success = + extractor.Dump(&s, 0, custom_format, item_byte_size, 1, 1, LLDB_INVALID_ADDRESS, bitfield_higher-bitfield_lower+1, bitfield_lower) > 0; + //printf("var_success = %s\n",var_success ? "true" : "false"); + } + else + { + //printf("here I come 1\n"); + // format this as usual + if(custom_format != eFormatInvalid) + target->SetFormat(custom_format); + //printf("here I come 2\n"); + if(!use_summary) + targetvalue = target->GetValueAsCString(); + else + targetvalue = target->GetSummaryAsCString(); + //printf("here I come 3\n"); + if(targetvalue) + s.PutCString(targetvalue); + var_success = targetvalue; + //printf("here I come 4 : %s\n",var_success ? "good" : "bad"); + if(custom_format != eFormatInvalid) + target->SetFormat(eFormatDefault); + //printf("here I come 5\n"); + } + break; + } case 'a': if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) { @@ -1321,27 +1610,76 @@ } bool -Debugger::GetFormatForType (const ConstString &type, lldb::Format& format, bool& cascade) +Debugger::ValueFormats::Get(ValueObject& vobj, ValueFormat::SharedPointer &entry) +{ + return GetFormatManager().Value().Get(vobj,entry); +} + +void +Debugger::ValueFormats::Add(const ConstString &type, const ValueFormat::SharedPointer &entry) +{ + GetFormatManager().Value().Add(type.AsCString(),entry); +} + +bool +Debugger::ValueFormats::Delete(const ConstString &type) { - return GetFormatManager().GetFormatForType(type, format, cascade); + return GetFormatManager().Value().Delete(type.AsCString()); } void -Debugger::AddFormatForType (const ConstString &type, lldb::Format format, bool cascade) +Debugger::ValueFormats::Clear() { - GetFormatManager().AddFormatForType(type,format, cascade); + GetFormatManager().Value().Clear(); } +void +Debugger::ValueFormats::LoopThrough(FormatManager::ValueCallback callback, void* callback_baton) +{ + GetFormatManager().Value().LoopThrough(callback, callback_baton); +} + +uint32_t +Debugger::ValueFormats::GetCurrentRevision() +{ + return GetFormatManager().GetCurrentRevision(); +} + + bool -Debugger::DeleteFormatForType (const ConstString &type) +Debugger::SummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry) { - return GetFormatManager().DeleteFormatForType(type); + return GetFormatManager().Summary().Get(vobj,entry); } void -Debugger::LoopThroughFormatList (FormatManager::Callback callback, void* callback_baton) +Debugger::SummaryFormats::Add(const ConstString &type, const SummaryFormat::SharedPointer &entry) +{ + GetFormatManager().Summary().Add(type.AsCString(),entry); +} + +bool +Debugger::SummaryFormats::Delete(const ConstString &type) +{ + return GetFormatManager().Summary().Delete(type.AsCString()); +} + +void +Debugger::SummaryFormats::Clear() +{ + GetFormatManager().Summary().Clear(); +} + +void +Debugger::SummaryFormats::LoopThrough(FormatManager::SummaryCallback callback, void* callback_baton) +{ + GetFormatManager().Summary().LoopThrough(callback, callback_baton); +} + +uint32_t +Debugger::SummaryFormats::GetCurrentRevision() { - return GetFormatManager().LoopThroughFormatList(callback, callback_baton); + return GetFormatManager().GetCurrentRevision(); } #pragma mark Debugger::SettingsController Modified: lldb/trunk/source/Core/FormatManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/source/Core/FormatManager.cpp (original) +++ lldb/trunk/source/Core/FormatManager.cpp Wed Jun 29 17:27:15 2011 @@ -151,61 +151,3 @@ return g_format_infos[format].format_name; return NULL; } - -bool -FormatManager::GetFormatForType (const ConstString &type_name, lldb::Format& format, bool& cascade) -{ - Mutex::Locker locker (m_format_map_mutex); - FormatMap& fmtmap = m_format_map; - FormatMap::iterator iter = fmtmap.find(type_name.GetCString()); - if(iter == fmtmap.end()) - return false; - else { - format = iter->second.format; - cascade = iter->second.cascades; - return true; - } -} - -void -FormatManager::AddFormatForType (const ConstString &type_name, lldb::Format format, bool cascade) -{ - Entry entry(format, cascade); - Mutex::Locker locker (m_format_map_mutex); - FormatMap& fmtmap = m_format_map; - fmtmap[type_name.GetCString()] = entry; -} - -bool -FormatManager::DeleteFormatForType (const ConstString &type_name) -{ - Mutex::Locker locker (m_format_map_mutex); - FormatMap& fmtmap = m_format_map; - const char* typeCS = type_name.GetCString(); - FormatMap::iterator iter = fmtmap.find(typeCS); - if (iter != fmtmap.end()) - { - fmtmap.erase(typeCS); - return true; - } - return false; -} - -void -FormatManager::LoopThroughFormatList (Callback callback, void* param) -{ - if (callback) - { - Mutex::Locker locker (m_format_map_mutex); - FormatIterator pos, end = m_format_map.end(); - for (pos = m_format_map.begin(); pos != end; ++pos) - { - const char* type = pos->first; - lldb::Format format = pos->second.format; - bool cascade = pos->second.cascades; - if (!callback(param, type, format, cascade)) - break; - } - } -} - Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Wed Jun 29 17:27:15 2011 @@ -19,6 +19,7 @@ // Project includes #include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/StreamString.h" #include "lldb/Core/ValueObjectChild.h" #include "lldb/Core/ValueObjectConstResult.h" @@ -71,7 +72,10 @@ m_children_count_valid (false), m_old_value_valid (false), m_pointers_point_to_load_addrs (false), - m_is_deref_of_parent (false) + m_is_deref_of_parent (false), + m_last_format_mgr_revision(0), + m_last_summary_format(), + m_last_value_format() { m_manager->ManageObject(this); } @@ -103,7 +107,10 @@ m_children_count_valid (false), m_old_value_valid (false), m_pointers_point_to_load_addrs (false), - m_is_deref_of_parent (false) + m_is_deref_of_parent (false), + m_last_format_mgr_revision(0), + m_last_summary_format(), + m_last_value_format() { m_manager = new ValueObjectManager(); m_manager->ManageObject (this); @@ -119,6 +126,9 @@ bool ValueObject::UpdateValueIfNeeded () { + + UpdateFormatsIfNeeded(); + // If this is a constant value, then our success is predicated on whether // we have an error or not if (GetIsConstant()) @@ -168,6 +178,26 @@ return m_error.Success(); } +void +ValueObject::UpdateFormatsIfNeeded() +{ + /*printf("CHECKING FOR UPDATES. I am at revision %d, while the format manager is at revision %d\n", + m_last_format_mgr_revision, + Debugger::ValueFormats::GetCurrentRevision());*/ + if (m_last_format_mgr_revision != Debugger::ValueFormats::GetCurrentRevision()) + { + if (m_last_summary_format.get()) + m_last_summary_format.reset((SummaryFormat*)NULL); + if (m_last_value_format.get()) + m_last_value_format.reset((ValueFormat*)NULL); + Debugger::ValueFormats::Get(*this, m_last_value_format); + Debugger::SummaryFormats::Get(*this, m_last_summary_format); + m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision(); + m_value_str.clear(); + m_summary_str.clear(); + } +} + DataExtractor & ValueObject::GetDataExtractor () { @@ -454,9 +484,23 @@ ValueObject::GetSummaryAsCString () { if (UpdateValueIfNeeded ()) - { + { if (m_summary_str.empty()) { + if (m_last_summary_format.get()) + { + StreamString s; + ExecutionContext exe_ctx; + this->GetExecutionContextScope()->CalculateExecutionContext(exe_ctx); + SymbolContext sc = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything); + if (Debugger::FormatPrompt(m_last_summary_format->m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, this)) + { + m_summary_str.swap(s.GetString()); + return m_summary_str.c_str(); + } + return NULL; + } + clang_type_t clang_type = GetClangType(); // See if this is a pointer to a C string? @@ -664,28 +708,6 @@ { if (UpdateValueIfNeeded()) { - /* - this is a quick fix for the case in which we display a variable, then change its format with - type format add and the old display string keeps showing until one steps through the code - */ - { - const Value::ContextType context_type = m_value.GetContextType(); - switch (context_type) - { - case Value::eContextTypeClangType: - case Value::eContextTypeLLDBType: - case Value::eContextTypeVariable: - { - Format format = GetFormat(); - if (format != m_last_format) - m_value_str.clear(); - } - break; - - default: - break; - } - } if (m_value_str.empty()) { const Value::ContextType context_type = m_value.GetContextType(); @@ -701,13 +723,18 @@ { StreamString sstr; Format format = GetFormat(); - if (format == eFormatDefault) - format = ClangASTType::GetFormat(clang_type); + if (format == eFormatDefault) + { + if (m_last_value_format) + format = m_last_value_format->m_format; + else + format = ClangASTType::GetFormat(clang_type); + } if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST clang_type, // The clang type to display &sstr, - m_last_format = format, // Format to display this type with + format, // Format to display this type with m_data, // Data to extract from 0, // Byte offset into "m_data" GetByteSize(), // Byte size of item in "m_data" @@ -1123,16 +1150,22 @@ } void -ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes) +ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat) { const bool is_deref_of_parent = IsDereferenceOfParent (); - - if (is_deref_of_parent) - s.PutCString("*("); - if (GetParent()) - GetParent()->GetExpressionPath (s, qualify_cxx_base_classes); + if(is_deref_of_parent && epformat == eDereferencePointers) { + // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely + // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName. + // the eHonorPointers mode is meant to produce strings in this latter format + s.PutCString("*("); + } + ValueObject* parent = GetParent(); + + if (parent) + parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat); + if (!IsBaseClass()) { if (!is_deref_of_parent) @@ -1145,14 +1178,21 @@ { const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL); - if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer) + if(parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers) { s.PutCString("->"); } - else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) && - !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray)) - { - s.PutChar('.'); + else + { + if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer) + { + s.PutCString("->"); + } + else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) && + !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray)) + { + s.PutChar('.'); + } } } } @@ -1170,8 +1210,9 @@ } } - if (is_deref_of_parent) + if (is_deref_of_parent && epformat == eDereferencePointers) { s.PutChar(')'); + } } void @@ -1245,6 +1286,8 @@ } const char *val_cstr = NULL; + const char *sum_cstr = NULL; + SummaryFormat* entry = valobj->m_last_summary_format.get(); if (err_cstr == NULL) { @@ -1261,10 +1304,13 @@ const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference); if (print_valobj) { - const char *sum_cstr = valobj->GetSummaryAsCString(); + + sum_cstr = valobj->GetSummaryAsCString(); - if (val_cstr) - s.Printf(" %s", val_cstr); + // We must calculate this value in realtime because entry might alter this variable's value + // (e.g. by saying ${var%fmt}) and render precached values useless + if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr)) + s.Printf(" %s", valobj->GetValueAsCString()); if (sum_cstr) s.Printf(" %s", sum_cstr); @@ -1314,7 +1360,32 @@ print_children = false; } - if (print_children) + if (entry && entry->IsOneliner()) + { + const uint32_t num_children = valobj->GetNumChildren(); + if (num_children) + { + + s.PutChar('('); + + for (uint32_t idx=0; idxGetChildAtIndex(idx, true)); + if (child_sp.get()) + { + if (idx) + s.PutCString(", "); + s.PutCString(child_sp.get()->GetName().AsCString()); + s.PutChar('='); + s.PutCString(child_sp.get()->GetValueAsCString()); + } + } + + s.PutChar(')'); + s.EOL(); + } + } + else if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr)) { const uint32_t num_children = valobj->GetNumChildren(); if (num_children) Modified: lldb/trunk/source/Symbol/ClangASTType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTType.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTType.cpp Wed Jun 29 17:27:15 2011 @@ -247,25 +247,8 @@ lldb::Format ClangASTType::GetFormat (clang_type_t clang_type) { - // first of all, check for a valid format for this type itself clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - lldb::Format format; - bool cascade; - if(Debugger::GetFormatForType(GetClangTypeName(qual_type), format, cascade)) - return format; // return it if found - - // here, I know this type does not have a direct format. two things can happen: - // 1) this is a typedef - I expand this to its parent type and look there - // 2) this is not a typedef - I use the default formatting options - const clang::TypedefType *typedef_type = qual_type->getAs(); - while (typedef_type) { - qual_type = typedef_type->getDecl()->getUnderlyingType(); - std::string name = qual_type.getAsString(); - if(Debugger::GetFormatForType(GetClangTypeName(qual_type), format, cascade) && cascade) // if I have a cascading format... - return format; // ...use it - typedef_type = qual_type->getAs(); // try to expand another level - } - + switch (qual_type->getTypeClass()) { case clang::Type::FunctionNoProto: @@ -1347,6 +1330,23 @@ data); } +uint32_t +ClangASTType::GetTypeByteSize() +{ + return GetTypeByteSize(m_ast, + m_type); +} + +uint32_t +ClangASTType::GetTypeByteSize( + clang::ASTContext *ast_context, + lldb::clang_type_t opaque_clang_qual_type) +{ + clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)); + + return (ast_context->getTypeSize (qual_type) + 7) / 8; +} + bool ClangASTType::ReadFromMemory Modified: lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py (original) +++ lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py Wed Jun 29 17:27:15 2011 @@ -51,11 +51,8 @@ # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): - self.runCmd('type format delete Speed', check=False) - self.runCmd('type format delete Bitfield', check=False) - self.runCmd('type format delete RealNumber', check=False) - self.runCmd('type format delete Type2', check=False) - self.runCmd('type format delete Type1', check=False) + self.runCmd('type format clear', check=False) + self.runCmd('type summary clear', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) @@ -87,6 +84,33 @@ # Delete type format for 'Speed', we should expect an error message. self.expect("type format delete Speed", error=True, substrs = ['no custom format for Speed']) + + # For some reason the type system is calling this "struct" + self.runCmd("type summary add -o yes \"\" Point") + + self.expect("frame variable iAmSomewhere", + substrs = ['x=4', + 'y=6']) + + self.expect("type summary list", + substrs = ['Point', + 'one-line']) + + self.runCmd("type summary add \"y=${var.y%x}\" Point") + + self.expect("frame variable iAmSomewhere", + substrs = ['y=0x']) + + self.runCmd("type summary add \"hello\" Point -h yes") + + self.expect("type summary list", + substrs = ['Point', + 'show children']) + + self.expect("frame variable iAmSomewhere", + substrs = ['hello', + 'x = 4', + '}']) if __name__ == '__main__': Modified: lldb/trunk/test/functionalities/data-formatter/main.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/main.cpp?rev=134108&r1=134107&r2=134108&view=diff ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/main.cpp (original) +++ lldb/trunk/test/functionalities/data-formatter/main.cpp Wed Jun 29 17:27:15 2011 @@ -31,6 +31,12 @@ typedef int ChildType; // should show as int typedef int AnotherChildType; // should show as int +struct Point { + int x; + int y; + Point(int X = 3, int Y = 2) : x(X), y(Y) {} +}; + int main (int argc, const char * argv[]) { @@ -57,6 +63,8 @@ Speed* SPPtrILookHex = new Speed(16); + Point iAmSomewhere(4,6); + return 0; // Set break point at this line. } From johnny.chen at apple.com Wed Jun 29 17:45:07 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 29 Jun 2011 22:45:07 -0000 Subject: [Lldb-commits] [lldb] r134109 - in /lldb/trunk/test/python_api/target: TestTargetAPI.py main.c Message-ID: <20110629224507.215F12A6C12C@llvm.org> Author: johnny Date: Wed Jun 29 17:45:06 2011 New Revision: 134109 URL: http://llvm.org/viewvc/llvm-project?rev=134109&view=rev Log: Add test cases to TestTargetAPI.py to exercise the newly added SBTarget.FindGlobalVariables() API. Modified: lldb/trunk/test/python_api/target/TestTargetAPI.py lldb/trunk/test/python_api/target/main.c Modified: lldb/trunk/test/python_api/target/TestTargetAPI.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/target/TestTargetAPI.py?rev=134109&r1=134108&r2=134109&view=diff ============================================================================== --- lldb/trunk/test/python_api/target/TestTargetAPI.py (original) +++ lldb/trunk/test/python_api/target/TestTargetAPI.py Wed Jun 29 17:45:06 2011 @@ -14,6 +14,19 @@ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") @python_api_test + def test_find_global_variables_with_dsym(self): + """Exercise SBTaget.FindGlobalVariables() API.""" + self.buildDsym() + self.find_global_variables() + + @python_api_test + def test_find_global_variables_with_dwarf(self): + """Exercise SBTarget.FindGlobalVariables() API.""" + self.buildDwarf() + self.find_global_variables() + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test def test_get_description_with_dsym(self): """Exercise SBTaget.GetDescription() API.""" self.buildDsym() @@ -58,6 +71,24 @@ self.line1 = line_number('main.c', '// Find the line number for breakpoint 1 here.') self.line2 = line_number('main.c', '// Find the line number for breakpoint 2 here.') + def find_global_variables(self): + """Exercise SBTaget.FindGlobalVariables() API.""" + exe = os.path.join(os.getcwd(), "a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + value_list = target.FindGlobalVariables('my_global_var_of_char_type', 1) + self.assertTrue(value_list.GetSize() == 1) + my_global_var = value_list.GetValueAtIndex(0) + self.expect(my_global_var.GetName(), exe=False, + startstr = "my_global_var_of_char_type") + self.expect(my_global_var.GetTypeName(), exe=False, + startstr = "char") + self.expect(my_global_var.GetValue(), exe=False, + startstr = "'X'") + def get_description(self): """Exercise SBTaget.GetDescription() API.""" exe = os.path.join(os.getcwd(), "a.out") Modified: lldb/trunk/test/python_api/target/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/target/main.c?rev=134109&r1=134108&r2=134109&view=diff ============================================================================== --- lldb/trunk/test/python_api/target/main.c (original) +++ lldb/trunk/test/python_api/target/main.c Wed Jun 29 17:45:06 2011 @@ -18,6 +18,8 @@ // // The two symbol context should point to the same symbol, i.e., 'a' function. +char my_global_var_of_char_type = 'X'; // Test SBTarget.FindGlobalVariables(...). + int a(int); int b(int); int c(int); From peter at pcc.me.uk Wed Jun 29 18:50:00 2011 From: peter at pcc.me.uk (Peter Collingbourne) Date: Thu, 30 Jun 2011 00:50:00 +0100 Subject: [Lldb-commits] Hi All! In-Reply-To: <4DF22EFC.3040307@cern.ch> References: <4DF22EFC.3040307@cern.ch> Message-ID: <20110629235000.GA21133@pcc.me.uk> Hi Vassil, On Fri, Jun 10, 2011 at 04:49:32PM +0200, Vassil Vassilev wrote: > Hi, > Can I say Hi to lldb community with the attached patch. > I saw that lldb didn't have doxygen documentation on the website and > decided to see what I could do. Recently I did that for cling so I've > made few changes to adapt it for lldb. It is customization of clang's > approach of generating documentation. Be careful it's slow and space > consuming ;) Thanks for the patch. I don't think we can accept it yet, because it will only work for a website-style build (i.e. if BUILD_FOR_WEBSITE is set) because there is no way to build the doxygen.cfg otherwise. Ideally we would like "make doxygen" in the docs directory to work for a standard build. For LLVM and clang this is done by having LLVM's configure script run an AC_CONFIG_FILES pass over the doxygen.cfg.in file (yes, this isn't ideal for a large number of projects, but I don't think we're at that point yet). You can see the necessary changes I made in clang r131282 and LLVM r131279. Thanks, -- Peter From johnny.chen at apple.com Wed Jun 29 19:24:31 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 30 Jun 2011 00:24:31 -0000 Subject: [Lldb-commits] [lldb] r134118 - /lldb/trunk/test/python_api/target/TestTargetAPI.py Message-ID: <20110630002431.5BF982A6C12C@llvm.org> Author: johnny Date: Wed Jun 29 19:24:31 2011 New Revision: 134118 URL: http://llvm.org/viewvc/llvm-project?rev=134118&view=rev Log: While we are at it, let's also exercise the similar SBModule.FindGlobalVariables() API within the find_global_variables() test method. Skipping test_find_global_variables_with_dwarf(self) due to segmentation fault. Modified: lldb/trunk/test/python_api/target/TestTargetAPI.py Modified: lldb/trunk/test/python_api/target/TestTargetAPI.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/target/TestTargetAPI.py?rev=134118&r1=134117&r2=134118&view=diff ============================================================================== --- lldb/trunk/test/python_api/target/TestTargetAPI.py (original) +++ lldb/trunk/test/python_api/target/TestTargetAPI.py Wed Jun 29 19:24:31 2011 @@ -16,14 +16,20 @@ @python_api_test def test_find_global_variables_with_dsym(self): """Exercise SBTaget.FindGlobalVariables() API.""" - self.buildDsym() - self.find_global_variables() + d = {'EXE': 'a.out'} + self.buildDsym(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.find_global_variables('a.out') + #rdar://problem/9700873 + @unittest2.skip("segmentation fault -- skipping") @python_api_test def test_find_global_variables_with_dwarf(self): """Exercise SBTarget.FindGlobalVariables() API.""" - self.buildDwarf() - self.find_global_variables() + d = {'EXE': 'b.out'} + self.buildDwarf(dictionary=d) + self.setTearDownCleanup(dictionary=d) + self.find_global_variables('b.out') @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") @python_api_test @@ -71,15 +77,15 @@ self.line1 = line_number('main.c', '// Find the line number for breakpoint 1 here.') self.line2 = line_number('main.c', '// Find the line number for breakpoint 2 here.') - def find_global_variables(self): + def find_global_variables(self, exe_name): """Exercise SBTaget.FindGlobalVariables() API.""" - exe = os.path.join(os.getcwd(), "a.out") + exe = os.path.join(os.getcwd(), exe_name) # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) - value_list = target.FindGlobalVariables('my_global_var_of_char_type', 1) + value_list = target.FindGlobalVariables('my_global_var_of_char_type', 3) self.assertTrue(value_list.GetSize() == 1) my_global_var = value_list.GetValueAtIndex(0) self.expect(my_global_var.GetName(), exe=False, @@ -89,6 +95,14 @@ self.expect(my_global_var.GetValue(), exe=False, startstr = "'X'") + # While we are at it, let's also exercise the similar SBModule.FindGlobalVariables() API. + for m in target.module_iter(): + if m.GetFileSpec().GetDirectory() == os.getcwd() and m.GetFileSpec().GetFilename() == exe_name: + value_list = m.FindGlobalVariables(target, 'my_global_var_of_char_type', 3) + self.assertTrue(value_list.GetSize() == 1) + self.assertTrue(value_list.GetValueAtIndex(0).GetValue() == "'X'") + break + def get_description(self): """Exercise SBTaget.GetDescription() API.""" exe = os.path.join(os.getcwd(), "a.out") From gclayton at apple.com Wed Jun 29 21:28:26 2011 From: gclayton at apple.com (Greg Clayton) Date: Thu, 30 Jun 2011 02:28:26 -0000 Subject: [Lldb-commits] [lldb] r134132 - in /lldb/trunk: include/lldb/Expression/ include/lldb/Symbol/ source/API/ source/Core/ source/Expression/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Plugins/SymbolFile/DWARF/ source/Symbol/ test/lang/c/forward/ test/lang/cpp/dynamic-value/ test/lang/objc/foundation/ Message-ID: <20110630022826.BFE0A2A6C12C@llvm.org> Author: gclayton Date: Wed Jun 29 21:28:26 2011 New Revision: 134132 URL: http://llvm.org/viewvc/llvm-project?rev=134132&view=rev Log: Centralize all of the type name code so that we always strip the leading "struct ", "class ", and "union " from the start of any type names that are extracted from clang QualType objects. I had to fix test suite cases that were expecting the struct/union/class prefix to be there. Modified: lldb/trunk/include/lldb/Expression/ClangFunction.h lldb/trunk/include/lldb/Symbol/ClangASTContext.h lldb/trunk/include/lldb/Symbol/ClangASTType.h lldb/trunk/source/API/SBType.cpp lldb/trunk/source/Core/ValueObjectChild.cpp lldb/trunk/source/Core/ValueObjectConstResult.cpp lldb/trunk/source/Core/ValueObjectDynamicValue.cpp lldb/trunk/source/Core/ValueObjectMemory.cpp lldb/trunk/source/Core/ValueObjectRegister.cpp lldb/trunk/source/Expression/ClangFunction.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp lldb/trunk/source/Symbol/ClangASTType.cpp lldb/trunk/source/Symbol/Type.cpp lldb/trunk/test/lang/c/forward/TestForwardDeclaration.py lldb/trunk/test/lang/cpp/dynamic-value/TestDynamicValue.py lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py Modified: lldb/trunk/include/lldb/Expression/ClangFunction.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangFunction.h?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangFunction.h (original) +++ lldb/trunk/include/lldb/Expression/ClangFunction.h Wed Jun 29 21:28:26 2011 @@ -612,7 +612,7 @@ Function *m_function_ptr; ///< The function we're going to call. May be NULL if we don't have debug info for the function. Address m_function_addr; ///< If we don't have the FunctionSP, we at least need the address & return type. - void *m_function_return_qual_type; ///< The opaque clang qual type for the function return type. + lldb::clang_type_t m_function_return_qual_type; ///< The opaque clang qual type for the function return type. ClangASTContext *m_clang_ast_context; ///< This is the clang_ast_context that we're getting types from the and value, and the function return the function pointer is NULL. std::string m_wrapper_function_name; ///< The name of the wrapper function. Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Wed Jun 29 21:28:26 2011 @@ -659,9 +659,6 @@ //------------------------------------------------------------------ // Type names //------------------------------------------------------------------ - static std::string - GetTypeName(lldb::clang_type_t clang_type); - static bool IsFloatingPointType (lldb::clang_type_t clang_type, uint32_t &count, bool &is_complex); Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Wed Jun 29 21:28:26 2011 @@ -69,14 +69,17 @@ } ConstString - GetClangTypeName (); + GetConstTypeName (); static ConstString - GetClangTypeName (lldb::clang_type_t clang_type); - - static ConstString - GetClangTypeName (clang::QualType qual_type); + GetConstTypeName (lldb::clang_type_t clang_type); + static std::string + GetTypeNameForQualType (clang::QualType qual_type); + + static std::string + GetTypeNameForOpaqueQualType (lldb::clang_type_t opaque_qual_type); + uint32_t GetClangTypeBitWidth (); Modified: lldb/trunk/source/API/SBType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBType.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/API/SBType.cpp (original) +++ lldb/trunk/source/API/SBType.cpp Wed Jun 29 21:28:26 2011 @@ -71,7 +71,7 @@ SBType::GetName () { if (IsValid ()) - return ClangASTType::GetClangTypeName (m_type).AsCString(NULL); + return ClangASTType::GetConstTypeName (m_type).AsCString(NULL); return NULL; } Modified: lldb/trunk/source/Core/ValueObjectChild.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectChild.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectChild.cpp (original) +++ lldb/trunk/source/Core/ValueObjectChild.cpp Wed Jun 29 21:28:26 2011 @@ -71,7 +71,7 @@ { if (m_type_name.IsEmpty()) { - m_type_name = ClangASTType::GetClangTypeName (GetClangType()); + m_type_name = ClangASTType::GetConstTypeName (GetClangType()); if (m_type_name) { if (m_bitfield_bit_size > 0) Modified: lldb/trunk/source/Core/ValueObjectConstResult.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectConstResult.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectConstResult.cpp (original) +++ lldb/trunk/source/Core/ValueObjectConstResult.cpp Wed Jun 29 21:28:26 2011 @@ -273,7 +273,7 @@ ValueObjectConstResult::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = ClangASTType::GetClangTypeName (GetClangType()); + m_type_name = ClangASTType::GetConstTypeName (GetClangType()); return m_type_name; } Modified: lldb/trunk/source/Core/ValueObjectDynamicValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectDynamicValue.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectDynamicValue.cpp (original) +++ lldb/trunk/source/Core/ValueObjectDynamicValue.cpp Wed Jun 29 21:28:26 2011 @@ -62,7 +62,7 @@ { const bool success = UpdateValueIfNeeded(); if (success && m_type_sp) - return ClangASTType::GetClangTypeName (GetClangType()); + return ClangASTType::GetConstTypeName (GetClangType()); else return m_parent->GetTypeName(); } Modified: lldb/trunk/source/Core/ValueObjectMemory.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectMemory.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectMemory.cpp (original) +++ lldb/trunk/source/Core/ValueObjectMemory.cpp Wed Jun 29 21:28:26 2011 @@ -140,11 +140,7 @@ { if (m_type_sp) return m_type_sp->GetName(); - ConstString name; - std::string type_name (ClangASTContext::GetTypeName (m_clang_type.GetOpaqueQualType())); - if (!type_name.empty()) - name.SetCString (type_name.c_str()); - return name; + return ClangASTType::GetConstTypeName (m_clang_type.GetOpaqueQualType()); } uint32_t Modified: lldb/trunk/source/Core/ValueObjectRegister.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectRegister.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectRegister.cpp (original) +++ lldb/trunk/source/Core/ValueObjectRegister.cpp Wed Jun 29 21:28:26 2011 @@ -322,7 +322,7 @@ ValueObjectRegister::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = ClangASTType::GetClangTypeName (GetClangType()); + m_type_name = ClangASTType::GetConstTypeName (GetClangType()); return m_type_name; } Modified: lldb/trunk/source/Expression/ClangFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangFunction.cpp (original) +++ lldb/trunk/source/Expression/ClangFunction.cpp Wed Jun 29 21:28:26 2011 @@ -118,7 +118,7 @@ // FIXME: How does clang tell us there's no return value? We need to handle that case. unsigned num_errors = 0; - std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type); + std::string return_type_str (ClangASTType::GetTypeNameForOpaqueQualType (m_function_return_qual_type)); // Cons up the function we're going to wrap our call in, then compile it... // We declare the function "extern "C"" because the compiler might be in C++ @@ -164,15 +164,15 @@ if (trust_function) { lldb::clang_type_t arg_clang_type = m_function_ptr->GetArgumentTypeAtIndex(i); - type_name = ClangASTContext::GetTypeName(arg_clang_type); + type_name = ClangASTType::GetTypeNameForOpaqueQualType (arg_clang_type); } else { Value *arg_value = m_arg_values.GetValueAtIndex(i); - void *clang_qual_type = arg_value->GetClangType (); + lldb::clang_type_t clang_qual_type = arg_value->GetClangType (); if (clang_qual_type != NULL) { - type_name = ClangASTContext::GetTypeName(clang_qual_type); + type_name = ClangASTType::GetTypeNameForOpaqueQualType (clang_qual_type); } else { Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Wed Jun 29 21:28:26 2011 @@ -528,7 +528,7 @@ size_t AppleObjCRuntimeV2::GetByteOffsetForIvar (ClangASTType &parent_ast_type, const char *ivar_name) { - const char *class_name = parent_ast_type.GetClangTypeName().AsCString(); + const char *class_name = parent_ast_type.GetConstTypeName().AsCString(); if (!class_name || *class_name == '\0' || !ivar_name || *ivar_name == '\0') return LLDB_INVALID_IVAR_OFFSET; Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Jun 29 21:28:26 2011 @@ -1493,7 +1493,7 @@ if (class_language == eLanguageTypeObjC) { - std::string class_str (ClangASTContext::GetTypeName (clang_type)); + std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type)); if (!class_str.empty()) { Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Wed Jun 29 21:28:26 2011 @@ -2571,9 +2571,8 @@ // Base classes should be a multiple of 8 bits in size assert (bit_offset % 8 == 0); child_byte_offset = bit_offset/8; - std::string base_class_type_name(base_class->getType().getAsString()); - - child_name.assign(base_class_type_name.c_str()); + + child_name = ClangASTType::GetTypeNameForQualType(base_class->getType()); uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType()); @@ -3401,7 +3400,8 @@ if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false) continue; - if (base_class->getType().getAsString().compare (name) == 0) + std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(base_class->getType())); + if (base_class_type_name.compare (name) == 0) return child_idx; ++child_idx; } @@ -4660,28 +4660,6 @@ return NULL; } - -std::string -ClangASTContext::GetTypeName (clang_type_t opaque_qual_type) -{ - std::string return_name; - - QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type)); - - const TypedefType *typedef_type = qual_type->getAs(); - if (typedef_type) - { - const TypedefNameDecl *typedef_decl = typedef_type->getDecl(); - return_name = typedef_decl->getQualifiedNameAsString(); - } - else - { - return_name = qual_type.getAsString(); - } - - return return_name; -} - // Disable this for now since I can't seem to get a nicely formatted float // out of the APFloat class without just getting the float, double or quad // and then using a formatted print on it which defeats the purpose. We ideally Modified: lldb/trunk/source/Symbol/ClangASTType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTType.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTType.cpp Wed Jun 29 21:28:26 2011 @@ -38,57 +38,88 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" - using namespace lldb; using namespace lldb_private; -ClangASTType::~ClangASTType() -{ -} -ConstString -ClangASTType::GetClangTypeName () +ClangASTType::~ClangASTType() { - return GetClangTypeName (m_type); } -ConstString -ClangASTType::GetClangTypeName (clang_type_t clang_type) +std::string +ClangASTType::GetTypeNameForQualType (clang::QualType qual_type) { - ConstString clang_type_name; - if (clang_type) + std::string type_name; + + const clang::TypedefType *typedef_type = qual_type->getAs(); + if (typedef_type) { - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - return GetClangTypeName(qual_type); - + const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); + type_name = typedef_decl->getQualifiedNameAsString(); } else { - clang_type_name.SetCString (""); + type_name = qual_type.getAsString(); + } + + // There is no call to a clang type to get the type name without the + // class/struct/union on the front, so lets strip it here + const char *type_name_cstr = type_name.c_str(); + if (type_name_cstr[0] == 'c' && + type_name_cstr[1] == 'l' && + type_name_cstr[2] == 'a' && + type_name_cstr[3] == 's' && + type_name_cstr[4] == 's' && + type_name_cstr[5] == ' ') + { + type_name.erase (0, 6); + } + else if (type_name_cstr[0] == 's' && + type_name_cstr[1] == 't' && + type_name_cstr[2] == 'r' && + type_name_cstr[3] == 'u' && + type_name_cstr[4] == 'c' && + type_name_cstr[5] == 't' && + type_name_cstr[6] == ' ') + { + type_name.erase (0, 7); + } + else if (type_name_cstr[0] == 'u' && + type_name_cstr[1] == 'n' && + type_name_cstr[2] == 'i' && + type_name_cstr[3] == 'o' && + type_name_cstr[4] == 'n' && + type_name_cstr[5] == ' ') + { + type_name.erase (0, 6); } + return type_name; +} - return clang_type_name; +std::string +ClangASTType::GetTypeNameForOpaqueQualType (clang_type_t opaque_qual_type) +{ + return GetTypeNameForQualType (clang::QualType::getFromOpaquePtr(opaque_qual_type)); } + ConstString -ClangASTType::GetClangTypeName (clang::QualType qual_type) +ClangASTType::GetConstTypeName () { - ConstString clang_type_name; - const clang::TypedefType *typedef_type = qual_type->getAs(); - if (typedef_type) - { - const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); - std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString()); - if (!clang_typedef_name.empty()) - clang_type_name.SetCString (clang_typedef_name.c_str()); - } + return GetConstTypeName (m_type); +} + +ConstString +ClangASTType::GetConstTypeName (clang_type_t clang_type) +{ + clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); + std::string type_name (GetTypeNameForQualType (qual_type)); + ConstString const_type_name; + if (type_name.empty()) + const_type_name.SetCString (""); else - { - std::string type_name(qual_type.getAsString()); - if (!type_name.empty()) - clang_type_name.SetCString (type_name.c_str()); - } - return clang_type_name; + const_type_name.SetCString(type_name.c_str()); + return const_type_name; } clang_type_t Modified: lldb/trunk/source/Symbol/Type.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Type.cpp?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Type.cpp (original) +++ lldb/trunk/source/Symbol/Type.cpp Wed Jun 29 21:28:26 2011 @@ -194,14 +194,10 @@ const ConstString & Type::GetName() { - if (!(m_name)) + if (!m_name) { if (ResolveClangType(eResolveStateForward)) - { - std::string type_name = ClangASTContext::GetTypeName (m_clang_type); - if (!type_name.empty()) - m_name.SetCString (type_name.c_str()); - } + m_name = ClangASTType::GetConstTypeName (m_clang_type); } return m_name; } Modified: lldb/trunk/test/lang/c/forward/TestForwardDeclaration.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/forward/TestForwardDeclaration.py?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/test/lang/c/forward/TestForwardDeclaration.py (original) +++ lldb/trunk/test/lang/c/forward/TestForwardDeclaration.py Wed Jun 29 21:28:26 2011 @@ -47,13 +47,13 @@ # This should display correctly. # Note that the member fields of a = 1 and b = 2 is by design. self.expect("frame variable -T *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY, - substrs = ['(struct bar) *bar_ptr = ', + substrs = ['(bar) *bar_ptr = ', '(int) a = 1', '(int) b = 2']) # And so should this. self.expect("expression *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY, - substrs = ['(struct bar)', + substrs = ['(bar)', '(int) a = 1', '(int) b = 2']) Modified: lldb/trunk/test/lang/cpp/dynamic-value/TestDynamicValue.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/cpp/dynamic-value/TestDynamicValue.py?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/test/lang/cpp/dynamic-value/TestDynamicValue.py (original) +++ lldb/trunk/test/lang/cpp/dynamic-value/TestDynamicValue.py Wed Jun 29 21:28:26 2011 @@ -168,7 +168,7 @@ # make sure that works as well: self.expect('frame var -d run-target anotherA.m_client_A._M_ptr', 'frame var finds its way into a child member', - patterns = ['\(.* B \*\)']) + patterns = ['\(B \*\)']) # Now make sure we also get it right for a reference as well: Modified: lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py?rev=134132&r1=134131&r2=134132&view=diff ============================================================================== --- lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py (original) +++ lldb/trunk/test/lang/objc/foundation/TestObjCMethods.py Wed Jun 29 21:28:26 2011 @@ -143,7 +143,7 @@ self.expect("frame variable -T -s", VARIABLES_DISPLAYED_CORRECTLY, substrs = ["ARG: (MyString *) self"], patterns = ["ARG: \(.*\) _cmd", - "(struct objc_selector *)|(SEL)"]) + "(objc_selector *)|(SEL)"]) # rdar://problem/8651752 # don't crash trying to ask clang how many children an empty record has From jmolenda at apple.com Thu Jun 30 02:25:17 2011 From: jmolenda at apple.com (Jason Molenda) Date: Thu, 30 Jun 2011 07:25:17 -0000 Subject: [Lldb-commits] [lldb] r134135 - /lldb/trunk/tools/darwin-threads/examine-threads.c Message-ID: <20110630072517.43E2B2A6C12C@llvm.org> Author: jmolenda Date: Thu Jun 30 02:25:17 2011 New Revision: 134135 URL: http://llvm.org/viewvc/llvm-project?rev=134135&view=rev Log: Restructure to be modular instead of a single big function; should make it a little easier to use this as an example of how to fetch all the different bits of information about threads. Modified: lldb/trunk/tools/darwin-threads/examine-threads.c Modified: lldb/trunk/tools/darwin-threads/examine-threads.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/darwin-threads/examine-threads.c?rev=134135&r1=134134&r2=134135&view=diff ============================================================================== --- lldb/trunk/tools/darwin-threads/examine-threads.c (original) +++ lldb/trunk/tools/darwin-threads/examine-threads.c Thu Jun 30 02:25:17 2011 @@ -6,6 +6,231 @@ #include #include #include +#include + +/* Step through the process table, find a matching process name, return + the pid of that matched process. + If there are multiple processes with that name, issue a warning on stdout + and return the highest numbered process. + The proc_pidpath() call is used which gets the full process name including + directories to the executable and the full (longer than 16 character) + executable name. */ + +pid_t +get_pid_for_process_name (const char *procname) +{ + int process_count = proc_listpids (PROC_ALL_PIDS, 0, NULL, 0) / sizeof (pid_t); + if (process_count < 1) + { + printf ("Only found %d processes running!\n", process_count); + exit (1); + } + + // Allocate a few extra slots in case new processes are spawned + int all_pids_size = sizeof (pid_t) * (process_count + 3); + pid_t *all_pids = (pid_t *) malloc (all_pids_size); + + // re-set process_count in case the number of processes changed (got smaller; we won't do bigger) + process_count = proc_listpids (PROC_ALL_PIDS, 0, all_pids, all_pids_size) / sizeof (pid_t); + + int i; + pid_t highest_pid = 0; + int match_count = 0; + for (i = 1; i < process_count; i++) + { + char pidpath[PATH_MAX]; + int pidpath_len = proc_pidpath (all_pids[i], pidpath, sizeof (pidpath)); + if (pidpath_len == 0) + continue; + char *j = strrchr (pidpath, '/'); + if ((j == NULL && strcmp (procname, pidpath) == 0) + || (j != NULL && strcmp (j + 1, procname) == 0)) + { + match_count++; + if (all_pids[i] > highest_pid) + highest_pid = all_pids[i]; + } + } + free (all_pids); + + if (match_count == 0) + { + printf ("Did not find process '%s'.\n", procname); + exit (1); + } + if (match_count > 1) + { + printf ("Warning: More than one process '%s'!\n", procname); + printf (" defaulting to the highest-pid one, %d\n", highest_pid); + } + return highest_pid; +} + +/* Given a pid, get the full executable name (including directory + paths and the longer-than-16-chars executable name) and return + the basename of that (i.e. do not include the directory components). + This function mallocs the memory for the string it returns; + the caller must free this memory. */ + +const char * +get_process_name_for_pid (pid_t pid) +{ + char tmp_name[PATH_MAX]; + if (proc_pidpath (pid, tmp_name, sizeof (tmp_name)) == 0) + { + printf ("Could not find process with pid of %d\n", (int) pid); + exit (1); + } + if (strrchr (tmp_name, '/')) + return strdup (strrchr (tmp_name, '/') + 1); + else + return strdup (tmp_name); +} + +/* Get a struct kinfo_proc structure for a given pid. + Process name is required for error printing. + Gives you the current state of the process and whether it is being debugged by anyone. + memory is malloc()'ed for the returned struct kinfo_proc + and must be freed by the caller. */ + +struct kinfo_proc * +get_kinfo_proc_for_pid (pid_t pid, const char *process_name) +{ + struct kinfo_proc *all_kinfos; + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; + size_t len; + if (sysctl (mib, 3, NULL, &len, NULL, 0) != 0) + { + printf ("Could not number of processes\n"); + exit (1); + } + all_kinfos = (struct kinfo_proc *) malloc (len); + if (sysctl (mib, 3, all_kinfos, &len, NULL, 0) != 0) + { + printf ("Could not get process infos\n"); + exit (1); + } + + int proc_count, i; + proc_count = len / sizeof (struct kinfo_proc); + for (i = 0 ; i < proc_count; i++) + if (all_kinfos[i].kp_proc.p_pid == pid) + { + struct kinfo_proc *kinfo = (struct kinfo_proc *) malloc (sizeof (struct kinfo_proc)); + memcpy (kinfo, &all_kinfos[i], sizeof (struct kinfo_proc)); + free ((void *) all_kinfos); + return kinfo; + } + printf ("Did not find process '%s' when re-getting proc table.\n", process_name); + exit (1); +} + +/* Get the basic information (thread_basic_info_t) about a given + thread. + Gives you the suspend count; thread state; user time; system time; sleep time; etc. + The return value is a pointer to malloc'ed memory - it is the caller's + responsibility to free it. */ + +thread_basic_info_t +get_thread_basic_info (thread_t thread) +{ + kern_return_t kr; + integer_t *thinfo = (integer_t *) malloc (sizeof (integer_t) * THREAD_INFO_MAX); + mach_msg_type_number_t thread_info_count = THREAD_INFO_MAX; + kr = thread_info (thread, THREAD_BASIC_INFO, + (thread_info_t) thinfo, &thread_info_count); + if (kr != KERN_SUCCESS) + { + printf ("Error - unable to get basic thread info for a thread\n"); + exit (1); + } + return (thread_basic_info_t) thinfo; +} + +/* Get the thread identifier info (thread_identifier_info_data_t) + about a given thread. + Gives you the system-wide unique thread number; the pthread identifier number +*/ + +thread_identifier_info_data_t +get_thread_identifier_info (thread_t thread) +{ + kern_return_t kr; + thread_identifier_info_data_t tident; + mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT; + kr = thread_info (thread, THREAD_IDENTIFIER_INFO, + (thread_info_t) &tident, &tident_count); + if (kr != KERN_SUCCESS) + { + printf ("Error - unable to get thread ident for a thread\n"); + exit (1); + } + return tident; +} + +/* Get the current pc value for a given thread. */ + +uint64_t +get_current_pc (thread_t thread, int *wordsize) +{ + kern_return_t kr; + +#if defined (__x86_64__) || defined (__i386__) + x86_thread_state_t gp_regs; + mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; + kr = thread_get_state (thread, x86_THREAD_STATE, + (thread_state_t) &gp_regs, &gp_count); + if (kr != KERN_SUCCESS) + { + printf ("Error - unable to get registers for a thread\n"); + exit (1); + } + + if (gp_regs.tsh.flavor == x86_THREAD_STATE64) + { + *wordsize = 8; + return gp_regs.uts.ts64.__rip; + } + else + { + *wordsize = 4; + return gp_regs.uts.ts32.__eip; + } +#endif + +#if defined (__arm__) + arm_thread_state_t gp_regs; + mach_msg_type_number_t gp_count = ARM_THREAD_STATE_COUNT; + kr = thread_get_state (thread, ARM_THREAD_STATE, + (thread_state_t) &gp_regs, &gp_count); + if (kr != KERN_SUCCESS) + { + printf ("Error - unable to get registers for a thread\n"); + exit (1); + } + return gp_regs.__pc; + *wordsize = 4; +#endif + +} + +/* Get the proc_threadinfo for a given thread. + Gives you the thread name, if set; current and max priorities. + Returns 1 if successful + Returns 0 if proc_pidinfo() failed +*/ + +int +get_proc_threadinfo (pid_t pid, uint64_t thread_handle, struct proc_threadinfo *pth) +{ + pth->pth_name[0] = '\0'; + int ret = proc_pidinfo (pid, PROC_PIDTHREADINFO, thread_handle, + pth, sizeof (struct proc_threadinfo)); + if (ret != 0) + return 1; + else + return 0; +} int main (int argc, char **argv) @@ -56,113 +281,28 @@ c++; } - // the argument is a pid - if (arg_is_procname == 0) + if (arg_is_procname && procname) { - pid = atoi (argv[argc - 1]); - if (pid == 0) - { - printf ("Usage: tdump [-l] [-v] pid/procname\n"); - exit (1); - } + pid = get_pid_for_process_name (procname); } - - // Look up the pid for the provided process name - if (arg_is_procname) + else { - int process_count = proc_listpids (PROC_ALL_PIDS, 0, NULL, 0) / sizeof (pid_t); - if (process_count < 1) - { - printf ("Only found %d processes running!\n", process_count); - exit (1); - } - - // Allocate a few extra slots in case new processes are spawned - int all_pids_size = sizeof (pid_t) * (process_count + 3); - pid_t *all_pids = (pid_t *) malloc (all_pids_size); - - // re-set process_count in case the number of processes changed (got smaller; we won't do bigger) - process_count = proc_listpids (PROC_ALL_PIDS, 0, all_pids, all_pids_size) / sizeof (pid_t); - - int i; - pid_t highest_pid = 0; - int match_count = 0; - for (i = 1; i < process_count; i++) + errno = 0; + pid = (pid_t) strtol (argv[argc - 1], NULL, 10); + if (pid == 0 && errno == EINVAL) { - char pidpath[PATH_MAX]; - int pidpath_len = proc_pidpath (all_pids[i], pidpath, sizeof (pidpath)); - if (pidpath_len == 0) - continue; - char *j = strrchr (pidpath, '/'); - if ((j == NULL && strcmp (procname, pidpath) == 0) - || (j != NULL && strcmp (j + 1, procname) == 0)) - { - match_count++; - if (all_pids[i] > highest_pid) - highest_pid = all_pids[i]; - } - } - free (all_pids); - - if (match_count == 0) - { - printf ("Did not find process '%s'.\n", procname); + printf ("Usage: tdump [-l] [-v] pid/procname\n"); exit (1); } - if (match_count > 1) - { - printf ("Warning: More than one process '%s'!\n", procname); - printf (" defaulting to the highest-pid one, %d\n", highest_pid); - } - pid = highest_pid; } - - char process_name[PATH_MAX]; - char tmp_name[PATH_MAX]; - if (proc_pidpath (pid, tmp_name, sizeof (tmp_name)) == 0) - { - printf ("Could not find process with pid of %d\n", (int) pid); - exit (1); - } - if (strrchr (tmp_name, '/')) - strcpy (process_name, strrchr (tmp_name, '/') + 1); - else - strcpy (process_name, tmp_name); + const char *process_name = get_process_name_for_pid (pid); // At this point "pid" is the process id and "process_name" is the process name // Now we have to get the process list from the kernel (which only has the truncated // 16 char names) - struct kinfo_proc *all_kinfos; - int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; - size_t len; - if (sysctl (mib, 3, NULL, &len, NULL, 0) != 0) - { - printf ("Could not number of processes\n"); - exit (1); - } - all_kinfos = (struct kinfo_proc *) malloc (len); - if (sysctl (mib, 3, all_kinfos, &len, NULL, 0) != 0) - { - printf ("Could not get process infos\n"); - exit (1); - } - - struct kinfo_proc *kinfo = NULL; - int proc_count, i; - proc_count = len / sizeof (struct kinfo_proc); - for (i = 0 ; i < proc_count; i++) - if (all_kinfos[i].kp_proc.p_pid == pid) - { - kinfo = &all_kinfos[i]; - break; - } - if (kinfo == NULL) - { - printf ("Did not find process '%s' when re-getting proc table.\n", process_name); - exit (1); - } + struct kinfo_proc *kinfo = get_kinfo_proc_for_pid (pid, process_name); printf ("pid %d (%s) is currently ", pid, process_name); switch (kinfo->kp_proc.p_stat) { @@ -175,6 +315,7 @@ } if (kinfo->kp_proc.p_flag & P_TRACED) printf (" and is being debugged."); + free ((void *) kinfo); printf ("\n"); @@ -205,78 +346,27 @@ exit (1); } printf ("pid %d has %d threads\n", pid, thread_count); + if (verbose) + printf ("\n"); for (i = 0; i < thread_count; i++) { - thread_info_data_t thinfo; - mach_msg_type_number_t thread_info_count = THREAD_INFO_MAX; - kr = thread_info (thread_list[i], THREAD_BASIC_INFO, - (thread_info_t) thinfo, &thread_info_count); - if (kr != KERN_SUCCESS) - { - printf ("Error - unable to get basic thread info for a thread\n"); - exit (1); - } - thread_basic_info_t basic_info_th = (thread_basic_info_t) thinfo; - - thread_identifier_info_data_t tident; - mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT; - kr = thread_info (thread_list[i], THREAD_IDENTIFIER_INFO, - (thread_info_t) &tident, &tident_count); - if (kr != KERN_SUCCESS) - { - printf ("Error - unable to get thread ident for a thread\n"); - exit (1); - } + thread_basic_info_t basic_info = get_thread_basic_info (thread_list[i]); - uint64_t pc; - int width; -#if defined (__x86_64__) || defined (__i386__) - x86_thread_state_t gp_regs; - mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; - kr = thread_get_state (thread_list[i], x86_THREAD_STATE, - (thread_state_t) &gp_regs, &gp_count); - if (kr != KERN_SUCCESS) - { - printf ("Error - unable to get registers for a thread\n"); - exit (1); - } + thread_identifier_info_data_t identifier_info = get_thread_identifier_info (thread_list[i]); - if (gp_regs.tsh.flavor == x86_THREAD_STATE64) - { - pc = gp_regs.uts.ts64.__rip; - width = 8; - } - else - { - pc = gp_regs.uts.ts32.__eip; - width = 4; - } -#endif - -#if defined (__arm__) - arm_thread_state_t gp_regs; - mach_msg_type_number_t gp_count = ARM_THREAD_STATE_COUNT; - kr = thread_get_state (thread_list[i], ARM_THREAD_STATE, - (thread_state_t) &gp_regs, &gp_count); - if (kr != KERN_SUCCESS) - { - printf ("Error - unable to get registers for a thread\n"); - exit (1); - } - pc = gp_regs.__pc; - width = 4; -#endif + int wordsize; + uint64_t pc = get_current_pc (thread_list[i], &wordsize); printf ("thread #%d, unique tid %lld, suspend count is %d, ", i, - tident.thread_id, - basic_info_th->suspend_count); - if (width == 8) + identifier_info.thread_id, + basic_info->suspend_count); + if (wordsize == 8) printf ("pc 0x%016llx, ", pc); else printf ("pc 0x%08llx, ", pc); printf ("run state is "); - switch (basic_info_th->run_state) { + switch (basic_info->run_state) { case TH_STATE_RUNNING: puts ("running"); break; case TH_STATE_STOPPED: puts ("stopped"); break; case TH_STATE_WAITING: puts ("waiting"); break; @@ -288,43 +378,44 @@ { printf (" "); printf ("mach thread #0x%4.4x ", (int) thread_list[i]); - printf ("pthread handle id 0x%llx ", (uint64_t) tident.thread_handle); + printf ("pthread handle id 0x%llx ", (uint64_t) identifier_info.thread_handle); struct proc_threadinfo pth; - pth.pth_name[0] = '\0'; - int ret = proc_pidinfo (pid, PROC_PIDTHREADINFO, tident.thread_handle, - &pth, sizeof (pth)); - if (ret != 0 && pth.pth_name[0] != '\0') + int proc_threadinfo_succeeded = get_proc_threadinfo (pid, identifier_info.thread_handle, &pth); + + if (proc_threadinfo_succeeded && pth.pth_name[0] != '\0') printf ("thread name '%s' ", pth.pth_name); printf ("\n "); printf ("user %d.%06ds, system %d.%06ds", - basic_info_th->user_time.seconds, basic_info_th->user_time.microseconds, - basic_info_th->system_time.seconds, basic_info_th->system_time.microseconds); - if (basic_info_th->cpu_usage > 0) + basic_info->user_time.seconds, basic_info->user_time.microseconds, + basic_info->system_time.seconds, basic_info->system_time.microseconds); + if (basic_info->cpu_usage > 0) { - float cpu_percentage = basic_info_th->cpu_usage / 10.0; + float cpu_percentage = basic_info->cpu_usage / 10.0; printf (", using %.1f%% cpu currently", cpu_percentage); } - if (basic_info_th->sleep_time > 0) - printf (", this thread has slept for %d seconds", basic_info_th->sleep_time); + if (basic_info->sleep_time > 0) + printf (", this thread has slept for %d seconds", basic_info->sleep_time); printf ("\n "); - printf ("scheduling policy %d", basic_info_th->policy); + printf ("scheduling policy %d", basic_info->policy); - if (basic_info_th->flags != 0) + if (basic_info->flags != 0) { - printf (", flags %d", basic_info_th->flags); - if ((basic_info_th->flags | TH_FLAGS_SWAPPED) == TH_FLAGS_SWAPPED) + printf (", flags %d", basic_info->flags); + if ((basic_info->flags | TH_FLAGS_SWAPPED) == TH_FLAGS_SWAPPED) printf (" (thread is swapped out)"); - if ((basic_info_th->flags | TH_FLAGS_IDLE) == TH_FLAGS_IDLE) + if ((basic_info->flags | TH_FLAGS_IDLE) == TH_FLAGS_IDLE) printf (" (thread is idle)"); } - if (ret != 0) + if (proc_threadinfo_succeeded) printf (", current pri %d, max pri %d", pth.pth_curpri, pth.pth_maxpriority); - puts (""); + printf ("\n\n"); } + + free ((void *) basic_info); } if (do_loop) printf ("\n"); @@ -334,6 +425,7 @@ } while (do_loop); vm_deallocate (mytask, (vm_address_t) task, sizeof (task_t)); + free ((void *) process_name); return 0; } From johnny.chen at apple.com Thu Jun 30 13:40:27 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 30 Jun 2011 18:40:27 -0000 Subject: [Lldb-commits] [lldb] r134176 - /lldb/trunk/include/lldb/API/SBType.h Message-ID: <20110630184027.991952A6C12C@llvm.org> Author: johnny Date: Thu Jun 30 13:40:27 2011 New Revision: 134176 URL: http://llvm.org/viewvc/llvm-project?rev=134176&view=rev Log: Ifdef out the 'lldb::Encoding GetEncoding(uint32_t &count)' API from Python SWIG, since it cannot hanlde the (uint32_t &count) parameter. Modified: lldb/trunk/include/lldb/API/SBType.h Modified: lldb/trunk/include/lldb/API/SBType.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBType.h?rev=134176&r1=134175&r2=134176&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBType.h (original) +++ lldb/trunk/include/lldb/API/SBType.h Thu Jun 30 13:40:27 2011 @@ -40,8 +40,10 @@ uint64_t GetByteSize(); - lldb::Encoding +#ifndef SWIG + lldb::Encoding GetEncoding (uint32_t &count); +#endif uint64_t GetNumberChildren (bool omit_empty_base_classes); From johnny.chen at apple.com Thu Jun 30 16:29:50 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 30 Jun 2011 21:29:50 -0000 Subject: [Lldb-commits] [lldb] r134192 - /lldb/trunk/scripts/lldb.swig Message-ID: <20110630212950.2D4202A6C12C@llvm.org> Author: johnny Date: Thu Jun 30 16:29:50 2011 New Revision: 134192 URL: http://llvm.org/viewvc/llvm-project?rev=134192&view=rev Log: Add module docstring to the auto-generated lldb.py file. Modified: lldb/trunk/scripts/lldb.swig Modified: lldb/trunk/scripts/lldb.swig URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=134192&r1=134191&r2=134192&view=diff ============================================================================== --- lldb/trunk/scripts/lldb.swig (original) +++ lldb/trunk/scripts/lldb.swig Thu Jun 30 16:29:50 2011 @@ -4,12 +4,34 @@ This is the input file for SWIG, to create the appropriate C++ wrappers and functions for various scripting languages, to enable them to call the liblldb Script Bridge functions. - */ +/* Define our module docstring. */ +%define DOCSTRING +"The lldb module contains the public APIs for Python binding. + +Some of the important classes are describe here: + +o SBTarget: Represents the target program running under the debugger. +o SBProcess: Represents the process associated with the target program. +o SBThread: Represents a thread of execution. SBProcess contains SBThread(s). +o SBFrame: Represents one of the stack frames associated with a thread. SBThread + contains SBFrame(s). +o SBSymbolContext: A container that stores various debugger related info. +o SBValue: Represents the value of a variable, a register, or an expression. +o SBModule: Represents an executable image and its associated object and symbol + files. +o SBSymbol: Represents the symbol associated with a stack frame. +o SBCompileUnit: Represents a compilation unit, or compiled source file. +o SBFunction: Represents a generic function, which can be inlined or not. +o SBBlock: Represents a lexical block. SBFunction contains SBBlock(s). +o SBLineEntry: Specifies an association with a contiguous range of instructions + and a source file location. SBCompileUnit contains SBLineEntry(s)" +%enddef + /* The name of the module to be created. */ +%module(docstring=DOCSTRING) lldb -%module lldb /* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */ From gclayton at apple.com Thu Jun 30 22:43:03 2011 From: gclayton at apple.com (Greg Clayton) Date: Fri, 01 Jul 2011 03:43:03 -0000 Subject: [Lldb-commits] [lldb] r134230 - /lldb/trunk/lldb.xcodeproj/project.pbxproj Message-ID: <20110701034303.459722A6C12C@llvm.org> Author: gclayton Date: Thu Jun 30 22:43:03 2011 New Revision: 134230 URL: http://llvm.org/viewvc/llvm-project?rev=134230&view=rev Log: Useless Xcode project change that Xcode keeps wanting to add to my project so I am giving up the fight... Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=134230&r1=134229&r2=134230&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Jun 30 22:43:03 2011 @@ -924,7 +924,7 @@ 26BC7E9610F1B85900F91463 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Timer.cpp; path = source/Core/Timer.cpp; sourceTree = ""; }; 26BC7E9810F1B85900F91463 /* UserID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UserID.cpp; path = source/Core/UserID.cpp; sourceTree = ""; }; 26BC7E9910F1B85900F91463 /* Value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Value.cpp; path = source/Core/Value.cpp; sourceTree = ""; }; - 26BC7E9A10F1B85900F91463 /* ValueObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; name = ValueObject.cpp; path = source/Core/ValueObject.cpp; sourceTree = ""; }; + 26BC7E9A10F1B85900F91463 /* ValueObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObject.cpp; path = source/Core/ValueObject.cpp; sourceTree = ""; }; 26BC7E9B10F1B85900F91463 /* ValueObjectChild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectChild.cpp; path = source/Core/ValueObjectChild.cpp; sourceTree = ""; }; 26BC7E9C10F1B85900F91463 /* ValueObjectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectList.cpp; path = source/Core/ValueObjectList.cpp; sourceTree = ""; }; 26BC7E9D10F1B85900F91463 /* ValueObjectVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectVariable.cpp; path = source/Core/ValueObjectVariable.cpp; sourceTree = ""; }; From gclayton at apple.com Thu Jun 30 23:31:33 2011 From: gclayton at apple.com (Greg Clayton) Date: Fri, 01 Jul 2011 04:31:33 -0000 Subject: [Lldb-commits] [lldb] r134232 - in /lldb/trunk: lldb.xcodeproj/project.pbxproj resources/LLDB-Info.plist tools/debugserver/debugserver.xcodeproj/project.pbxproj Message-ID: <20110701043133.AEF322A6C12C@llvm.org> Author: gclayton Date: Thu Jun 30 23:31:33 2011 New Revision: 134232 URL: http://llvm.org/viewvc/llvm-project?rev=134232&view=rev Log: Bump Xcode project version to lldb-66 and debugserver-141. Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/resources/LLDB-Info.plist lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=134232&r1=134231&r2=134232&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Jun 30 23:31:33 2011 @@ -3412,10 +3412,10 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 65; + CURRENT_PROJECT_VERSION = 66; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 65; + DYLIB_CURRENT_VERSION = 66; EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3464,11 +3464,11 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 65; + CURRENT_PROJECT_VERSION = 66; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 65; + DYLIB_CURRENT_VERSION = 66; EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3515,8 +3515,8 @@ isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 65; - DYLIB_CURRENT_VERSION = 65; + CURRENT_PROJECT_VERSION = 66; + DYLIB_CURRENT_VERSION = 66; EXECUTABLE_EXTENSION = a; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3554,9 +3554,9 @@ isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 65; + CURRENT_PROJECT_VERSION = 66; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_CURRENT_VERSION = 65; + DYLIB_CURRENT_VERSION = 66; EXECUTABLE_EXTENSION = a; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3594,9 +3594,9 @@ isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 65; + CURRENT_PROJECT_VERSION = 66; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_CURRENT_VERSION = 65; + DYLIB_CURRENT_VERSION = 66; EXECUTABLE_EXTENSION = a; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3664,7 +3664,7 @@ isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 65; + CURRENT_PROJECT_VERSION = 66; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3695,11 +3695,11 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 65; + CURRENT_PROJECT_VERSION = 66; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 65; + DYLIB_CURRENT_VERSION = 66; EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3824,7 +3824,7 @@ isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 65; + CURRENT_PROJECT_VERSION = 66; DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3856,7 +3856,7 @@ isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 65; + CURRENT_PROJECT_VERSION = 66; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", Modified: lldb/trunk/resources/LLDB-Info.plist URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/resources/LLDB-Info.plist?rev=134232&r1=134231&r2=134232&view=diff ============================================================================== --- lldb/trunk/resources/LLDB-Info.plist (original) +++ lldb/trunk/resources/LLDB-Info.plist Thu Jun 30 23:31:33 2011 @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 65 + 66 CFBundleName ${EXECUTABLE_NAME} Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=134232&r1=134231&r2=134232&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original) +++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Thu Jun 30 23:31:33 2011 @@ -467,7 +467,7 @@ i386, ); COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 140; + CURRENT_PROJECT_VERSION = 141; "GCC_VERSION[sdk=iphoneos*][arch=*]" = 4.2; "GCC_VERSION[sdk=macosx*][arch=*]" = ""; GCC_WARN_ABOUT_RETURN_TYPE = YES; @@ -488,7 +488,7 @@ x86_64, i386, ); - CURRENT_PROJECT_VERSION = 140; + CURRENT_PROJECT_VERSION = 141; DEAD_CODE_STRIPPING = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; @@ -509,7 +509,7 @@ x86_64, i386, ); - CURRENT_PROJECT_VERSION = 140; + CURRENT_PROJECT_VERSION = 141; DEAD_CODE_STRIPPING = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; @@ -527,7 +527,7 @@ buildSettings = { "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 140; + CURRENT_PROJECT_VERSION = 141; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( @@ -567,7 +567,7 @@ "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 140; + CURRENT_PROJECT_VERSION = 141; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( "$(SDKROOT)/System/Library/PrivateFrameworks", @@ -607,7 +607,7 @@ "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 140; + CURRENT_PROJECT_VERSION = 141; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( From gclayton at apple.com Thu Jun 30 23:32:00 2011 From: gclayton at apple.com (Greg Clayton) Date: Fri, 01 Jul 2011 04:32:00 -0000 Subject: [Lldb-commits] [lldb] r134233 - /lldb/tags/lldb-66/ Message-ID: <20110701043200.8752E2A6C12C@llvm.org> Author: gclayton Date: Thu Jun 30 23:32:00 2011 New Revision: 134233 URL: http://llvm.org/viewvc/llvm-project?rev=134233&view=rev Log: lldb-66 Added: lldb/tags/lldb-66/ - copied from r134232, lldb/trunk/ From johnny.chen at apple.com Fri Jul 1 13:39:47 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 01 Jul 2011 18:39:47 -0000 Subject: [Lldb-commits] [lldb] r134246 - in /lldb/trunk: include/lldb/API/SBBlock.h include/lldb/API/SBCompileUnit.h include/lldb/API/SBFrame.h include/lldb/API/SBFunction.h include/lldb/API/SBLineEntry.h include/lldb/API/SBModule.h include/lldb/API/SBProcess.h include/lldb/API/SBSymbol.h include/lldb/API/SBSymbolContext.h include/lldb/API/SBTarget.h include/lldb/API/SBThread.h include/lldb/API/SBValue.h scripts/lldb.swig Message-ID: <20110701183947.DFE3A2A6C12C@llvm.org> Author: johnny Date: Fri Jul 1 13:39:47 2011 New Revision: 134246 URL: http://llvm.org/viewvc/llvm-project?rev=134246&view=rev Log: Add docstrings for some API classes and auto-generates docstrings for the methods of them. A few of the auto-generated method docstrings don't look right, and may need to be fixed by either overwriting the auto-gened docstrings or some post-processing steps. Modified: lldb/trunk/include/lldb/API/SBBlock.h lldb/trunk/include/lldb/API/SBCompileUnit.h lldb/trunk/include/lldb/API/SBFrame.h lldb/trunk/include/lldb/API/SBFunction.h lldb/trunk/include/lldb/API/SBLineEntry.h lldb/trunk/include/lldb/API/SBModule.h lldb/trunk/include/lldb/API/SBProcess.h lldb/trunk/include/lldb/API/SBSymbol.h lldb/trunk/include/lldb/API/SBSymbolContext.h lldb/trunk/include/lldb/API/SBTarget.h lldb/trunk/include/lldb/API/SBThread.h lldb/trunk/include/lldb/API/SBValue.h lldb/trunk/scripts/lldb.swig Modified: lldb/trunk/include/lldb/API/SBBlock.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBlock.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBBlock.h (original) +++ lldb/trunk/include/lldb/API/SBBlock.h Fri Jul 1 13:39:47 2011 @@ -14,8 +14,16 @@ namespace lldb { +#ifdef SWIG +%feature("docstring", + "Represents a lexical block. SBFunction contains SBBlock(s)." + ) SBBlock; +#endif class SBBlock { +#ifdef SWIG + %feature("autodoc", "1"); +#endif public: SBBlock (); Modified: lldb/trunk/include/lldb/API/SBCompileUnit.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBCompileUnit.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBCompileUnit.h (original) +++ lldb/trunk/include/lldb/API/SBCompileUnit.h Fri Jul 1 13:39:47 2011 @@ -15,8 +15,16 @@ namespace lldb { +#ifdef SWIG +%feature("docstring", + "Represents a compilation unit, or compiled source file." + ) SBCompileUnit; +#endif class SBCompileUnit { +#ifdef SWIG + %feature("autodoc", "1"); +#endif public: SBCompileUnit (); Modified: lldb/trunk/include/lldb/API/SBFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFrame.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBFrame.h (original) +++ lldb/trunk/include/lldb/API/SBFrame.h Fri Jul 1 13:39:47 2011 @@ -17,8 +17,18 @@ class SBValue; +#ifdef SWIG +%feature("docstring", + "Represents one of the stack frames associated with a thread." + " SBThread contains SBFrame(s)." + ) SBFrame; +#endif class SBFrame { +#ifdef SWIG + %feature("autodoc", "1"); +#endif + public: SBFrame (); @@ -161,7 +171,9 @@ bool GetDescription (lldb::SBStream &description); +#ifndef SWIG SBFrame (const lldb::StackFrameSP &lldb_object_sp); +#endif protected: friend class SBValue; Modified: lldb/trunk/include/lldb/API/SBFunction.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFunction.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBFunction.h (original) +++ lldb/trunk/include/lldb/API/SBFunction.h Fri Jul 1 13:39:47 2011 @@ -16,8 +16,16 @@ namespace lldb { +#ifdef SWIG +%feature("docstring", + "Represents a generic function, which can be inlined or not." + ) SBFunction; +#endif class SBFunction { +#ifdef SWIG + %feature("autodoc", "1"); +#endif public: SBFunction (); Modified: lldb/trunk/include/lldb/API/SBLineEntry.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBLineEntry.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBLineEntry.h (original) +++ lldb/trunk/include/lldb/API/SBLineEntry.h Fri Jul 1 13:39:47 2011 @@ -16,8 +16,17 @@ namespace lldb { +#ifdef SWIG +%feature("docstring", + "Specifies an association with a contiguous range of instructions and" + " a source file location. SBCompileUnit contains SBLineEntry(s)." + ) SBLineEntry; +#endif class SBLineEntry { +#ifdef SWIG + %feature("autodoc", "1"); +#endif public: SBLineEntry (); Modified: lldb/trunk/include/lldb/API/SBModule.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBModule.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBModule.h (original) +++ lldb/trunk/include/lldb/API/SBModule.h Fri Jul 1 13:39:47 2011 @@ -16,8 +16,18 @@ namespace lldb { +#ifdef SWIG +%feature("docstring", + "Represents an executable image and its associated object and symbol" + " files." + ) SBModule; +#endif class SBModule { +#ifdef SWIG + %feature("autodoc", "1"); +#endif + public: SBModule (); Modified: lldb/trunk/include/lldb/API/SBProcess.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBProcess.h (original) +++ lldb/trunk/include/lldb/API/SBProcess.h Fri Jul 1 13:39:47 2011 @@ -19,8 +19,17 @@ class SBEvent; +#ifdef SWIG +%feature("docstring", + "Represents the process associated with the target program." + ) SBProcess; +#endif class SBProcess { +#ifdef SWIG + %feature("autodoc", "1"); +#endif + public: //------------------------------------------------------------------ /// Broadcaster event bits definitions. Modified: lldb/trunk/include/lldb/API/SBSymbol.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBSymbol.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBSymbol.h (original) +++ lldb/trunk/include/lldb/API/SBSymbol.h Fri Jul 1 13:39:47 2011 @@ -17,8 +17,16 @@ namespace lldb { +#ifdef SWIG +%feature("docstring", + "Represents the symbol associated with a stack frame." + ) SBSymbol; +#endif class SBSymbol { +#ifdef SWIG + %feature("autodoc", "1"); +#endif public: SBSymbol (); Modified: lldb/trunk/include/lldb/API/SBSymbolContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBSymbolContext.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBSymbolContext.h (original) +++ lldb/trunk/include/lldb/API/SBSymbolContext.h Fri Jul 1 13:39:47 2011 @@ -20,8 +20,16 @@ namespace lldb { +#ifdef SWIG +%feature("docstring", + "A container that stores various debugger related info." + ) SBSymbolContext; +#endif class SBSymbolContext { +#ifdef SWIG + %feature("autodoc", "1"); +#endif public: SBSymbolContext (); Modified: lldb/trunk/include/lldb/API/SBTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBTarget.h (original) +++ lldb/trunk/include/lldb/API/SBTarget.h Fri Jul 1 13:39:47 2011 @@ -18,8 +18,16 @@ class SBBreakpoint; +#ifdef SWIG +%feature("docstring", + "Represents the target program running under the debugger." + ) SBTarget; +#endif class SBTarget { +#ifdef SWIG + %feature("autodoc", "1"); +#endif public: //------------------------------------------------------------------ // Broadcaster bits. Modified: lldb/trunk/include/lldb/API/SBThread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBThread.h (original) +++ lldb/trunk/include/lldb/API/SBThread.h Fri Jul 1 13:39:47 2011 @@ -18,8 +18,18 @@ class SBFrame; +#ifdef SWIG +%feature("docstring", + "Represents a thread of execution." + " SBProcess contains SBThread(s)." + ) SBThread; +#endif class SBThread { +#ifdef SWIG + %feature("autodoc", "1"); +#endif + public: SBThread (); Modified: lldb/trunk/include/lldb/API/SBValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBValue.h (original) +++ lldb/trunk/include/lldb/API/SBValue.h Fri Jul 1 13:39:47 2011 @@ -16,8 +16,16 @@ namespace lldb { +#ifdef SWIG +%feature("docstring", + "Represents the value of a variable, a register, or an expression." + ) SBValue; +#endif class SBValue { +#ifdef SWIG + %feature("autodoc", "1"); +#endif public: SBValue (); Modified: lldb/trunk/scripts/lldb.swig URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=134246&r1=134245&r2=134246&view=diff ============================================================================== --- lldb/trunk/scripts/lldb.swig (original) +++ lldb/trunk/scripts/lldb.swig Fri Jul 1 13:39:47 2011 @@ -26,7 +26,7 @@ o SBFunction: Represents a generic function, which can be inlined or not. o SBBlock: Represents a lexical block. SBFunction contains SBBlock(s). o SBLineEntry: Specifies an association with a contiguous range of instructions - and a source file location. SBCompileUnit contains SBLineEntry(s)" + and a source file location. SBCompileUnit contains SBLineEntry(s)." %enddef /* The name of the module to be created. */ From johnny.chen at apple.com Fri Jul 1 17:14:07 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 01 Jul 2011 22:14:07 -0000 Subject: [Lldb-commits] [lldb] r134269 - in /lldb/trunk: include/lldb/API/SBTarget.h scripts/Python/modify-python-lldb.py Message-ID: <20110701221407.B37B22A6C12C@llvm.org> Author: johnny Date: Fri Jul 1 17:14:07 2011 New Revision: 134269 URL: http://llvm.org/viewvc/llvm-project?rev=134269&view=rev Log: Add some documentation blocks to SBTarget.h and use swig docstring feature to take advantage of them. Update modify-python-lldb.py to remove some 'residues' resulting from swigification. Modified: lldb/trunk/include/lldb/API/SBTarget.h lldb/trunk/scripts/Python/modify-python-lldb.py Modified: lldb/trunk/include/lldb/API/SBTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=134269&r1=134268&r2=134269&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBTarget.h (original) +++ lldb/trunk/include/lldb/API/SBTarget.h Fri Jul 1 17:14:07 2011 @@ -62,6 +62,9 @@ lldb::SBProcess GetProcess (); +#ifdef SWIG + %feature("autodoc", " +#endif //------------------------------------------------------------------ /// Launch a new process. /// @@ -115,6 +118,9 @@ /// @return /// A process object for the newly created process. //------------------------------------------------------------------ +#ifdef SWIG + ") Launch; +#endif lldb::SBProcess Launch (SBListener &listener, char const **argv, @@ -128,6 +134,9 @@ lldb::SBError& error); +#ifdef SWIG + %feature("autodoc", " +#endif //------------------------------------------------------------------ /// Launch a new process with sensible defaults. /// @@ -154,26 +163,107 @@ /// @return /// A process object for the newly created process. //------------------------------------------------------------------ +#ifdef SWIG + ") LaunchSimple; +#endif lldb::SBProcess LaunchSimple (const char **argv, const char **envp, const char *working_directory); +#ifdef SWIG + %feature("autodoc", " +#endif + //------------------------------------------------------------------ + /// Attach to process with pid. + /// + /// @param[in] listener + /// An optional listener that will receive all process events. + /// If \a listener is valid then \a listener will listen to all + /// process events. If not valid, then this target's debugger + /// (SBTarget::GetDebugger()) will listen to all process events. + /// + /// @param[in] pid + /// The process ID to attach to. + /// + /// @param[out] + /// An error explaining what went wrong if attach fails. + /// + /// @return + /// A process object for the attached process. + //------------------------------------------------------------------ +#ifdef SWIG + ") AttachToProcessWithID; +#endif lldb::SBProcess - AttachToProcessWithID (SBListener &listener, - lldb::pid_t pid, // The process ID to attach to - lldb::SBError& error); // An error explaining what went wrong if attach fails + AttachToProcessWithID (SBListener &listener, + lldb::pid_t pid, + lldb::SBError& error); +#ifdef SWIG + %feature("autodoc", " +#endif + //------------------------------------------------------------------ + /// Attach to process with name. + /// + /// @param[in] listener + /// An optional listener that will receive all process events. + /// If \a listener is valid then \a listener will listen to all + /// process events. If not valid, then this target's debugger + /// (SBTarget::GetDebugger()) will listen to all process events. + /// + /// @param[in] name + /// Basename of process to attach to. + /// + /// @param[in] wait_for + /// If true wait for a new instance of 'name' to be launched. + /// + /// @param[out] + /// An error explaining what went wrong if attach fails. + /// + /// @return + /// A process object for the attached process. + //------------------------------------------------------------------ +#ifdef SWIG + ") AttachToProcessWithName; +#endif lldb::SBProcess - AttachToProcessWithName (SBListener &listener, - const char *name, // basename of process to attach to - bool wait_for, // if true wait for a new instance of "name" to be launched - lldb::SBError& error); // An error explaining what went wrong if attach fails + AttachToProcessWithName (SBListener &listener, + const char *name, + bool wait_for, + lldb::SBError& error); +#ifdef SWIG + %feature("autodoc", " +#endif + //------------------------------------------------------------------ + /// Attach to process with name. + /// + /// @param[in] listener + /// An optional listener that will receive all process events. + /// If \a listener is valid then \a listener will listen to all + /// process events. If not valid, then this target's debugger + /// (SBTarget::GetDebugger()) will listen to all process events. + /// + /// @param[in] url + /// The url to connect to, e.g., 'connect://localhost:12345'. + /// + /// @param[in] plugin_name + /// The plugin name to be used; can be NULL. + /// + /// @param[out] + /// An error explaining what went wrong if the connect fails. + /// + /// @return + /// A process object for the connected process. + //------------------------------------------------------------------ +#ifdef SWIG + ") ConnectRemote; +#endif lldb::SBProcess ConnectRemote (SBListener &listener, const char *url, - const char *plugin_name, // Can be NULL + const char *plugin_name, SBError& error); lldb::SBFileSpec Modified: lldb/trunk/scripts/Python/modify-python-lldb.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=134269&r1=134268&r2=134269&view=diff ============================================================================== --- lldb/trunk/scripts/Python/modify-python-lldb.py (original) +++ lldb/trunk/scripts/Python/modify-python-lldb.py Fri Jul 1 17:14:07 2011 @@ -6,6 +6,12 @@ # objects, implements truth value testing for certain lldb objects, and adds a # global variable 'debugger_unique_id' which is initialized to 0. # +# As a cleanup step, it also removes the 'residues' from the autodoc features of +# swig. For an example, take a look at SBTarget.h header file, where we take +# advantage of the already existing C++-style headerdoc and make it the Python +# docstring for the same method. The 'residues' in this context include the +# '#endif' and the '#ifdef SWIG' lines. +# # It also calls SBDebugger.Initialize() to initialize the lldb debugger # subsystem. # @@ -19,6 +25,10 @@ # print "output_name is '" + output_name + "'" +# Residues to be removed. +c_endif_swig = "#endif" +c_ifdef_swig = "#ifdef SWIG" + # # lldb_iter() should appear before our first SB* class definition. # @@ -148,6 +158,12 @@ # value testing and the built-in operation bool(). state = NORMAL for line in content.splitlines(): + # Cleanse the lldb.py of the autodoc'ed residues. + if c_ifdef_swig in line or c_endif_swig in line: + continue + # Also remove the '\a ' substrings. + line = line.replace('\a ', '') + if state == NORMAL: match = class_pattern.search(line) # Inserts the lldb_iter() definition before the first class definition. From johnny.chen at apple.com Fri Jul 1 17:45:43 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 01 Jul 2011 22:45:43 -0000 Subject: [Lldb-commits] [lldb] r134284 - /lldb/trunk/include/lldb/API/SBTarget.h Message-ID: <20110701224543.966342A6C12C@llvm.org> Author: johnny Date: Fri Jul 1 17:45:43 2011 New Revision: 134284 URL: http://llvm.org/viewvc/llvm-project?rev=134284&view=rev Log: SWIG doesn't need two methods of the same name 'GetDescription' but differ in the presence of 'const'. Ifndef the non-const one out. Modified: lldb/trunk/include/lldb/API/SBTarget.h Modified: lldb/trunk/include/lldb/API/SBTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=134284&r1=134283&r2=134284&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBTarget.h (original) +++ lldb/trunk/include/lldb/API/SBTarget.h Fri Jul 1 17:45:43 2011 @@ -350,11 +350,13 @@ #endif +#ifndef SWIG bool - GetDescription (lldb::SBStream &description, lldb::DescriptionLevel); + GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level); +#endif bool - GetDescription (lldb::SBStream &description, lldb::DescriptionLevel) const; + GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) const; protected: friend class SBAddress; From granata.enrico at gmail.com Fri Jul 1 19:25:22 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Sat, 02 Jul 2011 00:25:22 -0000 Subject: [Lldb-commits] [lldb] r134293 - in /lldb/trunk: include/lldb/ include/lldb/Core/ source/Commands/ source/Core/ source/Interpreter/ source/Symbol/ test/functionalities/data-formatter/ Message-ID: <20110702002522.A0C152A6C12C@llvm.org> Author: enrico Date: Fri Jul 1 19:25:22 2011 New Revision: 134293 URL: http://llvm.org/viewvc/llvm-project?rev=134293&view=rev Log: several improvements to "type summary": - type names can now be regular expressions (exact matching is done first, and is faster) - integral (and floating) types can be printed as bitfields, i.e. ${var[low-high]} will extract bits low thru high of the value and print them - array subscripts are supported, both for arrays and for pointers. the syntax is ${*var[low-high]}, or ${*var[]} to print the whole array (the latter only works for statically sized arrays) - summary is now printed by default when a summary string references a variable. if that variable's type has no summary, value is printed instead. to force value, you can use %V as a format specifier - basic support for ObjectiveC: - ObjectiveC inheritance chains are now walked through - %@ can be specified as a summary format, to print the ObjectiveC runtime description for an object - some bug fixes Removed: lldb/trunk/test/functionalities/data-formatter/Makefile lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py lldb/trunk/test/functionalities/data-formatter/main.cpp Modified: lldb/trunk/include/lldb/Core/Debugger.h lldb/trunk/include/lldb/Core/FormatManager.h lldb/trunk/include/lldb/Core/RegularExpression.h lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/include/lldb/lldb-forward-rtti.h lldb/trunk/source/Commands/CommandObjectType.cpp lldb/trunk/source/Core/Debugger.cpp lldb/trunk/source/Core/FormatManager.cpp lldb/trunk/source/Core/RegularExpression.cpp lldb/trunk/source/Core/ValueObject.cpp lldb/trunk/source/Core/ValueObjectDynamicValue.cpp lldb/trunk/source/Interpreter/CommandObject.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/include/lldb/Core/Debugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Debugger.h (original) +++ lldb/trunk/include/lldb/Core/Debugger.h Fri Jul 1 19:25:22 2011 @@ -476,48 +476,82 @@ class ValueFormats { - public: - static bool - Get(ValueObject& vobj, ValueFormat::SharedPointer &entry); - - static void - Add(const ConstString &type, const ValueFormat::SharedPointer &entry); - - static bool - Delete(const ConstString &type); - - static void - Clear(); - - static void - LoopThrough(FormatManager::ValueCallback callback, void* callback_baton); - - static uint32_t GetCurrentRevision(); + public: + static bool + Get(ValueObject& vobj, ValueFormat::SharedPointer &entry); + + static void + Add(const ConstString &type, const ValueFormat::SharedPointer &entry); + + static bool + Delete(const ConstString &type); + + static void + Clear(); + + static void + LoopThrough(ValueFormat::ValueCallback callback, void* callback_baton); + + static uint32_t + GetCurrentRevision(); + + static uint32_t + GetCount(); }; class SummaryFormats { - public: + public: + + static bool + Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry); + + static void + Add(const ConstString &type, const SummaryFormat::SharedPointer &entry); + + static bool + Delete(const ConstString &type); - static bool - Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry); - - static void - Add(const ConstString &type, const SummaryFormat::SharedPointer &entry); - - static bool - Delete(const ConstString &type); - - static void - Clear(); - - static void - LoopThrough(FormatManager::SummaryCallback callback, void* callback_baton); - - static uint32_t - GetCurrentRevision(); + static void + Clear(); + + static void + LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton); + + static uint32_t + GetCurrentRevision(); + + static uint32_t + GetCount(); }; + class RegexSummaryFormats + { + public: + + static bool + Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry); + + static void + Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry); + + static bool + Delete(const ConstString &type); + + static void + Clear(); + + static void + LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton); + + static uint32_t + GetCurrentRevision(); + + static uint32_t + GetCount(); + }; + + }; } // namespace lldb_private Modified: lldb/trunk/include/lldb/Core/FormatManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/FormatManager.h (original) +++ lldb/trunk/include/lldb/Core/FormatManager.h Fri Jul 1 19:25:22 2011 @@ -33,6 +33,10 @@ #include // Other libraries and framework includes +#include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" +#include "clang/AST/DeclObjC.h" + // Project includes #include "lldb/lldb-public.h" #include "lldb/lldb-enumerations.h" @@ -40,6 +44,7 @@ #include "lldb/Core/Communication.h" #include "lldb/Core/InputReaderStack.h" #include "lldb/Core/Listener.h" +#include "lldb/Core/RegularExpression.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/SourceManager.h" #include "lldb/Core/UserID.h" @@ -49,9 +54,6 @@ #include "lldb/Target/Platform.h" #include "lldb/Target/TargetList.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/Type.h" - namespace lldb_private { class IFormatChangeListener @@ -72,12 +74,22 @@ bool m_dont_show_value; bool m_show_members_oneliner; bool m_cascades; - SummaryFormat(std::string f = "", bool c = false, bool nochildren = true, bool novalue = true, bool oneliner = false) : + bool m_skip_references; + bool m_skip_pointers; + SummaryFormat(std::string f = "", + bool c = false, + bool nochildren = true, + bool novalue = true, + bool oneliner = false, + bool skipptr = false, + bool skipref = false) : m_format(f), m_dont_show_children(nochildren), m_dont_show_value(novalue), m_show_members_oneliner(oneliner), - m_cascades(c) + m_cascades(c), + m_skip_references(skipref), + m_skip_pointers(skipptr) { } @@ -100,6 +112,8 @@ } typedef lldb::SharedPtr::Type SharedPointer; + typedef bool(*SummaryCallback)(void*, const char*, const SummaryFormat::SharedPointer&); + typedef bool(*RegexSummaryCallback)(void*, lldb::RegularExpressionSP, const SummaryFormat::SharedPointer&); }; @@ -107,13 +121,21 @@ { lldb::Format m_format; bool m_cascades; - ValueFormat (lldb::Format f = lldb::eFormatInvalid, bool c = false) : + bool m_skip_references; + bool m_skip_pointers; + ValueFormat (lldb::Format f = lldb::eFormatInvalid, + bool c = false, + bool skipptr = false, + bool skipref = false) : m_format (f), - m_cascades (c) + m_cascades (c), + m_skip_references(skipref), + m_skip_pointers(skipptr) { } typedef lldb::SharedPtr::Type SharedPointer; + typedef bool(*ValueCallback)(void*, const char*, const ValueFormat::SharedPointer&); ~ValueFormat() { @@ -160,7 +182,7 @@ } bool - Delete(const MapKeyType& type) + Delete(const char* type) { Mutex::Locker(m_map_mutex); MapIterator iter = m_map.find(type); @@ -197,6 +219,12 @@ } } + uint32_t + GetCount() + { + return m_map.size(); + } + ~FormatNavigator() { } @@ -210,7 +238,7 @@ DISALLOW_COPY_AND_ASSIGN(FormatNavigator); bool - Get(const MapKeyType &type, MapValueType& entry) + Get(const char* type, MapValueType& entry) { Mutex::Locker(m_map_mutex); MapIterator iter = m_map.find(type); @@ -228,16 +256,62 @@ return false; clang::QualType type = q_type.getUnqualifiedType(); type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict(); - ConstString name(type.getAsString().c_str()); + const clang::Type* typePtr = type.getTypePtrOrNull(); + if (!typePtr) + return false; + ConstString name(ClangASTType::GetTypeNameForQualType(type).c_str()); //printf("trying to get format for VO name %s of type %s\n",vobj.GetName().AsCString(),name.AsCString()); if (Get(name.GetCString(), entry)) return true; // look for a "base type", whatever that means - const clang::Type* typePtr = type.getTypePtrOrNull(); - if (!typePtr) - return false; if (typePtr->isReferenceType()) - return Get(vobj,type.getNonReferenceType(),entry); + { + if (Get(vobj,type.getNonReferenceType(),entry) && !entry->m_skip_references) + return true; + } + if (typePtr->isPointerType()) + { + if (Get(vobj, typePtr->getPointeeType(), entry) && !entry->m_skip_pointers) + return true; + } + if (typePtr->isObjCObjectPointerType()) + { + /* + for some reason, C++ can quite easily obtain the type hierarchy for a ValueObject + even if the VO represent a pointer-to-class, as long as the typePtr is right + Objective-C on the other hand cannot really complete an @interface when + the VO refers to a pointer-to- at interface + */ + Error error; + ValueObject* target = vobj.Dereference(error).get(); + if(error.Fail() || !target) + return false; + if (Get(*target, typePtr->getPointeeType(), entry) && !entry->m_skip_pointers) + return true; + } + const clang::ObjCObjectType *objc_class_type = typePtr->getAs(); + if (objc_class_type) + { + //printf("working with ObjC\n"); + clang::ASTContext *ast = vobj.GetClangAST(); + if (ClangASTContext::GetCompleteType(ast, vobj.GetClangType()) && !objc_class_type->isObjCId()) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + if(class_interface_decl) + { + //printf("down here\n"); + clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + //printf("one further step and we're there...\n"); + if(superclass_interface_decl) + { + //printf("the end is here\n"); + clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl)); + if (Get(vobj, ivar_qual_type, entry) && entry->m_cascades) + return true; + } + } + } + } // for C++ classes, navigate up the hierarchy if (typePtr->isRecordType()) { @@ -245,15 +319,7 @@ if (record) { if (!record->hasDefinition()) - // dummy call to do the complete - ClangASTContext::GetNumChildren(vobj.GetClangAST(), vobj.GetClangType(), false); - clang::IdentifierInfo *info = record->getIdentifier(); - if (info) { - // this is the class name, plain and simple - ConstString id_info(info->getName().str().c_str()); - if (Get(id_info.GetCString(), entry)) - return true; - } + ClangASTContext::GetCompleteType(vobj.GetClangAST(), vobj.GetClangType()); if (record->hasDefinition()) { clang::CXXRecordDecl::base_class_iterator pos,end; @@ -287,25 +353,34 @@ } }; - + +template<> +bool +FormatNavigator, SummaryFormat::RegexSummaryCallback>::Get(const char* key, + SummaryFormat::SharedPointer& value); + +template<> +bool +FormatNavigator, SummaryFormat::RegexSummaryCallback>::Delete(const char* type); + class FormatManager : public IFormatChangeListener { public: - typedef bool(*ValueCallback)(void*, const char*, const ValueFormat::SharedPointer&); - typedef bool(*SummaryCallback)(void*, const char*, const SummaryFormat::SharedPointer&); - private: typedef std::map ValueMap; typedef std::map SummaryMap; + typedef std::map RegexSummaryMap; - typedef FormatNavigator ValueNavigator; - typedef FormatNavigator SummaryNavigator; + typedef FormatNavigator ValueNavigator; + typedef FormatNavigator SummaryNavigator; + typedef FormatNavigator RegexSummaryNavigator; ValueNavigator m_value_nav; SummaryNavigator m_summary_nav; + RegexSummaryNavigator m_regex_summary_nav; uint32_t m_last_revision; @@ -314,6 +389,7 @@ FormatManager() : m_value_nav(this), m_summary_nav(this), + m_regex_summary_nav(this), m_last_revision(0) { } @@ -321,6 +397,8 @@ ValueNavigator& Value() { return m_value_nav; } SummaryNavigator& Summary() { return m_summary_nav; } + RegexSummaryNavigator& RegexSummary() { return m_regex_summary_nav; } + static bool GetFormatFromCString (const char *format_cstr, Modified: lldb/trunk/include/lldb/Core/RegularExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RegularExpression.h?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/RegularExpression.h (original) +++ lldb/trunk/include/lldb/Core/RegularExpression.h Fri Jul 1 19:25:22 2011 @@ -149,6 +149,9 @@ //------------------------------------------------------------------ bool IsValid () const; + + bool + operator < (const RegularExpression& rhs) const; private: //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Core/ValueObject.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObject.h (original) +++ lldb/trunk/include/lldb/Core/ValueObject.h Fri Jul 1 19:25:22 2011 @@ -70,6 +70,13 @@ eDereferencePointers = 1, eHonorPointers, }; + + enum ValueObjectRepresentationStyle + { + eDisplayValue, + eDisplaySummary, + eDisplayLanguageSpecific + }; class EvaluationPoint { @@ -344,6 +351,10 @@ const char * GetObjectDescription (); + + const char * + GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display = eDisplaySummary, + lldb::Format custom_format = lldb::eFormatInvalid); bool GetValueIsValid () const; @@ -352,7 +363,7 @@ GetValueDidChange (); bool - UpdateValueIfNeeded (); + UpdateValueIfNeeded (bool update_format = true); void UpdateFormatsIfNeeded(); @@ -525,7 +536,8 @@ m_children_count_valid:1, m_old_value_valid:1, m_pointers_point_to_load_addrs:1, - m_is_deref_of_parent:1; + m_is_deref_of_parent:1, + m_is_array_item_for_pointer:1; friend class ClangExpressionDeclMap; // For GetValue friend class ClangExpressionVariable; // For SetName Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Fri Jul 1 19:25:22 2011 @@ -351,6 +351,7 @@ eArgTypeExprFormat, eArgTypeFilename, eArgTypeFormat, + eArgTypeFormatString, eArgTypeFrameIndex, eArgTypeFullName, eArgTypeFunctionName, Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward-rtti.h (original) +++ lldb/trunk/include/lldb/lldb-forward-rtti.h Fri Jul 1 19:25:22 2011 @@ -53,6 +53,7 @@ typedef SharedPtr::Type PlatformSP; typedef SharedPtr::Type ProcessSP; typedef SharedPtr::Type RegisterContextSP; + typedef SharedPtr::Type RegularExpressionSP; typedef SharedPtr::Type SectionSP; typedef SharedPtr::Type SearchFilterSP; typedef SharedPtr::Type StackFrameSP; Modified: lldb/trunk/source/Commands/CommandObjectType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectType.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectType.cpp Fri Jul 1 19:25:22 2011 @@ -15,6 +15,7 @@ #include "lldb/Core/ConstString.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatManager.h" +#include "lldb/Core/RegularExpression.h" #include "lldb/Core/State.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObject.h" @@ -54,11 +55,14 @@ switch (short_option) { - case 'c': + case 'C': m_cascade = Args::StringToBoolean(option_arg, true, &success); if (!success) error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); break; + case 'f': + error = Args::StringToFormat(option_arg, m_format, NULL); + break; default: error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); break; @@ -71,6 +75,7 @@ OptionParsingStarting () { m_cascade = true; + m_format = eFormatInvalid; } const OptionDefinition* @@ -86,6 +91,7 @@ // Instance variables to hold the values for command options. bool m_cascade; + lldb::Format m_format; }; CommandOptions m_options; @@ -103,21 +109,14 @@ "Add a new formatting style for a type.", NULL), m_options (interpreter) { - CommandArgumentEntry format_arg; - CommandArgumentData format_style_arg; CommandArgumentEntry type_arg; CommandArgumentData type_style_arg; - format_style_arg.arg_type = eArgTypeFormat; - format_style_arg.arg_repetition = eArgRepeatPlain; - type_style_arg.arg_type = eArgTypeName; type_style_arg.arg_repetition = eArgRepeatPlus; - format_arg.push_back (format_style_arg); type_arg.push_back (type_style_arg); - - m_arguments.push_back (format_arg); + m_arguments.push_back (type_arg); } @@ -130,40 +129,27 @@ { const size_t argc = command.GetArgumentCount(); - if (argc < 2) + if (argc < 1) { - result.AppendErrorWithFormat ("%s takes two or more args.\n", m_cmd_name.c_str()); + result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); result.SetStatus(eReturnStatusFailed); return false; } - const char* format_cstr = command.GetArgumentAtIndex(0); - - if (!format_cstr || !format_cstr[0]) + if(m_options.m_format == eFormatInvalid) { - result.AppendError("empty format strings not allowed"); + result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str()); result.SetStatus(eReturnStatusFailed); return false; } - lldb::Format format; - Error error; - - error = Args::StringToFormat(format_cstr, format, NULL); - ValueFormat::SharedPointer entry; + ValueFormatSP entry; - entry.reset(new ValueFormat(format,m_options.m_cascade)); + entry.reset(new ValueFormat(m_options.m_format,m_options.m_cascade)); - if (error.Fail()) - { - result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); - return false; - } - // now I have a valid format, let's add it to every type - for(int i = 1; i < argc; i++) { + for(int i = 0; i < argc; i++) { const char* typeA = command.GetArgumentAtIndex(i); ConstString typeCS(typeA); if (typeCS) @@ -179,13 +165,13 @@ result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); } - }; OptionDefinition CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "cascade", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, + { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, + { LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeFormat, "The format to use to display this type."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; @@ -411,25 +397,31 @@ switch (short_option) { - case 'c': + case 'C': m_cascade = Args::StringToBoolean(option_arg, true, &success); if (!success) error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); break; - case 'h': - m_no_children = !Args::StringToBoolean(option_arg, true, &success); - if (!success) - error.SetErrorStringWithFormat("Invalid value for nochildren: %s.\n", option_arg); + case 'e': + m_no_children = false; break; case 'v': - m_no_value = !Args::StringToBoolean(option_arg, true, &success); - if (!success) - error.SetErrorStringWithFormat("Invalid value for novalue: %s.\n", option_arg); + m_no_value = true; break; - case 'o': - m_one_liner = Args::StringToBoolean(option_arg, true, &success); - if (!success) - error.SetErrorStringWithFormat("Invalid value for oneliner: %s.\n", option_arg); + case 'c': + m_one_liner = true; + break; + case 'f': + m_format_string = std::string(option_arg); + break; + case 'p': + m_skip_pointers = true; + break; + case 'r': + m_skip_references = true; + break; + case 'x': + m_regex = true; break; default: error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); @@ -446,6 +438,9 @@ m_no_children = true; m_no_value = false; m_one_liner = false; + m_skip_references = false; + m_skip_pointers = false; + m_regex = false; } const OptionDefinition* @@ -464,6 +459,10 @@ bool m_no_children; bool m_no_value; bool m_one_liner; + bool m_skip_references; + bool m_skip_pointers; + bool m_regex; + std::string m_format_string; }; CommandOptions m_options; @@ -481,21 +480,14 @@ "Add a new summary style for a type.", NULL), m_options (interpreter) { - CommandArgumentEntry format_arg; - CommandArgumentData format_style_arg; CommandArgumentEntry type_arg; CommandArgumentData type_style_arg; - format_style_arg.arg_type = eArgTypeFormat; - format_style_arg.arg_repetition = eArgRepeatPlain; - type_style_arg.arg_type = eArgTypeName; type_style_arg.arg_repetition = eArgRepeatPlus; - format_arg.push_back (format_style_arg); type_arg.push_back (type_style_arg); - m_arguments.push_back (format_arg); m_arguments.push_back (type_arg); } @@ -508,34 +500,29 @@ { const size_t argc = command.GetArgumentCount(); - // we support just one custom syntax: type summary add -o yes typeName - // anything else, must take the usual route - // e.g. type summary add -o yes "" type1 type2 ... typeN - - bool isValidShortcut = m_options.m_one_liner && (argc == 1); - bool isValid = (argc >= 2); - - if (!isValidShortcut && !isValid) + if (argc < 1) { - result.AppendErrorWithFormat ("%s takes two or more args.\n", m_cmd_name.c_str()); + result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); result.SetStatus(eReturnStatusFailed); return false; } - const char* format_cstr = (isValidShortcut ? "" : command.GetArgumentAtIndex(0)); - - if ( (!format_cstr || !format_cstr[0]) && !m_options.m_one_liner ) + if(!m_options.m_one_liner && m_options.m_format_string.empty()) { result.AppendError("empty summary strings not allowed"); result.SetStatus(eReturnStatusFailed); return false; } + const char* format_cstr = (m_options.m_one_liner ? "" : m_options.m_format_string.c_str()); + Error error; SummaryFormat::SharedPointer entry(new SummaryFormat(format_cstr,m_options.m_cascade, m_options.m_no_children,m_options.m_no_value, - m_options.m_one_liner)); + m_options.m_one_liner, + m_options.m_skip_pointers, + m_options.m_skip_references)); if (error.Fail()) { @@ -546,17 +533,31 @@ // now I have a valid format, let's add it to every type - for(int i = (isValidShortcut ? 0 : 1); i < argc; i++) { + for(int i = 0; i < argc; i++) { const char* typeA = command.GetArgumentAtIndex(i); - ConstString typeCS(typeA); - if (typeCS) - Debugger::SummaryFormats::Add(typeCS, entry); - else + if(!typeA || typeA[0] == '\0') { result.AppendError("empty typenames not allowed"); result.SetStatus(eReturnStatusFailed); return false; } + ConstString typeCS(typeA); + if(!m_options.m_regex) + { + Debugger::SummaryFormats::Add(typeCS, entry); + } + else + { + RegularExpressionSP typeRX(new RegularExpression()); + if(!typeRX->Compile(typeA)) + { + result.AppendError("regex format error (maybe this is not really a regex?)"); + result.SetStatus(eReturnStatusFailed); + return false; + } + Debugger::RegexSummaryFormats::Delete(typeCS); + Debugger::RegexSummaryFormats::Add(typeRX, entry); + } } result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); @@ -567,10 +568,14 @@ OptionDefinition CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "cascade", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, - { LLDB_OPT_SET_ALL, false, "show-children", 'h', required_argument, NULL, 0, eArgTypeBoolean, "If true, print children."}, - { LLDB_OPT_SET_ALL, false, "show-value", 'v', required_argument, NULL, 0, eArgTypeBoolean, "If true, print value."}, - { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, 0, eArgTypeBoolean, "If true, just print a one-line preformatted summary."}, + { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, + { LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeBoolean, "Don't show the value, just show the summary, for this type."}, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for pointers-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for references-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeBoolean, "Type names are actually regular expressions."}, + { LLDB_OPT_SET_1 , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeBoolean, "If true, inline all child values into summary string."}, + { LLDB_OPT_SET_2 , true, "format-string", 'f', required_argument, NULL, 0, eArgTypeFormatString, "Format string used to display text and object contents."}, + { LLDB_OPT_SET_2, false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean, "Expand aggregate data types to show children on separate lines."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; @@ -626,8 +631,9 @@ return false; } - - if (Debugger::SummaryFormats::Delete(typeCS)) + bool delete_summary = Debugger::SummaryFormats::Delete(typeCS); + bool delete_regex = Debugger::RegexSummaryFormats::Delete(typeCS); + if (delete_summary || delete_regex) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); @@ -666,6 +672,7 @@ Execute (Args& command, CommandReturnObject &result) { Debugger::SummaryFormats::Clear(); + Debugger::RegexSummaryFormats::Clear(); result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } @@ -677,6 +684,7 @@ //------------------------------------------------------------------------- bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry); +bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry); class CommandObjectTypeSummaryList; @@ -688,6 +696,14 @@ RegularExpression* X = NULL) : self(S), result(R), regex(X) {} }; +struct CommandObjectTypeRXSummaryList_LoopCallbackParam { + CommandObjectTypeSummaryList* self; + CommandReturnObject* result; + RegularExpression* regex; + CommandObjectTypeRXSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R, + RegularExpression* X = NULL) : self(S), result(R), regex(X) {} +}; + class CommandObjectTypeSummaryList : public CommandObject { public: @@ -718,6 +734,7 @@ const size_t argc = command.GetArgumentCount(); CommandObjectTypeSummaryList_LoopCallbackParam *param; + CommandObjectTypeRXSummaryList_LoopCallbackParam *rxparam; if (argc == 1) { RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); @@ -728,6 +745,24 @@ param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result); Debugger::SummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param); delete param; + + if(Debugger::RegexSummaryFormats::GetCount() == 0) + { + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } + + result.GetOutputStream().Printf("Regex-based summaries (slower):\n"); + if (argc == 1) { + RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); + regex->Compile(command.GetArgumentAtIndex(0)); + rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result,regex); + } + else + rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result); + Debugger::RegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam); + delete rxparam; + result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } @@ -742,18 +777,21 @@ { if (regex == NULL || regex->Execute(type)) { - result->GetOutputStream().Printf ("%s: `%s`%s%s%s%s\n", type, + result->GetOutputStream().Printf ("%s: `%s`%s%s%s%s%s%s\n", type, entry->m_format.c_str(), entry->m_cascades ? "" : " (not cascading)", entry->m_dont_show_children ? "" : " (show children)", - entry->m_dont_show_value ? "" : " (show value)", - entry->m_show_members_oneliner ? " (one-line printout)" : ""); + entry->m_dont_show_value ? " (hide value)" : "", + entry->m_show_members_oneliner ? " (one-line printout)" : "", + entry->m_skip_pointers ? " (skip pointers)" : "", + entry->m_skip_references ? " (skip references)" : ""); } return true; } friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry); - + friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry); + }; bool @@ -766,6 +804,15 @@ return param->self->LoopCallback(type, entry, param->regex, param->result); } +bool +CommandObjectTypeRXSummaryList_LoopCallback ( + void* pt2self, + lldb::RegularExpressionSP regex, + const SummaryFormat::SharedPointer& entry) +{ + CommandObjectTypeRXSummaryList_LoopCallbackParam* param = (CommandObjectTypeRXSummaryList_LoopCallbackParam*)pt2self; + return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); +} @@ -796,7 +843,7 @@ public: CommandObjectTypeSummary (CommandInterpreter &interpreter) : CommandObjectMultiword (interpreter, - "type format", + "type summary", "A set of commands for editing variable summary display options", "type summary [] ") { Modified: lldb/trunk/source/Core/Debugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/source/Core/Debugger.cpp (original) +++ lldb/trunk/source/Core/Debugger.cpp Fri Jul 1 19:25:22 2011 @@ -791,15 +791,201 @@ case '*': { if (!vobj) break; - var_name_begin++; lldb::clang_type_t pointer_clang_type = vobj->GetClangType(); clang_type_t elem_or_pointee_clang_type; const Flags type_flags (ClangASTContext::GetTypeInfo (pointer_clang_type, vobj->GetClangAST(), &elem_or_pointee_clang_type)); - if (type_flags.Test (ClangASTContext::eTypeIsPointer)) + bool is_pointer = type_flags.Test (ClangASTContext::eTypeIsPointer), + is_array = type_flags.Test (ClangASTContext::eTypeIsArray); + if ( is_array || + ( is_pointer && ::strchr(var_name_begin,'[') && ::strchr(var_name_begin,'[') < var_name_end ) + ) + { + const char* var_name_final; + char* close_bracket_position = NULL; + const char* percent_position = NULL; + const char* targetvalue; + lldb::Format custom_format = eFormatInvalid; + int index_lower = -1; + int index_higher = -1; + ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eDisplaySummary; + { + percent_position = ::strchr(var_name_begin,'%'); + if(!percent_position || percent_position > var_name_end) + var_name_final = var_name_end; + else + { + var_name_final = percent_position; + char* format_name = new char[var_name_end-var_name_final]; format_name[var_name_end-var_name_final-1] = '\0'; + memcpy(format_name, var_name_final+1, var_name_end-var_name_final-1); + if ( !FormatManager::GetFormatFromCString(format_name, + true, + custom_format) ) + { + // if this is an @ sign, print ObjC description + if(*format_name == '@') + val_obj_display = ValueObject::eDisplayLanguageSpecific; + // if this is a V, print the value using the default format + if(*format_name == 'V') + val_obj_display = ValueObject::eDisplayValue; + } + // a good custom format tells us to print the value using it + else + val_obj_display = ValueObject::eDisplayValue; + } + } + + { + const char* open_bracket_position = ::strchr(var_name_begin,'['); + if(open_bracket_position && open_bracket_position < var_name_final) + { + // TODO: pick a way to say "all entries". this will make more sense once + // regex typenames are in place. now, you need to be size-aware anyways + char* separator_position = ::strchr(open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield + close_bracket_position = ::strchr(open_bracket_position,']'); + // as usual, we assume that [] will come before % + //printf("trying to expand a []\n"); + var_name_final = open_bracket_position; + if(close_bracket_position - open_bracket_position == 1) + { + if(is_array) + { + index_lower = 0; + index_higher = vobj->GetNumChildren() - 1; + } + else + break; // cannot auto-determine size for pointers + } + else if (separator_position == NULL || separator_position > var_name_end) + { + char *end = NULL; + index_lower = ::strtoul (open_bracket_position+1, &end, 0); + index_higher = index_lower; + //printf("got to read low=%d high same\n",bitfield_lower); + } + else if(close_bracket_position && close_bracket_position < var_name_end) + { + char *end = NULL; + index_lower = ::strtoul (open_bracket_position+1, &end, 0); + index_higher = ::strtoul (separator_position+1, &end, 0); + //printf("got to read low=%d high=%d\n",bitfield_lower,bitfield_higher); + } + else + break; + if (index_lower > index_higher) + { + int temp = index_lower; + index_lower = index_higher; + index_higher = temp; + } + //*((char*)open_bracket_position) = '\0'; + //printf("variable name is %s\n",var_name_begin); + //*((char*)open_bracket_position) = '['; + } + } + + // if you just type a range, lldb will do the "right thing" in picking + // a reasonable display for the array entries. you can override this by + // giving other input (e.g. ${*var[1-3].member1%uint8_t[]}) and they + // will be honored + char* special_directions = NULL; + if (close_bracket_position && (var_name_end-close_bracket_position > 1)) + { + int base_len = var_name_end-close_bracket_position; + special_directions = new char[8+base_len]; + special_directions[0] = '$'; + special_directions[1] = '{'; + special_directions[2] = 'v'; + special_directions[3] = 'a'; + special_directions[4] = 'r'; + memcpy(special_directions+5, close_bracket_position+1, base_len); + special_directions[base_len+7] = '\0'; + printf("%s\n",special_directions); + } + + // let us display items index_lower thru index_higher of this array + s.PutChar('['); + var_success = true; + const char* expr_path = NULL; + const char* ptr_deref_format = "%s[%d]"; + char* ptr_deref_buffer = new char[1024]; + StreamString expr_path_string; + + if(is_pointer) + { + vobj->GetExpressionPath(expr_path_string, true, ValueObject::eHonorPointers); + expr_path = expr_path_string.GetData(); + } + + for(;index_lower<=index_higher;index_lower++) + { + ValueObject* item; + + if(is_array) + item = vobj->GetChildAtIndex(index_lower, true).get(); + else + { +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("name to deref in phase 0: %s\n",expr_path); +#endif //VERBOSE_FORMATPROMPT_OUTPUT + ::sprintf(ptr_deref_buffer, ptr_deref_format, expr_path, index_lower); +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("name to deref in phase 1: %s\n",ptr_deref_buffer); +#endif //VERBOSE_FORMATPROMPT_OUTPUT + lldb::VariableSP var_sp; + Error error; + item = exe_ctx->frame->GetValueForVariableExpressionPath (ptr_deref_buffer, + eNoDynamicValues, + 0, + var_sp, + error).get(); + if (error.Fail()) + { +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("ERROR: %s\n",error.AsCString("unknown")); +#endif //VERBOSE_FORMATPROMPT_OUTPUT + break; + } + } + + if (!special_directions) + { + targetvalue = item->GetPrintableRepresentation(val_obj_display, custom_format); + if(targetvalue) + s.PutCString(targetvalue); + var_success &= (targetvalue != NULL); + if(custom_format != eFormatInvalid) + item->SetFormat(eFormatDefault); + } + else + { + var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item); + } + + if(index_lower < index_higher) + s.PutChar(','); + } + s.PutChar(']'); + break; + + } + else if (is_pointer) { - if (ClangASTContext::IsCharType (elem_or_pointee_clang_type)) + var_name_begin++; + uint32_t offset = 0; + DataExtractor read_for_null = vobj->GetDataExtractor(); + if (read_for_null.GetPointer(&offset) == 0) + break; + if (ClangASTContext::IsAggregateType (elem_or_pointee_clang_type) ) + { + Error error; + realvobj = vobj; + vobj = vobj->Dereference(error).get(); + if(!vobj || error.Fail()) + break; + } + else if (ClangASTContext::IsCharType (elem_or_pointee_clang_type)) { StreamString sstr; ExecutionContextScope *exe_scope = vobj->GetExecutionContextScope(); @@ -849,7 +1035,7 @@ break; } } - else /*if (ClangASTContext::IsAggregateType (elem_or_pointee_clang_type)) or this is some other pointer type*/ + else /*some other pointer type*/ { Error error; realvobj = vobj; @@ -864,7 +1050,7 @@ case 'v': { const char* targetvalue; - bool use_summary = false; + ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eDisplaySummary; ValueObject* target; lldb::Format custom_format = eFormatInvalid; int bitfield_lower = -1; @@ -872,12 +1058,16 @@ if (!vobj) break; // simplest case ${var}, just print vobj's value if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) + { target = vobj; + val_obj_display = ValueObject::eDisplayValue; + } else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) { // this is a variable with some custom format applied to it const char* var_name_final; target = vobj; + val_obj_display = ValueObject::eDisplayValue; { const char* percent_position = ::strchr(var_name_begin,'%'); // TODO: make this a constant //if(!percent_position || percent_position > var_name_end) @@ -887,9 +1077,14 @@ var_name_final = percent_position; char* format_name = new char[var_name_end-var_name_final]; format_name[var_name_end-var_name_final-1] = '\0'; memcpy(format_name, var_name_final+1, var_name_end-var_name_final-1); - FormatManager::GetFormatFromCString(format_name, + if ( !FormatManager::GetFormatFromCString(format_name, true, - custom_format); // if this fails, custom_format is reset to invalid + custom_format) ) + { + // if this is an @ sign, print ObjC description + if(*format_name == '@') + val_obj_display = ValueObject::eDisplayLanguageSpecific; + } delete format_name; //} } @@ -899,7 +1094,7 @@ // this is a bitfield variable const char *var_name_final; target = vobj; - + val_obj_display = ValueObject::eDisplayValue; { const char* percent_position = ::strchr(var_name_begin,'%'); if(!percent_position || percent_position > var_name_end) @@ -909,10 +1104,15 @@ var_name_final = percent_position; char* format_name = new char[var_name_end-var_name_final]; format_name[var_name_end-var_name_final-1] = '\0'; memcpy(format_name, var_name_final+1, var_name_end-var_name_final-1); - FormatManager::GetFormatFromCString(format_name, - true, - custom_format); // if this fails, custom_format is reset to invalid - delete format_name; + if ( !FormatManager::GetFormatFromCString(format_name, + true, + custom_format) ) + { + delete format_name; + break; + } + else + delete format_name; } } @@ -943,7 +1143,11 @@ else break; if(bitfield_lower > bitfield_higher) - break; + { + int temp = bitfield_lower; + bitfield_lower = bitfield_higher; + bitfield_higher = temp; + } } } } @@ -966,10 +1170,20 @@ var_name_final = percent_position; char* format_name = new char[var_name_end-var_name_final]; format_name[var_name_end-var_name_final-1] = '\0'; memcpy(format_name, var_name_final+1, var_name_end-var_name_final-1); - FormatManager::GetFormatFromCString(format_name, - true, - custom_format); // if this fails, custom_format is reset to invalid - delete format_name; + if ( !FormatManager::GetFormatFromCString(format_name, + true, + custom_format) ) + { + // if this is an @ sign, print ObjC description + if(*format_name == '@') + val_obj_display = ValueObject::eDisplayLanguageSpecific; + // if this is a V, print the value using the default format + if(*format_name == 'V') + val_obj_display = ValueObject::eDisplayValue; + } + // a good custom format tells us to print the value using it + else + val_obj_display = ValueObject::eDisplayValue; } } @@ -999,7 +1213,11 @@ else break; if(bitfield_lower > bitfield_higher) - break; + { + int temp = bitfield_lower; + bitfield_lower = bitfield_higher; + bitfield_higher = temp; + } //*((char*)open_bracket_position) = '\0'; //printf("variable name is %s\n",var_name_begin); //*((char*)open_bracket_position) = '['; @@ -1010,9 +1228,13 @@ lldb::VariableSP var_sp; StreamString sstring; vobj->GetExpressionPath(sstring, true, ValueObject::eHonorPointers); - //printf("name to expand in phase 0: %s\n",sstring.GetData()); +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("name to expand in phase 0: %s\n",sstring.GetData()); +#endif //VERBOSE_FORMATPROMPT_OUTPUT sstring.PutRawBytes(var_name_begin+3, var_name_final-var_name_begin-3); - //printf("name to expand in phase 1: %s\n",sstring.GetData()); +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("name to expand in phase 1: %s\n",sstring.GetData()); +#endif //VERBOSE_FORMATPROMPT_OUTPUT std::string name = std::string(sstring.GetData()); target = exe_ctx->frame->GetValueForVariableExpressionPath (name.c_str(), eNoDynamicValues, @@ -1021,17 +1243,14 @@ error).get(); if (error.Fail()) { - //printf("ERROR: %s\n",error.AsCString("unknown")); +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("ERROR: %s\n",error.AsCString("unknown")); +#endif //VERBOSE_FORMATPROMPT_OUTPUT break; } } else break; - if(*(var_name_end+1)=='s') - { - use_summary = true; - var_name_end++; - } if (bitfield_lower >= 0) { //printf("trying to print a []\n"); @@ -1046,16 +1265,8 @@ } else { - //printf("here I come 1\n"); // format this as usual - if(custom_format != eFormatInvalid) - target->SetFormat(custom_format); - //printf("here I come 2\n"); - if(!use_summary) - targetvalue = target->GetValueAsCString(); - else - targetvalue = target->GetSummaryAsCString(); - //printf("here I come 3\n"); + targetvalue = target->GetPrintableRepresentation(val_obj_display, custom_format); if(targetvalue) s.PutCString(targetvalue); var_success = targetvalue; @@ -1634,7 +1845,7 @@ } void -Debugger::ValueFormats::LoopThrough(FormatManager::ValueCallback callback, void* callback_baton) +Debugger::ValueFormats::LoopThrough(ValueFormat::ValueCallback callback, void* callback_baton) { GetFormatManager().Value().LoopThrough(callback, callback_baton); } @@ -1645,6 +1856,11 @@ return GetFormatManager().GetCurrentRevision(); } +uint32_t +Debugger::ValueFormats::GetCount() +{ + return GetFormatManager().Value().GetCount(); +} bool Debugger::SummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry) @@ -1671,7 +1887,7 @@ } void -Debugger::SummaryFormats::LoopThrough(FormatManager::SummaryCallback callback, void* callback_baton) +Debugger::SummaryFormats::LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton) { GetFormatManager().Summary().LoopThrough(callback, callback_baton); } @@ -1682,6 +1898,54 @@ return GetFormatManager().GetCurrentRevision(); } +uint32_t +Debugger::SummaryFormats::GetCount() +{ + return GetFormatManager().Summary().GetCount(); +} + +bool +Debugger::RegexSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry) +{ + return GetFormatManager().RegexSummary().Get(vobj,entry); +} + +void +Debugger::RegexSummaryFormats::Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry) +{ + GetFormatManager().RegexSummary().Add(type,entry); +} + +bool +Debugger::RegexSummaryFormats::Delete(const ConstString &type) +{ + return GetFormatManager().RegexSummary().Delete(type.AsCString()); +} + +void +Debugger::RegexSummaryFormats::Clear() +{ + GetFormatManager().RegexSummary().Clear(); +} + +void +Debugger::RegexSummaryFormats::LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton) +{ + GetFormatManager().RegexSummary().LoopThrough(callback, callback_baton); +} + +uint32_t +Debugger::RegexSummaryFormats::GetCurrentRevision() +{ + return GetFormatManager().GetCurrentRevision(); +} + +uint32_t +Debugger::RegexSummaryFormats::GetCount() +{ + return GetFormatManager().RegexSummary().GetCount(); +} + #pragma mark Debugger::SettingsController //-------------------------------------------------- Modified: lldb/trunk/source/Core/FormatManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/source/Core/FormatManager.cpp (original) +++ lldb/trunk/source/Core/FormatManager.cpp Fri Jul 1 19:25:22 2011 @@ -151,3 +151,40 @@ return g_format_infos[format].format_name; return NULL; } + +template<> +bool +FormatNavigator, SummaryFormat::RegexSummaryCallback>::Get(const char* key, + SummaryFormat::SharedPointer& value) +{ + Mutex::Locker(m_map_mutex); + MapIterator pos, end = m_map.end(); + for (pos = m_map.begin(); pos != end; pos++) + { + lldb::RegularExpressionSP regex = pos->first; + if (regex->Execute(key)) + { + value = pos->second; + return true; + } + } + return false; +} + +template<> +bool +FormatNavigator, SummaryFormat::RegexSummaryCallback>::Delete(const char* type) +{ + Mutex::Locker(m_map_mutex); + MapIterator pos, end = m_map.end(); + for (pos = m_map.begin(); pos != end; pos++) + { + lldb::RegularExpressionSP regex = pos->first; + if ( ::strcmp(type,regex->GetText()) == 0) + { + m_map.erase(pos); + return true; + } + } + return false; +} Modified: lldb/trunk/source/Core/RegularExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/RegularExpression.cpp?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/source/Core/RegularExpression.cpp (original) +++ lldb/trunk/source/Core/RegularExpression.cpp Fri Jul 1 19:25:22 2011 @@ -176,4 +176,9 @@ return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len); } +bool +RegularExpression::operator < (const RegularExpression& rhs) const +{ + return (m_re < rhs.m_re); +} Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Fri Jul 1 19:25:22 2011 @@ -73,6 +73,7 @@ m_old_value_valid (false), m_pointers_point_to_load_addrs (false), m_is_deref_of_parent (false), + m_is_array_item_for_pointer(false), m_last_format_mgr_revision(0), m_last_summary_format(), m_last_value_format() @@ -108,6 +109,7 @@ m_old_value_valid (false), m_pointers_point_to_load_addrs (false), m_is_deref_of_parent (false), + m_is_array_item_for_pointer(false), m_last_format_mgr_revision(0), m_last_summary_format(), m_last_value_format() @@ -124,10 +126,11 @@ } bool -ValueObject::UpdateValueIfNeeded () +ValueObject::UpdateValueIfNeeded (bool update_format) { - UpdateFormatsIfNeeded(); + if (update_format) + UpdateFormatsIfNeeded(); // If this is a constant value, then our success is predicated on whether // we have an error or not @@ -191,7 +194,8 @@ if (m_last_value_format.get()) m_last_value_format.reset((ValueFormat*)NULL); Debugger::ValueFormats::Get(*this, m_last_value_format); - Debugger::SummaryFormats::Get(*this, m_last_summary_format); + if (!Debugger::SummaryFormats::Get(*this, m_last_summary_format)) + Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format); m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision(); m_value_str.clear(); m_summary_str.clear(); @@ -493,12 +497,47 @@ ExecutionContext exe_ctx; this->GetExecutionContextScope()->CalculateExecutionContext(exe_ctx); SymbolContext sc = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything); - if (Debugger::FormatPrompt(m_last_summary_format->m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, this)) + + if (m_last_summary_format->m_show_members_oneliner) { - m_summary_str.swap(s.GetString()); - return m_summary_str.c_str(); + const uint32_t num_children = GetNumChildren(); + if (num_children) + { + + s.PutChar('('); + + for (uint32_t idx=0; idxGetName().AsCString()); + s.PutChar('='); + s.PutCString(child_sp.get()->GetValueAsCString()); + } + } + + s.PutChar(')'); + + m_summary_str.swap(s.GetString()); + return m_summary_str.c_str(); + } + else + return "()"; + + } + else + { + if (Debugger::FormatPrompt(m_last_summary_format->m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, this)) + { + m_summary_str.swap(s.GetString()); + return m_summary_str.c_str(); + } + else + return NULL; } - return NULL; } clang_type_t clang_type = GetClangType(); @@ -655,12 +694,13 @@ const char * ValueObject::GetObjectDescription () { - if (!m_object_desc_str.empty()) - return m_object_desc_str.c_str(); - + if (!UpdateValueIfNeeded ()) return NULL; - + + if (!m_object_desc_str.empty()) + return m_object_desc_str.c_str(); + ExecutionContextScope *exe_scope = GetExecutionContextScope(); if (exe_scope == NULL) return NULL; @@ -782,6 +822,37 @@ return m_value_str.c_str(); } +const char * +ValueObject::GetPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display, + lldb::Format custom_format) +{ + if(custom_format != lldb::eFormatInvalid) + SetFormat(custom_format); + + const char * return_value; + + switch(val_obj_display) + { + case eDisplayValue: + return_value = GetValueAsCString(); + break; + case eDisplaySummary: + return_value = GetSummaryAsCString(); + break; + case eDisplayLanguageSpecific: + return_value = GetObjectDescription(); + break; + } + + + // try to use the value if the user's choice failed + if(!return_value && val_obj_display != eDisplayValue) + return_value = GetValueAsCString(); + + return return_value; + +} + addr_t ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address) { @@ -1049,6 +1120,8 @@ { AddSyntheticChild(index_const_str, synthetic_child); synthetic_child_sp = synthetic_child->GetSP(); + synthetic_child_sp->SetName(index_str); + synthetic_child_sp->m_is_array_item_for_pointer = true; } } } @@ -1165,6 +1238,12 @@ if (parent) parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat); + + // if we are a deref_of_parent just because we are synthetic array + // members made up to allow ptr[%d] syntax to work in variable + // printing, then add our name ([%d]) to the expression path + if(m_is_array_item_for_pointer && epformat == eHonorPointers) + s.PutCString(m_name.AsCString()); if (!IsBaseClass()) { @@ -1312,8 +1391,17 @@ if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr)) s.Printf(" %s", valobj->GetValueAsCString()); - if (sum_cstr) - s.Printf(" %s", sum_cstr); + if(sum_cstr) + { + // for some reason, using %@ (ObjC description) in a summary string, makes + // us believe we need to reset ourselves, thus invalidating the content of + // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty + // let us recalculate it! + if (sum_cstr[0] == '\0') + s.Printf(" %s", valobj->GetSummaryAsCString()); + else + s.Printf(" %s", sum_cstr); + } if (use_objc) { @@ -1323,7 +1411,7 @@ else s.Printf (" [no Objective-C description available]\n"); return; - } + } } if (curr_depth < max_depth) @@ -1360,32 +1448,7 @@ print_children = false; } - if (entry && entry->IsOneliner()) - { - const uint32_t num_children = valobj->GetNumChildren(); - if (num_children) - { - - s.PutChar('('); - - for (uint32_t idx=0; idxGetChildAtIndex(idx, true)); - if (child_sp.get()) - { - if (idx) - s.PutCString(", "); - s.PutCString(child_sp.get()->GetName().AsCString()); - s.PutChar('='); - s.PutCString(child_sp.get()->GetValueAsCString()); - } - } - - s.PutChar(')'); - s.EOL(); - } - } - else if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr)) + if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr)) { const uint32_t num_children = valobj->GetNumChildren(); if (num_children) Modified: lldb/trunk/source/Core/ValueObjectDynamicValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectDynamicValue.cpp?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectDynamicValue.cpp (original) +++ lldb/trunk/source/Core/ValueObjectDynamicValue.cpp Fri Jul 1 19:25:22 2011 @@ -80,7 +80,7 @@ clang::ASTContext * ValueObjectDynamicValue::GetClangAST () { - const bool success = UpdateValueIfNeeded(); + const bool success = UpdateValueIfNeeded(false); if (success && m_type_sp) return m_type_sp->GetClangAST(); else Modified: lldb/trunk/source/Interpreter/CommandObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandObject.cpp (original) +++ lldb/trunk/source/Interpreter/CommandObject.cpp Fri Jul 1 19:25:22 2011 @@ -627,6 +627,37 @@ return "A 'breakpoint id list' is a manner of specifying multiple breakpoints. This can be done through several mechanisms. The easiest way is to just enter a space-separated list of breakpoint ids. To specify all the breakpoint locations under a major breakpoint, you can use the major breakpoint number followed by '.*', eg. '5.*' means all the locations under breakpoint 5. You can also indicate a range of breakpoints by using - . The start-bp-id and end-bp-id for a range can be any valid breakpoint ids. It is not legal, however, to specify a range using specific locations that cross major breakpoint numbers. I.e. 3.2 - 3.7 is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal."; } +static const char * +FormatHelpTextCallback () +{ + StreamString sstr; + sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n"; + for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1)) + { + char format_char = FormatManager::GetFormatAsFormatChar(f); + if (format_char) + sstr.Printf("'%c' or ", format_char); + + sstr.Printf ("\"%s\" ; ", FormatManager::GetFormatAsCString(f)); + } + + sstr.Flush(); + + std::string data = sstr.GetString(); + + char* help = new char[data.length()+1]; + + data.copy(help, data.length()); + + return help; +} + +static const char * +FormatStringHelpTextCallback() +{ + return "Ask me tomorrow"; +} + const char * CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type) { @@ -662,7 +693,8 @@ { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, NULL, "Help text goes here." }, { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, NULL, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" }, { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, NULL, "The name of a file (can include path)." }, - { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, NULL, "Help text goes here." }, + { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, FormatHelpTextCallback, NULL }, + { eArgTypeFormatString, "format-string", CommandCompletions::eNoCompletion, FormatStringHelpTextCallback, NULL }, { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, NULL, "Index into a thread's list of frames." }, { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, NULL, "Help text goes here." }, { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, NULL, "The name of a function." }, Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=134293&r1=134292&r2=134293&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Jul 1 19:25:22 2011 @@ -117,21 +117,26 @@ clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); // We currently can't complete objective C types through the newly added ASTContext // because it only supports TagDecl objects right now... - bool is_forward_decl = class_interface_decl->isForwardDecl(); - if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage()) + if(class_interface_decl) { - if (ast) + bool is_forward_decl = class_interface_decl->isForwardDecl(); + if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage()) { - ExternalASTSource *external_ast_source = ast->getExternalSource(); - if (external_ast_source) + if (ast) { - external_ast_source->CompleteType (class_interface_decl); - is_forward_decl = class_interface_decl->isForwardDecl(); + ExternalASTSource *external_ast_source = ast->getExternalSource(); + if (external_ast_source) + { + external_ast_source->CompleteType (class_interface_decl); + is_forward_decl = class_interface_decl->isForwardDecl(); + } } + return is_forward_decl == false; } - return is_forward_decl == false; + return true; } - return true; + else + return false; } } break; Removed: lldb/trunk/test/functionalities/data-formatter/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/Makefile?rev=134292&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/Makefile (original) +++ lldb/trunk/test/functionalities/data-formatter/Makefile (removed) @@ -1,5 +0,0 @@ -LEVEL = ../../make - -CXX_SOURCES := main.cpp - -include $(LEVEL)/Makefile.rules Removed: lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py?rev=134292&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py (original) +++ lldb/trunk/test/functionalities/data-formatter/TestDataFormatter.py (removed) @@ -1,120 +0,0 @@ -""" -Test lldb data formatter subsystem. -""" - -import os, time -import unittest2 -import lldb -from lldbtest import * - -class DataFormatterTestCase(TestBase): - - mydir = os.path.join("functionalities", "data-formatter") - - @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") - def test_with_dsym_and_run_command(self): - """Test data formatter commands.""" - self.buildDsym() - self.data_formatter_commands() - - def test_with_dwarf_and_run_command(self): - """Test data formatter commands.""" - self.buildDwarf() - self.data_formatter_commands() - - def setUp(self): - # Call super's setUp(). - TestBase.setUp(self) - # Find the line number to break at. - self.line = line_number('main.cpp', '// Set break point at this line.') - - def data_formatter_commands(self): - """Test that that file and class static variables display correctly.""" - self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) - - self.expect("breakpoint set -f main.cpp -l %d" % self.line, - BREAKPOINT_CREATED, - startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" % - self.line) - - self.runCmd("run", RUN_SUCCEEDED) - - # The stop reason of the thread should be breakpoint. - self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, - substrs = ['stopped', - 'stop reason = breakpoint']) - - self.expect("frame variable", - substrs = ['(Speed) SPILookHex = 5.55' # Speed by default is 5.55. - ]); - - # This is the function to remove the custom formats in order to have a - # clean slate for the next test case. - def cleanup(): - self.runCmd('type format clear', check=False) - self.runCmd('type summary clear', check=False) - - # Execute the cleanup function during test case tear down. - self.addTearDownHook(cleanup) - - self.runCmd("type format add -c yes x Speed BitField") - self.runCmd("type format add -c no c RealNumber") - self.runCmd("type format add -c no x Type2") - self.runCmd("type format add -c yes c Type1") - - # The type format list should show our custom formats. - self.expect("type format list", - substrs = ['RealNumber', - 'Speed', - 'BitField', - 'Type1', - 'Type2']) - - self.expect("frame variable", - patterns = ['\(Speed\) SPILookHex = 0x[0-9a-f]+' # Speed should look hex-ish now. - ]); - - # Now let's delete the 'Speed' custom format. - self.runCmd("type format delete Speed") - - # The type format list should not show 'Speed' at this point. - self.expect("type format list", matching=False, - substrs = ['Speed']) - - # Delete type format for 'Speed', we should expect an error message. - self.expect("type format delete Speed", error=True, - substrs = ['no custom format for Speed']) - - # For some reason the type system is calling this "struct" - self.runCmd("type summary add -o yes \"\" Point") - - self.expect("frame variable iAmSomewhere", - substrs = ['x=4', - 'y=6']) - - self.expect("type summary list", - substrs = ['Point', - 'one-line']) - - self.runCmd("type summary add \"y=${var.y%x}\" Point") - - self.expect("frame variable iAmSomewhere", - substrs = ['y=0x']) - - self.runCmd("type summary add \"hello\" Point -h yes") - - self.expect("type summary list", - substrs = ['Point', - 'show children']) - - self.expect("frame variable iAmSomewhere", - substrs = ['hello', - 'x = 4', - '}']) - - -if __name__ == '__main__': - import atexit - lldb.SBDebugger.Initialize() - atexit.register(lambda: lldb.SBDebugger.Terminate()) - unittest2.main() Removed: lldb/trunk/test/functionalities/data-formatter/main.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/main.cpp?rev=134292&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/main.cpp (original) +++ lldb/trunk/test/functionalities/data-formatter/main.cpp (removed) @@ -1,70 +0,0 @@ -//===-- main.cpp ------------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include -#include -#include - -typedef float RealNumber; // should show as char -typedef RealNumber Temperature; // should show as float -typedef RealNumber Speed; // should show as hex - -typedef int Counter; // should show as int -typedef int BitField; // should show as hex - -typedef BitField SignalMask; // should show as hex -typedef BitField Modifiers; // should show as hex - -typedef Counter Accumulator; // should show as int - -typedef int Type1; // should show as char -typedef Type1 Type2; // should show as hex -typedef Type2 Type3; // should show as char -typedef Type3 Type4; // should show as char - -typedef int ChildType; // should show as int -typedef int AnotherChildType; // should show as int - -struct Point { - int x; - int y; - Point(int X = 3, int Y = 2) : x(X), y(Y) {} -}; - -int main (int argc, const char * argv[]) -{ - - int iAmInt = 1; - const float& IAmFloat = float(2.45); - - RealNumber RNILookChar = 3.14; - Temperature TMILookFloat = 4.97; - Speed SPILookHex = 5.55; - - Counter CTILookInt = 6; - BitField BFILookHex = 7; - SignalMask SMILookHex = 8; - Modifiers MFILookHex = 9; - - Accumulator* ACILookInt = new Accumulator(10); - - const Type1& T1ILookChar = 11; - Type2 T2ILookHex = 12; - Type3 T3ILookChar = 13; - Type4 T4ILookChar = 14; - - AnotherChildType AHILookInt = 15; - - Speed* SPPtrILookHex = new Speed(16); - - Point iAmSomewhere(4,6); - - return 0; // Set break point at this line. -} - From granata.enrico at gmail.com Fri Jul 1 19:27:12 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Sat, 02 Jul 2011 00:27:12 -0000 Subject: [Lldb-commits] [lldb] r134294 - in /lldb/trunk/test/functionalities/data-formatter: data-formatter-advanced/ data-formatter-advanced/Makefile data-formatter-advanced/TestDataFormatterAdv.py data-formatter-advanced/main.cpp data-formatter-cpp/ data-formatter-cpp/Makefile data-formatter-cpp/TestDataFormatterCpp.py data-formatter-cpp/main.cpp data-formatter-objc/ data-formatter-objc/Makefile data-formatter-objc/TestDataFormatterObjC.py data-formatter-objc/main.m Message-ID: <20110702002712.2AE4E2A6C12C@llvm.org> Author: enrico Date: Fri Jul 1 19:27:11 2011 New Revision: 134294 URL: http://llvm.org/viewvc/llvm-project?rev=134294&view=rev Log: test cases for the new features just committed Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/ lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/Makefile lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/ lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/Makefile lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/Makefile lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/Makefile?rev=134294&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/Makefile (added) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/Makefile Fri Jul 1 19:27:11 2011 @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py?rev=134294&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py (added) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py Fri Jul 1 19:27:11 2011 @@ -0,0 +1,112 @@ +""" +Test lldb data formatter subsystem. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class DataFormatterTestCase(TestBase): + + mydir = os.path.join("functionalities", "data-formatter", "data-formatter-advanced") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + """Test data formatter commands.""" + self.buildDsym() + self.data_formatter_commands() + + def test_with_dwarf_and_run_command(self): + """Test data formatter commands.""" + self.buildDwarf() + self.data_formatter_commands() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break at. + self.line = line_number('main.cpp', '// Set break point at this line.') + + def data_formatter_commands(self): + """Test that that file and class static variables display correctly.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.expect("breakpoint set -f main.cpp -l %d" % self.line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" % + self.line) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type format clear', check=False) + self.runCmd('type summary clear', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.runCmd("type summary add -f \"pippo\" -x \"IUseCharStar\"") + + self.expect("frame variable iEncapsulateCharStar", + substrs = ['pippo']) + + self.runCmd("type summary clear") + + self.runCmd("type summary add -f \"pippo\" \"i_am_cool\"") + + self.runCmd("type summary add -f \"pluto\" -x \"i_am_cool[a-z]*\"") + + self.expect("frame variable cool_boy", + substrs = ['pippo']) + + self.expect("frame variable cooler_boy", + substrs = ['pluto']) + + self.runCmd("type summary delete i_am_cool") + + self.expect("frame variable cool_boy", + substrs = ['pluto']) + + self.runCmd("type summary clear") + + self.runCmd("type summary add -f \"${*var[]}\" -x \"int \\[[0-9]\\]") + + self.expect("frame variable int_array", + substrs = ['1,2,3,4,5']) + + self.runCmd("type summary add -f \"${*var[].integer}\" -x \"i_am_cool \\[[0-9]\\]") + + self.expect("frame variable cool_array", + substrs = ['1,1,1,1,6']) + + self.runCmd("type summary clear") + + self.runCmd("type summary add -f \"${var[1-0]%x}\" \"int\"") + + self.expect("frame variable iAmInt", + substrs = ['01']) + + self.runCmd("type summary add -f \"${*var[0-1]%x}\" \"int\"") + + self.expect("frame variable iAmInt", matching=False, + substrs = ['01']) + + self.runCmd("type summary add -f \"${var[0-1]%x}\" \"int\"") + + self.expect("frame variable iAmInt", + substrs = ['01']) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp?rev=134294&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp (added) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp Fri Jul 1 19:27:11 2011 @@ -0,0 +1,64 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +struct i_am_cool +{ + int integer; + float floating; + char character; + i_am_cool(int I, float F, char C) : + integer(I), floating(F), character(C) {} + i_am_cool() : integer(1), floating(2), character('3') {} + +}; + +struct i_am_cooler +{ + i_am_cool first_cool; + i_am_cool second_cool; + float floating; + + i_am_cooler(int I1, int I2, float F1, float F2, char C1, char C2) : + first_cool(I1,F1,C1), + second_cool(I2,F2,C2), + floating((F1 + F2)/2) {} +}; + +struct IUseCharStar +{ + const char* pointer; + IUseCharStar() : pointer("Hello world") {} +}; + +int main (int argc, const char * argv[]) +{ + + int iAmInt = 1; + + i_am_cool cool_boy(1,0.5,3); + i_am_cooler cooler_boy(1,2,0.1,0.2,'A','B'); + + i_am_cool *cool_pointer = new i_am_cool(3,-3.141592,'E'); + + i_am_cool cool_array[5]; + + cool_array[3].floating = 5.25; + cool_array[4].integer = 6; + cool_array[2].character = 'Q'; + + int int_array[] = {1,2,3,4,5}; + + IUseCharStar iEncapsulateCharStar; + + return 0; // Set break point at this line. +} \ No newline at end of file Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/Makefile?rev=134294&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/Makefile (added) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/Makefile Fri Jul 1 19:27:11 2011 @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py?rev=134294&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py (added) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py Fri Jul 1 19:27:11 2011 @@ -0,0 +1,156 @@ +""" +Test lldb data formatter subsystem. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class DataFormatterTestCase(TestBase): + + mydir = os.path.join("functionalities", "data-formatter", "data-formatter-cpp") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + """Test data formatter commands.""" + self.buildDsym() + self.data_formatter_commands() + + def test_with_dwarf_and_run_command(self): + """Test data formatter commands.""" + self.buildDwarf() + self.data_formatter_commands() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break at. + self.line = line_number('main.cpp', '// Set break point at this line.') + + def data_formatter_commands(self): + """Test that that file and class static variables display correctly.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.expect("breakpoint set -f main.cpp -l %d" % self.line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" % + self.line) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + self.expect("frame variable", + substrs = ['(Speed) SPILookHex = 5.55' # Speed by default is 5.55. + ]); + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type format clear', check=False) + self.runCmd('type summary clear', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.runCmd("type format add -C yes -f x Speed BitField") + self.runCmd("type format add -C no -f c RealNumber") + self.runCmd("type format add -C no -f x Type2") + self.runCmd("type format add -C yes -f c Type1") + + # The type format list should show our custom formats. + self.expect("type format list", + substrs = ['RealNumber', + 'Speed', + 'BitField', + 'Type1', + 'Type2']) + + self.expect("frame variable", + patterns = ['\(Speed\) SPILookHex = 0x[0-9a-f]+' # Speed should look hex-ish now. + ]); + + # Now let's delete the 'Speed' custom format. + self.runCmd("type format delete Speed") + + # The type format list should not show 'Speed' at this point. + self.expect("type format list", matching=False, + substrs = ['Speed']) + + # Delete type format for 'Speed', we should expect an error message. + self.expect("type format delete Speed", error=True, + substrs = ['no custom format for Speed']) + + self.runCmd("type summary add -c Point") + + self.expect("frame variable iAmSomewhere", + substrs = ['x=4', + 'y=6']) + + self.expect("type summary list", + substrs = ['Point', + 'one-line']) + + self.runCmd("type summary add -f \"y=${var.y%x}\" Point") + + self.expect("frame variable iAmSomewhere", + substrs = ['y=0x']) + + self.runCmd("type summary add -f \"hello\" Point -e") + + self.expect("type summary list", + substrs = ['Point', + 'show children']) + + self.expect("frame variable iAmSomewhere", + substrs = ['hello', + 'x = 4', + '}']) + + self.runCmd("type summary add -f \"Sign: ${var[31]%B} Exponent: ${var[23-30]%x} Mantissa: ${var[0-22]%u}\" ShowMyGuts") + + self.expect("frame variable cool_pointer->floating", + substrs = ['Sign: true', + 'Exponent: 0x', + '80']) + + self.runCmd("type summary add -f \"a test\" i_am_cool") + + self.expect("frame variable cool_pointer", + substrs = ['a test']) + + self.runCmd("type summary add -f \"a test\" i_am_cool --skip-pointers") + + self.expect("frame variable cool_pointer", + substrs = ['a test'], + matching = False) + + self.runCmd("type summary add -f \"${*var[1-3]}\" \"int [5]\"") + + self.expect("frame variable int_array", + substrs = ['2', + '3', + '4']) + + self.runCmd("type summary clear") + + self.runCmd("type summary add -f \"${*var[0-2].integer}\" \"i_am_cool *\"") + self.runCmd("type summary add -f \"${*var[2-4].integer}\" \"i_am_cool [5]\"") + + self.expect("frame variable cool_array", + substrs = ['1,1,6']) + + self.expect("frame variable cool_pointer", + substrs = ['3,0,0']) + + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp?rev=134294&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp (added) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/main.cpp Fri Jul 1 19:27:11 2011 @@ -0,0 +1,113 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +typedef float RealNumber; // should show as char +typedef RealNumber Temperature; // should show as float +typedef RealNumber Speed; // should show as hex + +typedef int Counter; // should show as int +typedef int BitField; // should show as hex + +typedef BitField SignalMask; // should show as hex +typedef BitField Modifiers; // should show as hex + +typedef Counter Accumulator; // should show as int + +typedef int Type1; // should show as char +typedef Type1 Type2; // should show as hex +typedef Type2 Type3; // should show as char +typedef Type3 Type4; // should show as char + +typedef int ChildType; // should show as int +typedef int AnotherChildType; // should show as int + +struct Point { + int x; + int y; + Point(int X = 3, int Y = 2) : x(X), y(Y) {} +}; + +typedef float ShowMyGuts; + +struct i_am_cool +{ + int integer; + ShowMyGuts floating; + char character; + i_am_cool(int I, ShowMyGuts F, char C) : + integer(I), floating(F), character(C) {} + i_am_cool() : integer(1), floating(2), character('3') {} + +}; + +struct i_am_cooler +{ + i_am_cool first_cool; + i_am_cool second_cool; + ShowMyGuts floating; + + i_am_cooler(int I1, int I2, float F1, float F2, char C1, char C2) : + first_cool(I1,F1,C1), + second_cool(I2,F2,C2), + floating((F1 + F2)/2) {} +}; + +struct IUseCharStar +{ + const char* pointer; + IUseCharStar() : pointer("Hello world") {} +}; + +int main (int argc, const char * argv[]) +{ + + int iAmInt = 1; + const float& IAmFloat = float(2.45); + + RealNumber RNILookChar = 3.14; + Temperature TMILookFloat = 4.97; + Speed SPILookHex = 5.55; + + Counter CTILookInt = 6; + BitField BFILookHex = 7; + SignalMask SMILookHex = 8; + Modifiers MFILookHex = 9; + + Accumulator* ACILookInt = new Accumulator(10); + + const Type1& T1ILookChar = 11; + Type2 T2ILookHex = 12; + Type3 T3ILookChar = 13; + Type4 T4ILookChar = 14; + + AnotherChildType AHILookInt = 15; + + Speed* SPPtrILookHex = new Speed(16); + + Point iAmSomewhere(4,6); + + i_am_cool *cool_pointer = new i_am_cool(3,-3.141592,'E'); + + i_am_cool cool_array[5]; + + cool_array[3].floating = 5.25; + cool_array[4].integer = 6; + cool_array[2].character = 'Q'; + + int int_array[] = {1,2,3,4,5}; + + IUseCharStar iEncapsulateCharStar; + + return 0; // Set break point at this line. +} + Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/Makefile?rev=134294&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/Makefile (added) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/Makefile Fri Jul 1 19:27:11 2011 @@ -0,0 +1,7 @@ +LEVEL = ../../../make + +OBJC_SOURCES := main.m + +include $(LEVEL)/Makefile.rules + +LDFLAGS += -framework Foundation Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py?rev=134294&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py (added) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py Fri Jul 1 19:27:11 2011 @@ -0,0 +1,106 @@ +""" +Test lldb data formatter subsystem. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class DataFormatterTestCase(TestBase): + + mydir = os.path.join("functionalities", "data-formatter", "data-formatter-objc") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + """Test data formatter commands.""" + self.buildDsym() + self.data_formatter_commands() + + def test_with_dwarf_and_run_command(self): + """Test data formatter commands.""" + self.buildDwarf() + self.data_formatter_commands() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break at. + self.line = line_number('main.m', '// Set break point at this line.') + + def data_formatter_commands(self): + """Test that that file and class static variables display correctly.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.expect("breakpoint set -f main.m -l %d" % self.line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" % + self.line) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type format clear', check=False) + self.runCmd('type summary clear', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.runCmd("type summary add -f \"${var%@}\" MyClass") + + self.expect("frame variable object2", + substrs = ['MyOtherClass']); + + self.expect("frame variable *object2", + substrs = ['MyOtherClass']); + + # Now let's delete the 'MyClass' custom summary. + self.runCmd("type summary delete MyClass") + + # The type format list should not show 'MyClass' at this point. + self.expect("type summary list", matching=False, + substrs = ['MyClass']) + + self.runCmd("type summary add -f \"a test\" MyClass") + + self.expect("frame variable object2", + substrs = ['a test']); + + self.expect("frame variable *object2", + substrs = ['a test']); + + self.expect("frame variable object", + substrs = ['a test']); + + self.expect("frame variable *object", + substrs = ['a test']); + + self.runCmd("type summary add -f \"a test\" MyClass -C no") + + self.expect("frame variable *object2", + substrs = ['*object2 = {', + 'MyClass = a test', + 'backup = ']); + + self.expect("frame variable object2", matching=False, + substrs = ['a test']); + + self.expect("frame variable object", + substrs = ['a test']); + + self.expect("frame variable *object", + substrs = ['a test']); + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m?rev=134294&view=auto ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m (added) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m Fri Jul 1 19:27:11 2011 @@ -0,0 +1,87 @@ +//===-- main.m ------------------------------------------------*- ObjC -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#import + + at interface MyClass : NSObject +{ + int i; + char c; + float f; +} + +- (id)initWithInt: (int)x andFloat:(float)y andChar:(char)z; +- (int)doIncrementByInt: (int)x; + + at end + + at interface MyOtherClass : MyClass +{ + int i2; + MyClass *backup; +} +- (id)initWithInt: (int)x andFloat:(float)y andChar:(char)z andOtherInt:(int)q; + + at end + + at implementation MyClass + +- (id)initWithInt: (int)x andFloat:(float)y andChar:(char)z +{ + self = [super init]; + if (self) { + self->i = x; + self->f = y; + self->c = z; + } + return self; +} + +- (int)doIncrementByInt: (int)x +{ + self->i += x; + return self->i; +} + + at end + + at implementation MyOtherClass + +- (id)initWithInt: (int)x andFloat:(float)y andChar:(char)z andOtherInt:(int)q +{ + self = [super initWithInt:x andFloat:y andChar:z]; + if (self) { + self->i2 = q; + self->backup = [[MyClass alloc] initWithInt:x andFloat:y andChar:z]; + } + return self; +} + + at end + +int main (int argc, const char * argv[]) +{ + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + // insert code here... + NSLog(@"Hello, World!"); + + MyClass *object = [[MyClass alloc] initWithInt:1 andFloat:3.14 andChar: 'E']; + + [object doIncrementByInt:3]; + + MyOtherClass *object2 = [[MyOtherClass alloc] initWithInt:2 andFloat:6.28 andChar: 'G' andOtherInt:-1]; + + [object2 doIncrementByInt:3]; + // Set break point at this line. + [pool drain]; + return 0; +} + From johnny.chen at apple.com Fri Jul 1 19:57:53 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sat, 02 Jul 2011 00:57:53 -0000 Subject: [Lldb-commits] [lldb] r134301 - /lldb/trunk/include/lldb/API/SBProcess.h Message-ID: <20110702005753.27B902A6C12C@llvm.org> Author: johnny Date: Fri Jul 1 19:57:52 2011 New Revision: 134301 URL: http://llvm.org/viewvc/llvm-project?rev=134301&view=rev Log: Furnish some docstrings to be swigified into the generated lldb.py module. Especially SBProcess.ReadMemory() and SBProcess.WriteMemory() because the generated autodoc strings make no sense for Python programmers due to typemap (see lldb.swig). Modified: lldb/trunk/include/lldb/API/SBProcess.h Modified: lldb/trunk/include/lldb/API/SBProcess.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=134301&r1=134300&r2=134301&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBProcess.h (original) +++ lldb/trunk/include/lldb/API/SBProcess.h Fri Jul 1 19:57:52 2011 @@ -89,7 +89,11 @@ RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error); - // See SBTarget.Launch for argument description and usage. +#ifdef SWIG + %feature("docstring", + "See SBTarget.Launch for argument description and usage." + ) RemoteLaunch; +#endif bool RemoteLaunch (char const **argv, char const **envp, @@ -141,6 +145,12 @@ uint32_t GetAddressByteSize() const; +#ifdef SWIG + %feature("docstring", + "Kills the process and shuts down all threads that were spawned to" + " track and monitor process." + ) Destroy; +#endif lldb::SBError Destroy (); @@ -150,18 +160,48 @@ lldb::SBError Stop (); +#ifdef SWIG + %feature("docstring", "Same as Destroy(self).") Destroy; +#endif lldb::SBError Kill (); lldb::SBError Detach (); +#ifdef SWIG + %feature("docstring", "Sends the process a unix signal.") Signal; +#endif lldb::SBError Signal (int signal); +#ifdef SWIG + %feature("autodoc", +"Reads memory from the current process's address space and removes any +traps that may have been inserted into the memory. It returns the byte +buffer in a Python string. Example: + +# Read 4 bytes from address 'addr' and assume error.Success() is True. +content = process.ReadMemory(addr, 4, error) +# Use 'ascii' encoding as each byte of 'content' is within [0..255]. +new_bytes = bytearray(content, 'ascii')" + ) ReadMemory; +#endif size_t ReadMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error); +#ifdef SWIG + %feature("autodoc", +"Writes memory to the current process's address space and maintains any +traps that might be present due to software breakpoints. Example: + +# Create a Python string from the byte array. +new_value = str(bytes) +result = process.WriteMemory(addr, new_value, error) +if not error.Success() or result != len(bytes): + print 'SBProcess.WriteMemory() failed!'" + ) WriteMemory; +#endif size_t WriteMemory (addr_t addr, const void *buf, size_t size, lldb::SBError &error); From johnny.chen at apple.com Sat Jul 2 15:01:09 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sat, 02 Jul 2011 20:01:09 -0000 Subject: [Lldb-commits] [lldb] r134326 - /lldb/trunk/scripts/Python/modify-python-lldb.py Message-ID: <20110702200109.47D152A6C12C@llvm.org> Author: johnny Date: Sat Jul 2 15:01:09 2011 New Revision: 134326 URL: http://llvm.org/viewvc/llvm-project?rev=134326&view=rev Log: Refine the post-processing phase of lldb.py to remove some more doxygen/c++-comment residues. Modified: lldb/trunk/scripts/Python/modify-python-lldb.py Modified: lldb/trunk/scripts/Python/modify-python-lldb.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=134326&r1=134325&r2=134326&view=diff ============================================================================== --- lldb/trunk/scripts/Python/modify-python-lldb.py (original) +++ lldb/trunk/scripts/Python/modify-python-lldb.py Sat Jul 2 15:01:09 2011 @@ -8,7 +8,7 @@ # # As a cleanup step, it also removes the 'residues' from the autodoc features of # swig. For an example, take a look at SBTarget.h header file, where we take -# advantage of the already existing C++-style headerdoc and make it the Python +# advantage of the already existing doxygen C++-docblock and make it the Python # docstring for the same method. The 'residues' in this context include the # '#endif' and the '#ifdef SWIG' lines. # @@ -28,6 +28,9 @@ # Residues to be removed. c_endif_swig = "#endif" c_ifdef_swig = "#ifdef SWIG" +c_comment_marker = "//------------" +# The pattern for recognizing the doxygen comment block line. +doxygen_comment_start = re.compile("^\s*( /// ?)") # # lldb_iter() should appear before our first SB* class definition. @@ -161,8 +164,15 @@ # Cleanse the lldb.py of the autodoc'ed residues. if c_ifdef_swig in line or c_endif_swig in line: continue + # As well as the comment marker line. + if c_comment_marker in line: + continue # Also remove the '\a ' substrings. line = line.replace('\a ', '') + # And the leading '///' substring. + doxygen_comment_match = doxygen_comment_start.match(line) + if doxygen_comment_match: + line = line.replace(doxygen_comment_match.group(1), '', 1) if state == NORMAL: match = class_pattern.search(line) From peter at pcc.me.uk Sat Jul 2 15:42:56 2011 From: peter at pcc.me.uk (Peter Collingbourne) Date: Sat, 02 Jul 2011 20:42:56 -0000 Subject: [Lldb-commits] [lldb] r134347 - in /lldb/trunk: include/lldb/Symbol/ClangASTType.h source/Core/Debugger.cpp Message-ID: <20110702204256.E5BD92A6C12F@llvm.org> Author: pcc Date: Sat Jul 2 15:42:56 2011 New Revision: 134347 URL: http://llvm.org/viewvc/llvm-project?rev=134347&view=rev Log: Fix Linux build errors Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h lldb/trunk/source/Core/Debugger.cpp Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=134347&r1=134346&r2=134347&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Sat Jul 2 15:42:56 2011 @@ -10,6 +10,7 @@ #ifndef liblldb_ClangASTType_h_ #define liblldb_ClangASTType_h_ +#include #include "lldb/lldb-private.h" #include "lldb/Core/ClangForward.h" Modified: lldb/trunk/source/Core/Debugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=134347&r1=134346&r2=134347&view=diff ============================================================================== --- lldb/trunk/source/Core/Debugger.cpp (original) +++ lldb/trunk/source/Core/Debugger.cpp Sat Jul 2 15:42:56 2011 @@ -803,7 +803,7 @@ ) { const char* var_name_final; - char* close_bracket_position = NULL; + const char* close_bracket_position = NULL; const char* percent_position = NULL; const char* targetvalue; lldb::Format custom_format = eFormatInvalid; @@ -842,7 +842,7 @@ { // TODO: pick a way to say "all entries". this will make more sense once // regex typenames are in place. now, you need to be size-aware anyways - char* separator_position = ::strchr(open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield + const char* separator_position = ::strchr(open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield close_bracket_position = ::strchr(open_bracket_position,']'); // as usual, we assume that [] will come before % //printf("trying to expand a []\n"); @@ -1121,8 +1121,8 @@ const char* open_bracket_position = ::strchr(var_name_begin,'['); if(open_bracket_position && open_bracket_position < var_name_final) { - char* separator_position = ::strchr(open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield - char* close_bracket_position = ::strchr(open_bracket_position,']'); + const char* separator_position = ::strchr(open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield + const char* close_bracket_position = ::strchr(open_bracket_position,']'); // as usual, we assume that [] will come before % //printf("trying to expand a []\n"); var_name_final = open_bracket_position; @@ -1191,8 +1191,8 @@ const char* open_bracket_position = ::strchr(var_name_begin,'['); if(open_bracket_position && open_bracket_position < var_name_final) { - char* separator_position = ::strchr(open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield - char* close_bracket_position = ::strchr(open_bracket_position,']'); + const char* separator_position = ::strchr(open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield + const char* close_bracket_position = ::strchr(open_bracket_position,']'); // as usual, we assume that [] will come before % //printf("trying to expand a []\n"); var_name_final = open_bracket_position; From gclayton at apple.com Sat Jul 2 16:07:54 2011 From: gclayton at apple.com (Greg Clayton) Date: Sat, 02 Jul 2011 21:07:54 -0000 Subject: [Lldb-commits] [lldb] r134357 - in /lldb/trunk/source: Commands/CommandObjectProcess.cpp Interpreter/CommandReturnObject.cpp Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Message-ID: <20110702210754.DD2DF2A6C12C@llvm.org> Author: gclayton Date: Sat Jul 2 16:07:54 2011 New Revision: 134357 URL: http://llvm.org/viewvc/llvm-project?rev=134357&view=rev Log: Cleanup errors that come out of commands and make sure they all have newlines _only_ in the resulting stream, not in the error objects (lldb_private::Error). lldb_private::Error objects should always just have an error string with no terminating newline characters or periods. Fixed an issue with GDB remote packet detection that could end up deadlocking if a full packet wasn't received in one chunk. Also modified the packet checking function to properly toss one or more bytes when it detects bad data. Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp lldb/trunk/source/Interpreter/CommandReturnObject.cpp lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=134357&r1=134356&r2=134357&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Sat Jul 2 16:07:54 2011 @@ -366,7 +366,7 @@ } else { - result.AppendErrorWithFormat ("Process launch failed: %s", error.AsCString()); + result.AppendErrorWithFormat ("process launch failed: %s", error.AsCString()); result.SetStatus (eReturnStatusFailed); } @@ -1832,18 +1832,18 @@ "A set of commands for operating on a process.", "process []") { - LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); - LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); - LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); - LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter))); - LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); - LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); - LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); - LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); - LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); - LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); + LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); + LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); + LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); + LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter))); + LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); + LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); + LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); + LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter))); + LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter))); + LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter))); LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); - LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); + LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); } CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () Modified: lldb/trunk/source/Interpreter/CommandReturnObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandReturnObject.cpp?rev=134357&r1=134356&r2=134357&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandReturnObject.cpp (original) +++ lldb/trunk/source/Interpreter/CommandReturnObject.cpp Sat Jul 2 16:07:54 2011 @@ -18,6 +18,29 @@ using namespace lldb; using namespace lldb_private; +static void +DumpStringToStreamWithNewline (Stream &strm, const std::string &s, bool add_newline_if_empty) +{ + bool add_newline = false; + if (s.empty()) + { + add_newline = add_newline_if_empty; + } + else + { + // We already checked for empty above, now make sure there is a newline + // in the error, and if there isn't one, add one. + strm.Write(s.c_str(), s.size()); + + const char last_char = *s.rbegin(); + add_newline = last_char != '\n' && last_char != '\r'; + + } + if (add_newline) + strm.EOL(); +} + + CommandReturnObject::CommandReturnObject () : m_out_stream (), m_err_stream (), @@ -39,7 +62,14 @@ sstrm.PrintfVarArg(format, args); va_end (args); - GetErrorStream().Printf("error: %s", sstrm.GetData()); + + const std::string &s = sstrm.GetString(); + if (!s.empty()) + { + Stream &error_strm = GetErrorStream(); + error_strm.PutCString ("error: "); + DumpStringToStreamWithNewline (error_strm, s, false); + } } void Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=134357&r1=134356&r2=134357&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Sat Jul 2 16:07:54 2011 @@ -194,8 +194,7 @@ if (CheckForPacket (NULL, 0, packet)) return packet.GetStringRef().size(); - bool timed_out = false; - while (IsConnected() && !timed_out) + while (IsConnected()) { lldb::ConnectionStatus status; size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error); @@ -209,6 +208,7 @@ switch (status) { case eConnectionStatusSuccess: + case eConnectionStatusTimedOut: break; case eConnectionStatusEndOfFile: @@ -217,11 +217,10 @@ case eConnectionStatusError: Disconnect(); break; - - case eConnectionStatusTimedOut: - timed_out = true; - break; } + + // Get out of the while loop we we finally timeout without getting any data + break; } } packet.Clear (); @@ -233,11 +232,21 @@ { // Put the packet data into the buffer in a thread safe fashion Mutex::Locker locker(m_bytes_mutex); + + LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); + if (src && src_len > 0) + { + if (log) + { + StreamString s; + log->Printf ("GDBRemoteCommunication::%s adding %zu bytes: %s\n",__FUNCTION__, src_len, src); + } m_bytes.append ((const char *)src, src_len); + } // Parse up the packets into gdb remote packets - while (!m_bytes.empty()) + if (!m_bytes.empty()) { // end_idx must be one past the last valid packet byte. Start // it off with an invalid value that is the same as the current @@ -246,7 +255,6 @@ size_t content_length = 0; size_t total_length = 0; size_t checksum_idx = std::string::npos; - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); switch (m_bytes[0]) { @@ -283,9 +291,33 @@ default: { + // We have an unexpected byte and we need to flush all bad + // data that is in m_bytes, so we need to find the first + // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt), + // or '$' character (start of packet header) or of course, + // the end of the data in m_bytes... + const size_t bytes_len = m_bytes.size(); + bool done = false; + uint32_t idx; + for (idx = 1; !done && idx < bytes_len; ++idx) + { + switch (m_bytes[idx]) + { + case '+': + case '-': + case '\x03': + case '$': + done = true; + break; + + default: + break; + } + } if (log) - log->Printf ("GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]); - m_bytes.erase(0, 1); + log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'", + __FUNCTION__, idx, idx, m_bytes.c_str()); + m_bytes.erase(0, idx); } break; } From gclayton at apple.com Sat Jul 2 18:21:07 2011 From: gclayton at apple.com (Greg Clayton) Date: Sat, 02 Jul 2011 23:21:07 -0000 Subject: [Lldb-commits] [lldb] r134359 - in /lldb/trunk: include/lldb/Core/ConnectionFileDescriptor.h source/Core/ConnectionFileDescriptor.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Message-ID: <20110702232107.2B58E2A6C12C@llvm.org> Author: gclayton Date: Sat Jul 2 18:21:06 2011 New Revision: 134359 URL: http://llvm.org/viewvc/llvm-project?rev=134359&view=rev Log: When we use the "fd://%u" for file descriptors, we need to detect if this is a file or socket. We now make a getsockopt call to check if the fd is a socket. Also, the previous logic in the GDB communication needs to watch for success with an error so we can deal with EAGAIN and other normal "retry" error codes. Modified: lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h lldb/trunk/source/Core/ConnectionFileDescriptor.cpp lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Modified: lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h?rev=134359&r1=134358&r2=134359&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h (original) +++ lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h Sat Jul 2 18:21:06 2011 @@ -78,10 +78,13 @@ uint32_t m_socket_timeout_usec; static int + GetSocketOption(int fd, int level, int option_name, int &option_value); + + static int SetSocketOption(int fd, int level, int option_name, int option_value); bool - SetSocketRecieveTimeout (uint32_t timeout_usec); + SetSocketReceiveTimeout (uint32_t timeout_usec); private: DISALLOW_COPY_AND_ASSIGN (ConnectionFileDescriptor); Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=134359&r1=134358&r2=134359&view=diff ============================================================================== --- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original) +++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Sat Jul 2 18:21:06 2011 @@ -111,8 +111,7 @@ // We have what looks to be a valid file descriptor, but we // should make it is. We currently are doing this by trying to // get the flags from the file descriptor and making sure it - // isn't a bad fd. We also need to enable non blocking mode for - // the fd if it already isn't. + // isn't a bad fd. errno = 0; int flags = ::fcntl (m_fd, F_GETFL, 0); if (flags == -1 || errno == EBADF) @@ -124,11 +123,10 @@ } else { - if ((flags & O_NONBLOCK) == 0) - { - flags |= O_NONBLOCK; - ::fcntl (m_fd, F_SETFL, flags); - } + // Try and get a socket option from this file descriptor to + // see if this is a socket and set m_is_socket accordingly. + int resuse; + m_is_socket = GetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, resuse) == 0; m_should_close_fd = true; return eConnectionStatusSuccess; } @@ -200,13 +198,12 @@ if (timeout_usec == UINT32_MAX) { - if (m_is_socket) - SetSocketRecieveTimeout (0); - status = eConnectionStatusSuccess; + if (m_is_socket && SetSocketReceiveTimeout (timeout_usec)) + status = eConnectionStatusSuccess; } else { - if (m_is_socket && SetSocketRecieveTimeout (timeout_usec)) + if (m_is_socket && SetSocketReceiveTimeout (timeout_usec)) status = eConnectionStatusSuccess; else status = BytesAvailable (timeout_usec, error_ptr); @@ -215,7 +212,12 @@ return 0; Error error; - ssize_t bytes_read = ::read (m_fd, dst, dst_len); + ssize_t bytes_read; + if (m_is_socket) + bytes_read = ::recv (m_fd, dst, dst_len, 0); + else + bytes_read = ::read (m_fd, dst, dst_len); + if (bytes_read == 0) { error.Clear(); // End-of-file. Do not automatically close; pass along for the end-of-file handlers. @@ -713,26 +715,38 @@ return eConnectionStatusSuccess; } -int -ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value) -{ #if defined(__MINGW32__) || defined(__MINGW64__) - const char* option_value_p = static_cast(&option_value); +typedef const char * set_socket_option_arg_type; +typedef char * get_socket_option_arg_type; #else // #if defined(__MINGW32__) || defined(__MINGW64__) - const void* option_value_p = &option_name; +typedef const void * set_socket_option_arg_type; +typedef void * get_socket_option_arg_type; #endif // #if defined(__MINGW32__) || defined(__MINGW64__) +int +ConnectionFileDescriptor::GetSocketOption(int fd, int level, int option_name, int &option_value) +{ + get_socket_option_arg_type option_value_p = static_cast(&option_value); + socklen_t option_value_size = sizeof(int); + return ::getsockopt(fd, level, option_name, option_value_p, &option_value_size); +} + +int +ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value) +{ + set_socket_option_arg_type option_value_p = static_cast(&option_value); return ::setsockopt(fd, level, option_name, option_value_p, sizeof(option_value)); } bool -ConnectionFileDescriptor::SetSocketRecieveTimeout (uint32_t timeout_usec) +ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec) { if (m_is_socket) { // Check in case timeout for m_fd has already been set to this value if (timeout_usec == m_socket_timeout_usec) return true; + //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec); struct timeval timeout; timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec; Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=134359&r1=134358&r2=134359&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Sat Jul 2 18:21:06 2011 @@ -194,7 +194,8 @@ if (CheckForPacket (NULL, 0, packet)) return packet.GetStringRef().size(); - while (IsConnected()) + bool timed_out = false; + while (IsConnected() && !timed_out) { lldb::ConnectionStatus status; size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error); @@ -207,8 +208,11 @@ { switch (status) { - case eConnectionStatusSuccess: case eConnectionStatusTimedOut: + timed_out = true; + break; + case eConnectionStatusSuccess: + //printf ("status = success but error = %s\n", error.AsCString("")); break; case eConnectionStatusEndOfFile: @@ -218,9 +222,6 @@ Disconnect(); break; } - - // Get out of the while loop we we finally timeout without getting any data - break; } } packet.Clear (); @@ -237,10 +238,14 @@ if (src && src_len > 0) { - if (log) + if (log && log->GetVerbose()) { StreamString s; - log->Printf ("GDBRemoteCommunication::%s adding %zu bytes: %s\n",__FUNCTION__, src_len, src); + log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s", + __FUNCTION__, + (uint32_t)src_len, + (uint32_t)src_len, + src); } m_bytes.append ((const char *)src, src_len); } From johnny.chen at apple.com Sat Jul 2 20:43:29 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sun, 03 Jul 2011 01:43:29 -0000 Subject: [Lldb-commits] [lldb] r134360 - in /lldb/trunk: include/lldb/API/SBFrame.h scripts/Python/modify-python-lldb.py Message-ID: <20110703014329.6F5F72A6C12C@llvm.org> Author: johnny Date: Sat Jul 2 20:43:29 2011 New Revision: 134360 URL: http://llvm.org/viewvc/llvm-project?rev=134360&view=rev Log: Add swig docstrings for SBFrame.h. Add post-processing step to remove the trailing blank lines from the docstrings of lldb.py. Modified: lldb/trunk/include/lldb/API/SBFrame.h lldb/trunk/scripts/Python/modify-python-lldb.py Modified: lldb/trunk/include/lldb/API/SBFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFrame.h?rev=134360&r1=134359&r2=134360&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBFrame.h (original) +++ lldb/trunk/include/lldb/API/SBFrame.h Sat Jul 2 20:43:29 2011 @@ -77,41 +77,84 @@ lldb::SBSymbol GetSymbol () const; - // Gets the deepest block that contains the frame PC +#ifdef SWIG + %feature("docstring", " +#endif + /// Gets the deepest block that contains the frame PC. + /// + /// See also GetFrameBlock(). +#ifdef SWIG + ") GetBlock; +#endif lldb::SBBlock GetBlock () const; - // Get the appropriate function name for this frame. Inlined functions in - // LLDB are represented by Blocks that have inlined function information, so - // just looking at the SBFunction or SBSymbol for a frame isn't enough. - // This function will return the appriopriate function, symbol or inlined - // function name for the frame. +#ifdef SWIG + %feature("docstring", " +#endif + /// Get the appropriate function name for this frame. Inlined functions in + /// LLDB are represented by Blocks that have inlined function information, so + /// just looking at the SBFunction or SBSymbol for a frame isn't enough. + /// This function will return the appriopriate function, symbol or inlined + /// function name for the frame. + /// + /// This function returns: + /// - the name of the inlined function (if there is one) + /// - the name of the concrete function (if there is one) + /// - the name of the symbol (if there is one) + /// - NULL + /// + /// See also IsInlined(). +#ifdef SWIG + ") GetFunctionName; +#endif const char * GetFunctionName(); - // Return true if this frame represents and an inlined function. +#ifdef SWIG + %feature("docstring", " +#endif + /// Return true if this frame represents an inlined function. + /// + /// See also GetFunctionName(). +#ifdef SWIG + ") IsInlined; +#endif bool IsInlined(); - // The version that doesn't supply a "use_dynamic" value will use the target's default. +#ifdef SWIG + %feature("docstring", " +#endif + /// The version that doesn't supply a 'use_dynamic' value will use the + /// target's default. +#ifdef SWIG + ") EvaluateExpression; +#endif lldb::SBValue EvaluateExpression (const char *expr); lldb::SBValue EvaluateExpression (const char *expr, lldb::DynamicValueType use_dynamic); - // Gets the lexical block that defines the stack frame. Another way to think - // of this is it will return the block that contains all of the variables - // for a stack frame. Inlined functions are represented as SBBlock objects - // that have inlined function information: the name of the inlined function, - // where it was called from. The block that is returned will be the first - // block at or above the block for the PC (SBFrame::GetBlock()) that defines - // the scope of the frame. When a function contains no inlined functions, - // this will be the top most lexical block that defines the function. - // When a function has inlined functions and the PC is currently - // in one of those inlined functions, this method will return the inlined - // block that defines this frame. If the PC isn't currently in an inlined - // function, the lexical block that defines the function is returned. +#ifdef SWIG + %feature("docstring", " +#endif + /// Gets the lexical block that defines the stack frame. Another way to think + /// of this is it will return the block that contains all of the variables + /// for a stack frame. Inlined functions are represented as SBBlock objects + /// that have inlined function information: the name of the inlined function, + /// where it was called from. The block that is returned will be the first + /// block at or above the block for the PC (SBFrame::GetBlock()) that defines + /// the scope of the frame. When a function contains no inlined functions, + /// this will be the top most lexical block that defines the function. + /// When a function has inlined functions and the PC is currently + /// in one of those inlined functions, this method will return the inlined + /// block that defines this frame. If the PC isn't currently in an inlined + /// function, the lexical block that defines the function is returned. +#ifdef SWIG + ") GetFrameBlock; +#endif lldb::SBBlock GetFrameBlock () const; @@ -136,13 +179,20 @@ #endif +#ifdef SWIG + %feature("docstring", " +#endif + /// The version that doesn't supply a 'use_dynamic' value will use the + /// target's default. +#ifdef SWIG + ") GetVariables; +#endif lldb::SBValueList GetVariables (bool arguments, bool locals, bool statics, bool in_scope_only); - // The version that doesn't supply a "use_dynamic" value will use the target's default. lldb::SBValueList GetVariables (bool arguments, bool locals, @@ -153,15 +203,31 @@ lldb::SBValueList GetRegisters (); - // The version that doesn't supply a "use_dynamic" value will use the target's default. +#ifdef SWIG + %feature("docstring", " +#endif + /// The version that doesn't supply a 'use_dynamic' value will use the + /// target's default. +#ifdef SWIG + ") FindVariable; +#endif lldb::SBValue FindVariable (const char *var_name); lldb::SBValue FindVariable (const char *var_name, lldb::DynamicValueType use_dynamic); - // Find variables, register sets, registers, or persistent variables using - // the frame as the scope +#ifdef SWIG + %feature("docstring", " +#endif + /// Find variables, register sets, registers, or persistent variables using + /// the frame as the scope. + /// + /// The version that doesn't supply a 'use_dynamic' value will use the + /// target's default. +#ifdef SWIG + ") FindValue; +#endif lldb::SBValue FindValue (const char *name, ValueType value_type); Modified: lldb/trunk/scripts/Python/modify-python-lldb.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=134360&r1=134359&r2=134360&view=diff ============================================================================== --- lldb/trunk/scripts/Python/modify-python-lldb.py (original) +++ lldb/trunk/scripts/Python/modify-python-lldb.py Sat Jul 2 20:43:29 2011 @@ -29,6 +29,7 @@ c_endif_swig = "#endif" c_ifdef_swig = "#ifdef SWIG" c_comment_marker = "//------------" +trailing_blank_line = ' ' # The pattern for recognizing the doxygen comment block line. doxygen_comment_start = re.compile("^\s*( /// ?)") @@ -164,8 +165,8 @@ # Cleanse the lldb.py of the autodoc'ed residues. if c_ifdef_swig in line or c_endif_swig in line: continue - # As well as the comment marker line. - if c_comment_marker in line: + # As well as the comment marker line and trailing blank line. + if c_comment_marker in line or line == trailing_blank_line: continue # Also remove the '\a ' substrings. line = line.replace('\a ', '') From johnny.chen at apple.com Sun Jul 3 14:55:50 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sun, 03 Jul 2011 19:55:50 -0000 Subject: [Lldb-commits] [lldb] r134368 - /lldb/trunk/scripts/Python/modify-python-lldb.py Message-ID: <20110703195550.BA9EB2A6C12D@llvm.org> Author: johnny Date: Sun Jul 3 14:55:50 2011 New Revision: 134368 URL: http://llvm.org/viewvc/llvm-project?rev=134368&view=rev Log: Add a CLEANUP_DOCSTRING state to our FSM to do cleanup of the Python docstrings generated from the swig docstring features instead of blindly applying the cleanup action for all input lines. Modified: lldb/trunk/scripts/Python/modify-python-lldb.py Modified: lldb/trunk/scripts/Python/modify-python-lldb.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=134368&r1=134367&r2=134368&view=diff ============================================================================== --- lldb/trunk/scripts/Python/modify-python-lldb.py (original) +++ lldb/trunk/scripts/Python/modify-python-lldb.py Sun Jul 3 14:55:50 2011 @@ -10,7 +10,8 @@ # swig. For an example, take a look at SBTarget.h header file, where we take # advantage of the already existing doxygen C++-docblock and make it the Python # docstring for the same method. The 'residues' in this context include the -# '#endif' and the '#ifdef SWIG' lines. +# '#endif', the '#ifdef SWIG', the c comment marker, the trailing blank (SPC's) +# line, and the doxygen comment start marker. # # It also calls SBDebugger.Initialize() to initialize the lldb debugger # subsystem. @@ -32,6 +33,9 @@ trailing_blank_line = ' ' # The pattern for recognizing the doxygen comment block line. doxygen_comment_start = re.compile("^\s*( /// ?)") +# The demarcation point for turning on/off residue removal state. +# When bracketed by the lines, the CLEANUP_DOCSTRING state (see below) is ON. +toggle_docstring_cleanup_line = ' """' # # lldb_iter() should appear before our first SB* class definition. @@ -143,6 +147,7 @@ NORMAL = 0 DEFINING_ITERATOR = 1 DEFINING_EQUALITY = 2 +CLEANUP_DOCSTRING = 4 # The lldb_iter_def only needs to be inserted once. lldb_iter_defined = False; @@ -157,23 +162,25 @@ # method definition in order to insert the appropriate method(s) into the lldb # module. # +# The state CLEANUP_DOCSTRING can be entered from either the NORMAL or the +# DEFINING_ITERATOR/EQUALITY states. While in this state, the FSM is fixing/ +# cleaning the Python docstrings generated by the swig docstring features. +# # The FSM, in all possible states, also checks the current input for IsValid() # definition, and inserts a __nonzero__() method definition to implement truth # value testing and the built-in operation bool(). state = NORMAL for line in content.splitlines(): - # Cleanse the lldb.py of the autodoc'ed residues. - if c_ifdef_swig in line or c_endif_swig in line: - continue - # As well as the comment marker line and trailing blank line. - if c_comment_marker in line or line == trailing_blank_line: - continue - # Also remove the '\a ' substrings. - line = line.replace('\a ', '') - # And the leading '///' substring. - doxygen_comment_match = doxygen_comment_start.match(line) - if doxygen_comment_match: - line = line.replace(doxygen_comment_match.group(1), '', 1) + # Handle the state transition into CLEANUP_DOCSTRING state as it is possible + # to enter this state from either NORMAL or DEFINING_ITERATOR/EQUALITY. + # + # If ' """' is the sole line, prepare to transition to the + # CLEANUP_DOCSTRING state or out of it. + if line == toggle_docstring_cleanup_line: + if state & CLEANUP_DOCSTRING: + state ^= CLEANUP_DOCSTRING + else: + state |= CLEANUP_DOCSTRING if state == NORMAL: match = class_pattern.search(line) @@ -189,11 +196,12 @@ cls = match.group(1) if cls in d: # Adding support for iteration for the matched SB class. - state = (state | DEFINING_ITERATOR) + state |= DEFINING_ITERATOR if cls in e: # Adding support for eq and ne for the matched SB class. - state = (state | DEFINING_EQUALITY) - elif state > NORMAL: + state |= DEFINING_EQUALITY + + elif (state & DEFINING_ITERATOR) or (state & DEFINING_EQUALITY): match = init_pattern.search(line) if match: # We found the beginning of the __init__ method definition. @@ -214,6 +222,23 @@ # Next state will be NORMAL. state = NORMAL + elif (state & CLEANUP_DOCSTRING): + # Cleanse the lldb.py of the autodoc'ed residues. + if c_ifdef_swig in line or c_endif_swig in line: + continue + # As well as the comment marker line and trailing blank line. + if c_comment_marker in line or line == trailing_blank_line: + continue + # Also remove the '\a ' substrings. + line = line.replace('\a ', '') + # And the leading '///' substring. + doxygen_comment_match = doxygen_comment_start.match(line) + if doxygen_comment_match: + line = line.replace(doxygen_comment_match.group(1), '', 1) + + # Note that the transition out of CLEANUP_DOCSTRING is handled at the + # beginning of this function already. + # Look for 'def IsValid(*args):', and once located, add implementation # of truth value testing for this object by delegation. if isvalid_pattern.search(line):