From johnny.chen at apple.com Mon Dec 6 12:24:18 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 18:24:18 -0000 Subject: [Lldb-commits] [lldb] r121019 - /lldb/trunk/test/expression_command/test/TestExprs.py Message-ID: <20101206182418.8EB932A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 12:24:18 2010 New Revision: 121019 URL: http://llvm.org/viewvc/llvm-project?rev=121019&view=rev Log: Add two test cases to exercise many expression commands: o test_many_expr_commands() o test_expr_commands_can_handle_quotes() Mark test_expr_commands_can_handle_quotes() as @expectedFailure: # rdar://problem/8686536 # CommandInterpreter::HandleCommand is stripping \'s from input for WantsRawCommand commands Added: lldb/trunk/test/expression_command/test/TestExprs.py Added: lldb/trunk/test/expression_command/test/TestExprs.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/test/TestExprs.py?rev=121019&view=auto ============================================================================== --- lldb/trunk/test/expression_command/test/TestExprs.py (added) +++ lldb/trunk/test/expression_command/test/TestExprs.py Mon Dec 6 12:24:18 2010 @@ -0,0 +1,98 @@ +""" +Test many basic expression commands. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class BasicExprCommandsTestCase(TestBase): + + mydir = os.path.join("expression_command", "test") + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.c. + self.line = line_number('main.cpp', + '// Please test many expressions while stopped at this line:') + + def test_many_expr_commands(self): + """These basic expression commands should work as expected.""" + self.buildDefault() + + 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" % + self.line) + + self.runCmd("run", RUN_SUCCEEDED) + + self.expect("expression 2", + patterns = ["\(int\) \$.* = 2"]) + # (int) $0 = 1 + + self.expect("expression 2ull", + patterns = ["\(unsigned long long\) \$.* = 2"]) + # (unsigned long long) $1 = 2 + + self.expect("expression 2.234f", + patterns = ["\(float\) \$.* = 2\.234"]) + # (float) $2 = 2.234 + + self.expect("expression 2.234", + patterns = ["\(double\) \$.* = 2\.234"]) + # (double) $3 = 2.234 + + self.expect("expression 2+3", + patterns = ["\(int\) \$.* = 5"]) + # (int) $4 = 5 + + self.expect("expression argc", + patterns = ["\(int\) \$.* = 1"]) + # (int) $5 = 1 + + self.expect("expression argc + 22", + patterns = ["\(int\) \$.* = 23"]) + # (int) $6 = 23 + + self.expect("expression argv", + patterns = ["\(const char \*\*\) \$.* = 0x"]) + # (const char *) $7 = ... + + self.expect("expression argv[0]", + substrs = ["(const char *)", + os.path.join(self.mydir, "a.out")]) + # (const char *) $8 = 0x... "/Volumes/data/lldb/svn/trunk/test/expression_command/test/a.out" + + + @unittest2.expectedFailure + # rdar://problem/8686536 + # CommandInterpreter::HandleCommand is stripping \'s from input for WantsRawCommand commands + def test_expr_commands_can_handle_quotes(self): + """Throw some expression commands with quotes at lldb.""" + self.buildDefault() + + 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" % + self.line) + + self.runCmd("run", RUN_SUCCEEDED) + + self.runCmd("expression 'a'") + self.runCmd('expression printf("\t\x68\n")') + self.runCmd('expression printf("\"\n")') + self.runCmd('expression printf("\'\n")') + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() From gclayton at apple.com Mon Dec 6 13:08:45 2010 From: gclayton at apple.com (Greg Clayton) Date: Mon, 06 Dec 2010 19:08:45 -0000 Subject: [Lldb-commits] [lldb] r121027 - /lldb/trunk/test/foundation/main.m Message-ID: <20101206190845.67B1A2A6C12C@llvm.org> Author: gclayton Date: Mon Dec 6 13:08:45 2010 New Revision: 121027 URL: http://llvm.org/viewvc/llvm-project?rev=121027&view=rev Log: Added more test case functions to cover more objective C functionality. Modified: lldb/trunk/test/foundation/main.m Modified: lldb/trunk/test/foundation/main.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/main.m?rev=121027&r1=121026&r2=121027&view=diff ============================================================================== --- lldb/trunk/test/foundation/main.m (original) +++ lldb/trunk/test/foundation/main.m Mon Dec 6 13:08:45 2010 @@ -35,6 +35,8 @@ - (NSString *)description { + // Set a breakpoint on this function and test expressions: + // expression (char *)sel_getName(_cmd) if (self.descriptionPauses) { printf ("\nAbout to sleep.\n"); @@ -45,25 +47,86 @@ } @end -int main (int argc, char const *argv[]) +int +Test_Selector () { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSString *str = [NSString stringWithFormat:@"Hello from '%s'", argv[0]]; + SEL sel = @selector(length); + printf("sel = %p\n", sel); + // Expressions to test here: + // expression (char *)sel_getName(sel) + // The expression above should return "sel" as it should be just + // a uniqued C string pointer. We were seeing the result pointer being + // truncated with recent LLDBs. + return 0; +} + +int +Test_NSString (const char *program) +{ + NSString *str = [NSString stringWithFormat:@"Hello from '%s'", program]; NSLog(@"NSString instance: %@", str); + printf("str = '%s'\n", [str cStringUsingEncoding: [NSString defaultCStringEncoding]]); + printf("[str length] = %zu\n", (size_t)[str length]); + printf("[str description] = %s\n", [[str description] UTF8String]); + id str_id = str; + // Expressions to test here: + // expression (char *)sel_getName(sel) + // expression [str length] + // expression [id length] + // expression [str description] + // expression [id description] + // expression str.length + // expression str.description + // expression str = @"new" + // expression str = [NSString stringWithFormat: @"%cew", 'N'] + return 0; +} +void +Test_MyString (const char *program) +{ + NSString *str = [NSString stringWithFormat:@"Hello from '%s'", program]; MyString *my = [[MyString alloc] initWithNSString:str]; NSLog(@"MyString instance: %@", [my description]); - my.descriptionPauses = YES; + NSLog(@"MyString instance: %@", [my description]); +} + +int +Test_NSArray () +{ + NSArray *array1 = [NSArray arrayWithObjects: @"array1 object1", @"array1 object2", @"array1 object3", nil]; + NSArray *array2 = [NSArray arrayWithObjects: array1, @"array2 object2", @"array2 object3", nil]; + // Expressions to test here: + // expression [array1 count] + // expression array1.count + // expression [array2 count] + // expression array2.count + id obj; + // After each object at index call, use expression and validate object + obj = [array1 objectAtIndex: 0]; + obj = [array1 objectAtIndex: 1]; + obj = [array1 objectAtIndex: 2]; + + obj = [array2 objectAtIndex: 0]; + obj = [array2 objectAtIndex: 1]; + obj = [array2 objectAtIndex: 2]; + + return 0; +} + + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + Test_Selector(); + Test_NSArray (); + Test_NSString (argv[0]); + Test_MyString (argv[0]); - id str_id = str; // Set break point at this line. - SEL sel = @selector(length); - BOOL responds = [str respondsToSelector:sel]; printf("sizeof(id) = %zu\n", sizeof(id)); printf("sizeof(Class) = %zu\n", sizeof(Class)); printf("sizeof(SEL) = %zu\n", sizeof(SEL)); - printf("[str length] = %zu\n", (size_t)[str length]); - printf("str = '%s'\n", [str cStringUsingEncoding: [NSString defaultCStringEncoding]]); [pool release]; return 0; From johnny.chen at apple.com Mon Dec 6 15:08:51 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 21:08:51 -0000 Subject: [Lldb-commits] [lldb] r121036 - /lldb/trunk/test/load_unload/TestLoadUnload.py Message-ID: <20101206210852.08F852A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 15:08:51 2010 New Revision: 121036 URL: http://llvm.org/viewvc/llvm-project?rev=121036&view=rev Log: Add a test case test_lldb_process_load_and_unload_commands() for using lldb commands 'process load' and 'process unload' to load and unload shared library from lldb command lines. Modified: lldb/trunk/test/load_unload/TestLoadUnload.py Modified: lldb/trunk/test/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/TestLoadUnload.py?rev=121036&r1=121035&r2=121036&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Mon Dec 6 15:08:51 2010 @@ -3,6 +3,7 @@ """ import os, time +import re import unittest2 import lldb from lldbtest import * @@ -11,6 +12,63 @@ mydir = "load_unload" + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.line = line_number('main.c', + '// Set break point at this line for test_lldb_process_load_and_unload_commands().') + + def test_lldb_process_load_and_unload_commands(self): + """Test that lldb process load/unload command work correctly.""" + + # Invoke the default build rule. + self.buildDefault() + + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break at main.c before the call to dlopen(). + # Use lldb's process load command to load the dylib, instead. + + self.expect("breakpoint set -f main.c -l %d" % self.line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.c', line = %d" % + self.line) + + self.runCmd("run", RUN_SUCCEEDED) + + # Make sure that a_function does not exist at this point. + self.expect("image lookup -n a_function", "a_function should not exist yet", + error=True, matching=False, + patterns = ["1 match found .* %s" % self.mydir]) + + # Use lldb 'process load' to load the dylib. + self.expect("process load liba.dylib", "liba.dylib loaded correctly", + patterns = ['Loading "liba.dylib".*ok', + 'Image [0-9]+ loaded']) + + # Search for and match the "Image ([0-9]+) loaded" pattern. + output = self.res.GetOutput() + pattern = re.compile("Image ([0-9]+) loaded") + for l in output.split(os.linesep): + #print "l:", l + match = pattern.search(l) + if match: + break + index = match.group(1) + + # Now we should have an entry for a_function. + self.expect("image lookup -n a_function", "a_function should now exist", + patterns = ["1 match found .*%s" % self.mydir]) + + # Use lldb 'process unload' to unload the dylib. + self.expect("process unload %s" % index, "liba.dylib unloaded correctly", + patterns = ["Unloading .* with index %s.*ok" % index]) + + self.runCmd("process continue") + + def test_load_unload(self): """Test breakpoint by name works correctly with dlopen'ing.""" From johnny.chen at apple.com Mon Dec 6 15:48:09 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 21:48:09 -0000 Subject: [Lldb-commits] [lldb] r121039 - /lldb/trunk/test/lldbtest.py Message-ID: <20101206214809.084D82A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 15:48:08 2010 New Revision: 121039 URL: http://llvm.org/viewvc/llvm-project?rev=121039&view=rev Log: Fail fast by raising an exception if the 'string_to_match' cannot be located within the file 'filename'. Modified: lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=121039&r1=121038&r2=121039&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Dec 6 15:48:08 2010 @@ -213,7 +213,7 @@ if line.find(string_to_match) != -1: # Found our match. return i+1 - return -1 + raise Exception("Unable to find %s within file %s" % (string_to_match, filename)) def pointer_size(): """Return the pointer size of the host system.""" From johnny.chen at apple.com Mon Dec 6 16:07:36 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 22:07:36 -0000 Subject: [Lldb-commits] [lldb] r121045 - /lldb/trunk/test/load_unload/main.c Message-ID: <20101206220736.4BDE52A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 16:07:36 2010 New Revision: 121045 URL: http://llvm.org/viewvc/llvm-project?rev=121045&view=rev Log: Forgot to also check in this file with the previous r121036 change: /lldb/trunk/test/load_unload/TestLoadUnload.py Modified: lldb/trunk/test/load_unload/main.c Modified: lldb/trunk/test/load_unload/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/main.c?rev=121045&r1=121044&r2=121045&view=diff ============================================================================== --- lldb/trunk/test/load_unload/main.c (original) +++ lldb/trunk/test/load_unload/main.c Mon Dec 6 16:07:36 2010 @@ -23,7 +23,7 @@ void *c_dylib_handle = NULL; int (*a_function) (void); - a_dylib_handle = dlopen (a_name, RTLD_NOW); + a_dylib_handle = dlopen (a_name, RTLD_NOW); // Set break point at this line for test_lldb_process_load_and_unload_commands(). if (a_dylib_handle == NULL) { fprintf (stderr, "%s\n", dlerror()); From johnny.chen at apple.com Mon Dec 6 16:09:04 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 22:09:04 -0000 Subject: [Lldb-commits] [lldb] r121046 - in /lldb/trunk/test/foundation: TestObjCMethods.py main.m Message-ID: <20101206220904.4BF542A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 16:09:04 2010 New Revision: 121046 URL: http://llvm.org/viewvc/llvm-project?rev=121046&view=rev Log: Modified main.m and TestObjCMethods.py to unbreak the test/foundation directory. Modified: lldb/trunk/test/foundation/TestObjCMethods.py lldb/trunk/test/foundation/main.m Modified: lldb/trunk/test/foundation/TestObjCMethods.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestObjCMethods.py?rev=121046&r1=121045&r2=121046&view=diff ============================================================================== --- lldb/trunk/test/foundation/TestObjCMethods.py (original) +++ lldb/trunk/test/foundation/TestObjCMethods.py Mon Dec 6 16:09:04 2010 @@ -68,6 +68,12 @@ self.runCmd("process continue") + # Second stop is still +[NSString stringWithFormat:]. + self.expect("thread backtrace", "Stop at +[NSString stringWithFormat:]", + substrs = ["Foundation`+[NSString stringWithFormat:]"]) + + self.runCmd("process continue") + # Followed by a.out`-[MyString initWithNSString:]. self.expect("thread backtrace", "Stop at a.out`-[MyString initWithNSString:]", substrs = ["a.out`-[MyString initWithNSString:]"]) @@ -80,6 +86,12 @@ self.runCmd("process continue") + # Followed by the same -[MyString description]. + self.expect("thread backtrace", "Stop at -[MyString description]", + substrs = ["a.out`-[MyString description]"]) + + self.runCmd("process continue") + # Followed by -[NSAutoreleasePool release]. self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]", substrs = ["Foundation`-[NSAutoreleasePool release]"]) Modified: lldb/trunk/test/foundation/main.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/main.m?rev=121046&r1=121045&r2=121046&view=diff ============================================================================== --- lldb/trunk/test/foundation/main.m (original) +++ lldb/trunk/test/foundation/main.m Mon Dec 6 16:09:04 2010 @@ -88,6 +88,7 @@ NSString *str = [NSString stringWithFormat:@"Hello from '%s'", program]; MyString *my = [[MyString alloc] initWithNSString:str]; NSLog(@"MyString instance: %@", [my description]); + // Set break point at this line. Test 'expression -o -- my'. my.descriptionPauses = YES; NSLog(@"MyString instance: %@", [my description]); } From scallanan at apple.com Mon Dec 6 16:16:55 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 06 Dec 2010 22:16:55 -0000 Subject: [Lldb-commits] [lldb] r121048 - in /lldb/trunk/source: Expression/IRForTarget.cpp Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Symbol/ClangASTType.cpp Message-ID: <20101206221655.76A502A6C12C@llvm.org> Author: spyffe Date: Mon Dec 6 16:16:55 2010 New Revision: 121048 URL: http://llvm.org/viewvc/llvm-project?rev=121048&view=rev Log: Fixed a bug in which the SEL type was being resolved wrongly as the target of a pointer rather than the SEL pointer itself. This caused incorrect behavior when dealing with Objective-C selector variables. Modified: lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/trunk/source/Symbol/ClangASTType.cpp Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=121048&r1=121047&r2=121048&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Mon Dec 6 16:16:55 2010 @@ -846,7 +846,7 @@ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); if (log) - log->Printf("MaybeHandleVariable (%s)\n", PrintValue(llvm_value_ptr).c_str()); + log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str()); if (ConstantExpr *constant_expr = dyn_cast(llvm_value_ptr)) { 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=121048&r1=121047&r2=121048&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon Dec 6 16:16:55 2010 @@ -2933,7 +2933,7 @@ } else if (type_name_const_str == g_objc_type_name_selector) { - clang_type = ast.GetBuiltInType_objc_selector(); + clang_type = ast.CreatePointerType(ast.GetBuiltInType_objc_selector()); resolve_state = Type::eResolveStateFull; } } Modified: lldb/trunk/source/Symbol/ClangASTType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=121048&r1=121047&r2=121048&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTType.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTType.cpp Mon Dec 6 16:16:55 2010 @@ -160,6 +160,9 @@ case clang::BuiltinType::Float: case clang::BuiltinType::Double: case clang::BuiltinType::LongDouble: return lldb::eEncodingIEEE754; + + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCSel: return lldb::eEncodingUint; case clang::BuiltinType::NullPtr: return lldb::eEncodingUint; } From johnny.chen at apple.com Mon Dec 6 16:33:00 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 22:33:00 -0000 Subject: [Lldb-commits] [lldb] r121051 - /lldb/trunk/test/foundation/main.m Message-ID: <20101206223300.BBFC32A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 16:33:00 2010 New Revision: 121051 URL: http://llvm.org/viewvc/llvm-project?rev=121051&view=rev Log: Disambiguate the comment strings in order to be used from the .py test file. Modified: lldb/trunk/test/foundation/main.m Modified: lldb/trunk/test/foundation/main.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/main.m?rev=121051&r1=121050&r2=121051&view=diff ============================================================================== --- lldb/trunk/test/foundation/main.m (original) +++ lldb/trunk/test/foundation/main.m Mon Dec 6 16:33:00 2010 @@ -69,7 +69,7 @@ printf("[str length] = %zu\n", (size_t)[str length]); printf("[str description] = %s\n", [[str description] UTF8String]); id str_id = str; - // Expressions to test here: + // Expressions to test here for NSString: // expression (char *)sel_getName(sel) // expression [str length] // expression [id length] @@ -98,7 +98,7 @@ { NSArray *array1 = [NSArray arrayWithObjects: @"array1 object1", @"array1 object2", @"array1 object3", nil]; NSArray *array2 = [NSArray arrayWithObjects: array1, @"array2 object2", @"array2 object3", nil]; - // Expressions to test here: + // Expressions to test here for NSArray: // expression [array1 count] // expression array1.count // expression [array2 count] From johnny.chen at apple.com Mon Dec 6 16:34:54 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 22:34:54 -0000 Subject: [Lldb-commits] [lldb] r121052 - /lldb/trunk/test/foundation/main.m Message-ID: <20101206223454.E30FA2A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 16:34:54 2010 New Revision: 121052 URL: http://llvm.org/viewvc/llvm-project?rev=121052&view=rev Log: Modify Test_Selector's comment string, too. Modified: lldb/trunk/test/foundation/main.m Modified: lldb/trunk/test/foundation/main.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/main.m?rev=121052&r1=121051&r2=121052&view=diff ============================================================================== --- lldb/trunk/test/foundation/main.m (original) +++ lldb/trunk/test/foundation/main.m Mon Dec 6 16:34:54 2010 @@ -52,7 +52,7 @@ { SEL sel = @selector(length); printf("sel = %p\n", sel); - // Expressions to test here: + // Expressions to test here for selector: // expression (char *)sel_getName(sel) // The expression above should return "sel" as it should be just // a uniqued C string pointer. We were seeing the result pointer being From johnny.chen at apple.com Mon Dec 6 16:49:11 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 22:49:11 -0000 Subject: [Lldb-commits] [lldb] r121062 - /lldb/trunk/test/foundation/main.m Message-ID: <20101206224911.589382A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 16:49:11 2010 New Revision: 121062 URL: http://llvm.org/viewvc/llvm-project?rev=121062&view=rev Log: More descriptive comment string. Modified: lldb/trunk/test/foundation/main.m Modified: lldb/trunk/test/foundation/main.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/main.m?rev=121062&r1=121061&r2=121062&view=diff ============================================================================== --- lldb/trunk/test/foundation/main.m (original) +++ lldb/trunk/test/foundation/main.m Mon Dec 6 16:49:11 2010 @@ -35,7 +35,7 @@ - (NSString *)description { - // Set a breakpoint on this function and test expressions: + // Set a breakpoint on this function for '-[MyString description]' and test expressions: // expression (char *)sel_getName(_cmd) if (self.descriptionPauses) { From johnny.chen at apple.com Mon Dec 6 16:51:47 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 22:51:47 -0000 Subject: [Lldb-commits] [lldb] r121063 - /lldb/trunk/test/foundation/main.m Message-ID: <20101206225147.150202A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 16:51:46 2010 New Revision: 121063 URL: http://llvm.org/viewvc/llvm-project?rev=121063&view=rev Log: Minor comment string change. Modified: lldb/trunk/test/foundation/main.m Modified: lldb/trunk/test/foundation/main.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/main.m?rev=121063&r1=121062&r2=121063&view=diff ============================================================================== --- lldb/trunk/test/foundation/main.m (original) +++ lldb/trunk/test/foundation/main.m Mon Dec 6 16:51:46 2010 @@ -35,7 +35,7 @@ - (NSString *)description { - // Set a breakpoint on this function for '-[MyString description]' and test expressions: + // Set a breakpoint on '-[MyString description]' and test expressions: // expression (char *)sel_getName(_cmd) if (self.descriptionPauses) { From johnny.chen at apple.com Mon Dec 6 17:50:52 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 06 Dec 2010 23:50:52 -0000 Subject: [Lldb-commits] [lldb] r121068 - /lldb/trunk/test/foundation/TestObjCMethods2.py Message-ID: <20101206235052.2E6C72A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 17:50:52 2010 New Revision: 121068 URL: http://llvm.org/viewvc/llvm-project?rev=121068&view=rev Log: Add TestObjCMethods2.py to exercise more expression command sequences with objc. Mark NSArray_expr() and NSString_expr() as currently failing. Both are called from dsym and dwarf builds. So that makes the num of expected failures equal 4. ---------------------------------------------------------------------- Ran 6 tests in 19.856s OK (expected failures=4) Added: lldb/trunk/test/foundation/TestObjCMethods2.py Added: lldb/trunk/test/foundation/TestObjCMethods2.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestObjCMethods2.py?rev=121068&view=auto ============================================================================== --- lldb/trunk/test/foundation/TestObjCMethods2.py (added) +++ lldb/trunk/test/foundation/TestObjCMethods2.py Mon Dec 6 17:50:52 2010 @@ -0,0 +1,145 @@ +""" +Test more expression command sequences with objective-c. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + + at unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") +class FoundationTestCase2(TestBase): + + mydir = "foundation" + + def test_more_expr_commands_with_dsym(self): + """More expression commands for objective-c.""" + self.buildDsym() + self.more_expr_objc() + + def test_more_expr_commands_with_dwarf(self): + """More expression commands for objective-c.""" + self.buildDwarf() + self.more_expr_objc() + + def test_NSArray_expr_commands_with_dsym(self): + """Test expression commands for NSArray.""" + self.buildDsym() + self.NSArray_expr() + + def test_NSArray_expr_commands_with_dwarf(self): + """Test expression commands for NSArray.""" + self.buildDwarf() + self.NSArray_expr() + + def test_NSString_expr_commands_with_dsym(self): + """Test expression commands for NSString.""" + self.buildDsym() + self.NSString_expr() + + def test_NSString_expr_commands_with_dwarf(self): + """Test expression commands for NSString.""" + self.buildDwarf() + self.NSString_expr() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break at. + self.lines = [] + self.lines.append(line_number('main.m', '// Expressions to test here for selector:')) + self.lines.append(line_number('main.m', '// Expressions to test here for NSArray:')) + self.lines.append(line_number('main.m', '// Expressions to test here for NSString:')) + self.lines.append(line_number('main.m', "// Set a breakpoint on '-[MyString description]' and test expressions:")) + + def more_expr_objc(self): + """More expression commands for objective-c.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Create a bunch of breakpoints. + for line in self.lines: + self.expect("breakpoint set -f main.m -l %d" % line, BREAKPOINT_CREATED, + substrs = ["Breakpoint created:", + "file ='main.m', line = %d, locations = 1" % line]) + + self.runCmd("run", RUN_SUCCEEDED) + + # Test_Selector: + self.runCmd("thread backtrace") + self.expect("expression (char *)sel_getName(sel)", + substrs = ["(char *)", + "length"]) + + self.runCmd("process continue") + + # Test_NSArray: + self.runCmd("thread backtrace") + self.runCmd("process continue") + + # Test_NSString: + self.runCmd("thread backtrace") + self.runCmd("process continue") + + # Test_MyString: + self.runCmd("thread backtrace") + self.expect("expression (char *)sel_getName(_cmd)", + substrs = ["(char *)", + "description"]) + + self.runCmd("process continue") + + @unittest2.expectedFailure + def NSArray_expr(self): + """Test expression commands for NSArray.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside Test_NSArray: + line = self.lines[1] + self.expect("breakpoint set -f main.m -l %d" % line, BREAKPOINT_CREATED, + substrs = ["Breakpoint created:", + "file ='main.m', line = %d, locations = 1" % line]) + + self.runCmd("run", RUN_SUCCEEDED) + + # Test_NSArray: + self.runCmd("thread backtrace") + self.expect("expression [array1 count]") + self.expect("expression array1.count") + self.expect("expression [array2 count]") + self.expect("expression array2.count") + self.runCmd("process continue") + + @unittest2.expectedFailure + def NSString_expr(self): + """Test expression commands for NSString.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside Test_NSString: + line = self.lines[2] + self.expect("breakpoint set -f main.m -l %d" % line, BREAKPOINT_CREATED, + substrs = ["Breakpoint created:", + "file ='main.m', line = %d, locations = 1" % line]) + + self.runCmd("run", RUN_SUCCEEDED) + + # Test_NSString: + self.runCmd("thread backtrace") + self.expect("expression [str length]") + self.expect("expression [id length]") + self.expect("expression [str description]") + self.expect("expression [id description]") + self.expect("expression str.description") + self.expect("expression id.description") + self.expect('expression str = @"new"') + self.expect('expression str = [NSString stringWithFormat: @"%cew", \'N\']') + self.runCmd("process continue") + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() From gclayton at apple.com Mon Dec 6 17:51:26 2010 From: gclayton at apple.com (Greg Clayton) Date: Mon, 06 Dec 2010 23:51:26 -0000 Subject: [Lldb-commits] [lldb] r121069 - in /lldb/trunk: include/lldb/Core/ModuleList.h include/lldb/lldb-enumerations.h source/Breakpoint/Breakpoint.cpp source/Core/ModuleList.cpp source/Target/Target.cpp Message-ID: <20101206235126.F1F382A6C12C@llvm.org> Author: gclayton Date: Mon Dec 6 17:51:26 2010 New Revision: 121069 URL: http://llvm.org/viewvc/llvm-project?rev=121069&view=rev Log: When shared libraries are unloaded, they are now removed from the target ModuleList so they don't show up in the images. Breakpoint locations that are in shared libraries that get unloaded will persist though so that if you have plug-ins that load/unload and you have a breakpoint set on functions in the plug-ins, the hit counts will persist between loads/unloads. Modified: lldb/trunk/include/lldb/Core/ModuleList.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/source/Breakpoint/Breakpoint.cpp lldb/trunk/source/Core/ModuleList.cpp lldb/trunk/source/Target/Target.cpp Modified: lldb/trunk/include/lldb/Core/ModuleList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ModuleList.h?rev=121069&r1=121068&r2=121069&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ModuleList.h (original) +++ lldb/trunk/include/lldb/Core/ModuleList.h Mon Dec 6 17:51:26 2010 @@ -313,6 +313,9 @@ bool Remove (lldb::ModuleSP &module_sp); + size_t + Remove (ModuleList &module_list); + bool ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr); Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=121069&r1=121068&r2=121069&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Mon Dec 6 17:51:26 2010 @@ -56,7 +56,8 @@ { eLaunchFlagNone = 0u, eLaunchFlagDisableASLR = (1u << 0), ///< Disable Address Space Layout Randomization - eLaunchFlagDisableSTDIO = (1u << 1) /// Disable stdio for inferior process (e.g. for a GUI app) + eLaunchFlagDisableSTDIO = (1u << 1), ///< Disable stdio for inferior process (e.g. for a GUI app) + eLaunchFlagLaunchInTTY = (1u << 2) ///< Launch the process in a new TTY if supported by the host } LaunchFlags; //---------------------------------------------------------------------- Modified: lldb/trunk/source/Breakpoint/Breakpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=121069&r1=121068&r2=121069&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/Breakpoint.cpp (original) +++ lldb/trunk/source/Breakpoint/Breakpoint.cpp Mon Dec 6 17:51:26 2010 @@ -291,9 +291,9 @@ if (!m_filter_sp->ModulePasses (module_sp)) continue; - for (size_t j = 0; j < m_locations.GetSize(); j++) + for (size_t loc_idx = 0; loc_idx < m_locations.GetSize(); loc_idx++) { - BreakpointLocationSP break_loc = m_locations.GetByIndex(j); + BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx); if (!break_loc->IsEnabled()) continue; const Section *section = break_loc->GetAddress().GetSection(); @@ -333,24 +333,22 @@ for (size_t i = 0; i < module_list.GetSize(); i++) { ModuleSP module_sp (module_list.GetModuleAtIndex (i)); - if (!m_filter_sp->ModulePasses (module_sp)) - continue; - - for (size_t j = 0; j < m_locations.GetSize(); j++) + if (m_filter_sp->ModulePasses (module_sp)) { - BreakpointLocationSP break_loc = m_locations.GetByIndex(j); - const Section *section = break_loc->GetAddress().GetSection(); - if (section) + const size_t num_locs = m_locations.GetSize(); + for (size_t loc_idx = 0; loc_idx < num_locs; ++loc_idx) { - if (section->GetModule() == module_sp.get()) + BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx); + const Section *section = break_loc->GetAddress().GetSection(); + if (section && section->GetModule() == module_sp.get()) + { + // Remove this breakpoint since the shared library is + // unloaded, but keep the breakpoint location around + // so we always get complete hit count and breakpoint + // lifetime info break_loc->ClearBreakpointSite(); + } } -// else -// { -// Address temp_addr; -// if (module->ResolveLoadAddress(break_loc->GetLoadAddress(), m_target->GetProcess(), temp_addr)) -// break_loc->ClearBreakpointSite(); -// } } } } Modified: lldb/trunk/source/Core/ModuleList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=121069&r1=121068&r2=121069&view=diff ============================================================================== --- lldb/trunk/source/Core/ModuleList.cpp (original) +++ lldb/trunk/source/Core/ModuleList.cpp Mon Dec 6 17:51:26 2010 @@ -97,6 +97,20 @@ return false; } +size_t +ModuleList::Remove (ModuleList &module_list) +{ + Mutex::Locker locker(m_modules_mutex); + size_t num_removed = 0; + collection::iterator pos, end = module_list.m_modules.end(); + for (pos = module_list.m_modules.begin(); pos != end; ++pos) + { + if (Remove (*pos)) + ++num_removed; + } + return num_removed; +} + void Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=121069&r1=121068&r2=121069&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Mon Dec 6 17:51:26 2010 @@ -576,6 +576,10 @@ Target::ModulesDidUnload (ModuleList &module_list) { m_breakpoint_list.UpdateBreakpoints (module_list, false); + + // Remove the images from the target image list + m_images.Remove(module_list); + // TODO: make event data that packages up the module_list BroadcastEvent (eBroadcastBitModulesUnloaded, NULL); } From scallanan at apple.com Mon Dec 6 17:53:20 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 06 Dec 2010 23:53:20 -0000 Subject: [Lldb-commits] [lldb] r121070 - in /lldb/trunk/source: Expression/IRForTarget.cpp Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Symbol/ClangASTContext.cpp Message-ID: <20101206235320.749E32A6C12C@llvm.org> Author: spyffe Date: Mon Dec 6 17:53:20 2010 New Revision: 121070 URL: http://llvm.org/viewvc/llvm-project?rev=121070&view=rev Log: Fixes to make id work as well as well as fix minor errors when calling built-ins. Modified: lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=121070&r1=121069&r2=121070&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Mon Dec 6 17:53:20 2010 @@ -964,6 +964,10 @@ if (!fun) return false; } + else if (const_expr && const_expr->getOpcode() == Instruction::IntToPtr) + { + return true; // already resolved + } else { return false; 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=121070&r1=121069&r2=121070&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon Dec 6 17:53:20 2010 @@ -2933,7 +2933,7 @@ } else if (type_name_const_str == g_objc_type_name_selector) { - clang_type = ast.CreatePointerType(ast.GetBuiltInType_objc_selector()); + clang_type = ast.GetBuiltInType_objc_selector(); resolve_state = Type::eResolveStateFull; } } Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=121070&r1=121069&r2=121070&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Mon Dec 6 17:53:20 2010 @@ -677,7 +677,7 @@ clang_type_t ClangASTContext::GetBuiltInType_objc_id() { - return getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr(); + return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr(); } clang_type_t @@ -689,7 +689,7 @@ clang_type_t ClangASTContext::GetBuiltInType_objc_selector() { - return getASTContext()->ObjCBuiltinSelTy.getAsOpaquePtr(); + return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr(); } clang_type_t From johnny.chen at apple.com Mon Dec 6 18:31:29 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 07 Dec 2010 00:31:29 -0000 Subject: [Lldb-commits] [lldb] r121077 - /lldb/trunk/test/foundation/TestObjCMethods2.py Message-ID: <20101207003129.E43652A6C12C@llvm.org> Author: johnny Date: Mon Dec 6 18:31:29 2010 New Revision: 121077 URL: http://llvm.org/viewvc/llvm-project?rev=121077&view=rev Log: Add expect matching patterns for some self.expect() statements. Modified: lldb/trunk/test/foundation/TestObjCMethods2.py Modified: lldb/trunk/test/foundation/TestObjCMethods2.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestObjCMethods2.py?rev=121077&r1=121076&r2=121077&view=diff ============================================================================== --- lldb/trunk/test/foundation/TestObjCMethods2.py (original) +++ lldb/trunk/test/foundation/TestObjCMethods2.py Mon Dec 6 18:31:29 2010 @@ -105,10 +105,14 @@ # Test_NSArray: self.runCmd("thread backtrace") - self.expect("expression [array1 count]") - self.expect("expression array1.count") - self.expect("expression [array2 count]") - self.expect("expression array2.count") + self.expect("expression (int)[array1 count]", + patterns = ["\(int\) \$.* = 3"]) + self.expect("expression (int)[array2 count]", + patterns = ["\(int\) \$.* = 3"]) + self.expect("expression (int)array1.count", + patterns = ["\(int\) \$.* = 3"]) + self.expect("expression (int)array2.count", + patterns = ["\(int\) \$.* = 3"]) self.runCmd("process continue") @unittest2.expectedFailure @@ -127,8 +131,10 @@ # Test_NSString: self.runCmd("thread backtrace") - self.expect("expression [str length]") - self.expect("expression [id length]") + self.expect("expression (int)[str length]", + patterns = ["\(int\) \$.* ="]) + self.expect("expression (int)[id length]", + patterns = ["\(int\) \$.* ="]) self.expect("expression [str description]") self.expect("expression [id description]") self.expect("expression str.description") From jingham at apple.com Mon Dec 6 19:56:02 2010 From: jingham at apple.com (Jim Ingham) Date: Tue, 07 Dec 2010 01:56:02 -0000 Subject: [Lldb-commits] [lldb] r121099 - /lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Message-ID: <20101207015602.D8C0E2A6C12C@llvm.org> Author: jingham Date: Mon Dec 6 19:56:02 2010 New Revision: 121099 URL: http://llvm.org/viewvc/llvm-project?rev=121099&view=rev Log: Handle the case where you make a ClangExpressionDeclMap without a selected frame. Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=121099&r1=121098&r2=121099&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Mon Dec 6 19:56:02 2010 @@ -37,6 +37,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" #include "llvm/Support/raw_ostream.h" using namespace lldb; @@ -65,7 +66,9 @@ if (exe_ctx.frame) m_parser_vars->m_sym_ctx = exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything); - + else if (exe_ctx.thread) + m_parser_vars->m_sym_ctx = exe_ctx.thread->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything); + if (exe_ctx.process) m_parser_vars->m_persistent_vars = &exe_ctx.process->GetPersistentVariables(); } @@ -313,7 +316,9 @@ assert (m_parser_vars.get()); // Back out in all cases where we're not fully initialized - if (m_parser_vars->m_exe_ctx->frame == NULL) + if (m_parser_vars->m_exe_ctx->target == NULL) + return false; + if (!m_parser_vars->m_sym_ctx.target_sp) return false; SymbolContextList sc_list; From gclayton at apple.com Mon Dec 6 23:40:32 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 07 Dec 2010 05:40:32 -0000 Subject: [Lldb-commits] [lldb] r121112 - in /lldb/trunk: include/lldb/API/SBModule.h include/lldb/API/SBSymbol.h source/API/SBModule.cpp source/API/SBSymbol.cpp Message-ID: <20101207054032.1BF962A6C12C@llvm.org> Author: gclayton Date: Mon Dec 6 23:40:31 2010 New Revision: 121112 URL: http://llvm.org/viewvc/llvm-project?rev=121112&view=rev Log: Added symbol table access through the module for now. We might need to expose a SBSymtab class, but for now, we expose the symbols through the module. Modified: lldb/trunk/include/lldb/API/SBModule.h lldb/trunk/include/lldb/API/SBSymbol.h lldb/trunk/source/API/SBModule.cpp lldb/trunk/source/API/SBSymbol.cpp Modified: lldb/trunk/include/lldb/API/SBModule.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBModule.h?rev=121112&r1=121111&r2=121112&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBModule.h (original) +++ lldb/trunk/include/lldb/API/SBModule.h Mon Dec 6 23:40:31 2010 @@ -59,6 +59,12 @@ bool GetDescription (lldb::SBStream &description); + size_t + GetNumSymbols (); + + SBSymbol + GetSymbolAtIndex (size_t idx); + private: friend class SBSymbolContext; friend class SBTarget; Modified: lldb/trunk/include/lldb/API/SBSymbol.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBSymbol.h?rev=121112&r1=121111&r2=121112&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBSymbol.h (original) +++ lldb/trunk/include/lldb/API/SBSymbol.h Mon Dec 6 23:40:31 2010 @@ -62,9 +62,13 @@ private: friend class SBFrame; + friend class SBModule; friend class SBSymbolContext; SBSymbol (lldb_private::Symbol *lldb_object_ptr); + + void + SetSymbol (lldb_private::Symbol *lldb_object_ptr); lldb_private::Symbol *m_opaque_ptr; }; Modified: lldb/trunk/source/API/SBModule.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBModule.cpp?rev=121112&r1=121111&r2=121112&view=diff ============================================================================== --- lldb/trunk/source/API/SBModule.cpp (original) +++ lldb/trunk/source/API/SBModule.cpp Mon Dec 6 23:40:31 2010 @@ -181,3 +181,36 @@ return true; } + +size_t +SBModule::GetNumSymbols () +{ + if (m_opaque_sp) + { + ObjectFile *obj_file = m_opaque_sp->GetObjectFile(); + if (obj_file) + { + Symtab *symtab = obj_file->GetSymtab(); + if (symtab) + return symtab->GetNumSymbols(); + } + } + return 0; +} + +SBSymbol +SBModule::GetSymbolAtIndex (size_t idx) +{ + SBSymbol sb_symbol; + if (m_opaque_sp) + { + ObjectFile *obj_file = m_opaque_sp->GetObjectFile(); + if (obj_file) + { + Symtab *symtab = obj_file->GetSymtab(); + if (symtab) + sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx)); + } + } + return sb_symbol; +} Modified: lldb/trunk/source/API/SBSymbol.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBSymbol.cpp?rev=121112&r1=121111&r2=121112&view=diff ============================================================================== --- lldb/trunk/source/API/SBSymbol.cpp (original) +++ lldb/trunk/source/API/SBSymbol.cpp Mon Dec 6 23:40:31 2010 @@ -41,12 +41,17 @@ return *this; } - SBSymbol::~SBSymbol () { m_opaque_ptr = NULL; } +void +SBSymbol::SetSymbol (lldb_private::Symbol *lldb_object_ptr) +{ + m_opaque_ptr = lldb_object_ptr; +} + bool SBSymbol::IsValid () const { From gclayton at apple.com Mon Dec 6 23:59:17 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 07 Dec 2010 05:59:17 -0000 Subject: [Lldb-commits] [lldb] r121115 - /lldb/trunk/include/lldb/API/SBModule.h Message-ID: <20101207055917.2D3DD2A6C12C@llvm.org> Author: gclayton Date: Mon Dec 6 23:59:16 2010 New Revision: 121115 URL: http://llvm.org/viewvc/llvm-project?rev=121115&view=rev Log: Forgot to qualify SBSymbol with the lldb namespace for SWIG. Modified: lldb/trunk/include/lldb/API/SBModule.h Modified: lldb/trunk/include/lldb/API/SBModule.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBModule.h?rev=121115&r1=121114&r2=121115&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBModule.h (original) +++ lldb/trunk/include/lldb/API/SBModule.h Mon Dec 6 23:59:16 2010 @@ -62,7 +62,7 @@ size_t GetNumSymbols (); - SBSymbol + lldb::SBSymbol GetSymbolAtIndex (size_t idx); private: From gclayton at apple.com Tue Dec 7 01:37:38 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 07 Dec 2010 07:37:38 -0000 Subject: [Lldb-commits] [lldb] r121116 - in /lldb/trunk: lldb.xcodeproj/project.pbxproj source/Core/Section.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Message-ID: <20101207073738.A9A882A6C12C@llvm.org> Author: gclayton Date: Tue Dec 7 01:37:38 2010 New Revision: 121116 URL: http://llvm.org/viewvc/llvm-project?rev=121116&view=rev Log: Fixed an issue when debugging with DWARF in the .o files where if two functions had the same demangled names (constructors where we have the in charge and not in charge version) we could end up mixing the two up when making the function in the DWARF. This was because we need to lookup the symbol by name and we need to use the mangled name if there is one. This ensures we get the correct address and that we resolve the linked addresses correctly for DWARf with debug map. Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Core/Section.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=121116&r1=121115&r2=121116&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Dec 7 01:37:38 2010 @@ -2459,7 +2459,6 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, Modified: lldb/trunk/source/Core/Section.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Section.cpp?rev=121116&r1=121115&r2=121116&view=diff ============================================================================== --- lldb/trunk/source/Core/Section.cpp (original) +++ lldb/trunk/source/Core/Section.cpp Tue Dec 7 01:37:38 2010 @@ -272,7 +272,7 @@ addr = m_linked_section->GetFileAddress() + m_linked_offset; } - int indent = (sizeof(void*) + 1 + sizeof(user_id_t) + 1) * 2 + 3 + s->GetIndentLevel(); + int indent = 26 + s->GetIndentLevel(); s->Printf("%*.*s", indent, indent, ""); VMRange linked_range(addr, addr + m_byte_size); linked_range.Dump (s, 0); @@ -289,9 +289,7 @@ void Section::DumpName (Stream *s) const { - if (m_linked_section) - return m_linked_section->DumpName(s); - else if (m_parent == NULL) + if (m_parent == NULL) { // The top most section prints the module basename const char *module_basename = m_module->GetFileSpec().GetFilename().AsCString(); Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=121116&r1=121115&r2=121116&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Tue Dec 7 01:37:38 2010 @@ -282,7 +282,7 @@ // correctly to the new addresses in the main executable. // First we find the original symbol in the .o file's symbol table - Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); + Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); if (oso_fun_symbol) { // If we found the symbol, then we @@ -301,7 +301,7 @@ SectionSP oso_fun_section_sp (new Section (const_cast
(oso_fun_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()), oso_module, // Module (the .o file) sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs - exe_symbol->GetMangled().GetName(), // Name the section the same as the symbol for which is was generated! + exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated! eSectionTypeDebug, oso_fun_symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset(), // File VM address offset in the current section exe_symbol->GetByteSize(), // File size (we need the size from the executable) @@ -333,7 +333,7 @@ #if 0 // First we find the non-stab entry that corresponds to the N_GSYM in the executable - Symbol *exe_gsym_symbol = exe_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); + Symbol *exe_gsym_symbol = exe_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); #else // The mach-o object file parser already matches up the N_GSYM with with the non-stab // entry, so we shouldn't have to do that. If this ever changes, enable the code above @@ -352,7 +352,7 @@ SectionSP oso_gsym_section_sp (new Section (const_cast
(oso_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()), oso_module, // Module (the .o file) sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs - exe_symbol->GetMangled().GetName(), // Name the section the same as the symbol for which is was generated! + exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated! eSectionTypeDebug, oso_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset(), // File VM address offset in the current section 1, // We don't know the size of the global, just do the main address for now. From scallanan at apple.com Tue Dec 7 04:00:20 2010 From: scallanan at apple.com (Sean Callanan) Date: Tue, 07 Dec 2010 10:00:20 -0000 Subject: [Lldb-commits] [lldb] r121126 - in /lldb/trunk/source/Expression: ClangExpressionDeclMap.cpp ClangUserExpression.cpp Message-ID: <20101207100020.518952A6C12C@llvm.org> Author: spyffe Date: Tue Dec 7 04:00:20 2010 New Revision: 121126 URL: http://llvm.org/viewvc/llvm-project?rev=121126&view=rev Log: Logging improvements to help identify major events in LLDB expression execution. We also now print the argument structure after execution, to allow us to verify that the expression did indeed execute correctly. Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/ClangUserExpression.cpp Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=121126&r1=121125&r2=121126&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Dec 7 04:00:20 2010 @@ -507,6 +507,12 @@ return false; } + if (!m_material_vars->m_materialized_location) + { + err.SetErrorString("No materialized location"); + return false; + } + lldb::DataBufferSP data(new DataBufferHeap(m_struct_vars->m_struct_size, 0)); Error error; Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=121126&r1=121125&r2=121126&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangUserExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangUserExpression.cpp Tue Dec 7 04:00:20 2010 @@ -315,12 +315,14 @@ if (log) { - log->Printf("Function address : 0x%llx", (uint64_t)m_jit_addr); + log->Printf("-- Materializing for execution --"); + + log->Printf(" Function address : 0x%llx", (uint64_t)m_jit_addr); if (m_needs_object_ptr) - log->Printf("Object pointer : 0x%llx", (uint64_t)object_ptr); + log->Printf(" Object pointer : 0x%llx", (uint64_t)object_ptr); - log->Printf("Structure address : 0x%llx", (uint64_t)struct_address); + log->Printf(" Structure address : 0x%llx", (uint64_t)struct_address); StreamString args; @@ -330,11 +332,11 @@ { if (!m_expr_decl_map->DumpMaterializedStruct(exe_ctx, args, dump_error)) { - log->Printf("Couldn't extract variable values : %s", dump_error.AsCString("unknown error")); + log->Printf(" Couldn't extract variable values : %s", dump_error.AsCString("unknown error")); } else { - log->Printf("Structure contents:\n%s", args.GetData()); + log->Printf(" Structure contents:\n%s", args.GetData()); } } } @@ -371,6 +373,26 @@ { Error expr_error; + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + if (log) + { + log->Printf("-- Dematerializing after execution --"); + + StreamString args; + + Error dump_error; + + if (!m_expr_decl_map->DumpMaterializedStruct(exe_ctx, args, dump_error)) + { + log->Printf(" Couldn't extract variable values : %s", dump_error.AsCString("unknown error")); + } + else + { + log->Printf(" Structure contents:\n%s", args.GetData()); + } + } + if (!m_expr_decl_map->Dematerialize(exe_ctx, result, expr_error)) { error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error")); @@ -386,6 +408,8 @@ ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me, ClangExpressionVariable *&result) { + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + if (m_dwarf_opcodes.get()) { // TODO execute the JITted opcodes @@ -416,9 +440,16 @@ call_plan_sp->SetPrivate(true); uint32_t single_thread_timeout_usec = 10000000; + + if (log) + log->Printf("-- Execution of expression begins --"); + Process::ExecutionResults execution_result = exe_ctx.process->RunThreadPlan (exe_ctx, call_plan_sp, stop_others, try_all_threads, discard_on_error, single_thread_timeout_usec, error_stream); + + if (log) + log->Printf("-- Execution of expression completed --"); if (execution_result == Process::eExecutionInterrupted) { From johnny.chen at apple.com Tue Dec 7 11:08:17 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 07 Dec 2010 17:08:17 -0000 Subject: [Lldb-commits] [lldb] r121150 - /lldb/trunk/test/foundation/TestFoundationDisassembly.py Message-ID: <20101207170817.0DAD32A6C12C@llvm.org> Author: johnny Date: Tue Dec 7 11:08:16 2010 New Revision: 121150 URL: http://llvm.org/viewvc/llvm-project?rev=121150&view=rev Log: The do_simple_disasm() also needs to be modified to accommodate the recent changes to main.m. Modified: lldb/trunk/test/foundation/TestFoundationDisassembly.py Modified: lldb/trunk/test/foundation/TestFoundationDisassembly.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestFoundationDisassembly.py?rev=121150&r1=121149&r2=121150&view=diff ============================================================================== --- lldb/trunk/test/foundation/TestFoundationDisassembly.py (original) +++ lldb/trunk/test/foundation/TestFoundationDisassembly.py Tue Dec 7 11:08:16 2010 @@ -95,6 +95,8 @@ self.runCmd("disassemble -f") self.runCmd("process continue") + # Skip another breakpoint for +[NSString stringWithFormat:]. + self.runCmd("process continue") # Followed by a.out`-[MyString initWithNSString:]. self.expect("thread backtrace", "Stop at a.out`-[MyString initWithNSString:]", @@ -113,6 +115,8 @@ self.runCmd("disassemble -f") self.runCmd("process continue") + # Skip another breakpoint for -[MyString description]. + self.runCmd("process continue") # Followed by -[NSAutoreleasePool release]. self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]", From johnny.chen at apple.com Tue Dec 7 11:10:46 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 07 Dec 2010 17:10:46 -0000 Subject: [Lldb-commits] [lldb] r121151 - /lldb/trunk/test/signal/TestSendSignal.py Message-ID: <20101207171046.56AD22A6C12C@llvm.org> Author: johnny Date: Tue Dec 7 11:10:46 2010 New Revision: 121151 URL: http://llvm.org/viewvc/llvm-project?rev=121151&view=rev Log: 'thread backtrace', not 'thread backtrac'. Modified: lldb/trunk/test/signal/TestSendSignal.py Modified: lldb/trunk/test/signal/TestSendSignal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/signal/TestSendSignal.py?rev=121151&r1=121150&r2=121151&view=diff ============================================================================== --- lldb/trunk/test/signal/TestSendSignal.py (original) +++ lldb/trunk/test/signal/TestSendSignal.py Tue Dec 7 11:10:46 2010 @@ -39,7 +39,7 @@ self.line) self.runCmd("run", RUN_SUCCEEDED) - self.runCmd("thread backtrac") + self.runCmd("thread backtrace") # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, From gclayton at apple.com Tue Dec 7 12:05:22 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 07 Dec 2010 18:05:22 -0000 Subject: [Lldb-commits] [lldb] r121154 - /lldb/trunk/source/Core/Section.cpp Message-ID: <20101207180523.089A42A6C12C@llvm.org> Author: gclayton Date: Tue Dec 7 12:05:22 2010 New Revision: 121154 URL: http://llvm.org/viewvc/llvm-project?rev=121154&view=rev Log: Improved the "image dump section" command output by making sure it indents and shows things correctly. When we are debugging DWARF in .o files with debug map, we can see the remapped sections by dumping the sections for the .o files by explicitly dumping the module by name. For example, debugging the lldb/test/class_types example on MacOSX without a dSYM file we can make a query that causes the main.o file to be loaded, then we can do a: (lldb) image dump section main.o This will show the exact section map that is used and can help track down when things are going wrong with DWARF in .o files with debug map. Modified: lldb/trunk/source/Core/Section.cpp Modified: lldb/trunk/source/Core/Section.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Section.cpp?rev=121154&r1=121153&r2=121154&view=diff ============================================================================== --- lldb/trunk/source/Core/Section.cpp (original) +++ lldb/trunk/source/Core/Section.cpp Tue Dec 7 12:05:22 2010 @@ -234,7 +234,7 @@ s->Printf("%39s", ""); else { - if (target) + if (target && m_linked_section == NULL) addr = GetLoadBaseAddress (target); if (addr == LLDB_INVALID_ADDRESS) @@ -257,7 +257,7 @@ if (m_linked_section) { addr = LLDB_INVALID_ADDRESS; - + resolved = true; if (target) { addr = m_linked_section->GetLoadBaseAddress(target); @@ -668,6 +668,7 @@ void SectionList::Dump (Stream *s, Target *target, bool show_header) const { + bool target_has_loaded_sections = target && !target->GetSectionLoadList().IsEmpty(); if (show_header && !m_sections.empty()) { // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); @@ -676,7 +677,7 @@ // s->IndentMore(); // s->Printf("%*s", 2*(sizeof(void *) + 2), ""); s->Indent(); - s->Printf("SectID Type %s Address File Off. File Size Flags Section Name\n", (target && target->GetSectionLoadList().IsEmpty() == false) ? "Load" : "File"); + s->Printf("SectID Type %s Address File Off. File Size Flags Section Name\n", target_has_loaded_sections ? "Load" : "File"); // s->Printf("%*s", 2*(sizeof(void *) + 2), ""); s->Indent(); s->PutCString("---------- -------------- --------------------------------------- ---------- ---------- ---------- ----------------------------\n"); @@ -687,7 +688,7 @@ const_iterator end = m_sections.end(); for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) { - (*sect_iter)->Dump(s, target); + (*sect_iter)->Dump(s, target_has_loaded_sections ? target : NULL); } if (show_header && !m_sections.empty()) From gclayton at apple.com Tue Dec 7 12:26:09 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 07 Dec 2010 18:26:09 -0000 Subject: [Lldb-commits] [lldb] r121158 - in /lldb/trunk: include/lldb/Core/ValueObjectChild.h source/Core/ValueObjectChild.cpp Message-ID: <20101207182609.F30352A6C12C@llvm.org> Author: gclayton Date: Tue Dec 7 12:26:09 2010 New Revision: 121158 URL: http://llvm.org/viewvc/llvm-project?rev=121158&view=rev Log: Cleanup before making the objective C ivar changes. Modified: lldb/trunk/include/lldb/Core/ValueObjectChild.h lldb/trunk/source/Core/ValueObjectChild.cpp Modified: lldb/trunk/include/lldb/Core/ValueObjectChild.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectChild.h?rev=121158&r1=121157&r2=121158&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectChild.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectChild.h Tue Dec 7 12:26:09 2010 @@ -38,22 +38,40 @@ virtual ~ValueObjectChild(); virtual size_t - GetByteSize(); + GetByteSize() + { + return m_byte_size; + } virtual off_t - GetByteOffset(); + GetByteOffset() + { + return m_byte_offset; + } virtual uint32_t - GetBitfieldBitSize(); + GetBitfieldBitSize() + { + return m_bitfield_bit_size; + } virtual uint32_t - GetBitfieldBitOffset(); + GetBitfieldBitOffset() + { + return m_bitfield_bit_offset; + } virtual clang::ASTContext * - GetClangAST (); + GetClangAST () + { + return m_clang_ast; + } virtual void * - GetClangType (); + GetClangType () + { + return m_clang_type; + } virtual lldb::ValueType GetValueType() const; @@ -82,12 +100,10 @@ ConstString m_type_name; uint32_t m_byte_size; int32_t m_byte_offset; - uint32_t m_bitfield_bit_size; - uint32_t m_bitfield_bit_offset; + uint8_t m_bitfield_bit_size; + uint8_t m_bitfield_bit_offset; bool m_is_base_class; - uint32_t - GetByteOffset() const; // // void // ReadValueFromMemory (ValueObject* parent, lldb::addr_t address); Modified: lldb/trunk/source/Core/ValueObjectChild.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectChild.cpp?rev=121158&r1=121157&r2=121158&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectChild.cpp (original) +++ lldb/trunk/source/Core/ValueObjectChild.cpp Tue Dec 7 12:26:09 2010 @@ -45,8 +45,9 @@ m_bitfield_bit_offset (bitfield_bit_offset), m_is_base_class (is_base_class) { + assert (bitfield_bit_size < (sizeof(m_bitfield_bit_size ) * CHAR_BIT)); + assert (bitfield_bit_offset < (sizeof(m_bitfield_bit_offset) * CHAR_BIT)); assert(byte_size != 0 && "TEMPORARY DEBUGGING ASSERT"); - m_name = name; } @@ -54,12 +55,6 @@ { } -void * -ValueObjectChild::GetClangType() -{ - return m_clang_type; -} - lldb::ValueType ValueObjectChild::GetValueType() const { @@ -72,36 +67,6 @@ return ClangASTContext::GetNumChildren (m_clang_type, true); } -clang::ASTContext * -ValueObjectChild::GetClangAST () -{ - return m_clang_ast; -} - -size_t -ValueObjectChild::GetByteSize() -{ - return m_byte_size; -} - -off_t -ValueObjectChild::GetByteOffset() -{ - return m_byte_offset; -} - -uint32_t -ValueObjectChild::GetBitfieldBitSize() -{ - return m_bitfield_bit_size; -} - -uint32_t -ValueObjectChild::GetBitfieldBitOffset() -{ - return m_bitfield_bit_offset; -} - ConstString ValueObjectChild::GetTypeName() { From johnny.chen at apple.com Tue Dec 7 13:37:52 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 07 Dec 2010 19:37:52 -0000 Subject: [Lldb-commits] [lldb] r121168 - /lldb/trunk/test/foundation/TestSymbolTable.py Message-ID: <20101207193752.763DA2A6C12C@llvm.org> Author: johnny Date: Tue Dec 7 13:37:52 2010 New Revision: 121168 URL: http://llvm.org/viewvc/llvm-project?rev=121168&view=rev Log: Add test/foundation/TestSymbolTable.py to exercise accessing the symbol table entries (including synthesized properties) through the lldb Python APIs. Added: lldb/trunk/test/foundation/TestSymbolTable.py Added: lldb/trunk/test/foundation/TestSymbolTable.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestSymbolTable.py?rev=121168&view=auto ============================================================================== --- lldb/trunk/test/foundation/TestSymbolTable.py (added) +++ lldb/trunk/test/foundation/TestSymbolTable.py Tue Dec 7 13:37:52 2010 @@ -0,0 +1,81 @@ +""" +Test symbol table access for main.m. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + + at unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") +class FoundationSymtabTestCase(TestBase): + + mydir = "foundation" + + symbols_list = ['-[MyString initWithNSString:]', + '-[MyString dealloc]', + '-[MyString description]', + '-[MyString descriptionPauses]', # synthesized property + '-[MyString setDescriptionPauses:]', # synthesized property + 'Test_Selector', + 'Test_NSString', + 'Test_MyString', + 'Test_NSArray', + 'main' + ] + + def test_with_dsym_and_python_api(self): + """Test symbol table access with Python APIs.""" + self.buildDsym() + self.symtab_access_python() + + def test_with_dwarf_and_python_api(self): + """Test symbol table access with Python APIs.""" + self.buildDwarf() + self.symtab_access_python() + + def symtab_access_python(self): + """Test symbol table access with Python APIs.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchProcess([''], [''], os.ctermid(), 0, False) + + # + # Exercise Python APIs to access the symbol table entries. + # + + # Create the filespec by which to locate our a.out module. + filespec = lldb.SBFileSpec(exe, False) + + module = target.FindModule(filespec) + self.assertTrue(module.IsValid(), VALID_MODULE) + + # Create the set of known symbols. As we iterate through the symbol + # table, remove the symbol from the set if it is a known symbol. + expected_symbols = set(self.symbols_list) + from lldbutil import lldb_iter + for symbol in lldb_iter(module, 'GetNumSymbols', 'GetSymbolAtIndex'): + self.assertTrue(symbol.IsValid(), VALID_SYMBOL) + #print "symbol:", symbol + name = symbol.GetName() + if name in expected_symbols: + #print "Removing %s from known_symbols %s" % (name, expected_symbols) + expected_symbols.remove(name) + + # At this point, the known_symbols set should have become an empty set. + # If not, raise an error. + #print "symbols unaccounted for:", expected_symbols + self.assertTrue(len(expected_symbols) == 0, + "All the known symbols are accounted for") + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() From ctice at apple.com Tue Dec 7 13:58:26 2010 From: ctice at apple.com (Caroline Tice) Date: Tue, 07 Dec 2010 19:58:26 -0000 Subject: [Lldb-commits] [lldb] r121171 - in /lldb/trunk: include/lldb/Interpreter/Args.h include/lldb/Interpreter/CommandInterpreter.h include/lldb/lldb-private-log.h source/Commands/CommandObjectCommands.cpp source/Commands/CommandObjectHelp.cpp source/Interpreter/Args.cpp source/Interpreter/CommandInterpreter.cpp source/lldb-log.cpp test/set_values/TestSetValues.py Message-ID: <20101207195826.D96F92A6C12C@llvm.org> Author: ctice Date: Tue Dec 7 13:58:26 2010 New Revision: 121171 URL: http://llvm.org/viewvc/llvm-project?rev=121171&view=rev Log: - Fix alias-building & resolving to properly handle optional arguments for command options. - Add logging for command resolution ('log enable lldb commands') - Fix alias resolution to properly handle commands that take raw input (resolve the alias, but don't muck up the raw arguments). Net result: Among other things, 'expr' command can now take strings with escaped characters and not have the command handling & alias resolution code muck up the escaped characters. E.g. 'expr printf ("\n\n\tHello there!")' should now work properly. Not working yet: Creating aliases with raw input for commands that take raw input. Working on that. e.g. 'command alias print_hi expr printf ("\n\tHi!")' does not work yet. Modified: lldb/trunk/include/lldb/Interpreter/Args.h lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h lldb/trunk/include/lldb/lldb-private-log.h lldb/trunk/source/Commands/CommandObjectCommands.cpp lldb/trunk/source/Commands/CommandObjectHelp.cpp lldb/trunk/source/Interpreter/Args.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/source/lldb-log.cpp lldb/trunk/test/set_values/TestSetValues.py Modified: lldb/trunk/include/lldb/Interpreter/Args.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/Args.h?rev=121171&r1=121170&r2=121171&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/Args.h (original) +++ lldb/trunk/include/lldb/Interpreter/Args.h Tue Dec 7 13:58:26 2010 @@ -27,7 +27,8 @@ namespace lldb_private { -typedef std::pair OptionArgPair; +typedef std::pair OptionArgValue; +typedef std::pair OptionArgPair; typedef std::vector OptionArgVector; typedef lldb::SharedPtr::Type OptionArgVectorSP; @@ -301,6 +302,12 @@ //------------------------------------------------------------------ Error ParseOptions (Options &options); + + size_t + FindArgumentIndexForOption (struct option *long_options, int long_options_index); + + bool + IsPositionalArgument (const char *arg); // The following works almost identically to ParseOptions, except that no option is required to have arguments, // and it builds up the option_arg_vector as it parses the options. Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=121171&r1=121170&r2=121171&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Tue Dec 7 13:58:26 2010 @@ -193,8 +193,8 @@ HasAliasOptions (); void - BuildAliasCommandArgs (CommandObject *alias_cmd_obj, const char *alias_name, Args &cmd_args, - CommandReturnObject &result); + BuildAliasCommandArgs (CommandObject *alias_cmd_obj, const char *alias_name, Args &cmd_args, + std::string &raw_input_string, CommandReturnObject &result); int GetOptionArgumentPosition (const char *in_string); Modified: lldb/trunk/include/lldb/lldb-private-log.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-log.h?rev=121171&r1=121170&r2=121171&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-private-log.h (original) +++ lldb/trunk/include/lldb/lldb-private-log.h Tue Dec 7 13:58:26 2010 @@ -37,6 +37,7 @@ #define LIBLLDB_LOG_UNWIND (1u << 15) #define LIBLLDB_LOG_API (1u << 16) #define LIBLLDB_LOG_SCRIPT (1u << 17) +#define LIBLLDB_LOG_COMMANDS (1U << 18) #define LIBLLDB_LOG_ALL (UINT32_MAX) #define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ LIBLLDB_LOG_THREAD |\ @@ -44,7 +45,8 @@ LIBLLDB_LOG_BREAKPOINTS |\ LIBLLDB_LOG_WATCHPOINTS |\ LIBLLDB_LOG_STEP |\ - LIBLLDB_LOG_STATE ) + LIBLLDB_LOG_STATE |\ + LIBLLDB_LOG_COMMANDS) namespace lldb_private { Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=121171&r1=121170&r2=121171&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Tue Dec 7 13:58:26 2010 @@ -336,9 +336,11 @@ argc = args.GetArgumentCount(); for (size_t i = 0; i < argc; ++i) - if (strcmp (args.GetArgumentAtIndex (i), "") != 0) - option_arg_vector->push_back (OptionArgPair ("", - std::string (args.GetArgumentAtIndex (i)))); + if (strcmp (args.GetArgumentAtIndex (i), "") != 0) + option_arg_vector->push_back + (OptionArgPair ("", + OptionArgValue (-1, + std::string (args.GetArgumentAtIndex (i))))); } // Create the alias. Modified: lldb/trunk/source/Commands/CommandObjectHelp.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectHelp.cpp?rev=121171&r1=121170&r2=121171&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectHelp.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectHelp.cpp Tue Dec 7 13:58:26 2010 @@ -146,6 +146,10 @@ && (strlen (long_help) > 0)) output_strm.Printf ("\n%s", long_help); // Mark this help command with a success status. + if (sub_cmd_obj->WantsRawCommandString()) + { + m_interpreter.OutputFormattedHelpText (output_strm, "", "", "\nIMPORTANT NOTE: Because this command takes 'raw' input, if you use any command options you must use ' -- ' between the end of the command options and the beginning of the raw input.", 1); + } result.SetStatus (eReturnStatusSuccessFinishNoResult); } else if (sub_cmd_obj->IsMultiwordObject()) Modified: lldb/trunk/source/Interpreter/Args.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Args.cpp?rev=121171&r1=121170&r2=121171&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/Args.cpp (original) +++ lldb/trunk/source/Interpreter/Args.cpp Tue Dec 7 13:58:26 2010 @@ -801,6 +801,51 @@ } } +size_t +Args::FindArgumentIndexForOption (struct option *long_options, int long_options_index) +{ + char short_buffer[3]; + char long_buffer[255]; + ::snprintf (short_buffer, sizeof (short_buffer), "-%c", (char) long_options[long_options_index].val); + ::snprintf (long_buffer, sizeof (long_buffer), "--%s", long_options[long_options_index].name); + size_t end = GetArgumentCount (); + size_t idx = 0; + while (idx < end) + { + if ((::strncmp (GetArgumentAtIndex (idx), short_buffer, strlen (short_buffer)) == 0) + || (::strncmp (GetArgumentAtIndex (idx), long_buffer, strlen (long_buffer)) == 0)) + { + return idx; + } + ++idx; + } + + return end; +} + +bool +Args::IsPositionalArgument (const char *arg) +{ + if (arg == NULL) + return false; + + bool is_positional = true; + char *cptr = (char *) arg; + + if (cptr[0] == '%') + { + ++cptr; + while (isdigit (cptr[0])) + ++cptr; + if (cptr[0] != '\0') + is_positional = false; + } + else + is_positional = false; + + return is_positional; +} + void Args::ParseAliasOptions (Options &options, CommandReturnObject &result, @@ -889,14 +934,16 @@ switch (long_options[long_options_index].has_arg) { case no_argument: - option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), "")); + option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), + OptionArgValue (no_argument, ""))); result.SetStatus (eReturnStatusSuccessFinishNoResult); break; case required_argument: if (optarg != NULL) { option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - std::string (optarg))); + OptionArgValue (required_argument, + std::string (optarg)))); result.SetStatus (eReturnStatusSuccessFinishNoResult); } else @@ -910,13 +957,14 @@ if (optarg != NULL) { option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - std::string (optarg))); + OptionArgValue (optional_argument, + std::string (optarg)))); result.SetStatus (eReturnStatusSuccessFinishNoResult); } else { option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - "")); + OptionArgValue (optional_argument, ""))); result.SetStatus (eReturnStatusSuccessFinishNoResult); } break; @@ -938,24 +986,16 @@ { // Find option in the argument list; also see if it was supposed to take an argument and if one was // supplied. Remove option (and argument, if given) from the argument list. - StreamString short_opt_str; - StreamString long_opt_str; - short_opt_str.Printf ("-%c", (char) long_options[long_options_index].val); - long_opt_str.Printf ("-%s", long_options[long_options_index].name); - bool found = false; - size_t end = GetArgumentCount(); - for (size_t i = 0; i < end && !found; ++i) - if ((strcmp (GetArgumentAtIndex (i), short_opt_str.GetData()) == 0) - || (strcmp (GetArgumentAtIndex (i), long_opt_str.GetData()) == 0)) - { - found = true; - ReplaceArgumentAtIndex (i, ""); - if ((long_options[long_options_index].has_arg != no_argument) - && (optarg != NULL) - && (i+1 < end) - && (strcmp (optarg, GetArgumentAtIndex(i+1)) == 0)) - ReplaceArgumentAtIndex (i+1, ""); - } + size_t idx = FindArgumentIndexForOption (long_options, long_options_index); + if (idx < GetArgumentCount()) + { + ReplaceArgumentAtIndex (idx, ""); + if ((long_options[long_options_index].has_arg != no_argument) + && (optarg != NULL) + && (idx+1 < GetArgumentCount()) + && (strcmp (optarg, GetArgumentAtIndex(idx+1)) == 0)) + ReplaceArgumentAtIndex (idx+1, ""); + } } if (!result.Succeeded()) Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=121171&r1=121170&r2=121171&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Tue Dec 7 13:58:26 2010 @@ -406,7 +406,8 @@ { OptionArgPair cur_option = (*options)[i]; std::string opt = cur_option.first; - std::string value = cur_option.second; + OptionArgValue value_pair = cur_option.second; + std::string value = value_pair.second; if (opt.compare("") == 0) { help_string.Printf (" %s", value.c_str()); @@ -502,6 +503,7 @@ ExecutionContext *override_context ) { + LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS)); // FIXME: there should probably be a mutex to make sure only one thread can // run the interpreter at a time. @@ -542,10 +544,16 @@ add_to_history = false; } + if (log) + log->Printf ("CommandInterpreter::HandleCommand, command_line = '%s'", command_line); + Args command_args(command_line); if (command_args.GetArgumentCount() > 0) { + std::string raw_command_string (command_line); // For commands that take raw input but may be aliased or + // have command options. + const char *command_cstr = command_args.GetArgumentAtIndex(0); if (command_cstr) { @@ -556,20 +564,54 @@ if (command_obj != NULL) { + // Strip command name from the raw_command_string. + if (raw_command_string.find (command_cstr) == 0) + { + // The command name is at the front of the string (where it should be) so strip it off. + raw_command_string = raw_command_string.substr (strlen (command_cstr)); + } + + std::string aliased_cmd_str; if (command_obj->IsAlias()) { - BuildAliasCommandArgs (command_obj, command_cstr, command_args, result); + if (log) + log->Printf ("Command '%s' is an alias. Building alias command args.", command_cstr); + BuildAliasCommandArgs (command_obj, command_cstr, command_args, raw_command_string, result); if (!result.Succeeded()) + { + if (log) + log->Printf ("Building alias command args failed."); return false; + } else { // We need to transfer the newly constructed args back into the command_line, in case // this happens to be an alias for a command that takes raw input. if (command_args.GetCommandString (aliased_cmd_str)) { + if (log) + log->Printf ("Result string from BuildAliasCommandArgs is '%s'", aliased_cmd_str.c_str()); + if (command_obj->WantsRawCommandString()) + { + if (log) + { + log->Printf ("This command takes raw input."); + } + aliased_cmd_str.append (" "); + aliased_cmd_str.append (raw_command_string); + } + else + { + if (log) + log->Printf ("This command does NOT take raw input."); + } command_line = aliased_cmd_str.c_str(); command_cstr = command_args.GetArgumentAtIndex (0); + if (log) + { + log->Printf ("Final command line, after resolving aliases is '%s'", command_line); + } } } } @@ -594,6 +636,9 @@ stripped_command += strlen(command_cstr); while (isspace(*stripped_command)) ++stripped_command; + if (log) + log->Printf ("Input string being passed to ExecuteRawCommandString for '%s' command is '%s'", + command_obj->GetCommandName(), stripped_command); command_obj->ExecuteRawCommandString (stripped_command, result); } } @@ -601,6 +646,14 @@ { // Remove the command from the args. command_args.Shift(); + if (log) + { + size_t count = command_args.GetArgumentCount(); + log->Printf ("ExecuteWithOptions for '%s' command is being called with %d args:", + command_obj->GetCommandName(), count); + for (size_t k = 0; k < count; ++k) + log->Printf (" arg[%d]='%s'", k, command_args.GetArgumentAtIndex (k)); + } command_obj->ExecuteWithOptions (command_args, result); } } @@ -983,20 +1036,35 @@ CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj, const char *alias_name, Args &cmd_args, + std::string &raw_input_string, CommandReturnObject &result) { OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); + + bool wants_raw_input = alias_cmd_obj->WantsRawCommandString(); + // Make sure that the alias name is the 0th element in cmd_args + std::string alias_name_str = alias_name; + if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0) + cmd_args.Unshift (alias_name); + + Args new_args (alias_cmd_obj->GetCommandName()); + if (new_args.GetArgumentCount() == 2) + new_args.Shift(); + if (option_arg_vector_sp.get()) { - // Make sure that the alias name is the 0th element in cmd_args - std::string alias_name_str = alias_name; - if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0) - cmd_args.Unshift (alias_name); - - Args new_args (alias_cmd_obj->GetCommandName()); - if (new_args.GetArgumentCount() == 2) - new_args.Shift(); + if (wants_raw_input) + { + // We have a command that both has command options and takes raw input. Make *sure* it has a + // " -- " in the right place in the raw_input_string. + size_t pos = raw_input_string.find(" -- "); + if (pos == std::string::npos) + { + // None found; assume it goes at the beginning of the raw input string + raw_input_string.insert (0, " -- "); + } + } OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); int old_size = cmd_args.GetArgumentCount(); @@ -1007,19 +1075,36 @@ for (int i = 0; i < option_arg_vector->size(); ++i) { OptionArgPair option_pair = (*option_arg_vector)[i]; + OptionArgValue value_pair = option_pair.second; + int value_type = value_pair.first; std::string option = option_pair.first; - std::string value = option_pair.second; + std::string value = value_pair.second; if (option.compare ("") == 0) - new_args.AppendArgument (value.c_str()); + { + if (!wants_raw_input + || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice + new_args.AppendArgument (value.c_str()); + } else { - new_args.AppendArgument (option.c_str()); + if (value_type != optional_argument) + new_args.AppendArgument (option.c_str()); if (value.compare ("") != 0) { int index = GetOptionArgumentPosition (value.c_str()); if (index == 0) + { // value was NOT a positional argument; must be a real value - new_args.AppendArgument (value.c_str()); + if (value_type != optional_argument) + new_args.AppendArgument (value.c_str()); + else + { + char buffer[255]; + ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str()); + new_args.AppendArgument (buffer); + } + + } else if (index >= cmd_args.GetArgumentCount()) { result.AppendErrorWithFormat @@ -1030,7 +1115,22 @@ } else { - new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index)); + // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string + size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); + if (strpos != std::string::npos) + { + raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index))); + } + + if (value_type != optional_argument) + new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index)); + else + { + char buffer[255]; + ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(), + cmd_args.GetArgumentAtIndex (index)); + new_args.AppendArgument (buffer); + } used[index] = true; } } @@ -1039,7 +1139,7 @@ for (int j = 0; j < cmd_args.GetArgumentCount(); ++j) { - if (!used[j]) + if (!used[j] && !wants_raw_input) new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j)); } @@ -1049,7 +1149,14 @@ else { result.SetStatus (eReturnStatusSuccessFinishNoResult); - // This alias was not created with any options; nothing further needs to be done. + // This alias was not created with any options; nothing further needs to be done, unless it is a command that + // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw + // input string. + if (wants_raw_input) + { + cmd_args.Clear(); + cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); + } return; } Modified: lldb/trunk/source/lldb-log.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb-log.cpp?rev=121171&r1=121170&r2=121171&view=diff ============================================================================== --- lldb/trunk/source/lldb-log.cpp (original) +++ lldb/trunk/source/lldb-log.cpp Tue Dec 7 13:58:26 2010 @@ -116,6 +116,7 @@ if (strcasecmp(arg, "all") == 0 ) flag_bits &= ~LIBLLDB_LOG_ALL; else if (strcasecmp(arg, "api") == 0) flag_bits &= ~LIBLLDB_LOG_API; else if (strcasestr(arg, "break") == arg) flag_bits &= ~LIBLLDB_LOG_BREAKPOINTS; + else if (strcasecmp(arg, "commands")== 0) flag_bits &= ~LIBLLDB_LOG_COMMANDS; else if (strcasecmp(arg, "default") == 0 ) flag_bits &= ~LIBLLDB_LOG_DEFAULT; else if (strcasecmp(arg, "dyld") == 0 ) flag_bits &= ~LIBLLDB_LOG_DYNAMIC_LOADER; else if (strcasestr(arg, "event") == arg) flag_bits &= ~LIBLLDB_LOG_EVENTS; @@ -181,6 +182,7 @@ if (strcasecmp(arg, "all") == 0 ) flag_bits |= LIBLLDB_LOG_ALL; else if (strcasecmp(arg, "api") == 0) flag_bits |= LIBLLDB_LOG_API; else if (strcasestr(arg, "break") == arg) flag_bits |= LIBLLDB_LOG_BREAKPOINTS; + else if (strcasecmp(arg, "commands")== 0) flag_bits |= LIBLLDB_LOG_COMMANDS; else if (strcasecmp(arg, "default") == 0 ) flag_bits |= LIBLLDB_LOG_DEFAULT; else if (strcasecmp(arg, "dyld") == 0 ) flag_bits |= LIBLLDB_LOG_DYNAMIC_LOADER; else if (strcasestr(arg, "event") == arg) flag_bits |= LIBLLDB_LOG_EVENTS; Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=121171&r1=121170&r2=121171&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Tue Dec 7 13:58:26 2010 @@ -78,7 +78,7 @@ startstr = "(char) i = 'a'") # Now set variable 'i' and check that it is correctly displayed. - self.runCmd("expression i = \\'b\\'") # Escape the single quotes. + self.runCmd("expression i = 'b'") # Escape the single quotes. self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(char) i = 'b'") From johnny.chen at apple.com Tue Dec 7 14:22:32 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 07 Dec 2010 20:22:32 -0000 Subject: [Lldb-commits] [lldb] r121178 - /lldb/trunk/test/set_values/TestSetValues.py Message-ID: <20101207202232.C45072A6C12C@llvm.org> Author: johnny Date: Tue Dec 7 14:22:32 2010 New Revision: 121178 URL: http://llvm.org/viewvc/llvm-project?rev=121178&view=rev Log: Remove comment no longer applied. Modified: lldb/trunk/test/set_values/TestSetValues.py Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=121178&r1=121177&r2=121178&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Tue Dec 7 14:22:32 2010 @@ -78,7 +78,7 @@ startstr = "(char) i = 'a'") # Now set variable 'i' and check that it is correctly displayed. - self.runCmd("expression i = 'b'") # Escape the single quotes. + self.runCmd("expression i = 'b'") self.expect("frame variable -t", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(char) i = 'b'") From johnny.chen at apple.com Tue Dec 7 14:52:36 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 07 Dec 2010 20:52:36 -0000 Subject: [Lldb-commits] [lldb] r121183 - /lldb/trunk/test/expression_command/test/TestExprs.py Message-ID: <20101207205236.593BF2A6C12C@llvm.org> Author: johnny Date: Tue Dec 7 14:52:36 2010 New Revision: 121183 URL: http://llvm.org/viewvc/llvm-project?rev=121183&view=rev Log: Add a test sequence for test_expr_commands_can_handle_quotes(self): # runCmd: command alias print_hi expression printf ("\n\tHi!") # output: self.runCmd('command alias print_hi expression printf ("\\n\\tHi!")') # This fails currently. self.runCmd('print_hi') and modify existing test sequences to escape the escape character '\ to prevent it from being interpreted by Python before passing on to the lldb command interpreter. Modified: lldb/trunk/test/expression_command/test/TestExprs.py Modified: lldb/trunk/test/expression_command/test/TestExprs.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/test/TestExprs.py?rev=121183&r1=121182&r2=121183&view=diff ============================================================================== --- lldb/trunk/test/expression_command/test/TestExprs.py (original) +++ lldb/trunk/test/expression_command/test/TestExprs.py Tue Dec 7 14:52:36 2010 @@ -85,10 +85,31 @@ self.runCmd("run", RUN_SUCCEEDED) + # runCmd: expression 'a' + # output: (char) $0 = 'a' self.runCmd("expression 'a'") - self.runCmd('expression printf("\t\x68\n")') - self.runCmd('expression printf("\"\n")') - self.runCmd('expression printf("\'\n")') + + # runCmd: expression printf ("\n\n\tHello there!") + # output: (unsigned long) $1 = 15 + self.runCmd('expression printf ("\\n\\n\\tHello there!")') + + # runCmd: expression printf("\t\x68\n") + # output: (unsigned long) $2 = 3 + self.runCmd('expression printf("\\t\\x68\\n")') + + # runCmd: expression printf("\"\n") + # output: (unsigned long) $3 = 2 + self.runCmd('expression printf("\\"\\n")') + + # runCmd: expression printf("'\n") + # output: (unsigned long) $4 = 2 + self.runCmd('expression printf("\'\\n")') + + # runCmd: command alias print_hi expression printf ("\n\tHi!") + # output: + self.runCmd('command alias print_hi expression printf ("\\n\\tHi!")') + # This fails currently. + self.runCmd('print_hi') if __name__ == '__main__': From johnny.chen at apple.com Tue Dec 7 15:17:12 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 07 Dec 2010 21:17:12 -0000 Subject: [Lldb-commits] [lldb] r121185 - /lldb/trunk/test/expression_command/test/TestExprs.py Message-ID: <20101207211712.D89982A6C12C@llvm.org> Author: johnny Date: Tue Dec 7 15:17:12 2010 New Revision: 121185 URL: http://llvm.org/viewvc/llvm-project?rev=121185&view=rev Log: Make the various expression command test sequences more strict by also verifying the results against our golden ones. Modified: lldb/trunk/test/expression_command/test/TestExprs.py Modified: lldb/trunk/test/expression_command/test/TestExprs.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/test/TestExprs.py?rev=121185&r1=121184&r2=121185&view=diff ============================================================================== --- lldb/trunk/test/expression_command/test/TestExprs.py (original) +++ lldb/trunk/test/expression_command/test/TestExprs.py Tue Dec 7 15:17:12 2010 @@ -87,23 +87,33 @@ # runCmd: expression 'a' # output: (char) $0 = 'a' - self.runCmd("expression 'a'") - - # runCmd: expression printf ("\n\n\tHello there!") - # output: (unsigned long) $1 = 15 - self.runCmd('expression printf ("\\n\\n\\tHello there!")') + self.expect("expression 'a'", + substrs = ['(char) $', + "'a'"]) + + # runCmd: expression printf ("\n\n\tHello there!\\n") + # output: (unsigned long) $1 = 16 + self.expect('expression printf ("\\n\\n\\tHello there!\\n")', + substrs = ['(unsigned long) $', + '16']) # runCmd: expression printf("\t\x68\n") # output: (unsigned long) $2 = 3 - self.runCmd('expression printf("\\t\\x68\\n")') + self.expect('expression printf("\\t\\x68\\n")', + substrs = ['(unsigned long) $', + '3']) # runCmd: expression printf("\"\n") # output: (unsigned long) $3 = 2 - self.runCmd('expression printf("\\"\\n")') + self.expect('expression printf("\\"\\n")', + substrs = ['(unsigned long) $', + '2']) # runCmd: expression printf("'\n") # output: (unsigned long) $4 = 2 - self.runCmd('expression printf("\'\\n")') + self.expect('expression printf("\'\\n")', + substrs = ['(unsigned long) $', + '2']) # runCmd: command alias print_hi expression printf ("\n\tHi!") # output: From scallanan at apple.com Tue Dec 7 16:55:01 2010 From: scallanan at apple.com (Sean Callanan) Date: Tue, 07 Dec 2010 22:55:01 -0000 Subject: [Lldb-commits] [lldb] r121193 - in /lldb/trunk/source: API/SBFrame.cpp Expression/ClangUserExpression.cpp Message-ID: <20101207225501.5C0A52A6C12C@llvm.org> Author: spyffe Date: Tue Dec 7 16:55:01 2010 New Revision: 121193 URL: http://llvm.org/viewvc/llvm-project?rev=121193&view=rev Log: More logging for use in debugging the interactions between clients of the LLDB API and the expression parser. Modified: lldb/trunk/source/API/SBFrame.cpp lldb/trunk/source/Expression/ClangUserExpression.cpp Modified: lldb/trunk/source/API/SBFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=121193&r1=121192&r2=121193&view=diff ============================================================================== --- lldb/trunk/source/API/SBFrame.cpp (original) +++ lldb/trunk/source/API/SBFrame.cpp Tue Dec 7 16:55:01 2010 @@ -561,6 +561,8 @@ SBFrame::EvaluateExpression (const char *expr) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + LogSP expr_log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); lldb::SBValue expr_result; if (log) @@ -580,6 +582,9 @@ ClangUserExpression::Evaluate (exe_ctx, discard_on_error, expr, prefix, *expr_result); } + if (expr_log) + expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is %s, summary %s **", expr_result.GetValue(*this), expr_result.GetSummary(*this)); + if (log) log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p)", m_opaque_sp.get(), expr, expr_result.get()); Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=121193&r1=121192&r2=121193&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangUserExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangUserExpression.cpp Tue Dec 7 16:55:01 2010 @@ -315,7 +315,7 @@ if (log) { - log->Printf("-- Materializing for execution --"); + log->Printf("-- [ClangUserExpression::PrepareToExecuteJITExpression] Materializing for execution --"); log->Printf(" Function address : 0x%llx", (uint64_t)m_jit_addr); @@ -377,7 +377,7 @@ if (log) { - log->Printf("-- Dematerializing after execution --"); + log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --"); StreamString args; @@ -442,14 +442,14 @@ uint32_t single_thread_timeout_usec = 10000000; if (log) - log->Printf("-- Execution of expression begins --"); + log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --"); Process::ExecutionResults execution_result = exe_ctx.process->RunThreadPlan (exe_ctx, call_plan_sp, stop_others, try_all_threads, discard_on_error, single_thread_timeout_usec, error_stream); if (log) - log->Printf("-- Execution of expression completed --"); + log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --"); if (execution_result == Process::eExecutionInterrupted) { @@ -494,6 +494,8 @@ const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp) { + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + Error error; Process::ExecutionResults execution_results = Process::eExecutionSetupError; @@ -507,6 +509,9 @@ if (!exe_ctx.process->GetDynamicCheckers()) { + if (log) + log->Printf("== [ClangUserExpression::Evaluate] Installing dynamic checkers =="); + DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions(); StreamString install_errors; @@ -523,12 +528,18 @@ } exe_ctx.process->SetDynamicCheckers(dynamic_checkers); + + if (log) + log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers =="); } ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix)); StreamString error_stream; + if (log) + log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr); + if (!user_expression_sp->Parse (error_stream, exe_ctx, TypeFromUser(NULL, NULL))) { if (error_stream.GetString().empty()) @@ -541,6 +552,9 @@ ClangExpressionVariable *expr_result = NULL; error_stream.GetString().clear(); + + if (log) + log->Printf("== [ClangUserExpression::Evaluate] Executing expression =="); execution_results = user_expression_sp->Execute (error_stream, exe_ctx, @@ -549,6 +563,9 @@ expr_result); if (execution_results != Process::eExecutionCompleted) { + if (log) + log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally =="); + if (error_stream.GetString().empty()) error.SetErrorString ("expression failed to execute, unknown error"); else @@ -564,9 +581,15 @@ if (expr_result) { result_valobj_sp = expr_result->GetExpressionResult (&exe_ctx); + + if (log) + log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString(exe_ctx.GetBestExecutionContextScope())); } else { + if (log) + log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result =="); + error.SetErrorString ("Expression did not return a result"); } } From johnny.chen at apple.com Tue Dec 7 17:12:51 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 07 Dec 2010 23:12:51 -0000 Subject: [Lldb-commits] [lldb] r121199 - /lldb/trunk/test/expression_command/test/TestExprs.py Message-ID: <20101207231251.A371D2A6C12C@llvm.org> Author: johnny Date: Tue Dec 7 17:12:51 2010 New Revision: 121199 URL: http://llvm.org/viewvc/llvm-project?rev=121199&view=rev Log: Use Python raw string literal to avoid escaping the escape sequence and to make the command given to lldb command interpreter more readable. Modified: lldb/trunk/test/expression_command/test/TestExprs.py Modified: lldb/trunk/test/expression_command/test/TestExprs.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/test/TestExprs.py?rev=121199&r1=121198&r2=121199&view=diff ============================================================================== --- lldb/trunk/test/expression_command/test/TestExprs.py (original) +++ lldb/trunk/test/expression_command/test/TestExprs.py Tue Dec 7 17:12:51 2010 @@ -91,33 +91,33 @@ substrs = ['(char) $', "'a'"]) - # runCmd: expression printf ("\n\n\tHello there!\\n") + # runCmd: expression printf ("\n\n\tHello there!\n") # output: (unsigned long) $1 = 16 - self.expect('expression printf ("\\n\\n\\tHello there!\\n")', + self.expect(r'''expression printf ("\n\n\tHello there!\n")''', substrs = ['(unsigned long) $', '16']) # runCmd: expression printf("\t\x68\n") # output: (unsigned long) $2 = 3 - self.expect('expression printf("\\t\\x68\\n")', + self.expect(r'''expression printf("\t\x68\n")''', substrs = ['(unsigned long) $', '3']) # runCmd: expression printf("\"\n") # output: (unsigned long) $3 = 2 - self.expect('expression printf("\\"\\n")', + self.expect(r'''expression printf("\"\n")''', substrs = ['(unsigned long) $', '2']) # runCmd: expression printf("'\n") # output: (unsigned long) $4 = 2 - self.expect('expression printf("\'\\n")', + self.expect(r'''expression printf("'\n")''', substrs = ['(unsigned long) $', '2']) - # runCmd: command alias print_hi expression printf ("\n\tHi!") + # runCmd: command alias print_hi expression printf ("\n\tHi!\n") # output: - self.runCmd('command alias print_hi expression printf ("\\n\\tHi!")') + self.runCmd(r'''command alias print_hi expression printf ("\n\tHi!\n")''') # This fails currently. self.runCmd('print_hi') From johnny.chen at apple.com Tue Dec 7 19:08:27 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 08 Dec 2010 01:08:27 -0000 Subject: [Lldb-commits] [lldb] r121218 - /lldb/trunk/test/expression_command/test/TestExprs.py Message-ID: <20101208010828.01A6D2A6C12C@llvm.org> Author: johnny Date: Tue Dec 7 19:08:27 2010 New Revision: 121218 URL: http://llvm.org/viewvc/llvm-project?rev=121218&view=rev Log: Add test_evaluate_expression_python() to exercise SBFrame.EvaluateExpression() Python API. Launch the process with ['X', 'Y', 'Z'] as the args to make argc == 4 and verify that's the case, plus some other EvaluateExpression() calls. Modified: lldb/trunk/test/expression_command/test/TestExprs.py Modified: lldb/trunk/test/expression_command/test/TestExprs.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/test/TestExprs.py?rev=121218&r1=121217&r2=121218&view=diff ============================================================================== --- lldb/trunk/test/expression_command/test/TestExprs.py (original) +++ lldb/trunk/test/expression_command/test/TestExprs.py Tue Dec 7 19:08:27 2010 @@ -1,10 +1,11 @@ """ -Test many basic expression commands. +Test many basic expression commands and SBFrame.EvaluateExpression() API. """ import os, time import unittest2 import lldb +import lldbutil from lldbtest import * class BasicExprCommandsTestCase(TestBase): @@ -69,6 +70,89 @@ # (const char *) $8 = 0x... "/Volumes/data/lldb/svn/trunk/test/expression_command/test/a.out" + def test_evaluate_expression_python(self): + """These SBFrame.EvaluateExpression() API.""" + self.buildDefault() + + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Create the breakpoint. + filespec = lldb.SBFileSpec("main.cpp", False) + breakpoint = target.BreakpointCreateByLocation(filespec, self.line) + self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) + + # Verify the breakpoint just created. + self.expect(repr(breakpoint), BREAKPOINT_CREATED, exe=False, + substrs = ['main.cpp', + str(self.line)]) + + # Launch the process, and do not stop at the entry point. + # Pass 'X Y Z' as the args, which makes argc == 4. + rc = lldb.SBError() + self.process = target.Launch(['X', 'Y', 'Z'], [], os.ctermid(), 0, False, rc) + + if not rc.Success() or not self.process.IsValid(): + self.fail("SBTarget.LaunchProcess() failed") + + if self.process.GetState() != lldb.eStateStopped: + self.fail("Process should be in the 'stopped' state, " + "instead the actual state is: '%s'" % + lldbutil.StateTypeString(self.process.GetState())) + + # The stop reason of the thread should be breakpoint. + thread = self.process.GetThreadAtIndex(0) + if thread.GetStopReason() != lldb.eStopReasonBreakpoint: + from lldbutil import StopReasonString + self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % + StopReasonString(thread.GetStopReason())) + + # The filename of frame #0 should be 'main.cpp' and function is main. + self.expect(lldbutil.GetFilenames(thread)[0], + "Break correctly at main.cpp", exe=False, + startstr = "main.cpp") + self.expect(lldbutil.GetFunctionNames(thread)[0], + "Break correctly at main()", exe=False, + startstr = "main") + + # We should be stopped on the breakpoint with a hit count of 1. + self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) + + # + # Use Python API to evaluate expressions while stopped in a stack frame. + # + frame = thread.GetFrameAtIndex(0) + + val = frame.EvaluateExpression("2.234") + self.expect(val.GetValue(frame), "2.345 evaluated correctly", exe=False, + startstr = "2.234") + self.expect(val.GetTypeName(), "2.345 evaluated correctly", exe=False, + startstr = "double") + self.DebugSBValue(frame, val) + + val = frame.EvaluateExpression("argc") + self.expect(val.GetValue(frame), "Argc evaluated correctly", exe=False, + startstr = "4") + self.DebugSBValue(frame, val) + + val = frame.EvaluateExpression("*argv[1]") + self.expect(val.GetValue(frame), "Argv[1] evaluated correctly", exe=False, + startstr = "'X'") + self.DebugSBValue(frame, val) + + val = frame.EvaluateExpression("*argv[2]") + self.expect(val.GetValue(frame), "Argv[2] evaluated correctly", exe=False, + startstr = "'Y'") + self.DebugSBValue(frame, val) + + val = frame.EvaluateExpression("*argv[3]") + self.expect(val.GetValue(frame), "Argv[3] evaluated correctly", exe=False, + startstr = "'Z'") + self.DebugSBValue(frame, val) + + @unittest2.expectedFailure # rdar://problem/8686536 # CommandInterpreter::HandleCommand is stripping \'s from input for WantsRawCommand commands From johnny.chen at apple.com Tue Dec 7 19:25:21 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 08 Dec 2010 01:25:21 -0000 Subject: [Lldb-commits] [lldb] r121220 - in /lldb/trunk/test: array_types/TestArrayTypes.py bitfields/TestBitfields.py class_static/TestStaticVariables.py class_types/TestClassTypes.py conditional_break/TestConditionalBreak.py dotest.py foundation/TestSymbolTable.py hello_world/TestHelloWorld.py lldbtest.py threads/TestPrintStackTraces.py Message-ID: <20101208012521.D7F1D2A6C12C@llvm.org> Author: johnny Date: Tue Dec 7 19:25:21 2010 New Revision: 121220 URL: http://llvm.org/viewvc/llvm-project?rev=121220&view=rev Log: For SBTarget.Launch()/LaunchProcess(), there's no need to pass an empty string as the args and the envs to the launched process. o lldbtest.py: Forgot to check in some assertion messages changes for lldbtest.py. o dotest.py: Also add "api" category to the default lldb log option list. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/class_static/TestStaticVariables.py lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/conditional_break/TestConditionalBreak.py lldb/trunk/test/dotest.py lldb/trunk/test/foundation/TestSymbolTable.py lldb/trunk/test/hello_world/TestHelloWorld.py lldb/trunk/test/lldbtest.py lldb/trunk/test/threads/TestPrintStackTraces.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Tue Dec 7 19:25:21 2010 @@ -108,7 +108,7 @@ substrs = ["resolved = 1"]) # Now launch the process, and do not stop at entry point. - self.process = target.LaunchProcess([''], [''], os.ctermid(), 0, False) + self.process = target.LaunchProcess([], [], os.ctermid(), 0, False) self.process = target.GetProcess() self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Tue Dec 7 19:25:21 2010 @@ -94,7 +94,7 @@ self.runCmd("run", RUN_SUCCEEDED, setCookie=False) # This does not work, and results in the process stopped at dyld_start? - #process = target.LaunchProcess([''], [''], os.ctermid(), False) + #process = target.LaunchProcess([], [], os.ctermid(), False) self.process = target.GetProcess() self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) Modified: lldb/trunk/test/class_static/TestStaticVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_static/TestStaticVariables.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/class_static/TestStaticVariables.py (original) +++ lldb/trunk/test/class_static/TestStaticVariables.py Tue Dec 7 19:25:21 2010 @@ -78,7 +78,7 @@ self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) # Now launch the process, and do not stop at entry point. - self.process = target.LaunchProcess([''], [''], os.ctermid(), 0, False) + self.process = target.LaunchProcess([], [], os.ctermid(), 0, False) self.process = target.GetProcess() self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Tue Dec 7 19:25:21 2010 @@ -118,7 +118,7 @@ # Now launch the process, and do not stop at entry point. rc = lldb.SBError() - self.process = target.Launch([''], [''], os.ctermid(), 0, False, rc) + self.process = target.Launch([], [], os.ctermid(), 0, False, rc) #self.breakAfterLaunch(self.process, "C::C(int, int, int)") if not rc.Success() or not self.process.IsValid(): Modified: lldb/trunk/test/conditional_break/TestConditionalBreak.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/conditional_break/TestConditionalBreak.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/conditional_break/TestConditionalBreak.py (original) +++ lldb/trunk/test/conditional_break/TestConditionalBreak.py Tue Dec 7 19:25:21 2010 @@ -51,7 +51,7 @@ # Now launch the process, and do not stop at entry point. rc = lldb.SBError() - self.process = target.Launch([''], [''], os.ctermid(), 0, False, rc) + self.process = target.Launch([], [], os.ctermid(), 0, False, rc) self.assertTrue(rc.Success() and self.process.IsValid(), PROCESS_IS_VALID) Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Tue Dec 7 19:25:21 2010 @@ -557,7 +557,7 @@ if ("LLDB_LOG_OPTION" in os.environ): lldb_log_option = os.environ["LLDB_LOG_OPTION"] else: - lldb_log_option = "event process expr state" + lldb_log_option = "event process expr state api" ci.HandleCommand( "log enable -T -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option, res) Modified: lldb/trunk/test/foundation/TestSymbolTable.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestSymbolTable.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/foundation/TestSymbolTable.py (original) +++ lldb/trunk/test/foundation/TestSymbolTable.py Tue Dec 7 19:25:21 2010 @@ -43,7 +43,7 @@ self.assertTrue(target.IsValid(), VALID_TARGET) # Launch the process, and do not stop at the entry point. - process = target.LaunchProcess([''], [''], os.ctermid(), 0, False) + process = target.LaunchProcess([], [], os.ctermid(), 0, False) # # Exercise Python APIs to access the symbol table entries. Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Tue Dec 7 19:25:21 2010 @@ -51,7 +51,7 @@ # SBTarget.LaunchProcess() issue (or is there some race condition)? if useLaunchAPI: - process = target.LaunchProcess([''], [''], os.ctermid(), 0, False) + process = target.LaunchProcess([], [], os.ctermid(), 0, False) # The following isn't needed anymore, rdar://8364687 is fixed. # # Apply some dances after LaunchProcess() in order to break at "main". Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Tue Dec 7 19:25:21 2010 @@ -174,8 +174,12 @@ VALID_FILESPEC = "Got a valid filespec" +VALID_MODULE = "Got a valid module" + VALID_PROCESS = "Got a valid process" +VALID_SYMBOL = "Got a valid symbol" + VALID_TARGET = "Got a valid target" VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly" Modified: lldb/trunk/test/threads/TestPrintStackTraces.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/threads/TestPrintStackTraces.py?rev=121220&r1=121219&r2=121220&view=diff ============================================================================== --- lldb/trunk/test/threads/TestPrintStackTraces.py (original) +++ lldb/trunk/test/threads/TestPrintStackTraces.py Tue Dec 7 19:25:21 2010 @@ -35,7 +35,7 @@ # Now launch the process, and do not stop at entry point. rc = lldb.SBError() - self.process = target.Launch([''], [''], os.ctermid(), 0, False, rc) + self.process = target.Launch([], [], os.ctermid(), 0, False, rc) if not rc.Success() or not self.process.IsValid(): self.fail("SBTarget.LaunchProcess() failed") From scallanan at apple.com Tue Dec 7 19:51:31 2010 From: scallanan at apple.com (Sean Callanan) Date: Wed, 08 Dec 2010 01:51:31 -0000 Subject: [Lldb-commits] [lldb] r121225 - /lldb/trunk/source/Symbol/ClangASTContext.cpp Message-ID: <20101208015131.8549D2A6C12C@llvm.org> Author: spyffe Date: Tue Dec 7 19:51:31 2010 New Revision: 121225 URL: http://llvm.org/viewvc/llvm-project?rev=121225&view=rev Log: Fixed a problem where the AST importer would assert() because the diagnostic client for one of the AST contexts is NULL. Now we provide a form of Miranda rights to AST contexts: they are provided with a very simple diagnostic client if they do not have one themselves. Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=121225&r1=121224&r2=121225&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Dec 7 19:51:31 2010 @@ -747,7 +747,25 @@ ASTContext *src_ast, clang_type_t clang_type) { - // null_client's ownership is transferred to diagnostics + // we temporarily install diagnostic clients as needed to ensure that + // errors are properly handled + + std::auto_ptr diag_client; + + bool dst_needs_diag = !dst_ast->getDiagnostics().getClient(); + bool src_needs_diag = !src_ast->getDiagnostics().getClient(); + + if (dst_needs_diag || src_needs_diag) + { + diag_client.reset(new NullDiagnosticClient); + + if (dst_needs_diag) + dst_ast->getDiagnostics().setClient(diag_client.get(), false); + + if (src_needs_diag) + src_ast->getDiagnostics().setClient(diag_client.get(), false); + } + FileSystemOptions file_system_options; FileManager file_manager (file_system_options); ASTImporter importer(*dst_ast, file_manager, @@ -756,6 +774,12 @@ QualType src (QualType::getFromOpaquePtr(clang_type)); QualType dst (importer.Import(src)); + if (dst_needs_diag) + dst_ast->getDiagnostics().setClient(NULL, false); + + if (src_needs_diag) + src_ast->getDiagnostics().setClient(NULL, false); + return dst.getAsOpaquePtr(); } @@ -765,12 +789,36 @@ ASTContext *src_ast, clang::Decl *source_decl) { - // null_client's ownership is transferred to diagnostics + // we temporarily install diagnostic clients as needed to ensure that + // errors are properly handled + + std::auto_ptr diag_client; + + bool dst_needs_diag = !dst_ast->getDiagnostics().getClient(); + bool src_needs_diag = !src_ast->getDiagnostics().getClient(); + + if (dst_needs_diag || src_needs_diag) + { + diag_client.reset(new NullDiagnosticClient); + + if (dst_needs_diag) + dst_ast->getDiagnostics().setClient(diag_client.get(), false); + + if (src_needs_diag) + src_ast->getDiagnostics().setClient(diag_client.get(), false); + } + FileSystemOptions file_system_options; FileManager file_manager (file_system_options); ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager); + if (dst_needs_diag) + dst_ast->getDiagnostics().setClient(NULL, false); + + if (src_needs_diag) + src_ast->getDiagnostics().setClient(NULL, false); + return importer.Import(source_decl); } From gclayton at apple.com Tue Dec 7 22:55:11 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 08 Dec 2010 04:55:11 -0000 Subject: [Lldb-commits] [lldb] r121235 - /lldb/trunk/source/Target/TargetList.cpp Message-ID: <20101208045511.D557B2A6C12C@llvm.org> Author: gclayton Date: Tue Dec 7 22:55:11 2010 New Revision: 121235 URL: http://llvm.org/viewvc/llvm-project?rev=121235&view=rev Log: Fixed up the error message for when a file is not supported. Modified: lldb/trunk/source/Target/TargetList.cpp Modified: lldb/trunk/source/Target/TargetList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/TargetList.cpp?rev=121235&r1=121234&r2=121235&view=diff ============================================================================== --- lldb/trunk/source/Target/TargetList.cpp (original) +++ lldb/trunk/source/Target/TargetList.cpp Tue Dec 7 22:55:11 2010 @@ -78,23 +78,33 @@ if (!Host::ResolveExecutableInBundle (resolved_file)) resolved_file = file; - error = ModuleList::GetSharedModule(resolved_file, - arch, - uuid_ptr, - NULL, - 0, - exe_module_sp, - NULL, - NULL); + error = ModuleList::GetSharedModule (resolved_file, + arch, + uuid_ptr, + NULL, + 0, + exe_module_sp, + NULL, + NULL); if (exe_module_sp) { if (exe_module_sp->GetObjectFile() == NULL) { - error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s", - file.GetDirectory().AsCString(), - file.GetDirectory() ? "/" : "", - file.GetFilename().AsCString(), - arch.AsCString()); + if (arch.IsValid()) + { + error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s", + file.GetDirectory().AsCString(), + file.GetDirectory() ? "/" : "", + file.GetFilename().AsCString(), + arch.AsCString()); + } + else + { + error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"", + file.GetDirectory().AsCString(), + file.GetDirectory() ? "/" : "", + file.GetFilename().AsCString()); + } return error; } target_sp.reset(new Target(debugger)); From gclayton at apple.com Tue Dec 7 23:08:21 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 08 Dec 2010 05:08:21 -0000 Subject: [Lldb-commits] [lldb] r121236 - in /lldb/trunk: include/lldb/Core/ include/lldb/Target/ source/Commands/ source/Core/ source/Plugins/DynamicLoader/MacOSX-DYLD/ source/Plugins/ObjectFile/ELF/ source/Plugins/ObjectFile/Mach-O/ source/Plugins/Process/gdb-remote/ source/Target/ Message-ID: <20101208050822.1D6992A6C12C@llvm.org> Author: gclayton Date: Tue Dec 7 23:08:21 2010 New Revision: 121236 URL: http://llvm.org/viewvc/llvm-project?rev=121236&view=rev Log: Added the ability to dump sections to a certain depth (for when sections have children sections). Modified SectionLoadList to do it's own multi-threaded protected on its map. The ThreadSafeSTLMap class was difficult to deal with and wasn't providing much utility, it was only getting in the way. Make sure when the communication read thread is about to exit, it clears the thread in the main class. Fixed the ModuleList to correctly ignore architectures and UUIDs if they aren't valid when searching for a matching module. If we specified a file with no arch, and then modified the file and loaded it again, it would not match on subsequent searches if the arch was invalid since it would compare an invalid architecture to the one that was found or selected within the shared library or executable. This was causing stale modules to stay around in the global module list when they should have been removed. Removed deprecated functions from the DynamicLoaderMacOSXDYLD class. Modified "ProcessGDBRemote::IsAlive" to check if we are connected to a gdb server and also make sure our process hasn't exited. Modified: lldb/trunk/include/lldb/Core/Section.h lldb/trunk/include/lldb/Target/SectionLoadList.h lldb/trunk/source/Commands/CommandObjectImage.cpp lldb/trunk/source/Core/Communication.cpp lldb/trunk/source/Core/ModuleList.cpp lldb/trunk/source/Core/Section.cpp lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/trunk/source/Target/Process.cpp lldb/trunk/source/Target/SectionLoadList.cpp Modified: lldb/trunk/include/lldb/Core/Section.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Section.h?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Section.h (original) +++ lldb/trunk/include/lldb/Core/Section.h Tue Dec 7 23:08:21 2010 @@ -46,7 +46,7 @@ ContainsSection(lldb::user_id_t sect_id) const; void - Dump (Stream *s, Target *target, bool show_header) const; + Dump (Stream *s, Target *target, bool show_header, uint32_t depth) const; lldb::SectionSP FindSectionByName (const ConstString §ion_dstr) const; @@ -137,7 +137,7 @@ } void - Dump (Stream *s, Target *target) const; + Dump (Stream *s, Target *target, uint32_t depth) const; void DumpName (Stream *s) const; Modified: lldb/trunk/include/lldb/Target/SectionLoadList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/SectionLoadList.h?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/SectionLoadList.h (original) +++ lldb/trunk/include/lldb/Target/SectionLoadList.h Tue Dec 7 23:08:21 2010 @@ -12,10 +12,12 @@ // C Includes // C++ Includes +#include + // Other libraries and framework includes // Project includes #include "lldb/lldb-include.h" -#include "lldb/Core/ThreadSafeSTLMap.h" +#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -26,7 +28,9 @@ // Constructors and Destructors //------------------------------------------------------------------ SectionLoadList () : - m_section_load_info () + m_collection (), + m_mutex (Mutex::eMutexTypeRecursive) + { } @@ -61,10 +65,13 @@ size_t SetSectionUnloaded (const Section *section); + void + Dump (Stream &s, Target *target); protected: - typedef ThreadSafeSTLMap collection; - collection m_section_load_info; ///< A mapping of all currently loaded sections. + typedef std::map collection; + collection m_collection; + mutable Mutex m_mutex; private: DISALLOW_COPY_AND_ASSIGN (SectionLoadList); Modified: lldb/trunk/source/Commands/CommandObjectImage.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectImage.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectImage.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectImage.cpp Tue Dec 7 23:08:21 2010 @@ -185,7 +185,7 @@ strm << module->GetFileSpec(); strm.Printf ("' (%s):\n", module->GetArchitecture().AsCString()); strm.IndentMore(); - section_list->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, true); + section_list->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, true, UINT32_MAX); strm.IndentLess(); } } Modified: lldb/trunk/source/Core/Communication.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Communication.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Core/Communication.cpp (original) +++ lldb/trunk/source/Core/Communication.cpp Tue Dec 7 23:08:21 2010 @@ -346,6 +346,7 @@ // Let clients know that this thread is exiting comm->BroadcastEvent (eBroadcastBitReadThreadDidExit); + comm->m_read_thread = LLDB_INVALID_HOST_THREAD; return NULL; } Modified: lldb/trunk/source/Core/ModuleList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Core/ModuleList.cpp (original) +++ lldb/trunk/source/Core/ModuleList.cpp Tue Dec 7 23:08:21 2010 @@ -223,13 +223,13 @@ return false; } - if (m_arch_ptr) + if (m_arch_ptr && m_arch_ptr->IsValid()) { if (module_sp->GetArchitecture() != *m_arch_ptr) return false; } - if (m_uuid_ptr) + if (m_uuid_ptr && m_uuid_ptr->IsValid()) { if (module_sp->GetUUID() != *m_uuid_ptr) return false; Modified: lldb/trunk/source/Core/Section.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Section.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Core/Section.cpp (original) +++ lldb/trunk/source/Core/Section.cpp Tue Dec 7 23:08:21 2010 @@ -222,7 +222,7 @@ void -Section::Dump (Stream *s, Target *target) const +Section::Dump (Stream *s, Target *target, uint32_t depth) const { // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); s->Indent(); @@ -283,7 +283,8 @@ s->Printf(" + 0x%llx\n", m_linked_offset); } - m_children.Dump(s, target, false); + if (depth > 0) + m_children.Dump(s, target, false, depth - 1); } void @@ -666,7 +667,7 @@ } void -SectionList::Dump (Stream *s, Target *target, bool show_header) const +SectionList::Dump (Stream *s, Target *target, bool show_header, uint32_t depth) const { bool target_has_loaded_sections = target && !target->GetSectionLoadList().IsEmpty(); if (show_header && !m_sections.empty()) @@ -688,7 +689,7 @@ const_iterator end = m_sections.end(); for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) { - (*sect_iter)->Dump(s, target_has_loaded_sections ? target : NULL); + (*sect_iter)->Dump(s, target_has_loaded_sections ? target : NULL, depth); } if (show_header && !m_sections.empty()) Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original) +++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Tue Dec 7 23:08:21 2010 @@ -1019,33 +1019,13 @@ } } -//---------------------------------------------------------------------- -// Static callback function that gets called when the process state -// changes. -//---------------------------------------------------------------------- -void -DynamicLoaderMacOSXDYLD::Initialize(void *baton, Process *process) -{ - ((DynamicLoaderMacOSXDYLD*)baton)->PrivateInitialize(process); -} - void DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process) { DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); Clear(true); m_process = process; -} - - -//---------------------------------------------------------------------- -// Static callback function that gets called when the process state -// changes. -//---------------------------------------------------------------------- -void -DynamicLoaderMacOSXDYLD::ProcessStateChanged(void *baton, Process *process, StateType state) -{ - ((DynamicLoaderMacOSXDYLD*)baton)->PrivateProcessStateChanged(process, state); + m_process->GetTarget().GetSectionLoadList().Clear(); } bool Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original) +++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Tue Dec 7 23:08:21 2010 @@ -62,18 +62,6 @@ virtual void DidLaunch (); - //------------------------------------------------------------------ - // Process::Notifications callback functions - //------------------------------------------------------------------ - static void - Initialize (void *baton, - lldb_private::Process *process); - - static void - ProcessStateChanged (void *baton, - lldb_private::Process *process, - lldb::StateType state); - virtual lldb::ThreadPlanSP GetStepThroughTrampolinePlan (lldb_private::Thread &thread, bool stop_others); Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Tue Dec 7 23:08:21 2010 @@ -684,7 +684,7 @@ s->EOL(); SectionList *section_list = GetSectionList(); if (section_list) - section_list->Dump(s, NULL, true); + section_list->Dump(s, NULL, true, UINT32_MAX); Symtab *symtab = GetSymtab(); if (symtab) symtab->Dump(s, NULL, lldb::eSortOrderNone); Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Tue Dec 7 23:08:21 2010 @@ -1346,7 +1346,7 @@ *s << ", file = '" << m_file << "', arch = " << header_arch.AsCString() << "\n"; if (m_sections_ap.get()) - m_sections_ap->Dump(s, NULL, true); + m_sections_ap->Dump(s, NULL, true, UINT32_MAX); if (m_symtab_ap.get()) m_symtab_ap->Dump(s, NULL, eSortOrderNone); Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Dec 7 23:08:21 2010 @@ -1242,7 +1242,7 @@ bool ProcessGDBRemote::IsAlive () { - return m_gdb_comm.IsConnected(); + return m_gdb_comm.IsConnected() && m_private_state.GetValue() != eStateExited; } addr_t Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Tue Dec 7 23:08:21 2010 @@ -414,13 +414,18 @@ void Process::SetExitStatus (int status, const char *cstr) { - m_exit_status = status; - if (cstr) - m_exit_string = cstr; - else - m_exit_string.clear(); + if (m_private_state.GetValue() != eStateExited) + { + m_exit_status = status; + if (cstr) + m_exit_string = cstr; + else + m_exit_string.clear(); - SetPrivateState (eStateExited); + DidExit (); + + SetPrivateState (eStateExited); + } } // This static callback can be used to watch for local child processes on Modified: lldb/trunk/source/Target/SectionLoadList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/SectionLoadList.cpp?rev=121236&r1=121235&r2=121236&view=diff ============================================================================== --- lldb/trunk/source/Target/SectionLoadList.cpp (original) +++ lldb/trunk/source/Target/SectionLoadList.cpp Tue Dec 7 23:08:21 2010 @@ -28,13 +28,15 @@ bool SectionLoadList::IsEmpty() const { - return m_section_load_info.IsEmpty(); + Mutex::Locker locker(m_mutex); + return m_collection.empty(); } void SectionLoadList::Clear () { - m_section_load_info.Clear(); + Mutex::Locker locker(m_mutex); + return m_collection.clear(); } addr_t @@ -42,9 +44,22 @@ { // TODO: add support for the same section having multiple load addresses addr_t section_load_addr = LLDB_INVALID_ADDRESS; - if (m_section_load_info.GetFirstKeyForValue (section, section_load_addr)) - return section_load_addr; - return LLDB_INVALID_ADDRESS; + if (section) + { + Mutex::Locker locker(m_mutex); + collection::const_iterator pos, end = m_collection.end(); + for (pos = m_collection.begin(); pos != end; ++pos) + { + const addr_t pos_load_addr = pos->first; + const Section *pos_section = pos->second; + if (pos_section == section) + { + section_load_addr = pos_load_addr; + break; + } + } + } + return section_load_addr; } bool @@ -60,16 +75,19 @@ section->GetName().AsCString(), load_addr); - - const Section *existing_section = NULL; - Mutex::Locker locker(m_section_load_info.GetMutex()); - - if (m_section_load_info.GetValueForKeyNoLock (load_addr, existing_section)) + Mutex::Locker locker(m_mutex); + collection::iterator pos = m_collection.find(load_addr); + if (pos != m_collection.end()) { - if (existing_section == section) - return false; // No change + if (section == pos->second) + return false; // No change... + else + pos->second = section; + } + else + { + m_collection[load_addr] = section; } - m_section_load_info.SetValueForKeyNoLock (load_addr, section); return true; // Changed } @@ -85,14 +103,22 @@ section->GetModule()->GetFileSpec().GetFilename().AsCString(), section->GetName().AsCString()); - Mutex::Locker locker(m_section_load_info.GetMutex()); - size_t unload_count = 0; - addr_t section_load_addr; - while (m_section_load_info.GetFirstKeyForValueNoLock (section, section_load_addr)) + Mutex::Locker locker(m_mutex); + bool erased = false; + do { - unload_count += m_section_load_info.EraseNoLock (section_load_addr); - } + erased = false; + for (collection::iterator pos = m_collection.begin(); pos != m_collection.end(); ++pos) + { + if (pos->second == section) + { + m_collection.erase(pos); + erased = true; + } + } + } while (erased); + return unload_count; } @@ -108,28 +134,44 @@ section->GetModule()->GetFileSpec().GetFilename().AsCString(), section->GetName().AsCString(), load_addr); - - return m_section_load_info.Erase (load_addr) == 1; + Mutex::Locker locker(m_mutex); + return m_collection.erase (load_addr) != 0; } bool SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const { - addr_t section_load_addr = LLDB_INVALID_ADDRESS; - const Section *section = NULL; - - // First find the top level section that this load address exists in - if (m_section_load_info.LowerBound (load_addr, section_load_addr, section, true)) + // First find the top level section that this load address exists in + Mutex::Locker locker(m_mutex); + collection::const_iterator pos = m_collection.lower_bound (load_addr); + if (pos != m_collection.end()) { - addr_t offset = load_addr - section_load_addr; - if (offset < section->GetByteSize()) + if (load_addr != pos->first && pos != m_collection.begin()) + --pos; + assert (load_addr >= pos->first); + addr_t offset = load_addr - pos->first; + if (offset < pos->second->GetByteSize()) { // We have found the top level section, now we need to find the // deepest child section. - return section->ResolveContainedAddress (offset, so_addr); + return pos->second->ResolveContainedAddress (offset, so_addr); } } so_addr.Clear(); return false; } + +void +SectionLoadList::Dump (Stream &s, Target *target) +{ + Mutex::Locker locker(m_mutex); + collection::const_iterator pos, end; + for (pos = m_collection.begin(), end = m_collection.end(); pos != end; ++pos) + { + s.Printf("addr = 0x%16.16llx, section = %p: ", pos->first, pos->second); + pos->second->Dump (&s, target, 0); + } +} + + From gclayton at apple.com Tue Dec 7 23:24:05 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 08 Dec 2010 05:24:05 -0000 Subject: [Lldb-commits] [lldb] r121237 - in /lldb/trunk: lldb.xcodeproj/project.pbxproj resources/LLDB-Info.plist tools/debugserver/debugserver.xcodeproj/project.pbxproj tools/debugserver/source/MacOSX/MachThread.cpp Message-ID: <20101208052405.9890C2A6C12C@llvm.org> Author: gclayton Date: Tue Dec 7 23:24:05 2010 New Revision: 121237 URL: http://llvm.org/viewvc/llvm-project?rev=121237&view=rev Log: Bumped lldb Xcode version to 35 for lldb-35, and debugserver to 121 for debugserver-121. Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/resources/LLDB-Info.plist lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=121237&r1=121236&r2=121237&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Dec 7 23:24:05 2010 @@ -2459,6 +2459,7 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, @@ -3026,9 +3027,9 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 34; + DYLIB_CURRENT_VERSION = 35; EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3078,11 +3079,11 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 34; + DYLIB_CURRENT_VERSION = 35; EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3152,7 +3153,7 @@ isa = XCBuildConfiguration; buildSettings = { COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3187,11 +3188,11 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 34; + DYLIB_CURRENT_VERSION = 35; EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3240,7 +3241,7 @@ buildSettings = { CODE_SIGN_IDENTITY = lldb_codesign; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", @@ -3278,7 +3279,7 @@ ); CODE_SIGN_IDENTITY = lldb_codesign; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; 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=121237&r1=121236&r2=121237&view=diff ============================================================================== --- lldb/trunk/resources/LLDB-Info.plist (original) +++ lldb/trunk/resources/LLDB-Info.plist Tue Dec 7 23:24:05 2010 @@ -17,7 +17,7 @@ CFBundleSignature ???? CFBundleVersion - 34 + 35 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=121237&r1=121236&r2=121237&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original) +++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Tue Dec 7 23:24:05 2010 @@ -460,7 +460,7 @@ i386, ); COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 120; + CURRENT_PROJECT_VERSION = 121; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; STRIP_INSTALLED_PRODUCT = NO; @@ -478,7 +478,7 @@ x86_64, i386, ); - CURRENT_PROJECT_VERSION = 120; + CURRENT_PROJECT_VERSION = 121; DEAD_CODE_STRIPPING = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; @@ -498,7 +498,7 @@ x86_64, i386, ); - CURRENT_PROJECT_VERSION = 120; + CURRENT_PROJECT_VERSION = 121; DEAD_CODE_STRIPPING = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; @@ -515,7 +515,7 @@ buildSettings = { "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 120; + CURRENT_PROJECT_VERSION = 121; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( @@ -556,7 +556,7 @@ "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 120; + CURRENT_PROJECT_VERSION = 121; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( "$(SDKROOT)/System/Library/PrivateFrameworks", @@ -597,7 +597,7 @@ "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 120; + CURRENT_PROJECT_VERSION = 121; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp?rev=121237&r1=121236&r2=121237&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp Tue Dec 7 23:24:05 2010 @@ -199,8 +199,6 @@ switch (m_basicInfo.run_state) { default: - assert (!"Invalid run_state encountered"); - case TH_STATE_UNINTERRUPTIBLE: break; From johnny.chen at apple.com Wed Dec 8 12:14:20 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 08 Dec 2010 18:14:20 -0000 Subject: [Lldb-commits] [lldb] r121268 - in /lldb/trunk/test/foundation: TestObjCMethods2.py main.m Message-ID: <20101208181420.3C3272A6C12C@llvm.org> Author: johnny Date: Wed Dec 8 12:14:20 2010 New Revision: 121268 URL: http://llvm.org/viewvc/llvm-project?rev=121268&view=rev Log: Modify the TestObjCMethods2.py test to fix a typo (should be str_id, not id). Also, add bug info for expected failures that remain: Expressions should support properties Modified: lldb/trunk/test/foundation/TestObjCMethods2.py lldb/trunk/test/foundation/main.m Modified: lldb/trunk/test/foundation/TestObjCMethods2.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestObjCMethods2.py?rev=121268&r1=121267&r2=121268&view=diff ============================================================================== --- lldb/trunk/test/foundation/TestObjCMethods2.py (original) +++ lldb/trunk/test/foundation/TestObjCMethods2.py Wed Dec 8 12:14:20 2010 @@ -90,6 +90,7 @@ self.runCmd("process continue") @unittest2.expectedFailure + # Expressions should support properties def NSArray_expr(self): """Test expression commands for NSArray.""" exe = os.path.join(os.getcwd(), "a.out") @@ -116,6 +117,7 @@ self.runCmd("process continue") @unittest2.expectedFailure + # Expressions should support properties def NSString_expr(self): """Test expression commands for NSString.""" exe = os.path.join(os.getcwd(), "a.out") @@ -133,12 +135,14 @@ self.runCmd("thread backtrace") self.expect("expression (int)[str length]", patterns = ["\(int\) \$.* ="]) - self.expect("expression (int)[id length]", + self.expect("expression (int)[str_id length]", patterns = ["\(int\) \$.* ="]) - self.expect("expression [str description]") - self.expect("expression [id description]") + self.expect("expression [str description]", + patterns = ["\(id\) \$.* = 0x"]) + self.expect("expression [str_id description]", + patterns = ["\(id\) \$.* = 0x"]) self.expect("expression str.description") - self.expect("expression id.description") + self.expect("expression str_id.description") self.expect('expression str = @"new"') self.expect('expression str = [NSString stringWithFormat: @"%cew", \'N\']') self.runCmd("process continue") Modified: lldb/trunk/test/foundation/main.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/main.m?rev=121268&r1=121267&r2=121268&view=diff ============================================================================== --- lldb/trunk/test/foundation/main.m (original) +++ lldb/trunk/test/foundation/main.m Wed Dec 8 12:14:20 2010 @@ -72,9 +72,9 @@ // Expressions to test here for NSString: // expression (char *)sel_getName(sel) // expression [str length] - // expression [id length] + // expression [str_id length] // expression [str description] - // expression [id description] + // expression [str_id description] // expression str.length // expression str.description // expression str = @"new" From johnny.chen at apple.com Wed Dec 8 13:19:08 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 08 Dec 2010 19:19:08 -0000 Subject: [Lldb-commits] [lldb] r121271 - /lldb/trunk/test/lldbutil.py Message-ID: <20101208191908.64D092A6C12E@llvm.org> Author: johnny Date: Wed Dec 8 13:19:08 2010 New Revision: 121271 URL: http://llvm.org/viewvc/llvm-project?rev=121271&view=rev Log: Add more docstring for the lldb_iter() utility function which provides a compact way of iterating through an aggregate data structure. The added example usage is from an actual use in test/foundation/TestSymbolTable.py: 2. Pass a container of aggregate which provides APIs to get to the size and the element of the aggregate: # Module is a container of symbol table module = target.FindModule(filespec) for symbol in lldb_iter(module, 'GetNumSymbols', 'GetSymbolAtIndex'): name = symbol.GetName() ... Modified: lldb/trunk/test/lldbutil.py Modified: lldb/trunk/test/lldbutil.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbutil.py?rev=121271&r1=121270&r2=121271&view=diff ============================================================================== --- lldb/trunk/test/lldbutil.py (original) +++ lldb/trunk/test/lldbutil.py Wed Dec 8 13:19:08 2010 @@ -11,19 +11,29 @@ # =========================================== def lldb_iter(obj, getsize, getelem): - """ - A generator adaptor for lldb aggregate data structures. + """A generator adaptor for lldb aggregate data structures. + + API clients pass in an aggregate object or a container of it, the name of + the method to get the size of the aggregate, and the name of the method to + get the element by index. - API clients pass in the aggregate object, the name of the method to get the - size of the object, and the name of the method to get the element given an - index. + Example usages: - Example usage: + 1. Pass an aggregate as the first argument: def disassemble_instructions (insts): from lldbutil import lldb_iter for i in lldb_iter(insts, 'GetSize', 'GetInstructionAtIndex'): print i + + 2. Pass a container of aggregate which provides APIs to get to the size and + the element of the aggregate: + + # Module is a container of symbol table + module = target.FindModule(filespec) + for symbol in lldb_iter(module, 'GetNumSymbols', 'GetSymbolAtIndex'): + name = symbol.GetName() + ... """ size = getattr(obj, getsize) elem = getattr(obj, getelem) From gclayton at apple.com Wed Dec 8 14:16:12 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 08 Dec 2010 20:16:12 -0000 Subject: [Lldb-commits] [lldb] r121278 - in /lldb/trunk: include/lldb/Core/SourceManager.h source/Core/SourceManager.cpp Message-ID: <20101208201613.061D12A6C12C@llvm.org> Author: gclayton Date: Wed Dec 8 14:16:12 2010 New Revision: 121278 URL: http://llvm.org/viewvc/llvm-project?rev=121278&view=rev Log: Fixed an issue in our source manager where we were permanently caching source file data, so if a source file was modified, we would always show the first cached copy of the source data. We now check file modification times when displaying source info so we can show the update source info. Modified: lldb/trunk/include/lldb/Core/SourceManager.h lldb/trunk/source/Core/SourceManager.cpp Modified: lldb/trunk/include/lldb/Core/SourceManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/SourceManager.h?rev=121278&r1=121277&r2=121278&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/SourceManager.h (original) +++ lldb/trunk/include/lldb/Core/SourceManager.h Wed Dec 8 14:16:12 2010 @@ -53,6 +53,7 @@ CalculateLineOffsets (uint32_t line = UINT32_MAX); FileSpec m_file_spec; + TimeValue m_mod_time; // Keep the modification time that this file data is valid for lldb::DataBufferSP m_data_sp; typedef std::vector LineOffsets; LineOffsets m_offsets; Modified: lldb/trunk/source/Core/SourceManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/SourceManager.cpp?rev=121278&r1=121277&r2=121278&view=diff ============================================================================== --- lldb/trunk/source/Core/SourceManager.cpp (original) +++ lldb/trunk/source/Core/SourceManager.cpp Wed Dec 8 14:16:12 2010 @@ -171,6 +171,7 @@ SourceManager::File::File(const FileSpec &file_spec) : m_file_spec(file_spec), + m_mod_time (m_file_spec.GetModificationTime()), m_data_sp(file_spec.ReadFileContents ()), m_offsets() { @@ -211,6 +212,17 @@ size_t SourceManager::File::DisplaySourceLines (uint32_t line, uint32_t context_before, uint32_t context_after, Stream *s) { + // TODO: use host API to sign up for file modifications to anything in our + // source cache and only update when we determine a file has been updated. + // For now we check each time we want to display info for the file. + TimeValue curr_mod_time (m_file_spec.GetModificationTime()); + if (m_mod_time != curr_mod_time) + { + m_mod_time = curr_mod_time; + m_data_sp = m_file_spec.ReadFileContents (); + m_offsets.clear(); + } + const uint32_t start_line = line <= context_before ? 1 : line - context_before; const uint32_t start_line_offset = GetLineOffset (start_line); if (start_line_offset != UINT32_MAX) From gclayton at apple.com Wed Dec 8 16:23:24 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 08 Dec 2010 22:23:24 -0000 Subject: [Lldb-commits] [lldb] r121295 - in /lldb/trunk/tools/driver: Driver.cpp Driver.h Message-ID: <20101208222324.4212E2A6C12C@llvm.org> Author: gclayton Date: Wed Dec 8 16:23:24 2010 New Revision: 121295 URL: http://llvm.org/viewvc/llvm-project?rev=121295&view=rev Log: Any arguments that are not options to the "lldb" command line driver, now get used as the arguments for the inferior program. So for example you can do % lldb /bin/ls /tmp ~/Documents And "lldb" will use "/bin/ls" as the program and send arguments "/tmp" and "~/Documents" as the launch args. If you specify a file, then all remaining args after option parsing will be used for program arguments: % lldb -f /bin/ls /tmp ~/Documents If you need to pass option values to your inferior program, just terminate the "lldb" command line driver options with "--": % lldb -- /bin/ls -AFl /tmp The arguments are placed into the "settings" variable named "target.process.run-args". This allows you to just run the program using "process launch" and, if no args are specified on that command, the "target.process.run-args" values will be used: % lldb -- /bin/ls -AFl /tmp Current executable set to '/bin/ls' (x86_64). (lldb) settings show target.process.run-args target.process.run-args (array): [0]: '-AFl' [1]: '/tmp' (lldb) (lldb) r Process 56753 launched: '/bin/ls' (x86_64) lrwxr-xr-x@ 1 root wheel 11 Nov 19 2009 /tmp@ -> private/tmp Modified: lldb/trunk/tools/driver/Driver.cpp lldb/trunk/tools/driver/Driver.h Modified: lldb/trunk/tools/driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=121295&r1=121294&r2=121295&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.cpp (original) +++ lldb/trunk/tools/driver/Driver.cpp Wed Dec 8 16:23:24 2010 @@ -371,7 +371,7 @@ } Driver::OptionData::OptionData () : - m_filename(), + m_args(), m_script_lang (lldb::eScriptLanguageDefault), m_crash_log (), m_source_command_files (), @@ -390,7 +390,7 @@ void Driver::OptionData::Clear () { - m_filename.clear (); + m_args.clear (); m_script_lang = lldb::eScriptLanguageDefault; m_source_command_files.clear (); m_debug_mode = false; @@ -408,9 +408,9 @@ const char * Driver::GetFilename() const { - if (m_option_data.m_filename.empty()) + if (m_option_data.m_args.empty()) return NULL; - return m_option_data.m_filename.c_str(); + return m_option_data.m_args.front().c_str(); } const char * @@ -581,13 +581,15 @@ { SBFileSpec file(optarg); if (file.Exists()) - m_option_data.m_filename = optarg; + { + m_option_data.m_args.push_back (optarg); + } else if (file.ResolveExecutableLocation()) { char path[PATH_MAX]; int path_len; file.GetPath (path, path_len); - m_option_data.m_filename = path; + m_option_data.m_args.push_back (path); } else error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg); @@ -642,25 +644,6 @@ } } - // If there is a trailing argument, it is the filename. - if (optind == argc - 1) - { - if (m_option_data.m_filename.empty()) - { - m_option_data.m_filename = argv[optind]; - } - else - { - error.SetErrorStringWithFormat ("error: don't provide a file both on in the -f option and as an argument."); - } - - } - else if (optind < argc - 1) - { - // Trailing extra arguments... - error.SetErrorStringWithFormat ("error: trailing extra arguments - only one the filename is allowed."); - } - if (error.Fail() || m_option_data.m_print_help) { ShowUsage (out_fh, g_options, m_option_data); @@ -677,7 +660,26 @@ } else { - // All other combinations are valid; do nothing more here. + // Any arguments that are left over after option parsing are for + // the program. If a file was specified with -f then the filename + // is already in the m_option_data.m_args array, and any remaining args + // are arguments for the inferior program. If no file was specified with + // -f, then what is left is the program name followed by any arguments. + + // Skip any options we consumed with getopt_long + argc -= optind; + argv += optind; + + if (argc > 0) + { + for (int arg_idx=0; arg_idx 0) { char arch_name[64]; if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name))) - ::snprintf (command_string, sizeof (command_string), "file --arch=%s '%s'", arch_name, - m_option_data.m_filename.c_str()); + ::snprintf (command_string, + sizeof (command_string), + "file --arch=%s '%s'", + arch_name, + m_option_data.m_args[0].c_str()); else - ::snprintf (command_string, sizeof(command_string), "file '%s'", m_option_data.m_filename.c_str()); + ::snprintf (command_string, + sizeof(command_string), + "file '%s'", + m_option_data.m_args[0].c_str()); m_debugger.HandleCommand (command_string); + + if (num_args > 1) + { + m_debugger.HandleCommand ("settings clear target.process.run-args"); + char arg_cstr[1024]; + for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx) + { + ::snprintf (arg_cstr, sizeof(arg_cstr), "settings append target.process.run-args \"%s\"", m_option_data.m_args[arg_idx].c_str()); + m_debugger.HandleCommand (arg_cstr); + } + } } // Now that all option parsing is done, we try and parse the .lldbinit Modified: lldb/trunk/tools/driver/Driver.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.h?rev=121295&r1=121294&r2=121295&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.h (original) +++ lldb/trunk/tools/driver/Driver.h Wed Dec 8 16:23:24 2010 @@ -96,7 +96,7 @@ //static lldb::OptionDefinition m_cmd_option_table[]; - std::string m_filename; + std::vector m_args; lldb::ScriptLanguage m_script_lang; std::string m_crash_log; std::vector m_source_command_files; From johnny.chen at apple.com Thu Dec 9 12:22:12 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 09 Dec 2010 18:22:12 -0000 Subject: [Lldb-commits] [lldb] r121389 - in /lldb/trunk/test: lldbtest.py source-manager/ source-manager/Makefile source-manager/TestSourceManager.py source-manager/main.c Message-ID: <20101209182212.841B72A6C12C@llvm.org> Author: johnny Date: Thu Dec 9 12:22:12 2010 New Revision: 121389 URL: http://llvm.org/viewvc/llvm-project?rev=121389&view=rev Log: Add a test/source-manager directory for testing lldb core component SourceManager. Initial test case test_modify_source_file_while_debugging() in TestSourceManager.py tests the caching mechanism of the source manager. Added: lldb/trunk/test/source-manager/ lldb/trunk/test/source-manager/Makefile lldb/trunk/test/source-manager/TestSourceManager.py lldb/trunk/test/source-manager/main.c Modified: lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=121389&r1=121388&r2=121389&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu Dec 9 12:22:12 2010 @@ -151,6 +151,8 @@ BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3" +SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly" + STEP_OUT_SUCCEEDED = "Thread step-out succeeded" PROCESS_STOPPED = "Process status should be stopped" Added: lldb/trunk/test/source-manager/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/source-manager/Makefile?rev=121389&view=auto ============================================================================== --- lldb/trunk/test/source-manager/Makefile (added) +++ lldb/trunk/test/source-manager/Makefile Thu Dec 9 12:22:12 2010 @@ -0,0 +1,5 @@ +LEVEL = ../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/source-manager/TestSourceManager.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/source-manager/TestSourceManager.py?rev=121389&view=auto ============================================================================== --- lldb/trunk/test/source-manager/TestSourceManager.py (added) +++ lldb/trunk/test/source-manager/TestSourceManager.py Thu Dec 9 12:22:12 2010 @@ -0,0 +1,83 @@ +""" +Test lldb core component: SourceManager. + +Test cases: +1. test_modify_source_file_while_debugging: + Test the caching mechanism of the source manager. +""" + +import os, time +import re +import unittest2 +import lldb, lldbutil +from lldbtest import * + +class SourceManagerTestCase(TestBase): + + mydir = "source-manager" + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + def test_modify_source_file_while_debugging(self): + """Modify a source file while debugging the executable.""" + self.buildDefault() + self.modify_source_file_while_debugging() + + def modify_source_file_while_debugging(self): + """Modify a source file while debugging the executable.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + self.expect("breakpoint set -f main.c -l %d" % self.line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.c', 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 = ['state is stopped', + 'main.c', + 'stop reason = breakpoint']) + + # Display some source code. + self.expect("list -f main.c -l %d" % self.line, SOURCE_DISPLAYED_CORRECTLY, + substrs = ['Hello world']) + + # Read the main.c file content. + with open('main.c', 'r') as f: + original_content = f.read() + print "original content:", original_content + + # Modify the in-memory copy of the original source code. + new_content = original_content.replace('Hello world', 'Hello lldb', 1) + + # This is the function to restore the original content. + def restore_file(): + with open('main.c', 'w') as f: + f.write(original_content) + with open('main.c', 'r') as f: + print "content restored to:", f.read() + + # Modify the source code file. + with open('main.c', 'w') as f: + f.write(new_content) + print "new content:", new_content + # Add teardown hook to restore the file to the original content. + self.addTearDownHook(restore_file) + + # Display the source code again. We should see the updated line. + self.expect("list -f main.c -l %d" % self.line, SOURCE_DISPLAYED_CORRECTLY, + substrs = ['Hello lldb']) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/source-manager/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/source-manager/main.c?rev=121389&view=auto ============================================================================== --- lldb/trunk/test/source-manager/main.c (added) +++ lldb/trunk/test/source-manager/main.c Thu Dec 9 12:22:12 2010 @@ -0,0 +1,6 @@ +#include + +int main(int argc, char const *argv[]) { + printf("Hello world.\n"); // Set break point at this line. + return 0; +} From johnny.chen at apple.com Thu Dec 9 12:38:52 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 09 Dec 2010 18:38:52 -0000 Subject: [Lldb-commits] [lldb] r121393 - /lldb/trunk/test/source-manager/TestSourceManager.py Message-ID: <20101209183852.D6DD22A6C12C@llvm.org> Author: johnny Date: Thu Dec 9 12:38:52 2010 New Revision: 121393 URL: http://llvm.org/viewvc/llvm-project?rev=121393&view=rev Log: Remove unnecessary imports. Modified: lldb/trunk/test/source-manager/TestSourceManager.py Modified: lldb/trunk/test/source-manager/TestSourceManager.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/source-manager/TestSourceManager.py?rev=121393&r1=121392&r2=121393&view=diff ============================================================================== --- lldb/trunk/test/source-manager/TestSourceManager.py (original) +++ lldb/trunk/test/source-manager/TestSourceManager.py Thu Dec 9 12:38:52 2010 @@ -6,10 +6,8 @@ Test the caching mechanism of the source manager. """ -import os, time -import re import unittest2 -import lldb, lldbutil +import lldb from lldbtest import * class SourceManagerTestCase(TestBase): From jingham at apple.com Thu Dec 9 12:58:16 2010 From: jingham at apple.com (Jim Ingham) Date: Thu, 09 Dec 2010 18:58:16 -0000 Subject: [Lldb-commits] [lldb] r121396 - /lldb/trunk/source/Commands/CommandObjectProcess.cpp Message-ID: <20101209185816.2D6BF2A6C12C@llvm.org> Author: jingham Date: Thu Dec 9 12:58:16 2010 New Revision: 121396 URL: http://llvm.org/viewvc/llvm-project?rev=121396&view=rev Log: process launch now asks to kill the current process if it is alive, and if you affirm, does so for you. Also added #pragma mark for the command objects defined in the file. Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=121396&r1=121395&r2=121396&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Thu Dec 9 12:58:16 2010 @@ -29,7 +29,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessLaunch //------------------------------------------------------------------------- - +#pragma mark CommandObjectProjectLaunch class CommandObjectProcessLaunch : public CommandObject { public: @@ -163,13 +163,29 @@ Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; if (process && process->IsAlive()) - { - result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before running again.\n", - process->GetID()); - result.SetStatus (eReturnStatusFailed); - return false; + { + if (!m_interpreter.Confirm ("There is a running process, kill it and restart?", true)) + { + result.AppendErrorWithFormat ("Process %u is currently being debugged, restart cancelled.\n", + process->GetID()); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + Error error (process->Destroy()); + if (error.Success()) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + } } - + const char *plugin_name; if (!m_options.plugin_name.empty()) plugin_name = m_options.plugin_name.c_str(); @@ -357,7 +373,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessAttach //------------------------------------------------------------------------- - +#pragma mark CommandObjectProcessAttach class CommandObjectProcessAttach : public CommandObject { public: @@ -737,6 +753,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessContinue //------------------------------------------------------------------------- +#pragma mark CommandObjectProcessContinue class CommandObjectProcessContinue : public CommandObject { @@ -824,6 +841,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessDetach //------------------------------------------------------------------------- +#pragma mark CommandObjectProcessDetach class CommandObjectProcessDetach : public CommandObject { @@ -873,6 +891,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessLoad //------------------------------------------------------------------------- +#pragma mark CommandObjectProcessLoad class CommandObjectProcessLoad : public CommandObject { @@ -930,6 +949,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessUnload //------------------------------------------------------------------------- +#pragma mark CommandObjectProcessUnload class CommandObjectProcessUnload : public CommandObject { @@ -995,6 +1015,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessSignal //------------------------------------------------------------------------- +#pragma mark CommandObjectProcessSignal class CommandObjectProcessSignal : public CommandObject { @@ -1079,6 +1100,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessInterrupt //------------------------------------------------------------------------- +#pragma mark CommandObjectProcessInterrupt class CommandObjectProcessInterrupt : public CommandObject { @@ -1141,6 +1163,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessKill //------------------------------------------------------------------------- +#pragma mark CommandObjectProcessKill class CommandObjectProcessKill : public CommandObject { @@ -1198,6 +1221,8 @@ //------------------------------------------------------------------------- // CommandObjectProcessStatus //------------------------------------------------------------------------- +#pragma mark CommandObjectProcessStatus + class CommandObjectProcessStatus : public CommandObject { public: @@ -1274,6 +1299,7 @@ //------------------------------------------------------------------------- // CommandObjectProcessHandle //------------------------------------------------------------------------- +#pragma mark CommandObjectProcessHandle class CommandObjectProcessHandle : public CommandObject { From johnny.chen at apple.com Thu Dec 9 16:06:05 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 09 Dec 2010 22:06:05 -0000 Subject: [Lldb-commits] [lldb] r121419 - /lldb/trunk/test/source-manager/TestSourceManager.py Message-ID: <20101209220605.4CF362A6C12C@llvm.org> Author: johnny Date: Thu Dec 9 16:06:05 2010 New Revision: 121419 URL: http://llvm.org/viewvc/llvm-project?rev=121419&view=rev Log: Minor docstring change. Modified: lldb/trunk/test/source-manager/TestSourceManager.py Modified: lldb/trunk/test/source-manager/TestSourceManager.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/source-manager/TestSourceManager.py?rev=121419&r1=121418&r2=121419&view=diff ============================================================================== --- lldb/trunk/test/source-manager/TestSourceManager.py (original) +++ lldb/trunk/test/source-manager/TestSourceManager.py Thu Dec 9 16:06:05 2010 @@ -2,8 +2,9 @@ Test lldb core component: SourceManager. Test cases: -1. test_modify_source_file_while_debugging: - Test the caching mechanism of the source manager. + +o test_modify_source_file_while_debugging: + Test the caching mechanism of the source manager. """ import unittest2 From johnny.chen at apple.com Thu Dec 9 16:11:59 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 09 Dec 2010 22:11:59 -0000 Subject: [Lldb-commits] [lldb] r121421 - /lldb/trunk/test/expression_command/test/TestExprs.py Message-ID: <20101209221159.BD5282A6C12C@llvm.org> Author: johnny Date: Thu Dec 9 16:11:59 2010 New Revision: 121421 URL: http://llvm.org/viewvc/llvm-project?rev=121421&view=rev Log: Add more module docstring. Modified: lldb/trunk/test/expression_command/test/TestExprs.py Modified: lldb/trunk/test/expression_command/test/TestExprs.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/test/TestExprs.py?rev=121421&r1=121420&r2=121421&view=diff ============================================================================== --- lldb/trunk/test/expression_command/test/TestExprs.py (original) +++ lldb/trunk/test/expression_command/test/TestExprs.py Thu Dec 9 16:11:59 2010 @@ -1,5 +1,14 @@ """ Test many basic expression commands and SBFrame.EvaluateExpression() API. + +Test cases: + +o test_many_expr_commands: + Test many basic expression commands. +o test_evaluate_expression_python: + Use Python APIs (SBFrame.EvaluateExpression()) to evaluate expressions. +o test_expr_commands_can_handle_quotes: + Throw some expression commands with quotes at lldb. """ import os, time From ctice at apple.com Thu Dec 9 16:52:49 2010 From: ctice at apple.com (Caroline Tice) Date: Thu, 09 Dec 2010 22:52:49 -0000 Subject: [Lldb-commits] [lldb] r121423 - in /lldb/trunk: include/lldb/Interpreter/Args.h include/lldb/Interpreter/CommandInterpreter.h source/Commands/CommandObjectCommands.cpp source/Interpreter/Args.cpp source/Interpreter/CommandInterpreter.cpp Message-ID: <20101209225249.541F02A6C12C@llvm.org> Author: ctice Date: Thu Dec 9 16:52:49 2010 New Revision: 121423 URL: http://llvm.org/viewvc/llvm-project?rev=121423&view=rev Log: Modify HandleCommand to not do any argument processing until it has determined whether or not the command should take raw input, then handle & dispatch the arguments appropriately. Also change the 'alias' command to be a command that takes raw input. This is necessary to allow aliases to be created for other commands that take raw input and might want to include raw input in the alias itself. Fix a bug in the aliasing mechanism when creating aliases for commands with 3-or-more words. Raw input should now be properly handled by all the command and alias mechanisms. Modified: lldb/trunk/include/lldb/Interpreter/Args.h lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h lldb/trunk/source/Commands/CommandObjectCommands.cpp lldb/trunk/source/Interpreter/Args.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp Modified: lldb/trunk/include/lldb/Interpreter/Args.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/Args.h?rev=121423&r1=121422&r2=121423&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/Args.h (original) +++ lldb/trunk/include/lldb/Interpreter/Args.h Thu Dec 9 16:52:49 2010 @@ -313,7 +313,8 @@ // and it builds up the option_arg_vector as it parses the options. void - ParseAliasOptions (Options &options, CommandReturnObject &result, OptionArgVector *option_arg_vector); + ParseAliasOptions (Options &options, CommandReturnObject &result, OptionArgVector *option_arg_vector, + std::string &raw_input_line); void ParseArgsForCompletion (Options &options, OptionElementVector &option_element_vector, uint32_t cursor_index); Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=121423&r1=121422&r2=121423&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Thu Dec 9 16:52:49 2010 @@ -85,11 +85,21 @@ AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp); bool + StripFirstWord (std::string &command_string, std::string &next_word); + + void + BuildAliasResult (const char *alias_name, std::string &raw_input_string, std::string &alias_result, + CommandObject *&alias_cmd_obj, CommandReturnObject &result); + + bool HandleCommand (const char *command_line, bool add_to_history, CommandReturnObject &result, ExecutionContext *override_context = NULL); + CommandObject * + GetCommandObjectForCommand (std::string &command_line); + // This handles command line completion. You are given a pointer to the command string buffer, to the current cursor, // and to the end of the string (in case it is not NULL terminated). // You also passed in an Args object to fill with the returns. Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=121423&r1=121422&r2=121423&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Thu Dec 9 16:52:49 2010 @@ -239,6 +239,133 @@ { } + bool + WantsRawCommandString () + { + return true; + } + + bool + ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result) + { + Args args (raw_command_line); + std::string raw_command_string (raw_command_line); + + size_t argc = args.GetArgumentCount(); + + if (argc < 2) + { + result.AppendError ("'alias' requires at least two arguments"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + // Get the alias command. + + const std::string alias_command = args.GetArgumentAtIndex (0); + + // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which + // does the stripping itself. + size_t pos = raw_command_string.find (alias_command); + if (pos == 0) + { + raw_command_string = raw_command_string.substr (alias_command.size()); + pos = raw_command_string.find_first_not_of (' '); + if ((pos != std::string::npos) && (pos > 0)) + raw_command_string = raw_command_string.substr (pos); + } + else + { + result.AppendError ("Error parsing command string. No alias created."); + result.SetStatus (eReturnStatusFailed); + return false; + } + + + // Verify that the command is alias-able. + if (m_interpreter.CommandExists (alias_command.c_str())) + { + result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", + alias_command.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + + // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string. + // raw_command_string is returned with the name of the command object stripped off the front. + CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string); + + if (!cmd_obj) + { + result.AppendErrorWithFormat ("Invalid command given to 'alias'. '%s' does not begin with a valid command." + " No alias created.", raw_command_string.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + else if (!cmd_obj->WantsRawCommandString ()) + { + // Note that args was initialized with the original command, and has not been updated to this point. + // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias. + return Execute (args, result); + } + else + { + // Verify & handle any options/arguments passed to the alias command + + OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); + OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); + + // Check to see if there's anything left in the input command string. + if (raw_command_string.size() > 0) + { + + // Check to see if the command being aliased can take any command options. + Options *options = cmd_obj->GetOptions(); + if (options) + { + // See if any options were specified as part of the alias; if so, handle them appropriately + options->ResetOptionValues (); + Args tmp_args (raw_command_string.c_str()); + args.Unshift ("dummy_arg"); + args.ParseAliasOptions (*options, result, option_arg_vector, raw_command_string); + args.Shift (); + if (result.Succeeded()) + options->VerifyPartialOptions (result); + if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted) + { + result.AppendError ("Unable to create requested alias.\n"); + return false; + } + } + // Anything remaining must be plain raw input. Push it in as a single raw input argument. + if (raw_command_string.size() > 0) + option_arg_vector->push_back (OptionArgPair ("", + OptionArgValue (-1, + raw_command_string))); + } + + // Create the alias + if (m_interpreter.AliasExists (alias_command.c_str()) + || m_interpreter.UserCommandExists (alias_command.c_str())) + { + OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); + if (temp_option_arg_sp.get()) + { + if (option_arg_vector->size() == 0) + m_interpreter.RemoveAliasOptions (alias_command.c_str()); + } + result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", + alias_command.c_str()); + } + + CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); + m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp); + if (option_arg_vector->size() > 0) + m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + return result.Succeeded(); + } bool Execute @@ -282,7 +409,7 @@ OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); - if (cmd_obj->IsMultiwordObject()) + while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) { if (argc >= 3) { @@ -295,6 +422,7 @@ sub_cmd_obj = subcommand_obj_sp.get(); use_subcommand = true; args.Shift(); // Shift the sub_command word off the argument vector. + cmd_obj = sub_cmd_obj; } else { @@ -320,8 +448,9 @@ else options = cmd_obj->GetOptions(); options->ResetOptionValues (); + std::string empty_string; args.Unshift ("dummy_arg"); - args.ParseAliasOptions (*options, result, option_arg_vector); + args.ParseAliasOptions (*options, result, option_arg_vector, empty_string); args.Shift (); if (result.Succeeded()) options->VerifyPartialOptions (result); Modified: lldb/trunk/source/Interpreter/Args.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Args.cpp?rev=121423&r1=121422&r2=121423&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/Args.cpp (original) +++ lldb/trunk/source/Interpreter/Args.cpp Thu Dec 9 16:52:49 2010 @@ -849,7 +849,8 @@ void Args::ParseAliasOptions (Options &options, CommandReturnObject &result, - OptionArgVector *option_arg_vector) + OptionArgVector *option_arg_vector, + std::string &raw_input_string) { StreamString sstr; int i; @@ -985,16 +986,33 @@ if (long_options_index >= 0) { // Find option in the argument list; also see if it was supposed to take an argument and if one was - // supplied. Remove option (and argument, if given) from the argument list. + // supplied. Remove option (and argument, if given) from the argument list. Also remove them from + // the raw_input_string, if one was passed in. size_t idx = FindArgumentIndexForOption (long_options, long_options_index); if (idx < GetArgumentCount()) { + if (raw_input_string.size() > 0) + { + const char *tmp_arg = GetArgumentAtIndex (idx); + size_t pos = raw_input_string.find (tmp_arg); + if (pos != std::string::npos) + raw_input_string.erase (pos, strlen (tmp_arg)); + } ReplaceArgumentAtIndex (idx, ""); if ((long_options[long_options_index].has_arg != no_argument) && (optarg != NULL) && (idx+1 < GetArgumentCount()) && (strcmp (optarg, GetArgumentAtIndex(idx+1)) == 0)) + { + if (raw_input_string.size() > 0) + { + const char *tmp_arg = GetArgumentAtIndex (idx+1); + size_t pos = raw_input_string.find (tmp_arg); + if (pos != std::string::npos) + raw_input_string.erase (pos, strlen (tmp_arg)); + } ReplaceArgumentAtIndex (idx+1, ""); + } } } Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=121423&r1=121422&r2=121423&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Thu Dec 9 16:52:49 2010 @@ -494,30 +494,184 @@ result.AppendMessage("For more information on any particular command, try 'help '."); } +CommandObject * +CommandInterpreter::GetCommandObjectForCommand (std::string &command_string) +{ + // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will + // eventually be invoked by the given command line. + + CommandObject *cmd_obj = NULL; + std::string white_space (" \t\v"); + size_t start = command_string.find_first_not_of (white_space); + size_t end = 0; + bool done = false; + while (!done) + { + if (start != std::string::npos) + { + // Get the next word from command_string. + end = command_string.find_first_of (white_space, start); + if (end == std::string::npos) + end = command_string.size(); + std::string cmd_word = command_string.substr (start, end - start); + + if (cmd_obj == NULL) + // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid + // command or alias. + cmd_obj = GetCommandObject (cmd_word.c_str()); + else if (cmd_obj->IsMultiwordObject ()) + { + // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object. + CommandObject *sub_cmd_obj = + ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (cmd_word.c_str()); + if (sub_cmd_obj) + cmd_obj = sub_cmd_obj; + else // cmd_word was not a valid sub-command word, so we are donee + done = true; + } + else + // We have a cmd_obj and it is not a multi-word object, so we are done. + done = true; + + // If we didn't find a valid command object, or our command object is not a multi-word object, or + // we are at the end of the command_string, then we are done. Otherwise, find the start of the + // next word. + + if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size()) + done = true; + else + start = command_string.find_first_not_of (white_space, end); + } + else + // Unable to find any more words. + done = true; + } + + if (end == command_string.size()) + command_string.clear(); + else + command_string = command_string.substr(end); + + return cmd_obj; +} + bool -CommandInterpreter::HandleCommand -( - const char *command_line, - bool add_to_history, - CommandReturnObject &result, - ExecutionContext *override_context -) +CommandInterpreter::StripFirstWord (std::string &command_string, std::string &word) { - LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS)); - // FIXME: there should probably be a mutex to make sure only one thread can - // run the interpreter at a time. + std::string white_space (" \t\v"); + size_t start; + size_t end; + + start = command_string.find_first_not_of (white_space); + if (start != std::string::npos) + { + end = command_string.find_first_of (white_space, start); + if (end != std::string::npos) + { + word = command_string.substr (start, end - start); + command_string = command_string.substr (end); + size_t pos = command_string.find_first_not_of (white_space); + if ((pos != 0) && (pos != std::string::npos)) + command_string = command_string.substr (pos); + } + else + { + word = command_string.substr (start); + command_string.erase(); + } + + } + return true; +} + +void +CommandInterpreter::BuildAliasResult (const char *alias_name, std::string &raw_input_string, std::string &alias_result, + CommandObject *&alias_cmd_obj, CommandReturnObject &result) +{ + Args cmd_args (raw_input_string.c_str()); + alias_cmd_obj = GetCommandObject (alias_name); + StreamString result_str; + + if (alias_cmd_obj) + { + std::string alias_name_str = alias_name; + if ((cmd_args.GetArgumentCount() == 0) + || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)) + cmd_args.Unshift (alias_name); + + result_str.Printf ("%s", alias_cmd_obj->GetCommandName ()); + OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); + + if (option_arg_vector_sp.get()) + { + OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); + for (int i = 0; i < option_arg_vector->size(); ++i) + { + OptionArgPair option_pair = (*option_arg_vector)[i]; + OptionArgValue value_pair = option_pair.second; + int value_type = value_pair.first; + std::string option = option_pair.first; + std::string value = value_pair.second; + if (option.compare ("") == 0) + result_str.Printf (" %s", value.c_str()); + else + { + result_str.Printf (" %s", option.c_str()); + if (value_type != optional_argument) + result_str.Printf (" "); + if (value.compare ("") != 0) + { + int index = GetOptionArgumentPosition (value.c_str()); + if (index == 0) + result_str.Printf ("%s", value.c_str()); + else if (index >= cmd_args.GetArgumentCount()) + { + + result.AppendErrorWithFormat + ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", + index); + result.SetStatus (eReturnStatusFailed); + return; + } + else + { + size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); + if (strpos != std::string::npos) + raw_input_string = raw_input_string.erase (strpos, + strlen (cmd_args.GetArgumentAtIndex (index))); + result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index)); + } + } + } + } + } + + alias_result = result_str.GetData(); + } +} + +bool +CommandInterpreter::HandleCommand (const char *command_line, + bool add_to_history, + CommandReturnObject &result, + ExecutionContext *override_context) +{ + bool done = false; + CommandObject *cmd_obj = NULL; + std::string next_word; + bool wants_raw_input = false; + std::string command_string (command_line); + + LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS)); Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line); // Make a scoped cleanup object that will clear the crash description string // on exit of this function. lldb_utility::CleanUp crash_description_cleanup(NULL, Host::SetCrashDescription); - // TODO: this should be a logging channel in lldb. -// if (DebugSelf()) -// { -// result.AppendMessageWithFormat ("Processing command: %s\n", command_line); -// } + if (log) + log->Printf ("Processing command: %s", command_line); Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line); @@ -534,6 +688,7 @@ else { command_line = m_repeat_command.c_str(); + command_string = command_line; if (m_repeat_command.empty()) { result.AppendErrorWithFormat("No auto repeat.\n"); @@ -544,158 +699,171 @@ add_to_history = false; } - if (log) - log->Printf ("CommandInterpreter::HandleCommand, command_line = '%s'", command_line); - - Args command_args(command_line); + // Phase 1. + + // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object + // is for the specified command, and whether or not it wants raw input. This gets complicated by the fact that + // the user could have specified an alias, and in translating the alias there may also be command options and/or + // even data (including raw text strings) that need to be found and inserted into the command line as part of + // the translation. So this first step is plain look-up & replacement, resulting in three things: 1). the command + // object whose Execute method will actually be called; 2). a revised command string, with all substituitions & + // replacements taken care of; 3). whether or not the Execute function wants raw input or not. - if (command_args.GetArgumentCount() > 0) + StreamString revised_command_line; + while (!done) { - std::string raw_command_string (command_line); // For commands that take raw input but may be aliased or - // have command options. - - const char *command_cstr = command_args.GetArgumentAtIndex(0); - if (command_cstr) + StripFirstWord (command_string, next_word); + if (!cmd_obj && AliasExists (next_word.c_str())) { - - // We're looking up the command object here. So first find an exact match to the - // command in the commands. - CommandObject *command_obj = GetCommandObject(command_cstr); - - if (command_obj != NULL) + std::string alias_result; + BuildAliasResult (next_word.c_str(), command_string, alias_result, cmd_obj, result); + revised_command_line.Printf ("%s", alias_result.c_str()); + if (cmd_obj) + wants_raw_input = cmd_obj->WantsRawCommandString (); + } + else if (!cmd_obj) + { + cmd_obj = GetCommandObject (next_word.c_str()); + if (cmd_obj) { - // Strip command name from the raw_command_string. - if (raw_command_string.find (command_cstr) == 0) - { - // The command name is at the front of the string (where it should be) so strip it off. - raw_command_string = raw_command_string.substr (strlen (command_cstr)); - } - + revised_command_line.Printf ("%s", next_word.c_str()); + wants_raw_input = cmd_obj->WantsRawCommandString (); + } + else + { + revised_command_line.Printf ("%s", next_word.c_str()); + } + } + else if (cmd_obj->IsMultiwordObject ()) + { + CommandObject *sub_cmd_obj = ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (next_word.c_str()); + if (sub_cmd_obj) + { + revised_command_line.Printf (" %s", next_word.c_str()); + cmd_obj = sub_cmd_obj; + wants_raw_input = cmd_obj->WantsRawCommandString (); + } + else + { + revised_command_line.Printf (" %s", next_word.c_str()); + done = true; + } + } + else + { + revised_command_line.Printf (" %s", next_word.c_str()); + done = true; + } + + if (cmd_obj == NULL) + { + result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + + next_word.erase (); + if (command_string.length() == 0) + done = true; - std::string aliased_cmd_str; - if (command_obj->IsAlias()) - { - if (log) - log->Printf ("Command '%s' is an alias. Building alias command args.", command_cstr); - BuildAliasCommandArgs (command_obj, command_cstr, command_args, raw_command_string, result); - if (!result.Succeeded()) - { - if (log) - log->Printf ("Building alias command args failed."); - return false; - } - else - { - // We need to transfer the newly constructed args back into the command_line, in case - // this happens to be an alias for a command that takes raw input. - if (command_args.GetCommandString (aliased_cmd_str)) - { - if (log) - log->Printf ("Result string from BuildAliasCommandArgs is '%s'", aliased_cmd_str.c_str()); - if (command_obj->WantsRawCommandString()) - { - if (log) - { - log->Printf ("This command takes raw input."); - } - aliased_cmd_str.append (" "); - aliased_cmd_str.append (raw_command_string); - } - else - { - if (log) - log->Printf ("This command does NOT take raw input."); - } - command_line = aliased_cmd_str.c_str(); - command_cstr = command_args.GetArgumentAtIndex (0); - if (log) - { - log->Printf ("Final command line, after resolving aliases is '%s'", command_line); - } - } - } - } + } - if (add_to_history) - { - const char *repeat_command = command_obj->GetRepeatCommand(command_args, 0); - if (repeat_command != NULL) - m_repeat_command.assign(repeat_command); - else - m_repeat_command.assign(command_line); - - m_command_history.push_back (command_line); - } + if (command_string.size() > 0) + revised_command_line.Printf (" %s", command_string.c_str()); + // End of Phase 1. + // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command + // specified was valid; revised_command_line contains the complete command line (including command name(s)), + // fully translated with all substitutions & translations taken care of (still in raw text format); and + // wants_raw_input specifies whether the Execute method expects raw input or not. - if (command_obj->WantsRawCommandString()) - { - const char *stripped_command = ::strstr (command_line, command_cstr); - if (stripped_command) - { - stripped_command += strlen(command_cstr); - while (isspace(*stripped_command)) - ++stripped_command; - if (log) - log->Printf ("Input string being passed to ExecuteRawCommandString for '%s' command is '%s'", - command_obj->GetCommandName(), stripped_command); - command_obj->ExecuteRawCommandString (stripped_command, result); - } - } - else - { - // Remove the command from the args. - command_args.Shift(); - if (log) - { - size_t count = command_args.GetArgumentCount(); - log->Printf ("ExecuteWithOptions for '%s' command is being called with %d args:", - command_obj->GetCommandName(), count); - for (size_t k = 0; k < count; ++k) - log->Printf (" arg[%d]='%s'", k, command_args.GetArgumentAtIndex (k)); - } - command_obj->ExecuteWithOptions (command_args, result); - } - } - else - { - // We didn't find the first command object, so complete the first argument. - StringList matches; - int num_matches; - int cursor_index = 0; - int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0)); - bool word_complete; - num_matches = HandleCompletionMatches (command_args, - cursor_index, - cursor_char_position, - 0, - -1, - word_complete, - matches); + + if (log) + { + log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : ""); + log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData()); + log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False"); + } - if (num_matches > 0) - { - std::string error_msg; - error_msg.assign ("ambiguous command '"); - error_msg.append(command_cstr); - error_msg.append ("'."); + // Phase 2. + // Take care of things like setting up the history command & calling the appropriate Execute method on the + // CommandObject, with the appropriate arguments. + + if (cmd_obj != NULL) + { + if (add_to_history) + { + Args command_args (revised_command_line.GetData()); + const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); + if (repeat_command != NULL) + m_repeat_command.assign(repeat_command); + else + m_repeat_command.assign(command_line); + + m_command_history.push_back (command_line); + } + + command_string = revised_command_line.GetData(); + std::string command_name (cmd_obj->GetCommandName()); + std::string remainder (command_string.substr (command_name.size())); + + // Remove any initial spaces + std::string white_space (" \t\v"); + size_t pos = remainder.find_first_not_of (white_space); + if (pos != 0 && pos != std::string::npos) + remainder = remainder.substr (pos); - error_msg.append (" Possible completions:"); - for (int i = 0; i < num_matches; i++) - { - error_msg.append ("\n\t"); - error_msg.append (matches.GetStringAtIndex (i)); - } - error_msg.append ("\n"); - result.AppendRawError (error_msg.c_str(), error_msg.size()); - } - else - result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_cstr); + if (log) + log->Printf ("HandleCommand, command line after removing command name(s): '%s'\n", remainder.c_str()); + - result.SetStatus (eReturnStatusFailed); + if (wants_raw_input) + cmd_obj->ExecuteRawCommandString (remainder.c_str(), result); + else + { + Args cmd_args (remainder.c_str()); + cmd_obj->ExecuteWithOptions (cmd_args, result); + } + } + else + { + // We didn't find the first command object, so complete the first argument. + Args command_args (revised_command_line.GetData()); + StringList matches; + int num_matches; + int cursor_index = 0; + int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0)); + bool word_complete; + num_matches = HandleCompletionMatches (command_args, + cursor_index, + cursor_char_position, + 0, + -1, + word_complete, + matches); + + if (num_matches > 0) + { + std::string error_msg; + error_msg.assign ("ambiguous command '"); + error_msg.append(command_args.GetArgumentAtIndex(0)); + error_msg.append ("'."); + + error_msg.append (" Possible completions:"); + for (int i = 0; i < num_matches; i++) + { + error_msg.append ("\n\t"); + error_msg.append (matches.GetStringAtIndex (i)); } + error_msg.append ("\n"); + result.AppendRawError (error_msg.c_str(), error_msg.size()); } + else + result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0)); + + result.SetStatus (eReturnStatusFailed); } + return result.Succeeded(); } From jingham at apple.com Thu Dec 9 18:26:25 2010 From: jingham at apple.com (Jim Ingham) Date: Fri, 10 Dec 2010 00:26:25 -0000 Subject: [Lldb-commits] [lldb] r121437 - in /lldb/trunk: include/lldb/Target/ lldb.xcodeproj/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ Message-ID: <20101210002625.E48182A6C12C@llvm.org> Author: jingham Date: Thu Dec 9 18:26:25 2010 New Revision: 121437 URL: http://llvm.org/viewvc/llvm-project?rev=121437&view=rev Log: Changing the ObjC find method implementation to use a ClangUtilityFunction inserted into the target. Consolidate all the logic for finding the target of a method dispatch into this function, insert & call it. Gets calls to super, and all the fixup & fixedup variants working properly. Also gets the class from the object so that we step through KVO wrapper methods into the actual user code. Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h?rev=121437&r1=121436&r2=121437&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h (original) +++ lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h Thu Dec 9 18:26:25 2010 @@ -35,13 +35,13 @@ virtual bool WillStop (); virtual bool MischiefManaged (); -protected: ThreadPlanStepOut (Thread &thread, SymbolContext *addr_context, bool first_insn, bool stop_others, lldb::Vote stop_vote, lldb::Vote run_vote); +protected: private: SymbolContext *m_step_from_context; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=121437&r1=121436&r2=121437&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Dec 9 18:26:25 2010 @@ -2459,7 +2459,6 @@ isa = PBXProject; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, 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=121437&r1=121436&r2=121437&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Thu Dec 9 18:26:25 2010 @@ -136,7 +136,7 @@ if (m_has_object_getClass) { assert(snprintf(&buf->contents[0], sizeof(buf->contents), - "extern \"C\" int gdb_object_getClass(void *); \n" + "extern \"C\" void *gdb_object_getClass(void *); \n" "extern \"C\" void \n" "%s(void *$__lldb_arg_obj) \n" "{ \n" @@ -148,7 +148,7 @@ else { assert(snprintf(&buf->contents[0], sizeof(buf->contents), - "extern \"C\" int gdb_class_getClass(void *); \n" + "extern \"C\" void *gdb_class_getClass(void *); \n" "extern \"C\" void \n" "%s(void *$__lldb_arg_obj) \n" "{ \n" Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp?rev=121437&r1=121436&r2=121437&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp Thu Dec 9 18:26:25 2010 @@ -22,7 +22,6 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/Value.h" -#include "lldb/Expression/ClangFunction.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" @@ -35,7 +34,117 @@ using namespace lldb; using namespace lldb_private; - +const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector"; +const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = " \n\ +extern \"C\" \n\ +{ \n\ + extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\ + extern void *class_getMethodImplementation_stret(void *objc_class, void *sel); \n\ + extern void * sel_getUid(char *name); \n\ + extern int printf(const char *format, ...); \n\ +} \n\ +extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object, \n\ + void *sel, \n\ + int is_stret, \n\ + int is_super, \n\ + int is_super2, \n\ + int is_fixup, \n\ + int is_fixed, \n\ + int debug) \n\ +{ \n\ + struct __lldb_imp_return_struct \n\ + { \n\ + void *class_addr; \n\ + void *sel_addr; \n\ + void *impl_addr; \n\ + }; \n\ + \n\ + struct __lldb_objc_class { \n\ + void *isa; \n\ + void *super_ptr; \n\ + }; \n\ + struct __lldb_objc_super { \n\ + void *reciever; \n\ + struct __lldb_objc_class *class_ptr; \n\ + }; \n\ + struct __lldb_msg_ref { \n\ + void *dont_know; \n\ + void *sel; \n\ + }; \n\ + \n\ + struct __lldb_imp_return_struct return_struct; \n\ + \n\ + if (debug) \n\ + printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \" \n\ + \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\ + object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed); \n\ + if (is_super) \n\ + { \n\ + if (is_super2) \n\ + { \n\ + return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr; \n\ + } \n\ + else \n\ + { \n\ + return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr; \n\ + } \n\ + } \n\ + else \n\ + { \n\ + void *class_ptr = (void *) [(id) object class]; \n\ + if (class_ptr == object) \n\ + { \n\ + struct __lldb_objc_class *class_as_class_struct = (struct __lldb_objc_class *) class_ptr; \n\ + if (debug) \n\ + printf (\"Found a class object, need to return the meta class 0x%p -> 0x%p\\n\", \n\ + class_ptr, class_as_class_struct->isa); \n\ + return_struct.class_addr = class_as_class_struct->isa; \n\ + } \n\ + else \n\ + { \n\ + if (debug) \n\ + printf (\"[object class] returned: 0x%p.\\n\", class_ptr); \n\ + return_struct.class_addr = class_ptr; \n\ + } \n\ + } \n\ + \n\ + if (is_fixup) \n\ + { \n\ + if (is_fixed) \n\ + { \n\ + return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\ + } \n\ + else \n\ + { \n\ + char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\ + return_struct.sel_addr = sel_getUid (sel_name); \n\ + if (debug) \n\ + printf (\"\\n*** Got fixed up selector: 0x%p for name %s.\\n\", \n\ + return_struct.sel_addr, sel_name); \n\ + } \n\ + } \n\ + else \n\ + { \n\ + return_struct.sel_addr = sel; \n\ + } \n\ + \n\ + if (is_stret) \n\ + { \n\ + return_struct.impl_addr = class_getMethodImplementation_stret (return_struct.class_addr, \n\ + return_struct.sel_addr); \n\ + } \n\ + else \n\ + { \n\ + return_struct.impl_addr = class_getMethodImplementation (return_struct.class_addr, \n\ + return_struct.sel_addr); \n\ + } \n\ + if (debug) \n\ + printf (\"\\n*** Returning implementation: 0x%p.\\n\", return_struct.impl_addr); \n\ + \n\ + return return_struct.impl_addr; \n\ +} \n\ +"; + AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr) : m_valid (true), m_owner(owner), @@ -383,27 +492,27 @@ const AppleObjCTrampolineHandler::DispatchFunction AppleObjCTrampolineHandler::g_dispatch_functions[] = { - // NAME STRET SUPER FIXUP TYPE - {"objc_msgSend", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSend_fixup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSend_fixedup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSend_stret", true, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSend_stret_fixup", true, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSend_stret_fixedup", true, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSend_fpret", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSend_fpret_fixup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSend_fpret_fixedup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSend_fp2ret", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSend_fp2ret_fixup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSend_fp2ret_fixedup", false, false, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSendSuper", false, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSendSuper_stret", true, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSendSuper2", false, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSendSuper2_fixup", false, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSendSuper2_fixedup", false, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, - {"objc_msgSendSuper2_stret", true, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpNone }, - {"objc_msgSendSuper2_stret_fixup", true, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpToFix }, - {"objc_msgSendSuper2_stret_fixedup", true, true, AppleObjCTrampolineHandler::DispatchFunction::eFixUpFixed }, + // NAME STRET SUPER SUPER2 FIXUP TYPE + {"objc_msgSend", false, false, false, DispatchFunction::eFixUpNone }, + {"objc_msgSend_fixup", false, false, false, DispatchFunction::eFixUpToFix }, + {"objc_msgSend_fixedup", false, false, false, DispatchFunction::eFixUpFixed }, + {"objc_msgSend_stret", true, false, false, DispatchFunction::eFixUpNone }, + {"objc_msgSend_stret_fixup", true, false, false, DispatchFunction::eFixUpToFix }, + {"objc_msgSend_stret_fixedup", true, false, false, DispatchFunction::eFixUpFixed }, + {"objc_msgSend_fpret", false, false, false, DispatchFunction::eFixUpNone }, + {"objc_msgSend_fpret_fixup", false, false, false, DispatchFunction::eFixUpToFix }, + {"objc_msgSend_fpret_fixedup", false, false, false, DispatchFunction::eFixUpFixed }, + {"objc_msgSend_fp2ret", false, false, true, DispatchFunction::eFixUpNone }, + {"objc_msgSend_fp2ret_fixup", false, false, true, DispatchFunction::eFixUpToFix }, + {"objc_msgSend_fp2ret_fixedup", false, false, true, DispatchFunction::eFixUpFixed }, + {"objc_msgSendSuper", false, true, false, DispatchFunction::eFixUpNone }, + {"objc_msgSendSuper_stret", true, true, false, DispatchFunction::eFixUpNone }, + {"objc_msgSendSuper2", false, true, true, DispatchFunction::eFixUpNone }, + {"objc_msgSendSuper2_fixup", false, true, true, DispatchFunction::eFixUpToFix }, + {"objc_msgSendSuper2_fixedup", false, true, true, DispatchFunction::eFixUpFixed }, + {"objc_msgSendSuper2_stret", true, true, true, DispatchFunction::eFixUpNone }, + {"objc_msgSendSuper2_stret_fixup", true, true, true, DispatchFunction::eFixUpToFix }, + {"objc_msgSendSuper2_stret_fixedup", true, true, true, DispatchFunction::eFixUpFixed }, {NULL} }; @@ -411,21 +520,30 @@ m_process_sp (process_sp), m_objc_module_sp (objc_module_sp), m_impl_fn_addr (LLDB_INVALID_ADDRESS), - m_impl_stret_fn_addr (LLDB_INVALID_ADDRESS) + m_impl_stret_fn_addr (LLDB_INVALID_ADDRESS), + m_msg_forward_addr (LLDB_INVALID_ADDRESS) { // Look up the known resolution functions: ConstString get_impl_name("class_getMethodImplementation"); ConstString get_impl_stret_name("class_getMethodImplementation_stret"); + ConstString msg_forward_name("_objc_msgForward"); + ConstString msg_forward_stret_name("_objc_msgForward_stret"); Target *target = m_process_sp ? &m_process_sp->GetTarget() : NULL; const Symbol *class_getMethodImplementation = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_name, eSymbolTypeCode); const Symbol *class_getMethodImplementation_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (get_impl_stret_name, eSymbolTypeCode); + const Symbol *msg_forward = m_objc_module_sp->FindFirstSymbolWithNameAndType (msg_forward_name, eSymbolTypeCode); + const Symbol *msg_forward_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (msg_forward_stret_name, eSymbolTypeCode); if (class_getMethodImplementation) m_impl_fn_addr = class_getMethodImplementation->GetValue().GetLoadAddress(target); if (class_getMethodImplementation_stret) m_impl_stret_fn_addr = class_getMethodImplementation_stret->GetValue().GetLoadAddress(target); + if (msg_forward) + m_msg_forward_addr = msg_forward->GetValue().GetLoadAddress(target); + if (msg_forward_stret) + m_msg_forward_stret_addr = msg_forward_stret->GetValue().GetLoadAddress(target); // FIXME: Do some kind of logging here. if (m_impl_fn_addr == LLDB_INVALID_ADDRESS || m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS) @@ -467,6 +585,9 @@ DispatchFunction this_dispatch; bool found_it = false; + // First step is to look and see if we are in one of the known ObjC dispatch functions. We've already compiled + // a table of same, so consult it. + MsgsendMap::iterator pos; pos = m_msgSend_map.find (curr_pc); if (pos != m_msgSend_map.end()) @@ -475,6 +596,8 @@ found_it = true; } + // Next check to see if we are in a vtable region: + if (!found_it) { uint32_t flags; @@ -496,6 +619,8 @@ { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + // We are decoding a method dispatch. + // First job is to pull the arguments out: lldb::StackFrameSP thread_cur_frame = thread.GetStackFrameAtIndex(0); @@ -506,16 +631,12 @@ Target *target = thread.CalculateTarget(); - // FIXME: Since neither the value nor the Clang QualType know their ASTContext, - // we have to make sure the type we put in our value list comes from the same ASTContext - // the ABI will use to get the argument values. THis is the bottom-most frame's module. - ClangASTContext *clang_ast_context = target->GetScratchClangASTContext(); ValueList argument_values; - Value input_value; - void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); - input_value.SetValueType (Value::eValueTypeScalar); - input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); + Value void_ptr_value; + lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); + void_ptr_value.SetValueType (Value::eValueTypeScalar); + void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type); int obj_index; int sel_index; @@ -527,99 +648,185 @@ { obj_index = 1; sel_index = 2; - argument_values.PushValue(input_value); - argument_values.PushValue(input_value); - argument_values.PushValue(input_value); + argument_values.PushValue(void_ptr_value); + argument_values.PushValue(void_ptr_value); + argument_values.PushValue(void_ptr_value); } else { obj_index = 0; sel_index = 1; - argument_values.PushValue(input_value); - argument_values.PushValue(input_value); + argument_values.PushValue(void_ptr_value); + argument_values.PushValue(void_ptr_value); } bool success = abi->GetArgumentValues (thread, argument_values); if (!success) return ret_plan_sp; - - // Okay, the first value here is the object, we actually want the class of that object. - // For now we're just going with the ISA. - // FIXME: This should really be the return value of [object class] to properly handle KVO interposition. - + + // Pull the class out of the Object and see if we've already cached this method call, + // If so we can push a run-to-address plan directly. Otherwise we have to figure out where + // the implementation lives. + Value isa_value(*(argument_values.GetValueAtIndex(obj_index))); - - // This is a little cheesy, but since object->isa is the first field, + + // This is a little cheesy, but since object->isa is the first field, // making the object value a load address value and resolving it will get // the pointer sized data pointed to by that value... - ExecutionContext exec_ctx; - thread.CalculateExecutionContext (exec_ctx); + ExecutionContext exe_ctx; + thread.CalculateExecutionContext (exe_ctx); isa_value.SetValueType(Value::eValueTypeLoadAddress); - isa_value.ResolveValue(&exec_ctx, clang_ast_context->getASTContext()); - - if (this_dispatch.fixedup == DispatchFunction::eFixUpFixed) - { - // For the FixedUp method the Selector is actually a pointer to a - // structure, the second field of which is the selector number. - Value *sel_value = argument_values.GetValueAtIndex(sel_index); - sel_value->GetScalar() += process->GetAddressByteSize(); - sel_value->SetValueType(Value::eValueTypeLoadAddress); - sel_value->ResolveValue(&exec_ctx, clang_ast_context->getASTContext()); - } - else if (this_dispatch.fixedup == DispatchFunction::eFixUpToFix) - { - // FIXME: If the method dispatch is not "fixed up" then the selector is actually a - // pointer to the string name of the selector. We need to look that up... - // For now I'm going to punt on that and just return no plan. - if (log) - log->Printf ("Punting on stepping into un-fixed-up method dispatch."); - return ret_plan_sp; - } - - // FIXME: If this is a dispatch to the super-class, we need to get the super-class from - // the class, and disaptch to that instead. - // But for now I just punt and return no plan. - if (this_dispatch.is_super) - { - if (log) - log->Printf ("Punting on stepping into super method dispatch."); - return ret_plan_sp; - } - - ValueList dispatch_values; - dispatch_values.PushValue (isa_value); - dispatch_values.PushValue(*(argument_values.GetValueAtIndex(sel_index))); - + isa_value.ResolveValue(&exe_ctx, clang_ast_context->getASTContext()); + lldb::addr_t isa_addr = isa_value.GetScalar().ULongLong(); + lldb::addr_t sel_addr = argument_values.GetValueAtIndex(sel_index)->GetScalar().ULongLong(); + if (log) { log->Printf("Resolving method call for class - 0x%llx and selector - 0x%llx", - dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), - dispatch_values.GetValueAtIndex(1)->GetScalar().ULongLong()); + isa_addr, sel_addr); } ObjCLanguageRuntime *objc_runtime = m_process_sp->GetObjCLanguageRuntime (); assert(objc_runtime != NULL); - lldb::addr_t impl_addr = objc_runtime->LookupInMethodCache (dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), - dispatch_values.GetValueAtIndex(1)->GetScalar().ULongLong()); + + lldb::addr_t impl_addr = objc_runtime->LookupInMethodCache (isa_addr, sel_addr); if (impl_addr == LLDB_INVALID_ADDRESS) - { - - Address resolve_address(NULL, this_dispatch.stret_return ? m_impl_stret_fn_addr : m_impl_fn_addr); - + { + // We haven't seen this class/selector pair yet. Look it up. StreamString errors; + Address impl_code_address; + + ValueList dispatch_values; + + // We've will inject a little function in the target that takes the object, selector and some flags, + // and figures out the implementation. Looks like: + // void *__lldb_objc_find_implementation_for_selector (void *object, + // void *sel, + // int is_stret, + // int is_super, + // int is_super2, + // int is_fixup, + // int is_fixed, + // int debug) + // So set up the arguments for that call. + + dispatch_values.PushValue (*(argument_values.GetValueAtIndex(obj_index))); + dispatch_values.PushValue (*(argument_values.GetValueAtIndex(sel_index))); + + Value flag_value; + lldb::clang_type_t clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingSint, 32); + flag_value.SetValueType (Value::eValueTypeScalar); + flag_value.SetContext (Value::eContextTypeClangType, clang_int_type); + + if (this_dispatch.stret_return) + flag_value.GetScalar() = 1; + else + flag_value.GetScalar() = 0; + dispatch_values.PushValue (flag_value); + + if (this_dispatch.is_super) + flag_value.GetScalar() = 1; + else + flag_value.GetScalar() = 0; + dispatch_values.PushValue (flag_value); + + if (this_dispatch.is_super2) + flag_value.GetScalar() = 1; + else + flag_value.GetScalar() = 0; + dispatch_values.PushValue (flag_value); + + switch (this_dispatch.fixedup) + { + case DispatchFunction::eFixUpNone: + flag_value.GetScalar() = 0; + dispatch_values.PushValue (flag_value); + dispatch_values.PushValue (flag_value); + break; + case DispatchFunction::eFixUpFixed: + flag_value.GetScalar() = 1; + dispatch_values.PushValue (flag_value); + flag_value.GetScalar() = 1; + dispatch_values.PushValue (flag_value); + break; + case DispatchFunction::eFixUpToFix: + flag_value.GetScalar() = 1; + dispatch_values.PushValue (flag_value); + flag_value.GetScalar() = 0; + dispatch_values.PushValue (flag_value); + break; + } + if (log) + flag_value.GetScalar() = 1; + else + flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done. + dispatch_values.PushValue (flag_value); + + // Now, if we haven't already, make and insert the function as a ClangUtilityFunction, and make and insert + // it's runner ClangFunction. { // Scope for mutex locker: Mutex::Locker locker(m_impl_function_mutex); + + // First stage is to make the ClangUtility to hold our injected function: + +#define USE_BUILTIN_FUNCTION 0 // Define this to 1 and we will use the get_implementation function found in the target. + // This is useful for debugging additions to the get_impl function 'cause you don't have + // to bother with string-ifying the code into g_lookup_implementation_function_code. + + if (USE_BUILTIN_FUNCTION) + { + ConstString our_utility_function_name("__lldb_objc_find_implementation_for_selector"); + SymbolContextList sc_list; + exe_ctx.target->GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list); + if (sc_list.GetSize() == 1) + { + SymbolContext sc; + sc_list.GetContextAtIndex(0, sc); + if (sc.symbol != NULL) + impl_code_address = sc.symbol->GetValue(); + + lldb::addr_t addr = impl_code_address.GetLoadAddress (exe_ctx.target); + printf ("Getting address for our_utility_function: 0x%llx.\n", addr); + } + else + { + printf ("Could not find implementation function address.\n"); + return ret_plan_sp; + } + } + else if (!m_impl_code.get()) + { + m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code, + g_lookup_implementation_function_name)); + if (!m_impl_code->Install(errors, exe_ctx)) + { + if (log) + log->Printf ("Failed to install implementation lookup: %s.", errors.GetData()); + m_impl_code.reset(); + return ret_plan_sp; + } + impl_code_address.Clear(); + impl_code_address.SetOffset(m_impl_code->StartAddress()); + } + else + { + impl_code_address.Clear(); + impl_code_address.SetOffset(m_impl_code->StartAddress()); + } + + // Next make the runner function for our implementation utility function. if (!m_impl_function.get()) { m_impl_function.reset(new ClangFunction(process->GetTargetTriple().GetCString(), clang_ast_context, clang_void_ptr_type, - resolve_address, + impl_code_address, dispatch_values)); - + + errors.Clear(); unsigned num_errors = m_impl_function->CompileFunction(errors); if (num_errors) { @@ -629,7 +836,7 @@ } errors.Clear(); - if (!m_impl_function->WriteFunctionWrapper(exec_ctx, errors)) + if (!m_impl_function->WriteFunctionWrapper(exe_ctx, errors)) { if (log) log->Printf ("Error Inserting function: \"%s\".", errors.GetData()); @@ -637,19 +844,21 @@ } } - } + } errors.Clear(); - // Now write down the argument values for this call. + // Now write down the argument values for this particular call. This looks like it might be a race condition + // if other threads were calling into here, but actually it isn't because we allocate a new args structure for + // this call by passing args_addr = LLDB_INVALID_ADDRESS... + lldb::addr_t args_addr = LLDB_INVALID_ADDRESS; - if (!m_impl_function->WriteFunctionArguments (exec_ctx, args_addr, resolve_address, dispatch_values, errors)) + if (!m_impl_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, dispatch_values, errors)) return ret_plan_sp; - ret_plan_sp.reset (new AppleThreadPlanStepThroughObjCTrampoline (thread, this, args_addr, - argument_values.GetValueAtIndex(0)->GetScalar().ULongLong(), + ret_plan_sp.reset (new AppleThreadPlanStepThroughObjCTrampoline (thread, this, args_addr, dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(), - dispatch_values.GetValueAtIndex(1)->GetScalar().ULongLong(), + isa_addr, sel_addr, stop_others)); if (log) { Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h?rev=121437&r1=121436&r2=121437&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h Thu Dec 9 18:26:25 2010 @@ -18,6 +18,7 @@ // Project includes #include "lldb/Expression/ClangExpression.h" #include "lldb/Expression/ClangFunction.h" +#include "lldb/Expression/ClangUtilityFunction.h" #include "lldb/Host/Mutex.h" @@ -38,6 +39,12 @@ ClangFunction * GetLookupImplementationWrapperFunction (); + bool + AddrIsMsgForward (lldb::addr_t addr) const + { + return (addr == m_msg_forward_addr || addr == m_msg_forward_stret_addr); + } + struct DispatchFunction { public: @@ -51,10 +58,13 @@ const char *name; bool stret_return; bool is_super; + bool is_super2; FixUpState fixedup; }; private: + static const char *g_lookup_implementation_function_name; + static const char *g_lookup_implementation_function_code; class AppleObjCVTables { @@ -165,7 +175,7 @@ { return m_process_sp.get(); } - + private: ProcessSP m_process_sp; typedef std::vector region_collection; @@ -182,11 +192,13 @@ MsgsendMap m_msgSend_map; ProcessSP m_process_sp; ModuleSP m_objc_module_sp; - lldb::addr_t get_impl_addr; std::auto_ptr m_impl_function; + std::auto_ptr m_impl_code; Mutex m_impl_function_mutex; lldb::addr_t m_impl_fn_addr; lldb::addr_t m_impl_stret_fn_addr; + lldb::addr_t m_msg_forward_addr; + lldb::addr_t m_msg_forward_stret_addr; std::auto_ptr m_vtables_ap; Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp?rev=121437&r1=121436&r2=121437&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp Thu Dec 9 18:26:25 2010 @@ -20,6 +20,7 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Core/Log.h" using namespace lldb_private; @@ -31,19 +32,19 @@ Thread &thread, AppleObjCTrampolineHandler *trampoline_handler, lldb::addr_t args_addr, - lldb::addr_t object_ptr, - lldb::addr_t class_ptr, - lldb::addr_t sel_ptr, + lldb::addr_t object_addr, + lldb::addr_t isa_addr, + lldb::addr_t sel_addr, bool stop_others) : ThreadPlan (ThreadPlan::eKindGeneric, "MacOSX Step through ObjC Trampoline", thread, lldb::eVoteNoOpinion, lldb::eVoteNoOpinion), - m_stop_others (stop_others), - m_object_ptr (object_ptr), - m_class_ptr (class_ptr), - m_sel_ptr (sel_ptr), + m_trampoline_handler (trampoline_handler), m_args_addr (args_addr), - m_objc_trampoline_handler (trampoline_handler), - m_impl_function (trampoline_handler->GetLookupImplementationWrapperFunction()) + m_object_addr (object_addr), + m_isa_addr(isa_addr), + m_sel_addr(sel_addr), + m_impl_function (trampoline_handler->GetLookupImplementationWrapperFunction()), + m_stop_others (stop_others) { } @@ -74,8 +75,8 @@ s->Printf("Step through ObjC trampoline"); else { - s->Printf ("Stepping to implementation of ObjC method - obj: 0x%llx class: 0x%llx selector: 0x%llx", - m_object_ptr, m_class_ptr, m_sel_ptr); + s->Printf ("Stepping to implementation of ObjC method - obj: 0x%llx, isa: 0x%llx, sel: 0x%llx", + m_object_addr, m_isa_addr, m_sel_addr); } } @@ -122,12 +123,26 @@ SetPlanComplete(); return true; } + if (m_trampoline_handler->AddrIsMsgForward(target_addr)) + { + if (log) + log->Printf ("Implementation lookup returned msgForward function: 0x%llx, stopping.", target_addr); + + SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(eSymbolContextEverything); + m_run_to_sp.reset(new ThreadPlanStepOut(m_thread, &sc, true, m_stop_others, eVoteNoOpinion, eVoteNoOpinion)); + m_thread.QueueThreadPlan(m_run_to_sp, false); + m_run_to_sp->SetPrivate(true); + return false; + } + if (log) log->Printf("Running to ObjC method implementation: 0x%llx", target_addr); ObjCLanguageRuntime *objc_runtime = GetThread().GetProcess().GetObjCLanguageRuntime(); assert (objc_runtime != NULL); - objc_runtime->AddToMethodCache (m_class_ptr, m_sel_ptr, target_addr); + objc_runtime->AddToMethodCache (m_isa_addr, m_sel_addr, target_addr); + if (log) + log->Printf("Adding {0x%llx, 0x%llx} = 0x%llx to cache.", m_isa_addr, m_sel_addr, target_addr); // Extract the target address from the value: Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h?rev=121437&r1=121436&r2=121437&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h Thu Dec 9 18:26:25 2010 @@ -29,12 +29,12 @@ // Constructors and Destructors //------------------------------------------------------------------ AppleThreadPlanStepThroughObjCTrampoline(Thread &thread, - AppleObjCTrampolineHandler *trampoline_handler, - lldb::addr_t args_addr, - lldb::addr_t object_ptr, - lldb::addr_t class_ptr, - lldb::addr_t sel_ptr, - bool stop_others); + AppleObjCTrampolineHandler *trampoline_handler, + lldb::addr_t args_addr, + lldb::addr_t object_addr, + lldb::addr_t isa_addr, + lldb::addr_t sel_addr, + bool stop_others); virtual ~AppleThreadPlanStepThroughObjCTrampoline(); @@ -77,18 +77,17 @@ //------------------------------------------------------------------ // For AppleThreadPlanStepThroughObjCTrampoline only //------------------------------------------------------------------ - bool m_stop_others; - lldb::addr_t m_object_ptr; - lldb::addr_t m_class_ptr; - lldb::addr_t m_sel_ptr; - + AppleObjCTrampolineHandler *m_trampoline_handler; // FIXME - ensure this doesn't go away on us? SP maybe? + lldb::addr_t m_args_addr; // Stores the address for our step through function result structure. + lldb::addr_t m_object_addr; // This is only for Description. + lldb::addr_t m_isa_addr; // isa_addr and sel_addr are the keys we will use to cache the implementation. + lldb::addr_t m_sel_addr; ThreadPlanSP m_func_sp; // This is the function call plan. We fill it at start, then set it // to NULL when this plan is done. That way we know to go to: - lldb::addr_t m_args_addr; // Stores the address for our step through function result structure. ThreadPlanSP m_run_to_sp; // The plan that runs to the target. - AppleObjCTrampolineHandler *m_objc_trampoline_handler; ClangFunction *m_impl_function; // This is a pointer to a impl function that // is owned by the client that pushes this plan. + bool m_stop_others; }; } // namespace lldb_private From ctice at apple.com Thu Dec 9 18:26:54 2010 From: ctice at apple.com (Caroline Tice) Date: Fri, 10 Dec 2010 00:26:54 -0000 Subject: [Lldb-commits] [lldb] r121438 - in /lldb/trunk: include/lldb/Interpreter/Args.h source/Commands/CommandObjectSettings.cpp source/Core/UserSettingsController.cpp source/Interpreter/Args.cpp Message-ID: <20101210002654.E596C2A6C12C@llvm.org> Author: ctice Date: Thu Dec 9 18:26:54 2010 New Revision: 121438 URL: http://llvm.org/viewvc/llvm-project?rev=121438&view=rev Log: Various fixes mostly relating to the User Settings stuff: - Added new utility function to Arg, GetQuotedCommandString, which re-assembles the args into a string, replacing quotes that were originally there. - Modified user settings stuff to always show individual elements when printing out arrays and dictionaries. - Added more extensive help to 'settings set', explaining more about dictionaries and arrays (including current dictionary syntax). - Fixed bug in user settings where quotes were being stripped and lost, so that sometimes array or dictionary elements that ought to have been a single element were being split up. Modified: lldb/trunk/include/lldb/Interpreter/Args.h lldb/trunk/source/Commands/CommandObjectSettings.cpp lldb/trunk/source/Core/UserSettingsController.cpp lldb/trunk/source/Interpreter/Args.cpp Modified: lldb/trunk/include/lldb/Interpreter/Args.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/Args.h?rev=121438&r1=121437&r2=121438&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/Args.h (original) +++ lldb/trunk/include/lldb/Interpreter/Args.h Thu Dec 9 18:26:54 2010 @@ -122,6 +122,9 @@ bool GetCommandString (std::string &command); + bool + GetQuotedCommandString (std::string &command); + //------------------------------------------------------------------ /// Gets the number of arguments left in this command object. /// Modified: lldb/trunk/source/Commands/CommandObjectSettings.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSettings.cpp?rev=121438&r1=121437&r2=121438&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSettings.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectSettings.cpp Thu Dec 9 18:26:54 2010 @@ -90,6 +90,29 @@ // Push the data for the first argument into the m_arguments vector. m_arguments.push_back (arg1); m_arguments.push_back (arg2); + + SetHelpLong ( +"When setting a dictionary or array variable, you can set multiple entries \n\ +at once by giving the values to the set command. For example: \n\ +\n\ +(lldb) settings set target.process.run-args value1 value2 value3 \n\ +(lldb) settings set target.process.env-vars [\"MYPATH\"]=~/.:/usr/bin [\"SOME_ENV_VAR\"]=12345 \n\ +\n\ +(lldb) settings show target.process.run-args \n\ + [0]: 'value1' \n\ + [1]: 'value2' \n\ + [3]: 'value3' \n\ +(lldb) settings show target.process.env-vars \n\ + 'MYPATH=~/.:/usr/bin'\n\ + 'SOME_ENV_VAR=12345' \n\ +\n\ +Note the special syntax for setting a dictionary element: [\"\"]= \n\ +\n\ +Warning: The 'set' command re-sets the entire array or dictionary. If you \n\ +just want to add, remove or update individual values (or add something to \n\ +the end), use one of the other settings sub-commands: append, replace, \n\ +insert-before or insert-after.\n"); + } CommandObjectSettingsSet::~CommandObjectSettingsSet() @@ -126,7 +149,7 @@ const char *var_value; std::string value_string; - command.GetCommandString (value_string); + command.GetQuotedCommandString (value_string); var_value = value_string.c_str(); if (!m_options.m_reset @@ -342,14 +365,17 @@ if (value.GetSize() == 0) result.AppendMessageWithFormat ("%s%s = ''\n", variable_name, type_name); - else if (value.GetSize() == 1) + else if ((var_type != lldb::eSetVarTypeArray) && (var_type != lldb::eSetVarTypeDictionary)) result.AppendMessageWithFormat ("%s%s = '%s'\n", variable_name, type_name, value.GetStringAtIndex (0)); else { result.AppendMessageWithFormat ("%s%s:\n", variable_name, type_name); for (unsigned i = 0, e = value.GetSize(); i != e; ++i) { - result.AppendMessageWithFormat (" [%d]: '%s'\n", i, value.GetStringAtIndex (i)); + if (var_type == lldb::eSetVarTypeArray) + result.AppendMessageWithFormat (" [%d]: '%s'\n", i, value.GetStringAtIndex (i)); + else if (var_type == lldb::eSetVarTypeDictionary) + result.AppendMessageWithFormat (" '%s'\n", value.GetStringAtIndex (i)); } } result.SetStatus (eReturnStatusSuccessFinishNoResult); @@ -727,7 +753,7 @@ const char *var_value; std::string value_string; - command.GetCommandString (value_string); + command.GetQuotedCommandString (value_string); var_value = value_string.c_str(); if ((var_value == NULL) || (var_value[0] == '\0')) @@ -872,7 +898,7 @@ const char *var_value; std::string value_string; - command.GetCommandString (value_string); + command.GetQuotedCommandString (value_string); var_value = value_string.c_str(); if ((var_value == NULL) || (var_value[0] == '\0')) @@ -1019,7 +1045,7 @@ const char *var_value; std::string value_string; - command.GetCommandString (value_string); + command.GetQuotedCommandString (value_string); var_value = value_string.c_str(); if ((var_value == NULL) || (var_value[0] == '\0')) @@ -1144,7 +1170,7 @@ const char *var_value; std::string value_string; - command.GetCommandString (value_string); + command.GetQuotedCommandString (value_string); var_value = value_string.c_str(); if ((var_value == NULL) || (var_value[0] == '\0')) Modified: lldb/trunk/source/Core/UserSettingsController.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/UserSettingsController.cpp?rev=121438&r1=121437&r2=121438&view=diff ============================================================================== --- lldb/trunk/source/Core/UserSettingsController.cpp (original) +++ lldb/trunk/source/Core/UserSettingsController.cpp Thu Dec 9 18:26:54 2010 @@ -780,18 +780,31 @@ m_default_settings->GetInstanceSettingsValue (entry, var_name, tmp_value, NULL); StreamString value_string; + bool multi_value = false; if (tmp_value.GetSize() == 1) value_string.Printf ("%s", tmp_value.GetStringAtIndex (0)); else { for (int j = 0; j < tmp_value.GetSize(); ++j) - value_string.Printf ("%s ", tmp_value.GetStringAtIndex (j)); + { + if (entry.var_type == lldb::eSetVarTypeArray) + value_string.Printf ("\n [%d]: '%s'", j, tmp_value.GetStringAtIndex (j)); + else if (entry.var_type == lldb::eSetVarTypeDictionary) + value_string.Printf ("\n '%s'", tmp_value.GetStringAtIndex (j)); + } + multi_value = true; } if (! parent_prefix.empty()) - result_stream.Printf ("%s.%s (%s) = '%s'\n", prefix, var_name.AsCString(), - UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); + { + if (multi_value) + result_stream.Printf ("%s.%s (%s):%s\n", prefix, var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); + else + result_stream.Printf ("%s.%s (%s) = '%s'\n", prefix, var_name.AsCString(), + UserSettingsController::GetTypeString (entry.var_type), value_string.GetData()); + } } } @@ -1366,10 +1379,12 @@ value.GetStringAtIndex (0)); else { - description.Printf ("%s (%s) = '", full_var_name.GetData(), GetTypeString (entry.var_type)); + description.Printf ("%s (%s):\n", full_var_name.GetData(), GetTypeString (entry.var_type)); for (int j = 0; j < value.GetSize(); ++j) - description.Printf ("%s ", value.GetStringAtIndex (j)); - description.Printf ("'"); + if (entry.var_type == lldb::eSetVarTypeArray) + description.Printf (" [%d]: '%s'\n", j, value.GetStringAtIndex (j)); + else if (entry.var_type == lldb::eSetVarTypeDictionary) + description.Printf (" '%s'\n", value.GetStringAtIndex (j)); } result_stream.Printf ("%s\n", description.GetData()); Modified: lldb/trunk/source/Interpreter/Args.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Args.cpp?rev=121438&r1=121437&r2=121438&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/Args.cpp (original) +++ lldb/trunk/source/Interpreter/Args.cpp Thu Dec 9 18:26:54 2010 @@ -93,6 +93,28 @@ return argc > 0; } +bool +Args::GetQuotedCommandString (std::string &command) +{ + command.clear (); + int argc = GetArgumentCount (); + for (int i = 0; i < argc; ++i) + { + if (i > 0) + command += ' '; + char quote_char = m_args_quote_char[i]; + if (quote_char != '\0') + { + command += quote_char; + command += m_argv[i]; + command += quote_char; + } + else + command += m_argv[i]; + } + return argc > 0; +} + void Args::SetCommandString (const char *command, size_t len) { From jingham at apple.com Thu Dec 9 18:27:27 2010 From: jingham at apple.com (Jim Ingham) Date: Fri, 10 Dec 2010 00:27:27 -0000 Subject: [Lldb-commits] [lldb] r121440 - in /lldb/trunk/test/objc-stepping: ./ stepping-tests.m Message-ID: <20101210002727.9ABEC2A6C12C@llvm.org> Author: jingham Date: Thu Dec 9 18:27:27 2010 New Revision: 121440 URL: http://llvm.org/viewvc/llvm-project?rev=121440&view=rev Log: Added the source file for some ObjC stepping tests. No test yet. Added: lldb/trunk/test/objc-stepping/ lldb/trunk/test/objc-stepping/stepping-tests.m Added: lldb/trunk/test/objc-stepping/stepping-tests.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-stepping/stepping-tests.m?rev=121440&view=auto ============================================================================== --- lldb/trunk/test/objc-stepping/stepping-tests.m (added) +++ lldb/trunk/test/objc-stepping/stepping-tests.m Thu Dec 9 18:27:27 2010 @@ -0,0 +1,133 @@ +#import +#include + +struct return_me +{ + int first; + int second; +}; + + at interface SourceBase: NSObject +{ + struct return_me my_return; +} +- (SourceBase *) initWithFirst: (int) first andSecond: (int) second; +- (void) randomMethod; +- (struct return_me) returnsStruct; + at end + + at implementation SourceBase +- (void) randomMethod +{ + printf ("Called in SourceBase version of randomMethod.\n"); +} + +- (struct return_me) returnsStruct +{ + return my_return; +} + +- (SourceBase *) initWithFirst: (int) first andSecond: (int) second +{ + my_return.first = first; + my_return.second = second; + + return self; +} + at end + + at interface Source : SourceBase +{ + int _property; +} +- (void) setProperty: (int) newValue; +- (void) randomMethod; +- (struct return_me) returnsStruct; + at end + + at implementation Source +- (void) setProperty: (int) newValue +{ + _property = newValue; +} + +- (void) randomMethod +{ + [super randomMethod]; + printf ("Called in Source version of random method."); +} + +- (struct return_me) returnsStruct +{ + printf ("Called in Source version of returnsStruct.\n"); + return [super returnsStruct]; +} + + at end + + at interface Observer : NSObject +{ + Source *_source; +} ++ (Observer *) observerWithSource: (Source *) source; +- (Observer *) initWithASource: (Source *) source; +- (void) observeValueForKeyPath: (NSString *) path + ofObject: (id) object + change: (NSDictionary *) change + context: (void *) context; + at end + + at implementation Observer + ++ (Observer *) observerWithSource: (Source *) inSource; +{ + Observer *retval; + + retval = [[Observer alloc] initWithASource: inSource]; + return retval; +} + +- (Observer *) initWithASource: (Source *) source +{ + [super init]; + _source = source; + [_source addObserver: self + forKeyPath: @"property" + options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) + context: NULL]; + return self; +} + +- (void) observeValueForKeyPath: (NSString *) path + ofObject: (id) object + change: (NSDictionary *) change + context: (void *) context +{ + printf ("Observer function called.\n"); + return; +} + at end + +int main () +{ + Source *mySource; + Observer *myObserver; + struct return_me ret_val; + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + mySource = [[Source alloc] init]; + + [mySource randomMethod]; // Set first breakpoint here. + ret_val = [mySource returnsStruct]; // Set second breakpoint here. + + myObserver = [Observer observerWithSource: mySource]; + + [mySource randomMethod]; // Set third breakpoint here. + ret_val = [mySource returnsStruct]; // Set fourth breakpoint here. + [mySource setProperty: 5]; // Set fifth breakpoint here. + + [pool release]; + return 0; + +} From johnny.chen at apple.com Thu Dec 9 18:51:23 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 10 Dec 2010 00:51:23 -0000 Subject: [Lldb-commits] [lldb] r121442 - in /lldb/trunk/test: dotest.py expression_command/test/TestExprs.py lldbtest.py Message-ID: <20101210005123.548812A6C12C@llvm.org> Author: johnny Date: Thu Dec 9 18:51:23 2010 New Revision: 121442 URL: http://llvm.org/viewvc/llvm-project?rev=121442&view=rev Log: Add an infrastructure to mark the Python APIs only test using a decorator. Example: @python_api_test def test_evaluate_expression_python(self): """Test SBFrame.EvaluateExpression() API for evaluating an expression.""" ... The opposite of Python APIs only test is an lldb command line test, which sends commands to the lldb command interpreter. Add a '-a' option to the test driver to skip Python API only tests. Modify TestExprs.py to mark a test as @python_api_test and remove an @expectedFailure decorator as the bug has been fixed. Modified: lldb/trunk/test/dotest.py lldb/trunk/test/expression_command/test/TestExprs.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=121442&r1=121441&r2=121442&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Thu Dec 9 18:51:23 2010 @@ -45,6 +45,14 @@ # The test suite. suite = unittest2.TestSuite() +# By default, both command line and Python API tests are performed. +# See @python_api_test decorator in lldbtest.py. +dont_do_python_api_test = False + +# By default, both command line and Python API tests are performed. +# This does not work yet as the @lldb_command_test decorator is needed. +just_do_python_api_test = False + # The blacklist is optional (-b blacklistFile) and allows a central place to skip # testclass's and/or testclass.testmethod's. blacklist = None @@ -113,6 +121,8 @@ Usage: dotest.py [option] [args] where options: -h : print this help message and exit (also --help) +-a : don't do lldb Python API tests + use @python_api_test to decorate a test case as lldb Python API test -b : read a blacklist file specified after this option -c : read a config file specified after this option (see also lldb-trunk/example/test/usage-config) @@ -231,6 +241,8 @@ '-h/--help as the first option prints out usage info and exit the program. """ + global dont_do_python_api_test + global just_do_python_api_test global blacklist global blacklistConfig global configFile @@ -253,12 +265,21 @@ # Process possible trace and/or verbose flag, among other things. index = 1 while index < len(sys.argv): - if not sys.argv[index].startswith('-'): + if sys.argv[index].startswith('-') or sys.argv[index].startswith('+'): + # We should continue processing... + pass + else: # End of option processing. break if sys.argv[index].find('-h') != -1: usage() + elif sys.argv[index].startswith('-a'): + dont_do_python_api_test = True + index += 1 + elif sys.argv[index].startswith('+a'): + just_do_python_api_test = True + index += 1 elif sys.argv[index].startswith('-b'): # Increment by 1 to fetch the blacklist file name option argument. index += 1 @@ -624,9 +645,13 @@ # Create a singleton SBDebugger in the lldb namespace. lldb.DBG = lldb.SBDebugger.Create() -# And put the blacklist in the lldb namespace, to be used by lldb.TestBase. +# Put the blacklist in the lldb namespace, to be used by lldb.TestBase. lldb.blacklist = blacklist +# Put dont/just_do_python_api_test in the lldb namespace, too. +lldb.dont_do_python_api_test = dont_do_python_api_test +lldb.just_do_python_api_test = just_do_python_api_test + # Turn on lldb loggings if necessary. lldbLoggings() Modified: lldb/trunk/test/expression_command/test/TestExprs.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/test/TestExprs.py?rev=121442&r1=121441&r2=121442&view=diff ============================================================================== --- lldb/trunk/test/expression_command/test/TestExprs.py (original) +++ lldb/trunk/test/expression_command/test/TestExprs.py Thu Dec 9 18:51:23 2010 @@ -78,7 +78,7 @@ os.path.join(self.mydir, "a.out")]) # (const char *) $8 = 0x... "/Volumes/data/lldb/svn/trunk/test/expression_command/test/a.out" - + @python_api_test def test_evaluate_expression_python(self): """These SBFrame.EvaluateExpression() API.""" self.buildDefault() @@ -161,8 +161,6 @@ startstr = "'Z'") self.DebugSBValue(frame, val) - - @unittest2.expectedFailure # rdar://problem/8686536 # CommandInterpreter::HandleCommand is stripping \'s from input for WantsRawCommand commands def test_expr_commands_can_handle_quotes(self): @@ -212,7 +210,9 @@ # output: self.runCmd(r'''command alias print_hi expression printf ("\n\tHi!\n")''') # This fails currently. - self.runCmd('print_hi') + self.expect('print_hi', + substrs = ['(unsigned long) $', + '6']) if __name__ == '__main__': Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=121442&r1=121441&r2=121442&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu Dec 9 18:51:23 2010 @@ -227,6 +227,16 @@ a_pointer = ctypes.c_void_p(0xffff) return 8 * ctypes.sizeof(a_pointer) +from functools import wraps +def python_api_test(func): + """Decorate the item as a Python API only test.""" + @wraps(func) + def wrapper(self, *args, **kwargs): + if lldb.dont_do_python_api_test: + self.skipTest("Skip Python API tests") + return func(self, *args, **kwargs) + + return wrapper class recording(StringIO.StringIO): """ From johnny.chen at apple.com Thu Dec 9 18:58:18 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 10 Dec 2010 00:58:18 -0000 Subject: [Lldb-commits] [lldb] r121446 - /lldb/trunk/test/expression_command/test/TestExprs.py Message-ID: <20101210005818.BCE682A6C12C@llvm.org> Author: johnny Date: Thu Dec 9 18:58:18 2010 New Revision: 121446 URL: http://llvm.org/viewvc/llvm-project?rev=121446&view=rev Log: Fix a test method docstring. Modified: lldb/trunk/test/expression_command/test/TestExprs.py Modified: lldb/trunk/test/expression_command/test/TestExprs.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/test/TestExprs.py?rev=121446&r1=121445&r2=121446&view=diff ============================================================================== --- lldb/trunk/test/expression_command/test/TestExprs.py (original) +++ lldb/trunk/test/expression_command/test/TestExprs.py Thu Dec 9 18:58:18 2010 @@ -80,7 +80,7 @@ @python_api_test def test_evaluate_expression_python(self): - """These SBFrame.EvaluateExpression() API.""" + """Test SBFrame.EvaluateExpression() API for evaluating an expression.""" self.buildDefault() exe = os.path.join(os.getcwd(), "a.out") From johnny.chen at apple.com Thu Dec 9 19:21:27 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 10 Dec 2010 01:21:27 -0000 Subject: [Lldb-commits] [lldb] r121448 - in /lldb/trunk/test: array_types/TestArrayTypes.py bitfields/TestBitfields.py breakpoint_conditions/TestBreakpointConditions.py class_static/TestStaticVariables.py class_types/TestClassTypes.py class_types/TestClassTypesDisassembly.py conditional_break/TestConditionalBreak.py foundation/TestSymbolTable.py hello_world/TestHelloWorld.py Message-ID: <20101210012127.CFD4F2A6C12D@llvm.org> Author: johnny Date: Thu Dec 9 19:21:27 2010 New Revision: 121448 URL: http://llvm.org/viewvc/llvm-project?rev=121448&view=rev Log: Add @python_api_test decorator to the remaining Test*.py files. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py lldb/trunk/test/class_static/TestStaticVariables.py lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/class_types/TestClassTypesDisassembly.py lldb/trunk/test/conditional_break/TestConditionalBreak.py lldb/trunk/test/foundation/TestSymbolTable.py lldb/trunk/test/hello_world/TestHelloWorld.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=121448&r1=121447&r2=121448&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Dec 9 19:21:27 2010 @@ -16,6 +16,7 @@ self.array_types() @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test def test_with_dsym_and_python_api(self): """Use Python APIs to inspect variables with array types.""" self.buildDsym() @@ -26,6 +27,7 @@ self.buildDwarf() self.array_types() + @python_api_test def test_with_dwarf_and_python_api(self): """Use Python APIs to inspect variables with array types.""" self.buildDwarf() Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=121448&r1=121447&r2=121448&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Thu Dec 9 19:21:27 2010 @@ -16,6 +16,7 @@ self.bitfields_variable() @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test def test_with_dsym_and_python_api(self): """Use Python APIs to inspect a bitfields variable.""" self.buildDsym() @@ -26,6 +27,7 @@ self.buildDwarf() self.bitfields_variable() + @python_api_test def test_with_dwarf_and_python_api(self): """Use Python APIs to inspect a bitfields variable.""" self.buildDwarf() @@ -92,11 +94,7 @@ breakpoint = target.BreakpointCreateByLocation("main.c", self.line) self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) - self.runCmd("run", RUN_SUCCEEDED, setCookie=False) - # This does not work, and results in the process stopped at dyld_start? - #process = target.LaunchProcess([], [], os.ctermid(), False) - - self.process = target.GetProcess() + self.process = target.LaunchProcess([], [], os.ctermid(), False, 0) self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) # The stop reason of the thread should be breakpoint. Modified: lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py?rev=121448&r1=121447&r2=121448&view=diff ============================================================================== --- lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py (original) +++ lldb/trunk/test/breakpoint_conditions/TestBreakpointConditions.py Thu Dec 9 19:21:27 2010 @@ -19,6 +19,7 @@ self.breakpoint_conditions() @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test def test_with_dsym_and_python_api(self): """Use Python APIs to set breakpoint conditions.""" self.buildDsym() @@ -29,6 +30,7 @@ self.buildDwarf() self.breakpoint_conditions() + @python_api_test def test_with_dwarf_and_python_api(self): """Use Python APIs to set breakpoint conditions.""" self.buildDwarf() Modified: lldb/trunk/test/class_static/TestStaticVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_static/TestStaticVariables.py?rev=121448&r1=121447&r2=121448&view=diff ============================================================================== --- lldb/trunk/test/class_static/TestStaticVariables.py (original) +++ lldb/trunk/test/class_static/TestStaticVariables.py Thu Dec 9 19:21:27 2010 @@ -23,11 +23,13 @@ self.static_variable_commands() @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test def test_with_dsym_and_python_api(self): """Test Python APIs on file and class static variables.""" self.buildDsym() self.static_variable_python() + @python_api_test def test_with_dwarf_and_python_api(self): """Test Python APIs on file and class static variables.""" self.buildDwarf() Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=121448&r1=121447&r2=121448&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Thu Dec 9 19:21:27 2010 @@ -17,6 +17,7 @@ self.class_types() @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test def test_with_dsym_and_python_api(self): """Use Python APIs to create a breakpoint by (filespec, line).""" self.buildDsym() @@ -30,6 +31,7 @@ self.buildDwarf() self.class_types() + @python_api_test def test_with_dwarf_and_python_api(self): """Use Python APIs to create a breakpoint by (filespec, line).""" self.buildDwarf() Modified: lldb/trunk/test/class_types/TestClassTypesDisassembly.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypesDisassembly.py?rev=121448&r1=121447&r2=121448&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypesDisassembly.py (original) +++ lldb/trunk/test/class_types/TestClassTypesDisassembly.py Thu Dec 9 19:21:27 2010 @@ -23,15 +23,17 @@ self.disassemble_call_stack() @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test def test_with_dsym_and_python_api(self): """Disassemble each call frame when stopped on C's constructor.""" self.buildDsym() - self.disassemble_call_stack_api() + self.disassemble_call_stack_python() + @python_api_test def test_with_dwarf_and_python_api(self): """Disassemble each call frame when stopped on C's constructor.""" self.buildDwarf() - self.disassemble_call_stack_api() + self.disassemble_call_stack_python() def setUp(self): # Call super's setUp(). @@ -81,7 +83,7 @@ #print "function:", function self.runCmd("disassemble -n '%s'" % function) - def disassemble_call_stack_api(self): + def disassemble_call_stack_python(self): """Disassemble each call frame when stopped on C's constructor.""" self.breakOnCtor() Modified: lldb/trunk/test/conditional_break/TestConditionalBreak.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/conditional_break/TestConditionalBreak.py?rev=121448&r1=121447&r2=121448&view=diff ============================================================================== --- lldb/trunk/test/conditional_break/TestConditionalBreak.py (original) +++ lldb/trunk/test/conditional_break/TestConditionalBreak.py Thu Dec 9 19:21:27 2010 @@ -18,11 +18,13 @@ mydir = "conditional_break" @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test def test_with_dsym_python(self): """Exercise some thread and frame APIs to break if c() is called by a().""" self.buildDsym() self.do_conditional_break() + @python_api_test def test_with_dwarf_python(self): """Exercise some thread and frame APIs to break if c() is called by a().""" self.buildDwarf() Modified: lldb/trunk/test/foundation/TestSymbolTable.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/foundation/TestSymbolTable.py?rev=121448&r1=121447&r2=121448&view=diff ============================================================================== --- lldb/trunk/test/foundation/TestSymbolTable.py (original) +++ lldb/trunk/test/foundation/TestSymbolTable.py Thu Dec 9 19:21:27 2010 @@ -24,11 +24,13 @@ 'main' ] + @python_api_test def test_with_dsym_and_python_api(self): """Test symbol table access with Python APIs.""" self.buildDsym() self.symtab_access_python() + @python_api_test def test_with_dwarf_and_python_api(self): """Test symbol table access with Python APIs.""" self.buildDwarf() Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=121448&r1=121447&r2=121448&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Thu Dec 9 19:21:27 2010 @@ -18,6 +18,7 @@ self.buildDsym() self.hello_world_python(useLaunchAPI = False) + @python_api_test def test_with_dwarf_and_process_launch_api(self): """Create target, breakpoint, launch a process, and then kill it. From scallanan at apple.com Thu Dec 9 20:15:55 2010 From: scallanan at apple.com (Sean Callanan) Date: Fri, 10 Dec 2010 02:15:55 -0000 Subject: [Lldb-commits] [lldb] r121456 - /lldb/trunk/source/Symbol/ClangASTContext.cpp Message-ID: <20101210021555.99E2D2A6C12C@llvm.org> Author: spyffe Date: Thu Dec 9 20:15:55 2010 New Revision: 121456 URL: http://llvm.org/viewvc/llvm-project?rev=121456&view=rev Log: Fixed detection of overloaded operators in type information. Previously, "operator[]" was not being recognized because the detector was looking for "operator " as a prefix. Now we handle both cases. Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=121456&r1=121455&r2=121456&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Dec 9 20:15:55 2010 @@ -908,18 +908,42 @@ if (name == NULL || name[0] == '\0') return false; - if (::strstr(name, "operator ") != name) +#define OPERATOR_SPACE_PREFIX "operator " +#define OPERATOR_NOSPACE_PREFIX "operator" + + const char *post_op_name = NULL; + + bool no_space = false; + + if (!::strncmp(name, OPERATOR_SPACE_PREFIX, sizeof(OPERATOR_SPACE_PREFIX) - 1)) + { + post_op_name = name + sizeof(OPERATOR_SPACE_PREFIX) - 1; + } + else if (!::strncmp(name, OPERATOR_NOSPACE_PREFIX, sizeof(OPERATOR_NOSPACE_PREFIX) - 1)) + { + post_op_name = name + sizeof(OPERATOR_NOSPACE_PREFIX) - 1; + no_space = true; + } + +#undef OPERATOR_SPACE_PREFIX +#undef OPERATOR_NOSPACE_PREFIX + + if (!post_op_name) return false; - const char *post_op_name = name + 9; - // This is an operator, set the overloaded operator kind to invalid // in case this is a conversion operator... op_kind = NUM_OVERLOADED_OPERATORS; switch (post_op_name[0]) { + default: + if (no_space) + return false; + break; case 'n': + if (no_space) + return false; if (strcmp (post_op_name, "new") == 0) op_kind = OO_New; else if (strcmp (post_op_name, "new[]") == 0) @@ -927,6 +951,8 @@ break; case 'd': + if (no_space) + return false; if (strcmp (post_op_name, "delete") == 0) op_kind = OO_Delete; else if (strcmp (post_op_name, "delete[]") == 0) From jingham at apple.com Thu Dec 9 20:33:02 2010 From: jingham at apple.com (Jim Ingham) Date: Fri, 10 Dec 2010 02:33:02 -0000 Subject: [Lldb-commits] [lldb] r121457 - in /lldb/trunk/test/objc-stepping: Makefile TestObjCStepping.py stepping-tests.m Message-ID: <20101210023303.0112E2A6C12C@llvm.org> Author: jingham Date: Thu Dec 9 20:33:02 2010 New Revision: 121457 URL: http://llvm.org/viewvc/llvm-project?rev=121457&view=rev Log: Added some tests for ObjC stepping, step into ordinary and stret methods, and stepping through a KVO swizzled object's method calls. Added: lldb/trunk/test/objc-stepping/Makefile lldb/trunk/test/objc-stepping/TestObjCStepping.py Modified: lldb/trunk/test/objc-stepping/stepping-tests.m Added: lldb/trunk/test/objc-stepping/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-stepping/Makefile?rev=121457&view=auto ============================================================================== --- lldb/trunk/test/objc-stepping/Makefile (added) +++ lldb/trunk/test/objc-stepping/Makefile Thu Dec 9 20:33:02 2010 @@ -0,0 +1,6 @@ +LEVEL = ../make + +OBJC_SOURCES := stepping-tests.m +LDFLAGS = $(CFLAGS) -lobjc -framework Foundation + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/objc-stepping/TestObjCStepping.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-stepping/TestObjCStepping.py?rev=121457&view=auto ============================================================================== --- lldb/trunk/test/objc-stepping/TestObjCStepping.py (added) +++ lldb/trunk/test/objc-stepping/TestObjCStepping.py Thu Dec 9 20:33:02 2010 @@ -0,0 +1,160 @@ +"""Test stepping through ObjC method dispatch in various forms.""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class TestObjCStepping(TestBase): + + mydir = "objc-stepping" + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_run_command(self): + """Test 'frame variable var_name' on some variables with array types.""" + self.buildDsym() + self.objc_stepping() + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym_and_python_api(self): + """Use Python APIs to inspect variables with array types.""" + self.buildDsym() + self.objc_stepping() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "stepping-tests.m" + self.line1 = line_number(self.main_source, '// Set first breakpoint here.') + self.line2 = line_number(self.main_source, '// Set second breakpoint here.') + self.line3 = line_number(self.main_source, '// Set third breakpoint here.') + self.line4 = line_number(self.main_source, '// Set fourth breakpoint here.') + self.line5 = line_number(self.main_source, '// Set fifth breakpoint here.') + self.source_randomMethod_line = line_number (self.main_source, '// Source randomMethod start line.') + self.sourceBase_randomMethod_line = line_number (self.main_source, '// SourceBase randomMethod start line.') + self.source_returnsStruct_start_line = line_number (self.main_source, '// Source returnsStruct start line.') + self.source_returnsStruct_call_line = line_number (self.main_source, '// Source returnsStruct call line.') + self.sourceBase_returnsStruct_start_line = line_number (self.main_source, '// SourceBase returnsStruct start line.') + + def objc_stepping(self): + """Use Python APIs to test stepping into ObjC methods.""" + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + break1 = target.BreakpointCreateByLocation(self.main_source, self.line1) + self.assertTrue(break1.IsValid(), VALID_BREAKPOINT) + + break2 = target.BreakpointCreateByLocation(self.main_source, self.line2) + self.assertTrue(break2.IsValid(), VALID_BREAKPOINT) + + break3 = target.BreakpointCreateByLocation(self.main_source, self.line3) + self.assertTrue(break3.IsValid(), VALID_BREAKPOINT) + + break4 = target.BreakpointCreateByLocation(self.main_source, self.line4) + self.assertTrue(break4.IsValid(), VALID_BREAKPOINT) + + break5 = target.BreakpointCreateByLocation(self.main_source, self.line5) + self.assertTrue(break5.IsValid(), VALID_BREAKPOINT) + + break_returnStruct_call_super = target.BreakpointCreateByLocation(self.main_source, self.source_returnsStruct_call_line) + self.assertTrue(break_returnStruct_call_super.IsValid(), VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + self.process = target.LaunchProcess([], [], os.ctermid(), 0, False) + + self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread = self.process.GetThreadAtIndex(0) + if thread.GetStopReason() != lldb.eStopReasonBreakpoint: + from lldbutil import StopReasonString + self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % + StopReasonString(thread.GetStopReason())) + + # Make sure we stopped at the first breakpoint. + + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.line1, "Hit the first breakpoint.") + + mySource = thread.GetFrameAtIndex(0).LookupVar("mySource") + self.assertTrue(mySource.IsValid(), "Found mySource local variable.") + mySource_isa = mySource.GetChildMemberWithName ("isa") + self.assertTrue(mySource_isa.IsValid(), "Found mySource->isa local variable.") + mySource_isa.GetValue (thread.GetFrameAtIndex(0)) + + # Now step in, that should leave us in the Source randomMethod: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.source_randomMethod_line, "Stepped into Source randomMethod.") + + # Now step in again, through the super call, and that should leave us in the SourceBase randomMethod: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod.") + + self.process.Continue() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.line2, "Continued to second breakpoint in main.") + + # Again, step in twice gets us to a stret method and a stret super call: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct.") + + self.process.Continue() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.source_returnsStruct_call_line, "Stepped to the call super line in Source returnsStruct.") + + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.sourceBase_returnsStruct_start_line, "Stepped through super into SourceBase returnsStruct.") + + # Cool now continue to get past the call that intializes the Observer, and then do our steps in again to see that + # we can find our way when we're stepping through a KVO swizzled object. + + self.process.Continue() + frame = thread.GetFrameAtIndex(0) + line_number = frame.GetLineEntry().GetLine() + self.assertTrue (line_number == self.line3, "Continued to third breakpoint in main, our object should now be swizzled.") + + mySource_isa.GetValue (frame) + did_change = mySource_isa.GetValueDidChange (frame) + + self.assertTrue (did_change, "The isa did indeed change, swizzled!") + + # Now step in, that should leave us in the Source randomMethod: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.source_randomMethod_line, "Stepped into Source randomMethod in swizzled object.") + + # Now step in again, through the super call, and that should leave us in the SourceBase randomMethod: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod in swizzled object.") + + self.process.Continue() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.line4, "Continued to fourth breakpoint in main.") + + # Again, step in twice gets us to a stret method and a stret super call: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct in swizzled object.") + + self.process.Continue() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.source_returnsStruct_call_line, "Stepped to the call super line in Source returnsStruct - second time.") + + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue (line_number == self.sourceBase_returnsStruct_start_line, "Stepped through super into SourceBase returnsStruct in swizzled object.") + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Modified: lldb/trunk/test/objc-stepping/stepping-tests.m URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-stepping/stepping-tests.m?rev=121457&r1=121456&r2=121457&view=diff ============================================================================== --- lldb/trunk/test/objc-stepping/stepping-tests.m (original) +++ lldb/trunk/test/objc-stepping/stepping-tests.m Thu Dec 9 20:33:02 2010 @@ -19,12 +19,12 @@ @implementation SourceBase - (void) randomMethod { - printf ("Called in SourceBase version of randomMethod.\n"); + printf ("Called in SourceBase version of randomMethod.\n"); // SourceBase randomMethod start line. } - (struct return_me) returnsStruct { - return my_return; + return my_return; // SourceBase returnsStruct start line. } - (SourceBase *) initWithFirst: (int) first andSecond: (int) second @@ -53,14 +53,14 @@ - (void) randomMethod { - [super randomMethod]; + [super randomMethod]; // Source randomMethod start line. printf ("Called in Source version of random method."); } - (struct return_me) returnsStruct { - printf ("Called in Source version of returnsStruct.\n"); - return [super returnsStruct]; + printf ("Called in Source version of returnsStruct.\n"); // Source returnsStruct start line. + return [super returnsStruct]; // Source returnsStruct call line. } @end From johnny.chen at apple.com Fri Dec 10 11:15:34 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 10 Dec 2010 17:15:34 -0000 Subject: [Lldb-commits] [lldb] r121494 - /lldb/trunk/test/objc-stepping/TestObjCStepping.py Message-ID: <20101210171534.8332A2A6C12C@llvm.org> Author: johnny Date: Fri Dec 10 11:15:34 2010 New Revision: 121494 URL: http://llvm.org/viewvc/llvm-project?rev=121494&view=rev Log: Fix some typo in method names and docstrings. Modified: lldb/trunk/test/objc-stepping/TestObjCStepping.py Modified: lldb/trunk/test/objc-stepping/TestObjCStepping.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-stepping/TestObjCStepping.py?rev=121494&r1=121493&r2=121494&view=diff ============================================================================== --- lldb/trunk/test/objc-stepping/TestObjCStepping.py (original) +++ lldb/trunk/test/objc-stepping/TestObjCStepping.py Fri Dec 10 11:15:34 2010 @@ -10,15 +10,14 @@ mydir = "objc-stepping" @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") - def test_with_dsym_and_run_command(self): - """Test 'frame variable var_name' on some variables with array types.""" + def test_with_dsym_and_python_api(self): + """Test stepping through ObjC method dispatch in various forms.""" self.buildDsym() self.objc_stepping() - @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") - def test_with_dsym_and_python_api(self): - """Use Python APIs to inspect variables with array types.""" - self.buildDsym() + def test_with_dward_and_python_api(self): + """Test stepping through ObjC method dispatch in various forms.""" + self.buildDwarf() self.objc_stepping() def setUp(self): From johnny.chen at apple.com Fri Dec 10 12:42:07 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 10 Dec 2010 18:42:07 -0000 Subject: [Lldb-commits] [lldb] r121499 - /lldb/trunk/test/objc-stepping/TestObjCStepping.py Message-ID: <20101210184207.52F302A6C12C@llvm.org> Author: johnny Date: Fri Dec 10 12:42:07 2010 New Revision: 121499 URL: http://llvm.org/viewvc/llvm-project?rev=121499&view=rev Log: Add the @python_api_test decorator for two test cases. Modified: lldb/trunk/test/objc-stepping/TestObjCStepping.py Modified: lldb/trunk/test/objc-stepping/TestObjCStepping.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/objc-stepping/TestObjCStepping.py?rev=121499&r1=121498&r2=121499&view=diff ============================================================================== --- lldb/trunk/test/objc-stepping/TestObjCStepping.py (original) +++ lldb/trunk/test/objc-stepping/TestObjCStepping.py Fri Dec 10 12:42:07 2010 @@ -10,11 +10,13 @@ mydir = "objc-stepping" @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test def test_with_dsym_and_python_api(self): """Test stepping through ObjC method dispatch in various forms.""" self.buildDsym() self.objc_stepping() + @python_api_test def test_with_dward_and_python_api(self): """Test stepping through ObjC method dispatch in various forms.""" self.buildDwarf() From johnny.chen at apple.com Fri Dec 10 12:52:10 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 10 Dec 2010 18:52:10 -0000 Subject: [Lldb-commits] [lldb] r121500 - in /lldb/trunk/test: dotest.py lldbtest.py Message-ID: <20101210185210.9DDA72A6C12C@llvm.org> Author: johnny Date: Fri Dec 10 12:52:10 2010 New Revision: 121500 URL: http://llvm.org/viewvc/llvm-project?rev=121500&view=rev Log: Add a '+a' command line option to the test driver to run only the Python API tests. Add an attribute __python_api_test__ (set to True) to the @python_api_test decorated test method to distinguish them from the lldb command line tests. Modified: lldb/trunk/test/dotest.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=121500&r1=121499&r2=121500&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Fri Dec 10 12:52:10 2010 @@ -46,11 +46,11 @@ suite = unittest2.TestSuite() # By default, both command line and Python API tests are performed. -# See @python_api_test decorator in lldbtest.py. +# Use @python_api_test decorator, defined in lldbtest.py, to mark a test as +# a Python API test. dont_do_python_api_test = False # By default, both command line and Python API tests are performed. -# This does not work yet as the @lldb_command_test decorator is needed. just_do_python_api_test = False # The blacklist is optional (-b blacklistFile) and allows a central place to skip @@ -123,6 +123,7 @@ -h : print this help message and exit (also --help) -a : don't do lldb Python API tests use @python_api_test to decorate a test case as lldb Python API test ++a : just do lldb Python API tests -b : read a blacklist file specified after this option -c : read a config file specified after this option (see also lldb-trunk/example/test/usage-config) Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=121500&r1=121499&r2=121500&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Dec 10 12:52:10 2010 @@ -236,6 +236,8 @@ self.skipTest("Skip Python API tests") return func(self, *args, **kwargs) + # Mark this function as such to separate them from lldb command line tests. + wrapper.__python_api_test__ = True return wrapper class recording(StringIO.StringIO): @@ -477,6 +479,16 @@ elif classAndMethodName in lldb.blacklist: self.skipTest(lldb.blacklist.get(classAndMethodName)) + # Python API only test is decorated with @python_api_test, + # which also sets the "__python_api_test__" attribute of the + # function object to True. + if lldb.just_do_python_api_test: + testMethod = getattr(self, self._testMethodName) + if getattr(testMethod, "__python_api_test__", False): + pass + else: + self.skipTest("Skip lldb command line test") + if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] == 'YES'): waitTime = 1.0 From johnny.chen at apple.com Fri Dec 10 13:02:23 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 10 Dec 2010 19:02:23 -0000 Subject: [Lldb-commits] [lldb] r121501 - /lldb/trunk/test/dotest.py Message-ID: <20101210190223.D5B132A6C12D@llvm.org> Author: johnny Date: Fri Dec 10 13:02:23 2010 New Revision: 121501 URL: http://llvm.org/viewvc/llvm-project?rev=121501&view=rev Log: Do not specify both '-a' and '+a' at the same time. Modified: lldb/trunk/test/dotest.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=121501&r1=121500&r2=121501&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Fri Dec 10 13:02:23 2010 @@ -124,6 +124,7 @@ -a : don't do lldb Python API tests use @python_api_test to decorate a test case as lldb Python API test +a : just do lldb Python API tests + do not specify both '-a' and '+a' at the same time -b : read a blacklist file specified after this option -c : read a config file specified after this option (see also lldb-trunk/example/test/usage-config) @@ -370,6 +371,10 @@ print "Unknown option: ", sys.argv[index] usage() + # Do not specify both '-a' and '+a' at the same time. + if dont_do_python_api_test and just_do_python_api_test: + usage() + # Gather all the dirs passed on the command line. if len(sys.argv) > index: testdirs = map(os.path.abspath, sys.argv[index:]) From scallanan at apple.com Fri Dec 10 13:51:54 2010 From: scallanan at apple.com (Sean Callanan) Date: Fri, 10 Dec 2010 19:51:54 -0000 Subject: [Lldb-commits] [lldb] r121511 - /lldb/trunk/source/Symbol/ClangASTContext.cpp Message-ID: <20101210195154.D80BA2A6C12C@llvm.org> Author: spyffe Date: Fri Dec 10 13:51:54 2010 New Revision: 121511 URL: http://llvm.org/viewvc/llvm-project?rev=121511&view=rev Log: Simplified the code that handles overloaded operator names. Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=121511&r1=121510&r2=121511&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Dec 10 13:51:54 2010 @@ -908,28 +908,24 @@ if (name == NULL || name[0] == '\0') return false; -#define OPERATOR_SPACE_PREFIX "operator " -#define OPERATOR_NOSPACE_PREFIX "operator" +#define OPERATOR_PREFIX "operator" const char *post_op_name = NULL; - bool no_space = false; + bool no_space = true; - if (!::strncmp(name, OPERATOR_SPACE_PREFIX, sizeof(OPERATOR_SPACE_PREFIX) - 1)) - { - post_op_name = name + sizeof(OPERATOR_SPACE_PREFIX) - 1; - } - else if (!::strncmp(name, OPERATOR_NOSPACE_PREFIX, sizeof(OPERATOR_NOSPACE_PREFIX) - 1)) + if (!::strncmp(name, OPERATOR_PREFIX, sizeof(OPERATOR_PREFIX) - 1)) + post_op_name = name + sizeof(OPERATOR_PREFIX) - 1; + else + return false; + + if (post_op_name[0] == ' ') { - post_op_name = name + sizeof(OPERATOR_NOSPACE_PREFIX) - 1; - no_space = true; + post_op_name++; + no_space = false; } -#undef OPERATOR_SPACE_PREFIX -#undef OPERATOR_NOSPACE_PREFIX - - if (!post_op_name) - return false; +#undef OPERATOR_PREFIX // This is an operator, set the overloaded operator kind to invalid // in case this is a conversion operator... From johnny.chen at apple.com Fri Dec 10 15:33:31 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 10 Dec 2010 21:33:31 -0000 Subject: [Lldb-commits] [lldb] r121538 - /lldb/trunk/test/lldbtest.py Message-ID: <20101210213331.A3D142A6C12C@llvm.org> Author: johnny Date: Fri Dec 10 15:33:31 2010 New Revision: 121538 URL: http://llvm.org/viewvc/llvm-project?rev=121538&view=rev Log: Make sure that @python_api_test is only used to decorate a test method, not the test class. Modified: lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=121538&r1=121537&r2=121538&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Dec 10 15:33:31 2010 @@ -230,6 +230,8 @@ from functools import wraps def python_api_test(func): """Decorate the item as a Python API only test.""" + if isinstance(func, type) and issubclass(func, unittest2.TestCase): + raise Exception("@python_api_test can only be used to decorate a test method") @wraps(func) def wrapper(self, *args, **kwargs): if lldb.dont_do_python_api_test: From scallanan at apple.com Fri Dec 10 18:08:56 2010 From: scallanan at apple.com (Sean Callanan) Date: Sat, 11 Dec 2010 00:08:56 -0000 Subject: [Lldb-commits] [lldb] r121601 - in /lldb/trunk: include/lldb/Core/ClangForward.h include/lldb/Symbol/ClangASTContext.h source/Symbol/ClangASTContext.cpp Message-ID: <20101211000856.B0A532A6C12C@llvm.org> Author: spyffe Date: Fri Dec 10 18:08:56 2010 New Revision: 121601 URL: http://llvm.org/viewvc/llvm-project?rev=121601&view=rev Log: Made all LLDB-generated ASTContexts have valid DiagnosticClients, and removed code that was patching over the original problem. Modified: lldb/trunk/include/lldb/Core/ClangForward.h lldb/trunk/include/lldb/Symbol/ClangASTContext.h lldb/trunk/source/Symbol/ClangASTContext.cpp Modified: lldb/trunk/include/lldb/Core/ClangForward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ClangForward.h?rev=121601&r1=121600&r2=121601&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ClangForward.h (original) +++ lldb/trunk/include/lldb/Core/ClangForward.h Fri Dec 10 18:08:56 2010 @@ -51,6 +51,7 @@ class DeclStmt; class DependencyOutputOptions; class Diagnostic; + class DiagnosticClient; class DiagnosticOptions; class EnumDecl; class Expr; Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=121601&r1=121600&r2=121601&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Fri Dec 10 18:08:56 2010 @@ -80,6 +80,9 @@ clang::Diagnostic * getDiagnostic(); + + clang::DiagnosticClient * + getDiagnosticClient(); clang::TargetOptions * getTargetOptions(); @@ -614,6 +617,7 @@ std::auto_ptr m_file_system_options_ap; std::auto_ptr m_source_manager_ap; std::auto_ptr m_diagnostic_ap; + std::auto_ptr m_diagnostic_client_ap; std::auto_ptr m_target_options_ap; std::auto_ptr m_target_info_ap; std::auto_ptr m_identifier_table_ap; Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=121601&r1=121600&r2=121601&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Dec 10 18:08:56 2010 @@ -312,6 +312,8 @@ *getSelectorTable(), *getBuiltinContext(), 0)); + + m_ast_context_ap->getDiagnostics().setClient(getDiagnosticClient(), false); } return m_ast_context_ap.get(); } @@ -382,6 +384,37 @@ return m_diagnostic_ap.get(); } +class NullDiagnosticClient : public DiagnosticClient +{ +public: + NullDiagnosticClient () + { + m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + } + + void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info) + { + if (m_log) + { + llvm::SmallVectorImpl diag_str(10); + info.FormatDiagnostic(diag_str); + diag_str.push_back('\0'); + m_log->Printf("Compiler diagnostic: %s\n", diag_str.data()); + } + } +private: + LogSP m_log; +}; + +DiagnosticClient * +ClangASTContext::getDiagnosticClient() +{ + if (m_diagnostic_client_ap.get() == NULL) + m_diagnostic_client_ap.reset(new NullDiagnosticClient); + + return m_diagnostic_client_ap.get(); +} + TargetOptions * ClangASTContext::getTargetOptions() { @@ -720,52 +753,11 @@ return void_ptr_type.getAsOpaquePtr(); } -class NullDiagnosticClient : public DiagnosticClient -{ -public: - NullDiagnosticClient () - { - m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - } - - void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info) - { - if (m_log) - { - llvm::SmallVectorImpl diag_str(10); - info.FormatDiagnostic(diag_str); - diag_str.push_back('\0'); - m_log->Printf("Compiler diagnostic: %s\n", diag_str.data()); - } - } -private: - LogSP m_log; -}; - clang_type_t ClangASTContext::CopyType (ASTContext *dst_ast, ASTContext *src_ast, clang_type_t clang_type) { - // we temporarily install diagnostic clients as needed to ensure that - // errors are properly handled - - std::auto_ptr diag_client; - - bool dst_needs_diag = !dst_ast->getDiagnostics().getClient(); - bool src_needs_diag = !src_ast->getDiagnostics().getClient(); - - if (dst_needs_diag || src_needs_diag) - { - diag_client.reset(new NullDiagnosticClient); - - if (dst_needs_diag) - dst_ast->getDiagnostics().setClient(diag_client.get(), false); - - if (src_needs_diag) - src_ast->getDiagnostics().setClient(diag_client.get(), false); - } - FileSystemOptions file_system_options; FileManager file_manager (file_system_options); ASTImporter importer(*dst_ast, file_manager, @@ -774,12 +766,6 @@ QualType src (QualType::getFromOpaquePtr(clang_type)); QualType dst (importer.Import(src)); - if (dst_needs_diag) - dst_ast->getDiagnostics().setClient(NULL, false); - - if (src_needs_diag) - src_ast->getDiagnostics().setClient(NULL, false); - return dst.getAsOpaquePtr(); } @@ -788,37 +774,12 @@ ClangASTContext::CopyDecl (ASTContext *dst_ast, ASTContext *src_ast, clang::Decl *source_decl) -{ - // we temporarily install diagnostic clients as needed to ensure that - // errors are properly handled - - std::auto_ptr diag_client; - - bool dst_needs_diag = !dst_ast->getDiagnostics().getClient(); - bool src_needs_diag = !src_ast->getDiagnostics().getClient(); - - if (dst_needs_diag || src_needs_diag) - { - diag_client.reset(new NullDiagnosticClient); - - if (dst_needs_diag) - dst_ast->getDiagnostics().setClient(diag_client.get(), false); - - if (src_needs_diag) - src_ast->getDiagnostics().setClient(diag_client.get(), false); - } - +{ FileSystemOptions file_system_options; FileManager file_manager (file_system_options); ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager); - if (dst_needs_diag) - dst_ast->getDiagnostics().setClient(NULL, false); - - if (src_needs_diag) - src_ast->getDiagnostics().setClient(NULL, false); - return importer.Import(source_decl); } From johnny.chen at apple.com Fri Dec 10 19:20:39 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Sat, 11 Dec 2010 01:20:39 -0000 Subject: [Lldb-commits] [lldb] r121605 - in /lldb/trunk: include/lldb/API/SBSourceManager.h include/lldb/API/SBStream.h source/API/SBSourceManager.cpp source/API/SBStream.cpp test/source-manager/TestSourceManager.py Message-ID: <20101211012039.3BB4F2A6C12C@llvm.org> Author: johnny Date: Fri Dec 10 19:20:39 2010 New Revision: 121605 URL: http://llvm.org/viewvc/llvm-project?rev=121605&view=rev Log: Add test_display_source_python() test case to TestSourceManager.py which uses the lldb PyThon API SBSourceManager to display source files. To accomodate this, the C++ SBSourceManager API has been changed to take an lldb::SBStream as the destination for display of source lines. Modify SBStream::ctor() so that its opaque pointer is initialized with an StreamString instance. Modified: lldb/trunk/include/lldb/API/SBSourceManager.h lldb/trunk/include/lldb/API/SBStream.h lldb/trunk/source/API/SBSourceManager.cpp lldb/trunk/source/API/SBStream.cpp lldb/trunk/test/source-manager/TestSourceManager.py Modified: lldb/trunk/include/lldb/API/SBSourceManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBSourceManager.h?rev=121605&r1=121604&r2=121605&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBSourceManager.h (original) +++ lldb/trunk/include/lldb/API/SBSourceManager.h Fri Dec 10 19:20:39 2010 @@ -34,7 +34,7 @@ uint32_t context_before, uint32_t context_after, const char* current_line_cstr, - FILE *f); + lldb::SBStream &s); protected: Modified: lldb/trunk/include/lldb/API/SBStream.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBStream.h?rev=121605&r1=121604&r2=121605&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBStream.h (original) +++ lldb/trunk/include/lldb/API/SBStream.h Fri Dec 10 19:20:39 2010 @@ -66,6 +66,7 @@ friend class SBInstruction; friend class SBInstructionList; friend class SBModule; + friend class SBSourceManager; friend class SBSymbol; friend class SBSymbolContext; friend class SBTarget; Modified: lldb/trunk/source/API/SBSourceManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBSourceManager.cpp?rev=121605&r1=121604&r2=121605&view=diff ============================================================================== --- lldb/trunk/source/API/SBSourceManager.cpp (original) +++ lldb/trunk/source/API/SBSourceManager.cpp Fri Dec 10 19:20:39 2010 @@ -9,6 +9,7 @@ #include "lldb/API/SBSourceManager.h" +#include "lldb/API/SBStream.h" #include "lldb/API/SBFileSpec.h" #include "lldb/Core/Stream.h" @@ -49,26 +50,23 @@ uint32_t context_before, uint32_t context_after, const char* current_line_cstr, - FILE *f + SBStream &s ) { if (m_opaque_ptr == NULL) return 0; - if (f == NULL) + if (s.m_opaque_ap.get() == NULL) return 0; if (file.IsValid()) { - StreamFile str (f); - - return m_opaque_ptr->DisplaySourceLinesWithLineNumbers (*file, line, context_before, context_after, current_line_cstr, - &str); + s.m_opaque_ap.get()); } return 0; } Modified: lldb/trunk/source/API/SBStream.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBStream.cpp?rev=121605&r1=121604&r2=121605&view=diff ============================================================================== --- lldb/trunk/source/API/SBStream.cpp (original) +++ lldb/trunk/source/API/SBStream.cpp Fri Dec 10 19:20:39 2010 @@ -17,7 +17,7 @@ using namespace lldb_private; SBStream::SBStream () : - m_opaque_ap (), + m_opaque_ap (new StreamString()), m_is_file (false) { } Modified: lldb/trunk/test/source-manager/TestSourceManager.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/source-manager/TestSourceManager.py?rev=121605&r1=121604&r2=121605&view=diff ============================================================================== --- lldb/trunk/test/source-manager/TestSourceManager.py (original) +++ lldb/trunk/test/source-manager/TestSourceManager.py Fri Dec 10 19:20:39 2010 @@ -3,6 +3,8 @@ Test cases: +o test_display_source_python: + Test display of source using the SBSourceManager API. o test_modify_source_file_while_debugging: Test the caching mechanism of the source manager. """ @@ -21,11 +23,53 @@ # Find the line number to break inside main(). self.line = line_number('main.c', '// Set break point at this line.') + @python_api_test + def test_display_source_python(self): + """Test display of source using the SBSourceManager API.""" + self.buildDefault() + self.display_source_python() + def test_modify_source_file_while_debugging(self): """Modify a source file while debugging the executable.""" self.buildDefault() self.modify_source_file_while_debugging() + def display_source_python(self): + """Display source using the SBSourceManager API.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchProcess([], [], os.ctermid(), 0, False) + + # + # Exercise Python APIs to display source lines. + # + + # Create the filespec for 'main.c'. + filespec = lldb.SBFileSpec('main.c', False) + source_mgr = self.dbg.GetSourceManager() + # Use a string stream as the destination. + stream = lldb.SBStream() + source_mgr.DisplaySourceLinesWithLineNumbers(filespec, + self.line, + 2, # context before + 2, # context after + "=>", # prefix for current line + stream) + + # 2 + # 3 int main(int argc, char const *argv[]) { + # 4 => printf("Hello world.\n"); // Set break point at this line. + # 5 return 0; + # 6 } + self.expect(stream.GetData(), "Source code displayed correctly", + exe=False, + patterns = ['=>.*Hello world']) + def modify_source_file_while_debugging(self): """Modify a source file while debugging the executable.""" exe = os.path.join(os.getcwd(), "a.out") From ctice at apple.com Sat Dec 11 02:16:56 2010 From: ctice at apple.com (Caroline Tice) Date: Sat, 11 Dec 2010 08:16:56 -0000 Subject: [Lldb-commits] [lldb] r121607 - /lldb/trunk/source/Interpreter/CommandInterpreter.cpp Message-ID: <20101211081656.C95F12A6C12C@llvm.org> Author: ctice Date: Sat Dec 11 02:16:56 2010 New Revision: 121607 URL: http://llvm.org/viewvc/llvm-project?rev=121607&view=rev Log: Fix bug where using incomplete strings for command names causes lldb to crash (because of attempt to look for full names when full names were not used). Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=121607&r1=121606&r2=121607&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Sat Dec 11 02:16:56 2010 @@ -710,6 +710,7 @@ // replacements taken care of; 3). whether or not the Execute function wants raw input or not. StreamString revised_command_line; + size_t actual_cmd_name_len = 0; while (!done) { StripFirstWord (command_string, next_word); @@ -720,12 +721,14 @@ revised_command_line.Printf ("%s", alias_result.c_str()); if (cmd_obj) wants_raw_input = cmd_obj->WantsRawCommandString (); + actual_cmd_name_len = strlen (cmd_obj->GetCommandName()); } else if (!cmd_obj) { cmd_obj = GetCommandObject (next_word.c_str()); if (cmd_obj) { + actual_cmd_name_len += next_word.length(); revised_command_line.Printf ("%s", next_word.c_str()); wants_raw_input = cmd_obj->WantsRawCommandString (); } @@ -739,6 +742,7 @@ CommandObject *sub_cmd_obj = ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (next_word.c_str()); if (sub_cmd_obj) { + actual_cmd_name_len += next_word.length() + 1; revised_command_line.Printf (" %s", next_word.c_str()); cmd_obj = sub_cmd_obj; wants_raw_input = cmd_obj->WantsRawCommandString (); @@ -805,7 +809,12 @@ command_string = revised_command_line.GetData(); std::string command_name (cmd_obj->GetCommandName()); - std::string remainder (command_string.substr (command_name.size())); + std::string remainder; + if (actual_cmd_name_len < command_string.length()) + remainder = command_string.substr (actual_cmd_name_len); // Note: 'actual_cmd_name_len' may be considerably shorter + // than cmd_obj->GetCommandName(), because name completion + // allows users to enter short versions of the names, + // e.g. 'br s' for 'breakpoint set'. // Remove any initial spaces std::string white_space (" \t\v"); From gclayton at apple.com Sun Dec 12 13:25:26 2010 From: gclayton at apple.com (Greg Clayton) Date: Sun, 12 Dec 2010 19:25:26 -0000 Subject: [Lldb-commits] [lldb] r121638 - in /lldb/trunk: include/lldb/API/SBAddress.h include/lldb/API/SBBreakpoint.h include/lldb/API/SBTarget.h source/API/SBBreakpoint.cpp source/API/SBTarget.cpp Message-ID: <20101212192526.D552A2A6C12C@llvm.org> Author: gclayton Date: Sun Dec 12 13:25:26 2010 New Revision: 121638 URL: http://llvm.org/viewvc/llvm-project?rev=121638&view=rev Log: Added the ability for SBTarget to resolve load addresses (convert lldb::addr_t values into resolved SBAddress objects). These SBAddress objects can then be used to resolve a symbol context using "lldb::SBSymbolContext ResolveSymbolContextForAddress (const lldb::SBAddress& addr, uint32_t resolve_scope);". Modified: lldb/trunk/include/lldb/API/SBAddress.h lldb/trunk/include/lldb/API/SBBreakpoint.h lldb/trunk/include/lldb/API/SBTarget.h lldb/trunk/source/API/SBBreakpoint.cpp lldb/trunk/source/API/SBTarget.cpp Modified: lldb/trunk/include/lldb/API/SBAddress.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBAddress.h?rev=121638&r1=121637&r2=121638&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBAddress.h (original) +++ lldb/trunk/include/lldb/API/SBAddress.h Sun Dec 12 13:25:26 2010 @@ -54,6 +54,7 @@ friend class SBInstruction; friend class SBModule; friend class SBSymbolContext; + friend class SBTarget; friend class SBThread; #ifndef SWIG Modified: lldb/trunk/include/lldb/API/SBBreakpoint.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBreakpoint.h?rev=121638&r1=121637&r2=121638&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBBreakpoint.h (original) +++ lldb/trunk/include/lldb/API/SBBreakpoint.h Sun Dec 12 13:25:26 2010 @@ -33,6 +33,12 @@ #ifndef SWIG const lldb::SBBreakpoint & operator = (const lldb::SBBreakpoint& rhs); + + // Tests to see if the opaque breakpoint object in this object matches the + // opaque breakpoint object in "rhs". + bool + operator == (const lldb::SBBreakpoint& rhs); + #endif break_id_t Modified: lldb/trunk/include/lldb/API/SBTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=121638&r1=121637&r2=121638&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBTarget.h (original) +++ lldb/trunk/include/lldb/API/SBTarget.h Sun Dec 12 13:25:26 2010 @@ -103,6 +103,10 @@ bool DeleteTargetFromList (lldb_private::TargetList *list); + + bool + ResolveLoadAddress (lldb::addr_t vm_addr, + lldb::SBAddress& addr); lldb::SBBreakpoint BreakpointCreateByLocation (const char *file, uint32_t line); Modified: lldb/trunk/source/API/SBBreakpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpoint.cpp?rev=121638&r1=121637&r2=121638&view=diff ============================================================================== --- lldb/trunk/source/API/SBBreakpoint.cpp (original) +++ lldb/trunk/source/API/SBBreakpoint.cpp Sun Dec 12 13:25:26 2010 @@ -92,6 +92,14 @@ return *this; } +bool +SBBreakpoint::operator == (const lldb::SBBreakpoint& rhs) +{ + if (m_opaque_sp && rhs.m_opaque_sp) + return m_opaque_sp.get() == rhs.m_opaque_sp.get(); + return false; +} + break_id_t SBBreakpoint::GetID () const { Modified: lldb/trunk/source/API/SBTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=121638&r1=121637&r2=121638&view=diff ============================================================================== --- lldb/trunk/source/API/SBTarget.cpp (original) +++ lldb/trunk/source/API/SBTarget.cpp Sun Dec 12 13:25:26 2010 @@ -383,6 +383,17 @@ m_opaque_sp = target_sp; } +bool +SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr, + lldb::SBAddress& addr) +{ + if (m_opaque_sp) + return m_opaque_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, *addr); + + addr->Clear(); + return false; +} + SBBreakpoint SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line) { From gclayton at apple.com Sun Dec 12 15:03:32 2010 From: gclayton at apple.com (Greg Clayton) Date: Sun, 12 Dec 2010 21:03:32 -0000 Subject: [Lldb-commits] [lldb] r121641 - in /lldb/trunk: include/lldb/Core/ModuleList.h source/Breakpoint/Breakpoint.cpp source/Core/ModuleList.cpp source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Message-ID: <20101212210332.913532A6C12C@llvm.org> Author: gclayton Date: Sun Dec 12 15:03:32 2010 New Revision: 121641 URL: http://llvm.org/viewvc/llvm-project?rev=121641&view=rev Log: Fixed an issue where the macosx dynamic loader, on the first shared library loaded notification, wasn't properly removing shared libraries from the target that didn't get loaded. This usually happens when a different shared library is loaded in place of another due to DYLD_LIBRARY_PATH or DYLD_FRAMEWORK_PATH environment variables. We now properly remove any images that didn't make it into the executable. Modified: lldb/trunk/include/lldb/Core/ModuleList.h lldb/trunk/source/Breakpoint/Breakpoint.cpp lldb/trunk/source/Core/ModuleList.cpp lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Modified: lldb/trunk/include/lldb/Core/ModuleList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ModuleList.h?rev=121641&r1=121640&r2=121641&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ModuleList.h (original) +++ lldb/trunk/include/lldb/Core/ModuleList.h Sun Dec 12 15:03:32 2010 @@ -76,7 +76,7 @@ Append (lldb::ModuleSP &module_sp); bool - AppendInNeeded (lldb::ModuleSP &module_sp); + AppendIfNeeded (lldb::ModuleSP &module_sp); //------------------------------------------------------------------ /// Clear the object's state. Modified: lldb/trunk/source/Breakpoint/Breakpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=121641&r1=121640&r2=121641&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/Breakpoint.cpp (original) +++ lldb/trunk/source/Breakpoint/Breakpoint.cpp Sun Dec 12 15:03:32 2010 @@ -313,7 +313,7 @@ } if (!seen) - new_modules.AppendInNeeded (module_sp); + new_modules.AppendIfNeeded (module_sp); } if (new_modules.GetSize() > 0) Modified: lldb/trunk/source/Core/ModuleList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=121641&r1=121640&r2=121641&view=diff ============================================================================== --- lldb/trunk/source/Core/ModuleList.cpp (original) +++ lldb/trunk/source/Core/ModuleList.cpp Sun Dec 12 15:03:32 2010 @@ -67,7 +67,7 @@ } bool -ModuleList::AppendInNeeded (ModuleSP &module_sp) +ModuleList::AppendIfNeeded (ModuleSP &module_sp) { Mutex::Locker locker(m_modules_mutex); collection::iterator pos, end = m_modules.end(); Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=121641&r1=121640&r2=121641&view=diff ============================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original) +++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Sun Dec 12 15:03:32 2010 @@ -40,6 +40,23 @@ /// I am putting it here so I can invoke it in the Trampoline code here, but /// it should be moved to the ObjC Runtime support when it is set up. + +DynamicLoaderMacOSXDYLD::DYLDImageInfo * +DynamicLoaderMacOSXDYLD::GetImageInfo (const FileSpec &file_spec, const UUID &uuid) +{ + DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end(); + for (pos = m_dyld_image_infos.begin(); pos != end; ++pos) + { + if (pos->uuid == uuid && pos->file_spec == file_spec) + return &(*pos); + } + + if (m_dyld.uuid == uuid && m_dyld.file_spec == file_spec) + return &m_dyld; + + return NULL; +} + //---------------------------------------------------------------------- // Create an instance of this class. This function is filled into // the plugin info class that gets handed out by the plugin factory and @@ -226,7 +243,7 @@ // it again (since Target::SetExecutableModule() will clear the // images). So append the dyld module back to the list if it is /// unique! - if (m_process->GetTarget().GetImages().AppendInNeeded (dyld_module_sp)) + if (m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp)) UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld); return true; @@ -589,36 +606,57 @@ // If our new list is smaller than our old list, we have unloaded // some shared libraries - if (m_dyld_image_infos.size() < old_dyld_all_image_infos.size()) + if (m_dyld_image_infos.size() != old_dyld_all_image_infos.size()) { ModuleList unloaded_module_list; - uint32_t old_idx; - for (idx = 0; idx < old_dyld_all_image_infos.size(); ++idx) + if (old_dyld_all_image_infos.size() == 0) + { + // This is the first time we are loading shared libraries, + // we need to make sure to trim anything that isn't in the + // m_dyld_image_infos out of the target module list since + // we might have shared libraries that got loaded from + // elsewhere due to DYLD_FRAMEWORK_PATH, or DYLD_LIBRARY_PATH + // environment variables... + ModuleList& images = m_process->GetTarget().GetImages(); + const size_t num_images = images.GetSize(); + for (idx = 0; idx < num_images; ++idx) + { + ModuleSP module_sp (images.GetModuleAtIndex (idx)); + + if (GetImageInfo (module_sp->GetFileSpec(), module_sp->GetUUID()) == NULL) + unloaded_module_list.AppendIfNeeded (module_sp); + } + } + else { - for (old_idx = idx; old_idx < old_dyld_all_image_infos.size(); ++old_idx) + uint32_t old_idx; + for (idx = 0; idx < old_dyld_all_image_infos.size(); ++idx) { - if (m_dyld_image_infos[idx].file_spec == old_dyld_all_image_infos[old_idx].file_spec) + for (old_idx = idx; old_idx < old_dyld_all_image_infos.size(); ++old_idx) { - old_dyld_all_image_infos[old_idx].address = LLDB_INVALID_ADDRESS; - break; + if (m_dyld_image_infos[idx].file_spec == old_dyld_all_image_infos[old_idx].file_spec) + { + old_dyld_all_image_infos[old_idx].address = LLDB_INVALID_ADDRESS; + break; + } } } - } - if (log) - log->PutCString("Unloaded:"); + if (log) + log->PutCString("Unloaded:"); - for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx) - { - if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS) + for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx) { - if (log) - old_dyld_all_image_infos[old_idx].PutToLog (log.get()); - ModuleSP unload_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (old_dyld_all_image_infos[old_idx].file_spec)); - if (unload_image_module_sp.get()) + if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS) { - if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx])) - unloaded_module_list.AppendInNeeded (unload_image_module_sp); + if (log) + old_dyld_all_image_infos[old_idx].PutToLog (log.get()); + ModuleSP unload_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (old_dyld_all_image_infos[old_idx].file_spec)); + if (unload_image_module_sp.get()) + { + if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx])) + unloaded_module_list.AppendIfNeeded (unload_image_module_sp); + } } } } @@ -690,7 +728,7 @@ // shared libraries each time. if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx])) { - loaded_module_list.AppendInNeeded (image_module_sp); + loaded_module_list.AppendIfNeeded (image_module_sp); } } } Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=121641&r1=121640&r2=121641&view=diff ============================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original) +++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Sun Dec 12 15:03:32 2010 @@ -202,13 +202,13 @@ struct DYLDImageInfo { - lldb::addr_t address; // Address of mach header for this dylib - lldb::addr_t slide; // The amount to slide all segments by if there is a global slide. - lldb::addr_t mod_date; // Modification date for this dylib - lldb_private::FileSpec file_spec; // Resolved path for this dylib - lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros - llvm::MachO::mach_header header; // The mach header for this image - std::vector segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior) + lldb::addr_t address; // Address of mach header for this dylib + lldb::addr_t slide; // The amount to slide all segments by if there is a global slide. + lldb::addr_t mod_date; // Modification date for this dylib + lldb_private::FileSpec file_spec; // Resolved path for this dylib + lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros + llvm::MachO::mach_header header; // The mach header for this image + std::vector segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior) DYLDImageInfo() : address(LLDB_INVALID_ADDRESS), @@ -359,6 +359,10 @@ UnloadImageLoadAddress (lldb_private::Module *module, struct DYLDImageInfo& info); + DYLDImageInfo * + GetImageInfo (const lldb_private::FileSpec &file_spec, + const lldb_private::UUID &uuid); + bool NeedToLocateDYLD () const; From gclayton at apple.com Sun Dec 12 15:50:58 2010 From: gclayton at apple.com (Greg Clayton) Date: Sun, 12 Dec 2010 21:50:58 -0000 Subject: [Lldb-commits] [lldb] r121647 - /lldb/trunk/source/Core/Communication.cpp Message-ID: <20101212215058.17DAB2A6C12C@llvm.org> Author: gclayton Date: Sun Dec 12 15:50:57 2010 New Revision: 121647 URL: http://llvm.org/viewvc/llvm-project?rev=121647&view=rev Log: Fixed a multi-threaded race condition that could happen when communication classes are shutting down. We currently don't protect communication connection classes against multi-threaded access. The connection is stored in the lldb_private::Communication.m_connection_ap auto_ptr member. We either need to add protections when accessing this class or not let anything racy occur. With this fix, we are doing the latter. Modified: lldb/trunk/source/Core/Communication.cpp Modified: lldb/trunk/source/Core/Communication.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Communication.cpp?rev=121647&r1=121646&r2=121647&view=diff ============================================================================== --- lldb/trunk/source/Core/Communication.cpp (original) +++ lldb/trunk/source/Core/Communication.cpp Sun Dec 12 15:50:57 2010 @@ -94,7 +94,16 @@ if (m_connection_ap.get()) { ConnectionStatus status = m_connection_ap->Disconnect (error_ptr); - m_connection_ap.reset(); + // We currently don't protect m_connection_ap with any mutex for + // multi-threaded environments. So lets not nuke our connection class + // without putting some multi-threaded protections in. We also probably + // don't want to pay for the overhead it might cause if every time we + // access the connection we have to take a lock. + // + // This auto_ptr will cleanup after itself when this object goes away, + // so there is no need to currently have it destroy itself immediately + // upon disconnnect. + //m_connection_ap.reset(); return status; } return eConnectionStatusNoConnection; @@ -347,6 +356,7 @@ // Let clients know that this thread is exiting comm->BroadcastEvent (eBroadcastBitReadThreadDidExit); comm->m_read_thread = LLDB_INVALID_HOST_THREAD; + comm->Disconnect(); return NULL; } From scallanan at apple.com Sun Dec 12 19:26:28 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 13 Dec 2010 01:26:28 -0000 Subject: [Lldb-commits] [lldb] r121663 - in /lldb/trunk: llvm.zip scripts/build-llvm.pl source/Symbol/ClangASTContext.cpp source/Symbol/ClangASTType.cpp Message-ID: <20101213012628.2F6672A6C12C@llvm.org> Author: spyffe Date: Sun Dec 12 19:26:27 2010 New Revision: 121663 URL: http://llvm.org/viewvc/llvm-project?rev=121663&view=rev Log: Updated to latest Clang revision. This involved very minor changes, changing how we get the target type from a TypedefType, adding a parameter to EnumDecl::Create(), and other minor tweaks. Modified: lldb/trunk/llvm.zip lldb/trunk/scripts/build-llvm.pl lldb/trunk/source/Symbol/ClangASTContext.cpp lldb/trunk/source/Symbol/ClangASTType.cpp Modified: lldb/trunk/llvm.zip URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/llvm.zip?rev=121663&r1=121662&r2=121663&view=diff ============================================================================== Binary files - no diff available. Modified: lldb/trunk/scripts/build-llvm.pl URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/build-llvm.pl?rev=121663&r1=121662&r2=121663&view=diff ============================================================================== --- lldb/trunk/scripts/build-llvm.pl (original) +++ lldb/trunk/scripts/build-llvm.pl Sun Dec 12 19:26:27 2010 @@ -25,7 +25,7 @@ our $llvm_configuration = $ENV{LLVM_CONFIGURATION}; -our $llvm_revision = "120727"; +our $llvm_revision = "121655"; our $llvm_source_dir = "$ENV{SRCROOT}"; our $cc = "$ENV{DEVELOPER_BIN_DIR}/gcc-4.2"; our $cxx = "$ENV{DEVELOPER_BIN_DIR}/g++-4.2"; Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=121663&r1=121662&r2=121663&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Sun Dec 12 19:26:27 2010 @@ -1829,7 +1829,7 @@ case clang::Type::TemplateSpecialization: return eTypeIsTemplate; case clang::Type::Typedef: - return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), + return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), ast_context, pointee_or_element_clang_type); @@ -1867,7 +1867,7 @@ return true; case clang::Type::Typedef: - return ClangASTContext::IsAggregateType (cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); + return ClangASTContext::IsAggregateType (cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); default: break; @@ -2021,7 +2021,7 @@ case clang::Type::Typedef: - num_children = ClangASTContext::GetNumChildren (cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes); + num_children = ClangASTContext::GetNumChildren (cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), omit_empty_base_classes); break; default: @@ -2423,7 +2423,7 @@ case clang::Type::Typedef: return GetChildClangTypeAtIndex (ast_context, parent_name, - cast(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(), + cast(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), idx, transparent_pointers, omit_empty_base_classes, @@ -2877,7 +2877,7 @@ case clang::Type::Typedef: return GetIndexOfChildMemberWithName (ast_context, - cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), + cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), name, omit_empty_base_classes, child_indexes); @@ -3088,7 +3088,7 @@ case clang::Type::Typedef: return GetIndexOfChildWithName (ast_context, - cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), + cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), name, omit_empty_base_classes); @@ -3157,7 +3157,7 @@ case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr()); case clang::Type::Record: return cast(qual_type)->getDecl(); case clang::Type::Enum: return cast(qual_type)->getDecl(); - case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); + case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); case clang::Type::TypeOfExpr: break; case clang::Type::TypeOf: break; @@ -3401,7 +3401,10 @@ SourceLocation(), name && name[0] ? &ast_context->Idents.get(name) : NULL, SourceLocation(), - NULL, false, false); //IsScoped, IsFixed); + NULL, + false, // IsScoped + false, // IsScopedUsingClassTag + false); // IsFixed if (enum_decl) { // TODO: check if we should be setting the promotion type too? @@ -3580,7 +3583,7 @@ *target_type = cast(qual_type)->desugar().getAsOpaquePtr(); return true; case clang::Type::Typedef: - return ClangASTContext::IsPointerOrReferenceType (cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); + return ClangASTContext::IsPointerOrReferenceType (cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); default: break; } @@ -3643,7 +3646,7 @@ *target_type = cast(qual_type)->getPointeeType().getAsOpaquePtr(); return true; case clang::Type::Typedef: - return ClangASTContext::IsPointerOrReferenceType (cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type); + return ClangASTContext::IsPointerOrReferenceType (cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type); default: break; } @@ -3791,7 +3794,7 @@ switch (type_class) { case clang::Type::Typedef: - return ClangASTContext::IsFunctionPointerType (cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); + return ClangASTContext::IsFunctionPointerType (cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); case clang::Type::LValueReference: case clang::Type::RValueReference: Modified: lldb/trunk/source/Symbol/ClangASTType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=121663&r1=121662&r2=121663&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTType.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTType.cpp Sun Dec 12 19:26:27 2010 @@ -185,7 +185,7 @@ case clang::Type::Record: break; case clang::Type::Enum: return lldb::eEncodingSint; case clang::Type::Typedef: - return GetEncoding(cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), count); + return GetEncoding(cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count); break; case clang::Type::TypeOfExpr: @@ -274,7 +274,7 @@ case clang::Type::Record: break; case clang::Type::Enum: return lldb::eFormatEnum; case clang::Type::Typedef: - return ClangASTType::GetFormat(cast(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); + return ClangASTType::GetFormat(cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); case clang::Type::TypeOfExpr: case clang::Type::TypeOf: @@ -565,7 +565,7 @@ case clang::Type::Typedef: { - clang::QualType typedef_qual_type = cast(qual_type)->LookThroughTypedefs(); + clang::QualType typedef_qual_type = cast(qual_type)->getDecl()->getUnderlyingType(); lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr()); std::pair typedef_type_info = ast_context->getTypeInfo(typedef_qual_type); uint64_t typedef_byte_size = typedef_type_info.first / 8; @@ -673,7 +673,7 @@ case clang::Type::Typedef: { - clang::QualType typedef_qual_type = cast(qual_type)->LookThroughTypedefs(); + clang::QualType typedef_qual_type = cast(qual_type)->getDecl()->getUnderlyingType(); lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr()); std::pair typedef_type_info = ast_context->getTypeInfo(typedef_qual_type); uint64_t typedef_byte_size = typedef_type_info.first / 8; @@ -1295,6 +1295,6 @@ ClangASTType::RemoveFastQualifiers (lldb::clang_type_t clang_type) { clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - qual_type.removeFastQualifiers(); + qual_type.getQualifiers().removeFastQualifiers(); return qual_type.getAsOpaquePtr(); }