From johnny.chen at apple.com Mon Aug 23 12:10:45 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 23 Aug 2010 17:10:45 -0000 Subject: [Lldb-commits] [lldb] r111811 - in /lldb/trunk/test: dotest.py lldbtest.py stl/TestSTL.py Message-ID: <20100823171045.149452A6C12C@llvm.org> Author: johnny Date: Mon Aug 23 12:10:44 2010 New Revision: 111811 URL: http://llvm.org/viewvc/llvm-project?rev=111811&view=rev Log: Changed the keyword argument for runCmd()/expect() from 'verbose' to 'trace', which, defaults to False, and if set to True, will trace lldb command execution and result. Added "-t" command option to the test driver dotest.py which sets the LLDB_COMMAND_TRACE environment variable to "YES" and as a result always turns on command tracing regardless of the 'trace' keyword argument to runCmd()/expect(). Modified: lldb/trunk/test/dotest.py lldb/trunk/test/lldbtest.py lldb/trunk/test/stl/TestSTL.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=111811&r1=111810&r2=111811&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Mon Aug 23 12:10:44 2010 @@ -59,6 +59,7 @@ Usage: dotest.py [option] [args] where options: -h : print this help message and exit (also --help) +-t : trace lldb command execution and result -v : do verbose mode of unittest framework and: @@ -118,11 +119,15 @@ usage() sys.exit(0) else: - # Process possible verbose flag. + # Process possible trace and/or verbose flag. index = 1 - if sys.argv[1].find('-v') != -1: - verbose = 2 - index += 1 + for i in range(1, len(sys.argv) - 1): + if sys.argv[index].startswith('-t'): + os.environ["LLDB_COMMAND_TRACE"] = "YES" + index += 1 + if sys.argv[index].startswith('-v'): + verbose = 2 + index += 1 # Gather all the dirs passed on the command line. if len(sys.argv) > index: Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=111811&r1=111810&r2=111811&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Aug 23 12:10:44 2010 @@ -24,6 +24,84 @@ Ran 1 test in 0.363s OK +$ LLDB_COMMAND_TRACE=YES python array_types/TestArrayTypes.py +LLDB_COMMAND_TRACE=YES python array_types/TestArrayTypes.py +runCmd: file /Volumes/data/lldb/svn/trunk/test/array_types/a.out +output: Current executable set to '/Volumes/data/lldb/svn/trunk/test/array_types/a.out' (x86_64). + +runCmd: breakpoint set -f main.c -l 42 +output: Breakpoint created: 1: file ='main.c', line = 42, locations = 1 + +runCmd: run +output: Launching '/Volumes/data/lldb/svn/trunk/test/array_types/a.out' (x86_64) + +runCmd: thread list +output: Process 24987 state is Stopped + thread #1: tid = 0x2e03, pc = 0x0000000100000df4, where = a.out`main + 612 at /Volumes/data/lldb/svn/trunk/test/array_types/main.c:45, stop reason = breakpoint 1.1, queue = com.apple.main-thread + +runCmd: breakpoint list +output: Current breakpoints: +1: file ='main.c', line = 42, locations = 1, resolved = 1 + 1.1: where = a.out`main + 612 at /Volumes/data/lldb/svn/trunk/test/array_types/main.c:45, address = 0x0000000100000df4, resolved, hit count = 1 + + +runCmd: variable list strings +output: (char *[4]) strings = { + (char *) strings[0] = 0x0000000100000f0c "Hello", + (char *) strings[1] = 0x0000000100000f12 "Hola", + (char *) strings[2] = 0x0000000100000f17 "Bonjour", + (char *) strings[3] = 0x0000000100000f1f "Guten Tag" +} + +runCmd: variable list char_16 +output: (char [16]) char_16 = { + (char) char_16[0] = 'H', + (char) char_16[1] = 'e', + (char) char_16[2] = 'l', + (char) char_16[3] = 'l', + (char) char_16[4] = 'o', + (char) char_16[5] = ' ', + (char) char_16[6] = 'W', + (char) char_16[7] = 'o', + (char) char_16[8] = 'r', + (char) char_16[9] = 'l', + (char) char_16[10] = 'd', + (char) char_16[11] = '\n', + (char) char_16[12] = '\0', + (char) char_16[13] = '\0', + (char) char_16[14] = '\0', + (char) char_16[15] = '\0' +} + +runCmd: variable list ushort_matrix +output: (unsigned short [2][3]) ushort_matrix = { + (unsigned short [3]) ushort_matrix[0] = { + (unsigned short) ushort_matrix[0][0] = 0x0001, + (unsigned short) ushort_matrix[0][1] = 0x0002, + (unsigned short) ushort_matrix[0][2] = 0x0003 + }, + (unsigned short [3]) ushort_matrix[1] = { + (unsigned short) ushort_matrix[1][0] = 0x000b, + (unsigned short) ushort_matrix[1][1] = 0x0016, + (unsigned short) ushort_matrix[1][2] = 0x0021 + } +} + +runCmd: variable list long_6 +output: (long [6]) long_6 = { + (long) long_6[0] = 1, + (long) long_6[1] = 2, + (long) long_6[2] = 3, + (long) long_6[3] = 4, + (long) long_6[4] = 5, + (long) long_6[5] = 6 +} + +. +---------------------------------------------------------------------- +Ran 1 test in 0.349s + +OK $ """ @@ -70,6 +148,9 @@ # State pertaining to the inferior process, if any. runStarted = False + # os.environ["LLDB_COMMAND_TRACE"], if set to "YES", will turn on this flag. + traceAlways = False; + def setUp(self): #import traceback #traceback.print_stack() @@ -85,6 +166,10 @@ if ("LLDB_TEST" in os.environ): os.chdir(os.path.join(os.environ["LLDB_TEST"], self.mydir)); + if ("LLDB_COMMAND_TRACE" in os.environ and + os.environ["LLDB_COMMAND_TRACE"] == "YES"): + self.traceAlways = True + # Create the debugger instance if necessary. try: self.dbg = lldb.DBG @@ -115,7 +200,7 @@ # Restore old working directory. os.chdir(self.oldcwd) - def runCmd(self, cmd, msg=None, check=True, verbose=False): + def runCmd(self, cmd, msg=None, check=True, trace=False): """ Ask the command interpreter to handle the command and then check its return status. @@ -124,7 +209,9 @@ if not cmd or len(cmd) == 0: raise Exception("Bad 'cmd' parameter encountered") - if verbose: + trace = (True if self.traceAlways else trace) + + if trace: print >> sys.stderr, "runCmd:", cmd self.ci.HandleCommand(cmd, self.res) @@ -132,7 +219,7 @@ if cmd.startswith("run"): self.runStarted = True - if verbose: + if trace: if self.res.Succeeded(): print >> sys.stderr, "output:", self.res.GetOutput() else: @@ -142,7 +229,7 @@ self.assertTrue(self.res.Succeeded(), msg if msg else CMD_MSG(cmd)) - def expect(self, cmd, msg=None, startstr=None, substrs=None, verbose=False): + def expect(self, cmd, msg=None, startstr=None, substrs=None, trace=False): """ Similar to runCmd; with additional expect style output matching ability. @@ -152,21 +239,23 @@ 'startstr' and matches the substrings contained in 'substrs'. """ + trace = (True if self.traceAlways else trace) + # First run the command. - self.runCmd(cmd, verbose = (True if verbose else False)) + self.runCmd(cmd, trace = (True if trace else False)) # Then compare the output against expected strings. output = self.res.GetOutput() matched = output.startswith(startstr) if startstr else True - if not matched and startstr and verbose: + if not matched and startstr and trace: print >> sys.stderr, "Startstr not matched:", startstr if substrs: for str in substrs: matched = output.find(str) > 0 if not matched: - if verbose: + if trace: print >> sys.stderr, "Substring not matched:", str break Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=111811&r1=111810&r2=111811&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Mon Aug 23 12:10:44 2010 @@ -42,7 +42,7 @@ # This assertion currently always fails. # This might be related: rdar://problem/8247112. # - #self.runCmd("thread step-in", verbose=True) + #self.runCmd("thread step-in", trace=True) self.runCmd("thread step-in") self.expect("thread backtrace", "We have stepped in STL", From johnny.chen at apple.com Mon Aug 23 12:13:12 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 23 Aug 2010 17:13:12 -0000 Subject: [Lldb-commits] [lldb] r111812 - /lldb/trunk/source/Host/macosx/Host.mm Message-ID: <20100823171312.6C5A42A6C12C@llvm.org> Author: johnny Date: Mon Aug 23 12:13:12 2010 New Revision: 111812 URL: http://llvm.org/viewvc/llvm-project?rev=111812&view=rev Log: Fixed a crasher where during shutdown, loggings attempted to access the thread name but the static map instance had already been destructed. rdar://problem/8153284 Modified: lldb/trunk/source/Host/macosx/Host.mm Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=111812&r1=111811&r2=111812&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Mon Aug 23 12:13:12 2010 @@ -325,7 +325,13 @@ Mutex::Locker locker(&g_mutex); typedef std::map thread_name_map; - static thread_name_map g_thread_names; + // rdar://problem/8153284 + // Fixed a crasher where during shutdown, loggings attempted to access the + // thread name but the static map instance had already been destructed. + // Another approach is to introduce a static guard object which monitors its + // own destruction and raises a flag, but this incurs more overhead. + static thread_name_map *g_thread_names_ptr = new thread_name_map(); + thread_name_map &g_thread_names = *g_thread_names_ptr; if (get) { From scallanan at apple.com Mon Aug 23 18:09:38 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 23 Aug 2010 23:09:38 -0000 Subject: [Lldb-commits] [lldb] r111859 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/ClangExpressionVariable.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/DWARFExpression.cpp source/Expression/IRForTarget.cpp Message-ID: <20100823230938.540CE2A6C12D@llvm.org> Author: spyffe Date: Mon Aug 23 18:09:38 2010 New Revision: 111859 URL: http://llvm.org/viewvc/llvm-project?rev=111859&view=rev Log: Refactored ClangExpressionDeclMap to use ClangExpressionVariables for found external variables as well as for struct members, replacing the Tuple and StructMember data structures. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/DWARFExpression.cpp lldb/trunk/source/Expression/IRForTarget.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=111859&r1=111858&r2=111859&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Mon Aug 23 18:09:38 2010 @@ -93,6 +93,10 @@ /// [Used by IRForTarget] Add a variable to the list of persistent /// variables for the process. /// + /// @param[in] decl + /// The Clang declaration for the persistent variable, used for + /// lookup during parsing. + /// /// @param[in] name /// The name of the persistent variable, usually $something. /// @@ -102,23 +106,19 @@ /// @return /// True on success; false otherwise. //------------------------------------------------------------------ - bool AddPersistentVariable (const char *name, TypeFromParser type); + bool AddPersistentVariable (const clang::NamedDecl *decl, + const char *name, + TypeFromParser type); //------------------------------------------------------------------ /// [Used by IRForTarget] Add a variable to the struct that needs to /// be materialized each time the expression runs. /// - /// @param[in] value - /// The LLVM IR value for this variable. - /// /// @param[in] decl /// The Clang declaration for the variable. /// - /// @param[in] name - /// The name of the variable. - /// - /// @param[in] type - /// The type of the variable. + /// @param[in] value + /// The LLVM IR value for this variable. /// /// @param[in] size /// The size of the variable in bytes. @@ -129,10 +129,8 @@ /// @return /// True on success; false otherwise. //------------------------------------------------------------------ - bool AddValueToStruct (llvm::Value *value, - const clang::NamedDecl *decl, - std::string &name, - TypeFromParser type, + bool AddValueToStruct (const clang::NamedDecl *decl, + llvm::Value *value, size_t size, off_t alignment); @@ -239,19 +237,6 @@ uint64_t &ptr); //------------------------------------------------------------------ - /// [Used by DWARFExpression] Get the LLDB value for a variable given - /// its unique index into the value map. - /// - /// @param[in] index - /// The index of the variable into the tuple array, which keeps track - /// of Decls, types, and Values. - /// - /// @return - /// The LLDB value for the variable. - //------------------------------------------------------------------ - Value *GetValueForIndex (uint32_t index); - - //------------------------------------------------------------------ /// [Used by CommandObjectExpression] Materialize the entire struct /// at a given address, which should be aligned as specified by /// GetStructInfo(). @@ -335,51 +320,9 @@ void GetDecls (NameSearchContext &context, const char *name); private: - //---------------------------------------------------------------------- - /// @class Tuple ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h" - /// @brief A single entity that has been looked up on the behalf of the parser. - /// - /// When the Clang parser requests entities by name, ClangExpressionDeclMap - /// records what was looked up in a list of Tuples. - //---------------------------------------------------------------------- - struct Tuple - { - const clang::NamedDecl *m_decl; ///< The Decl generated for the entity. - TypeFromParser m_parser_type; ///< The type of the entity, as reported to the parser. - TypeFromUser m_user_type; ///< The type of the entity, as found in LLDB. - lldb_private::Value *m_value; ///< [owned by ClangExpressionDeclMap] A LLDB Value for the entity. - llvm::Value *m_llvm_value; ///< A LLVM IR Value for the entity, usually a GlobalVariable. - }; - - //---------------------------------------------------------------------- - /// @class StructMember ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h" - /// @brief An entity that needs to be materialized in order to make the - /// expression work. - /// - /// IRForTarget identifies those entities that actually made it into the - /// final IR and adds them to a list of StructMembers; this list is used - /// as the basis of struct layout and its fields are used for - /// materializing/dematerializing the struct. - //---------------------------------------------------------------------- - struct StructMember - { - const clang::NamedDecl *m_decl; ///< The Decl generated for the entity. - llvm::Value *m_value; ///< A LLVM IR Value for he entity, usually a GlobalVariable. - std::string m_name; ///< The name of the entity, for use in materialization. - TypeFromParser m_parser_type; ///< The expected type of the entity, for use in materialization. - off_t m_offset; ///< The laid-out offset of the entity in the struct. Only valid after DoStructLayout(). - size_t m_size; ///< The size of the entity. - off_t m_alignment; ///< The required alignment of the entity, in bytes. - }; - - typedef std::vector TupleVector; - typedef TupleVector::iterator TupleIterator; + ClangExpressionVariableStore m_found_entities; ///< All entities that were looked up for the parser. + ClangExpressionVariableList m_struct_members; ///< All entities that need to be placed in the struct. - typedef std::vector StructMemberVector; - typedef StructMemberVector::iterator StructMemberIterator; - - TupleVector m_tuples; ///< All entities that were looked up for the parser. - StructMemberVector m_members; ///< All fields of the struct that need to be materialized. ExecutionContext *m_exe_ctx; ///< The execution context where this expression was first defined. It determines types for all the external variables, even if the expression is re-used. SymbolContext *m_sym_ctx; ///< [owned by ClangExpressionDeclMap] The symbol context where this expression was first defined. ClangPersistentVariables *m_persistent_vars; ///< The list of persistent variables to use when resolving symbols in the expression and when creating new ones (like the result). @@ -416,22 +359,6 @@ TypeFromUser *type = NULL); //------------------------------------------------------------------ - /// Get the index into the Tuple array for the given Decl. Implements - /// vanilla linear search. - /// - /// @param[out] index - /// The index into the Tuple array that corresponds to the Decl. - /// - /// @param[in] decl - /// The Decl to be looked up. - /// - /// @return - /// True if the Decl was found; false otherwise. - //------------------------------------------------------------------ - bool GetIndexForDecl (uint32_t &index, - const clang::Decl *decl); - - //------------------------------------------------------------------ /// Get the value of a variable in a given execution context and return /// the associated Types if needed. /// Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=111859&r1=111858&r2=111859&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Mon Aug 23 18:09:38 2010 @@ -89,6 +89,7 @@ TypeFromParser m_parser_type; ///< The type of the variable according to the parser const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue + lldb_private::Value *m_lldb_value; ///< The value found in LLDB for this variable }; std::auto_ptr m_parser_vars; @@ -250,6 +251,27 @@ } return NULL; } + + //---------------------------------------------------------------------- + /// Finds a variable by NamedDecl in the list. + /// + /// @param[in] name + /// The name of the requested variable. + /// + /// @return + /// The variable requested, or NULL if that variable is not in the list. + //---------------------------------------------------------------------- + ClangExpressionVariable *GetVariable (const clang::NamedDecl *decl) + { + for (uint64_t index = 0, size = Size(); index < size; ++index) + { + ClangExpressionVariable &candidate (VariableAtIndex(index)); + if (candidate.m_parser_vars.get() && + candidate.m_parser_vars->m_named_decl == decl) + return &candidate; + } + return NULL; + } }; //---------------------------------------------------------------------- Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=111859&r1=111858&r2=111859&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Mon Aug 23 18:09:38 2010 @@ -51,36 +51,21 @@ } ClangExpressionDeclMap::~ClangExpressionDeclMap() -{ - uint32_t num_tuples = m_tuples.size (); - uint32_t tuple_index; - - for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index) - delete m_tuples[tuple_index].m_value; +{ + for (uint64_t entity_index = 0, num_entities = m_found_entities.Size(); + entity_index < num_entities; + ++entity_index) + { + ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index)); + if (entity.m_parser_vars.get() && + entity.m_parser_vars->m_lldb_value) + delete entity.m_parser_vars->m_lldb_value; + } if (m_sym_ctx) delete m_sym_ctx; } -bool -ClangExpressionDeclMap::GetIndexForDecl (uint32_t &index, - const clang::Decl *decl) -{ - uint32_t num_tuples = m_tuples.size (); - uint32_t tuple_index; - - for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index) - { - if (m_tuples[tuple_index].m_decl == decl) - { - index = tuple_index; - return true; - } - } - - return false; -} - // Interface for IRForTarget void @@ -92,7 +77,9 @@ } bool -ClangExpressionDeclMap::AddPersistentVariable (const char *name, TypeFromParser parser_type) +ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl, + const char *name, + TypeFromParser parser_type) { clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext()); @@ -101,40 +88,50 @@ parser_type.GetOpaqueQualType()), context); - return m_persistent_vars->CreatePersistentVariable (name, user_type); + if (!m_persistent_vars->CreatePersistentVariable (name, user_type)) + return false; + + ClangExpressionVariable *var = m_persistent_vars->GetVariable(name); + + if (!var) + return false; + + var->EnableParserVars(); + + var->m_parser_vars->m_named_decl = decl; + var->m_parser_vars->m_parser_type = parser_type; + + return true; } bool -ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value, - const clang::NamedDecl *decl, - std::string &name, - TypeFromParser type, +ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl, + llvm::Value *value, size_t size, off_t alignment) { m_struct_laid_out = false; - StructMemberIterator iter; + if (m_struct_members.GetVariable(decl)) + return true; - for (iter = m_members.begin(); - iter != m_members.end(); - ++iter) - { - if (iter->m_decl == decl) - return true; - } - - StructMember member; + ClangExpressionVariable *var = m_found_entities.GetVariable(decl); - member.m_value = value; - member.m_decl = decl; - member.m_name = name; - member.m_parser_type = type; - member.m_offset = 0; - member.m_size = size; - member.m_alignment = alignment; + if (!var) + var = m_persistent_vars->GetVariable(decl); - m_members.push_back(member); + if (!var) + return false; + + // We know entity->m_parser_vars is valid because we used a parser variable + // to find it + var->m_parser_vars->m_llvm_value = value; + + var->EnableJITVars(); + var->m_jit_vars->m_alignment = alignment; + var->m_jit_vars->m_size = size; + + m_struct_members.AddVariable(*var); return true; } @@ -145,25 +142,28 @@ if (m_struct_laid_out) return true; - StructMemberIterator iter; - off_t cursor = 0; m_struct_alignment = 0; m_struct_size = 0; - for (iter = m_members.begin(); - iter != m_members.end(); - ++iter) + for (uint64_t member_index = 0, num_members = m_struct_members.Size(); + member_index < num_members; + ++member_index) { - if (iter == m_members.begin()) - m_struct_alignment = iter->m_alignment; + ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index)); + + if (!member.m_jit_vars.get()) + return false; - if (cursor % iter->m_alignment) - cursor += (iter->m_alignment - (cursor % iter->m_alignment)); + if (member_index == 0) + m_struct_alignment = member.m_jit_vars->m_alignment; - iter->m_offset = cursor; - cursor += iter->m_size; + if (cursor % member.m_jit_vars->m_alignment) + cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment)); + + member.m_jit_vars->m_offset = cursor; + cursor += member.m_jit_vars->m_size; } m_struct_size = cursor; @@ -179,7 +179,7 @@ if (!m_struct_laid_out) return false; - num_elements = m_members.size(); + num_elements = m_struct_members.Size(); size = m_struct_size; alignment = m_struct_alignment; @@ -195,13 +195,19 @@ if (!m_struct_laid_out) return false; - if (index >= m_members.size()) + if (index >= m_struct_members.Size()) return false; - decl = m_members[index].m_decl; - value = m_members[index].m_value; - offset = m_members[index].m_offset; + ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index)); + + if (!member.m_parser_vars.get() || + !member.m_jit_vars.get()) + return false; + decl = member.m_parser_vars->m_named_decl; + value = member.m_parser_vars->m_llvm_value; + offset = member.m_jit_vars->m_offset; + return true; } @@ -210,21 +216,18 @@ llvm::Value**& value, uint64_t &ptr) { - TupleIterator iter; + ClangExpressionVariable *entity = m_found_entities.GetVariable(decl); + + if (!entity) + return false; - for (iter = m_tuples.begin(); - iter != m_tuples.end(); - ++iter) - { - if (decl == iter->m_decl) - { - value = &iter->m_llvm_value; - ptr = iter->m_value->GetScalar().ULongLong(); - return true; - } - } + // We know m_parser_vars is valid since we searched for the variable by + // its NamedDecl + + value = &entity->m_parser_vars->m_llvm_value; + ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong(); - return false; + return true; } bool @@ -260,16 +263,6 @@ return true; } -// Interface for DwarfExpression -lldb_private::Value -*ClangExpressionDeclMap::GetValueForIndex (uint32_t index) -{ - if (index >= m_tuples.size ()) - return NULL; - - return m_tuples[index].m_value; -} - // Interface for CommandObjectExpression bool @@ -334,23 +327,26 @@ DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize()); - StructMemberIterator iter; - - for (iter = m_members.begin(); - iter != m_members.end(); - ++iter) - { - s.Printf("[%s]\n", iter->m_name.c_str()); - - extractor.Dump(&s, // stream - iter->m_offset, // offset - lldb::eFormatBytesWithASCII, // format - 1, // byte size of individual entries - iter->m_size, // number of entries - 16, // entries per line - m_materialized_location + iter->m_offset, // address to print - 0, // bit size (bitfields only; 0 means ignore) - 0); // bit alignment (bitfields only; 0 means ignore) + for (uint64_t member_index = 0, num_members = m_struct_members.Size(); + member_index < num_members; + ++member_index) + { + ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index)); + + s.Printf("[%s]\n", member.m_name.c_str()); + + if (!member.m_jit_vars.get()) + return false; + + extractor.Dump(&s, // stream + member.m_jit_vars->m_offset, // offset + lldb::eFormatBytesWithASCII, // format + 1, // byte size of individual entries + member.m_jit_vars->m_size, // number of entries + 16, // entries per line + m_materialized_location + member.m_jit_vars->m_offset, // address to print + 0, // bit size (bitfields only; 0 means ignore) + 0); // bit alignment (bitfields only; 0 means ignore) s.PutChar('\n'); } @@ -407,81 +403,49 @@ m_materialized_location = m_allocated_area; if (m_materialized_location % m_struct_alignment) - { m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment)); - } - - StructMemberIterator iter; - for (iter = m_members.begin(); - iter != m_members.end(); - ++iter) - { - uint32_t tuple_index; - - if (!GetIndexForDecl(tuple_index, iter->m_decl)) - { - if (iter->m_name.find("___clang_expr_result") != std::string::npos) - { - if (dematerialize) - { - // Here we pick up the odd anomaly produced by - // IRForTarget::createResultVariable (and described in a comment - // there). - // - // We rename the variable to the name of the result PVar and - // incidentally drop the address of the PVar into *result - // (if it's non-NULL, of course). We then let this case fall - // through to the persistent variable handler. - - if (log) - log->PutCString("Found result member in the struct"); - - iter->m_name = m_result_name; - - if (result) - { - if (log) - log->PutCString("Returning result PVar"); - - *result = m_persistent_vars->GetVariable(m_result_name.c_str()); - - if (!*result) - { - err.SetErrorStringWithFormat("Couldn't find persistent variable for result %s", m_result_name.c_str()); - } - } - else - { - if (log) - log->PutCString("Didn't return result PVar; pointer was NULL"); - } - } - else - { - // The result variable doesn't need to be materialized, ever. - continue; - } - } + for (uint64_t member_index = 0, num_members = m_struct_members.Size(); + member_index < num_members; + ++member_index) + { + ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index)); + + if (!member.m_parser_vars.get()) + return false; + + ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl); + ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name.c_str()); + + if (entity) + { + if (!member.m_jit_vars.get()) + return false; - if (iter->m_name[0] == '$') - { - if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err)) - return false; - } - else - { - err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str()); + if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name.c_str(), member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err)) return false; + } + else if (persistent_variable) + { + if (!member.m_name.compare(m_result_name) && !dematerialize) + continue; + + if (dematerialize) + { + if (log) + log->PutCString("Found result member in the struct"); + + *result = &member; } - continue; + if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err)) + return false; } - - Tuple &tuple(m_tuples[tuple_index]); - - if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, iter->m_name.c_str(), tuple.m_user_type, m_materialized_location + iter->m_offset, err)) + else + { + err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.c_str()); return false; + } } return true; @@ -901,15 +865,15 @@ NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType()); - Tuple tuple; - - tuple.m_decl = var_decl; - tuple.m_value = var_location; - tuple.m_user_type = ut; - tuple.m_parser_type = pt; - tuple.m_llvm_value = NULL; - - m_tuples.push_back(tuple); + ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable())); + entity.m_name = context.Name.getAsString(); + entity.m_user_type = ut; + + entity.EnableParserVars(); + entity.m_parser_vars->m_parser_type = pt; + entity.m_parser_vars->m_named_decl = var_decl; + entity.m_parser_vars->m_llvm_value = NULL; + entity.m_parser_vars->m_lldb_value = var_location; if (log) log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl); @@ -926,7 +890,13 @@ user_type.GetOpaqueQualType()), context.GetASTContext()); - (void)context.AddVarDecl(parser_type.GetOpaqueQualType()); + NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); + + pvar->EnableParserVars(); + pvar->m_parser_vars->m_parser_type = parser_type; + pvar->m_parser_vars->m_named_decl = var_decl; + pvar->m_parser_vars->m_llvm_value = NULL; + pvar->m_parser_vars->m_lldb_value = NULL; } void @@ -989,15 +959,15 @@ fun_location->SetValueType(Value::eValueTypeLoadAddress); fun_location->GetScalar() = load_addr; - Tuple tuple; - - tuple.m_decl = fun_decl; - tuple.m_value = fun_location.release(); - tuple.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context); - tuple.m_llvm_value = NULL; - - m_tuples.push_back(tuple); - + ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable())); + entity.m_name = context.Name.getAsString(); + entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);; + + entity.EnableParserVars(); + entity.m_parser_vars->m_named_decl = fun_decl; + entity.m_parser_vars->m_llvm_value = NULL; + entity.m_parser_vars->m_lldb_value = fun_location.release(); + if (log) log->Printf("Found function %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), fun_decl); } Modified: lldb/trunk/source/Expression/DWARFExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=111859&r1=111858&r2=111859&view=diff ============================================================================== --- lldb/trunk/source/Expression/DWARFExpression.cpp (original) +++ lldb/trunk/source/Expression/DWARFExpression.cpp Mon Aug 23 18:09:38 2010 @@ -2466,6 +2466,7 @@ //---------------------------------------------------------------------- case DW_OP_APPLE_extern: { + /* uint32_t idx = opcodes.GetULEB128(&offset); if (!decl_map) { @@ -2483,6 +2484,7 @@ Value *proxy = extern_var->CreateProxy(); stack.push_back(*proxy); delete proxy; + */ } break; Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=111859&r1=111858&r2=111859&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Mon Aug 23 18:09:38 2010 @@ -137,7 +137,7 @@ std::string new_result_name; m_decl_map->GetPersistentResultName(new_result_name); - m_decl_map->AddPersistentVariable(new_result_name.c_str(), result_decl_type); + m_decl_map->AddPersistentVariable(result_decl, new_result_name.c_str(), result_decl_type); if (log) log->Printf("Creating a new result global: %s", new_result_name.c_str()); @@ -364,7 +364,7 @@ lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(), &decl->getASTContext()); - if (!m_decl_map->AddPersistentVariable(decl->getName().str().c_str(), result_decl_type)) + if (!m_decl_map->AddPersistentVariable(decl, decl->getName().str().c_str(), result_decl_type)) return false; GlobalVariable *persistent_global = new GlobalVariable(M, @@ -526,10 +526,8 @@ size_t value_size = m_target_data->getTypeStoreSize(value_type); off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type); - if (named_decl && !m_decl_map->AddValueToStruct(V, - named_decl, - name, - lldb_private::TypeFromParser(qual_type, ast_context), + if (named_decl && !m_decl_map->AddValueToStruct(named_decl, + V, value_size, value_alignment)) return false; @@ -939,6 +937,9 @@ bbi != function->end(); ++bbi) { + if (!removeGuards(M, *bbi)) + return false; + if (!rewritePersistentAllocs(M, *bbi)) return false; @@ -947,9 +948,6 @@ if (!resolveExternals(M, *bbi)) return false; - - if (!removeGuards(M, *bbi)) - return false; } if (log) From johnny.chen at apple.com Mon Aug 23 18:56:08 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 23 Aug 2010 23:56:08 -0000 Subject: [Lldb-commits] [lldb] r111868 - in /lldb/trunk/test: README-TestSuite array_types/Makefile class_types/Makefile dead-strip/Makefile function_types/Makefile global_variables/Makefile make/ make/Makefile.rules order/Makefile set_values/Makefile stl/Makefile struct_types/Makefile unsigned_types/Makefile Message-ID: <20100823235608.B63332A6C12C@llvm.org> Author: johnny Date: Mon Aug 23 18:56:08 2010 New Revision: 111868 URL: http://llvm.org/viewvc/llvm-project?rev=111868&view=rev Log: Makefile refactoring for the test suite. Added a make directory under test, which hosts the Makefile.rules and modified most of the Makefiles under each test case directories to utilize Mekefile.rules. Added a description of 'make' directory into README-TestSuite file. Added: lldb/trunk/test/make/ lldb/trunk/test/make/Makefile.rules Modified: lldb/trunk/test/README-TestSuite lldb/trunk/test/array_types/Makefile lldb/trunk/test/class_types/Makefile lldb/trunk/test/dead-strip/Makefile lldb/trunk/test/function_types/Makefile lldb/trunk/test/global_variables/Makefile lldb/trunk/test/order/Makefile lldb/trunk/test/set_values/Makefile lldb/trunk/test/stl/Makefile lldb/trunk/test/struct_types/Makefile lldb/trunk/test/unsigned_types/Makefile Modified: lldb/trunk/test/README-TestSuite URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/README-TestSuite?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/README-TestSuite (original) +++ lldb/trunk/test/README-TestSuite Mon Aug 23 18:56:08 2010 @@ -54,7 +54,12 @@ C/C++/ObjC source files; they were created to house the Python test case which does not involve lldb reading in an executable file at all. -o unittest2 +o make directory + + Contains Makefile.rules, which can be utilized by test cases to write Makefile + based rules to build native binaries. + +o unittest2 directory Many new features were added to unittest in Python 2.7, including test discovery. unittest2 allows you to use these features with earlier versions of Modified: lldb/trunk/test/array_types/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/array_types/Makefile (original) +++ lldb/trunk/test/array_types/Makefile Mon Aug 23 18:56:08 2010 @@ -1,125 +1,5 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES :=main.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../make +C_SOURCES := main.c +include $(LEVEL)/Makefile.rules Modified: lldb/trunk/test/class_types/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/class_types/Makefile (original) +++ lldb/trunk/test/class_types/Makefile Mon Aug 23 18:56:08 2010 @@ -1,125 +1,5 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES := -CXX_SOURCES :=main.cpp -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules Modified: lldb/trunk/test/dead-strip/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/Makefile (original) +++ lldb/trunk/test/dead-strip/Makefile Mon Aug 23 18:56:08 2010 @@ -1,126 +1,7 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES :=main.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := +LEVEL = ../make -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc +C_SOURCES := main.c LDFLAGS = $(CFLAGS) -Xlinker -dead_strip -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -# Don't make the dSYM so we can test DWARF with debug map... -# $(DSYM) : $(EXE) -# $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - - +MAKE_DSYM := NO +include $(LEVEL)/Makefile.rules Modified: lldb/trunk/test/function_types/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/function_types/Makefile (original) +++ lldb/trunk/test/function_types/Makefile Mon Aug 23 18:56:08 2010 @@ -1,125 +1,5 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES :=main.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../make +C_SOURCES := main.c +include $(LEVEL)/Makefile.rules Modified: lldb/trunk/test/global_variables/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/global_variables/Makefile (original) +++ lldb/trunk/test/global_variables/Makefile Mon Aug 23 18:56:08 2010 @@ -1,142 +1,8 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES :=main.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# dylib settings -#---------------------------------------------------------------------- -DYLIB_NAME=a -DYLIB_BASENAME=lib$(DYLIB_NAME).dylib -DYLIB_C_SOURCES :=a.c -ifneq "$(strip $(DYLIB_C_SOURCES))" "" - DYLIB_OBJECTS +=$(strip $(DYLIB_C_SOURCES:.c=.o)) -endif - - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) $(DYLIB_BASENAME) - $(LD) $(LDFLAGS) $(OBJECTS) -L. -l$(DYLIB_NAME) -o "$(EXE)" - -#---------------------------------------------------------------------- -# Make the dylib -#---------------------------------------------------------------------- -$(DYLIB_BASENAME) : $(DYLIB_OBJECTS) - $(LD) $(LDFLAGS) $(DYLIB_OBJECTS) -install_name "@executable_path/$(DYLIB_BASENAME)" -dynamiclib -o "$(DYLIB_BASENAME)" - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) $(DYLIB_OBJECTS) $(DYLIB_BASENAME) $(DYLIB_BASENAME).dSYM +LEVEL = ../make +C_SOURCES := main.c +DYLIB_NAME := liba.dylib +DYLIB_C_SOURCES := a.c +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/make/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/make/Makefile.rules?rev=111868&view=auto ============================================================================== --- lldb/trunk/test/make/Makefile.rules (added) +++ lldb/trunk/test/make/Makefile.rules Mon Aug 23 18:56:08 2010 @@ -0,0 +1,147 @@ +#---------------------------------------------------------------------- +# Clients fill in the source files to build +#---------------------------------------------------------------------- +# C_SOURCES := main.c +# CXX_SOURCES := +# OBJC_SOURCES := +# OBJCXX_SOURCES := +# DYLIB_C_SOURCES := + +# Uncomment line below for debugging shell commands +# SHELL = /bin/sh -x + +#---------------------------------------------------------------------- +# Change any build/tool options needed +#---------------------------------------------------------------------- +DS := /usr/bin/dsymutil +DSFLAGS = +CC = gcc +CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 +CPLUSPLUSFLAGS +=$(CFLAGS) +CPPFLAGS +=$(CFLAGS) +LD = gcc +LDFLAGS ?= $(CFLAGS) +OBJECTS = +EXE = a.out +DSYM = $(EXE).dSYM + +#---------------------------------------------------------------------- +# dylib settings +#---------------------------------------------------------------------- +ifneq "$(strip $(DYLIB_C_SOURCES))" "" + DYLIB_OBJECTS +=$(strip $(DYLIB_C_SOURCES:.c=.o)) +endif + + +#---------------------------------------------------------------------- +# Check if we have any C source files +#---------------------------------------------------------------------- +ifneq "$(strip $(C_SOURCES))" "" + OBJECTS +=$(strip $(C_SOURCES:.c=.o)) +endif + +#---------------------------------------------------------------------- +# Check if we have any C++ source files +#---------------------------------------------------------------------- +ifneq "$(strip $(CXX_SOURCES))" "" + OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) + LD = g++ +endif + +#---------------------------------------------------------------------- +# Check if we have any ObjC source files +#---------------------------------------------------------------------- +ifneq "$(strip $(OBJC_SOURCES))" "" + OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) + LDFLAGS +=-lobjc +endif + +#---------------------------------------------------------------------- +# Check if we have any ObjC++ source files +#---------------------------------------------------------------------- +ifneq "$(strip $(OBJCXX_SOURCES))" "" + OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) + LD = g++ + ifeq $(findstring lobjc,$(LDFLAGS)) "" + LDFLAGS +=-lobjc + endif +endif + + +#---------------------------------------------------------------------- +# Make the dSYM file from the executable if $(MAKE_DSYM) != "NO" +#---------------------------------------------------------------------- +ifneq "$(MAKE_DSYM)" "NO" +$(DSYM) : $(EXE) + $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" +endif + +#---------------------------------------------------------------------- +# Compile the executable from all the objects. +#---------------------------------------------------------------------- +ifeq "$(DYLIB_NAME)" "" +$(EXE) : $(OBJECTS) + $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" +else +$(EXE) : $(OBJECTS) $(DYLIB_NAME) + $(LD) $(LDFLAGS) $(OBJECTS) -L. -l$(subst lib,,$(basename $(DYLIB_NAME))) -o "$(EXE)" +endif + +#---------------------------------------------------------------------- +# Make the dylib +#---------------------------------------------------------------------- +$(DYLIB_NAME) : $(DYLIB_OBJECTS) + $(LD) $(LDFLAGS) $(DYLIB_OBJECTS) -install_name "@executable_path/$(DYLIB_NAME)" -dynamiclib -o "$(DYLIB_NAME)" + +#---------------------------------------------------------------------- +# Automatic variables based on items already entered. Below we create +# an objects lists from the list of sources by replacing all entries +# that end with .c with .o, and we also create a list of prerequisite +# files by replacing all .c files with .d. +#---------------------------------------------------------------------- +PREREQS := $(OBJECTS:.o=.d) + +#---------------------------------------------------------------------- +# Rule for Generating Prerequisites Automatically using .d files and +# the compiler -MM option. The -M option will list all system headers, +# and the -MM option will list all non-system dependencies. +#---------------------------------------------------------------------- +%.d: %.c + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.cpp + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.m + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.mm + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +#---------------------------------------------------------------------- +# Include all of the makefiles for each source file so we don't have +# to manually track all of the prerequisites for each source file. +#---------------------------------------------------------------------- +sinclude $(PREREQS) + +.PHONY: clean +dsym: $(DSYM) +all: $(EXE) $(DSYM) +clean: +ifeq "$(DYLIB_NAME)" "" + rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) +else + rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) $(DYLIB_OBJECTS) $(DYLIB_NAME) $(DYLIB_NAME).dSYM +endif Modified: lldb/trunk/test/order/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/order/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/order/Makefile (original) +++ lldb/trunk/test/order/Makefile Mon Aug 23 18:56:08 2010 @@ -1,127 +1,7 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES :=main.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := +LEVEL = ../make -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc +C_SOURCES := main.c LDFLAGS = $(CFLAGS) -Xlinker -order_file ./order-file -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -# Don't make the dSYM so we can test the DWARF with debug map with -# order files -#$(DSYM) : $(EXE) -# $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - - +MAKE_DSYM := NO +include $(LEVEL)/Makefile.rules Modified: lldb/trunk/test/set_values/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/set_values/Makefile (original) +++ lldb/trunk/test/set_values/Makefile Mon Aug 23 18:56:08 2010 @@ -1,125 +1,5 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES :=main.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../make +C_SOURCES := main.c +include $(LEVEL)/Makefile.rules Modified: lldb/trunk/test/stl/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/stl/Makefile (original) +++ lldb/trunk/test/stl/Makefile Mon Aug 23 18:56:08 2010 @@ -1,125 +1,6 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES := -CXX_SOURCES :=main.cpp -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -Os -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../make +CXX_SOURCES := main.cpp +CFLAGS :=-arch x86_64 -gdwarf-2 -Os +include $(LEVEL)/Makefile.rules Modified: lldb/trunk/test/struct_types/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/struct_types/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/struct_types/Makefile (original) +++ lldb/trunk/test/struct_types/Makefile Mon Aug 23 18:56:08 2010 @@ -1,125 +1,5 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES :=main.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../make +C_SOURCES := main.c +include $(LEVEL)/Makefile.rules Modified: lldb/trunk/test/unsigned_types/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/Makefile?rev=111868&r1=111867&r2=111868&view=diff ============================================================================== --- lldb/trunk/test/unsigned_types/Makefile (original) +++ lldb/trunk/test/unsigned_types/Makefile Mon Aug 23 18:56:08 2010 @@ -1,125 +1,5 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES := -CXX_SOURCES :=main.cpp -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules From gclayton at apple.com Mon Aug 23 19:45:41 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 24 Aug 2010 00:45:41 -0000 Subject: [Lldb-commits] [lldb] r111877 - in /lldb/trunk: include/lldb/Core/ include/lldb/Symbol/ include/lldb/Target/ source/API/ source/Breakpoint/ source/Commands/ source/Core/ source/Expression/ source/Plugins/Process/Utility/ source/Plugins/Process/gdb-remote/ source/Symbol/ source/Target/ Message-ID: <20100824004541.D48C52A6C12C@llvm.org> Author: gclayton Date: Mon Aug 23 19:45:41 2010 New Revision: 111877 URL: http://llvm.org/viewvc/llvm-project?rev=111877&view=rev Log: Added support for inlined stack frames being represented as real stack frames which is now on by default. Frames are gotten from the unwinder as concrete frames, then if inline frames are to be shown, extra information to track and reconstruct these frames is cached with each Thread and exanded as needed. I added an inline height as part of the lldb_private::StackID class, the class that helps us uniquely identify stack frames. This allows for two frames to shared the same call frame address, yet differ only in inline height. Fixed setting breakpoint by address to not require addresses to resolve. A quick example: % cat main.cpp % ./build/Debug/lldb test/stl/a.out Current executable set to 'test/stl/a.out' (x86_64). (lldb) breakpoint set --address 0x0000000100000d31 Breakpoint created: 1: address = 0x0000000100000d31, locations = 1 (lldb) r Launching 'a.out' (x86_64) (lldb) Process 38031 Stopped * thread #1: tid = 0x2e03, pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280, stop reason = breakpoint 1.1, queue = com.apple.main-thread 277 278 _CharT* 279 _M_data() const 280 -> { return _M_dataplus._M_p; } 281 282 _CharT* 283 _M_data(_CharT* __p) (lldb) bt thread #1: tid = 0x2e03, stop reason = breakpoint 1.1, queue = com.apple.main-thread frame #0: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280 frame #1: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_rep() const at /usr/include/c++/4.2.1/bits/basic_string.h:288 frame #2: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::size() const at /usr/include/c++/4.2.1/bits/basic_string.h:606 frame #3: pc = 0x0000000100000d31, where = a.out`main [inlined] operator<< , std::allocator > at /usr/include/c++/4.2.1/bits/basic_string.h:2414 frame #4: pc = 0x0000000100000d31, where = a.out`main + 33 at /Volumes/work/gclayton/Documents/src/lldb/test/stl/main.cpp:14 frame #5: pc = 0x0000000100000d08, where = a.out`start + 52 Each inline frame contains only the variables that they contain and each inlined stack frame is treated as a single entity. Modified: lldb/trunk/include/lldb/Core/VMRange.h lldb/trunk/include/lldb/Symbol/Block.h lldb/trunk/include/lldb/Symbol/Function.h lldb/trunk/include/lldb/Symbol/SymbolContext.h lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/Target/StackID.h lldb/trunk/include/lldb/Target/Thread.h lldb/trunk/source/API/SBBlock.cpp lldb/trunk/source/API/SBFrame.cpp lldb/trunk/source/API/SBThread.cpp lldb/trunk/source/Breakpoint/BreakpointLocation.cpp lldb/trunk/source/Commands/CommandObjectImage.cpp lldb/trunk/source/Commands/CommandObjectThread.cpp lldb/trunk/source/Commands/CommandObjectVariable.cpp lldb/trunk/source/Core/Address.cpp lldb/trunk/source/Core/Disassembler.cpp lldb/trunk/source/Core/VMRange.cpp lldb/trunk/source/Expression/DWARFExpression.cpp lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp lldb/trunk/source/Symbol/Block.cpp lldb/trunk/source/Symbol/Function.cpp lldb/trunk/source/Symbol/SymbolContext.cpp lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/StackID.cpp lldb/trunk/source/Target/Target.cpp lldb/trunk/source/Target/Thread.cpp Modified: lldb/trunk/include/lldb/Core/VMRange.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/VMRange.h?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/VMRange.h (original) +++ lldb/trunk/include/lldb/Core/VMRange.h Mon Aug 23 19:45:41 2010 @@ -148,6 +148,11 @@ static bool ContainsRange(const VMRange::collection& coll, const VMRange& range); + // Returns a valid index into coll when a match is found, else UINT32_MAX + // is returned + static uint32_t + FindRangeIndexThatContainsValue (const VMRange::collection& coll, lldb::addr_t value); + protected: lldb::addr_t m_base_addr; lldb::addr_t m_byte_size; Modified: lldb/trunk/include/lldb/Symbol/Block.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Block.h?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Block.h (original) +++ lldb/trunk/include/lldb/Symbol/Block.h Mon Aug 23 19:45:41 2010 @@ -181,6 +181,9 @@ //------------------------------------------------------------------ Block * GetParent () const; + + Block * + GetInlinedParent () const; //------------------------------------------------------------------ /// Get the sibling block for this block. @@ -243,6 +246,11 @@ /// If \b true, all variables from all parent blocks will be /// added to the variable list. /// + /// @param[in] stop_if_block_is_inlined_function + /// If \b true, all variables from all parent blocks will be + /// added to the variable list until there are no parent blocks + /// or the parent block has inlined function info. + /// /// @param[in/out] variable_list /// All variables in this block, and optionally all parent /// blocks will be added to this list. @@ -252,7 +260,10 @@ /// variable_list. //------------------------------------------------------------------ uint32_t - AppendVariables(bool can_create, bool get_parent_variables, VariableList *variable_list); + AppendVariables (bool can_create, + bool get_parent_variables, + bool stop_if_block_is_inlined_function, + VariableList *variable_list); //------------------------------------------------------------------ /// Get accessor for any inlined function information. @@ -352,6 +363,10 @@ Block * FindBlockByID (lldb::user_id_t block_id); + bool + GetRangeContainingAddress (const Address& addr, AddressRange &range); + + protected: typedef std::vector collection; //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Symbol/Function.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Function.h?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Function.h (original) +++ lldb/trunk/include/lldb/Symbol/Function.h Mon Aug 23 19:45:41 2010 @@ -241,6 +241,9 @@ void DumpStopContext (Stream *s) const; + const ConstString & + GetName () const; + //------------------------------------------------------------------ /// Get accessor for the call site declaration information. /// Modified: lldb/trunk/include/lldb/Symbol/SymbolContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolContext.h?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/SymbolContext.h (original) +++ lldb/trunk/include/lldb/Symbol/SymbolContext.h Mon Aug 23 19:45:41 2010 @@ -163,7 +163,8 @@ DumpStopContext (Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, - bool show_module = true) const; + bool show_module, + bool show_inlined_frames) const; //------------------------------------------------------------------ /// Get the address range contained within a symbol context. @@ -190,6 +191,10 @@ lldb::DescriptionLevel level, Process *process) const; + uint32_t + GetResolvedMask () const; + + //------------------------------------------------------------------ /// Find a function matching the given name, working out from this /// symbol context. Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Mon Aug 23 19:45:41 2010 @@ -27,15 +27,15 @@ namespace lldb_private { class StackFrame : - public UserID, public ExecutionContextScope { public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - StackFrame (lldb::user_id_t frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr = NULL); - StackFrame (lldb::user_id_t frame_idx, Thread &thread, lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr = NULL); + StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, lldb::addr_t cfa, uint32_t inline_height, lldb::addr_t pc, const SymbolContext *sc_ptr); + StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, uint32_t inline_height, lldb::addr_t pc, const SymbolContext *sc_ptr); + StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, uint32_t inline_height, const Address& pc, const SymbolContext *sc_ptr); virtual ~StackFrame (); Thread & @@ -64,6 +64,12 @@ RegisterContext * GetRegisterContext (); + const lldb::RegisterContextSP & + GetRegisterContextSP () const + { + return m_reg_context_sp; + } + VariableList * GetVariableList (); @@ -79,6 +85,17 @@ void Dump (Stream *strm, bool show_frame_index); + uint32_t + GetFrameIndex () const + { + return m_frame_index; + } + + uint32_t + GetConcreteFrameIndex () const + { + return m_concrete_frame_index; + } //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions //------------------------------------------------------------------ @@ -108,6 +125,8 @@ // For StackFrame only //------------------------------------------------------------------ Thread &m_thread; + uint32_t m_frame_index; + uint32_t m_concrete_frame_index; lldb::RegisterContextSP m_reg_context_sp; StackID m_id; Address m_pc; // PC as a section/offset address Modified: lldb/trunk/include/lldb/Target/StackID.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackID.h?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackID.h (original) +++ lldb/trunk/include/lldb/Target/StackID.h Mon Aug 23 19:45:41 2010 @@ -26,20 +26,34 @@ // Constructors and Destructors //------------------------------------------------------------------ StackID (); - explicit StackID (lldb::addr_t cfa); - StackID (const Address& start_address, lldb::addr_t cfa); + explicit StackID (lldb::addr_t cfa, uint32_t inline_id); + StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_id); StackID (const StackID& rhs); virtual ~StackID(); const Address& - GetStartAddress() const; + GetStartAddress() const + { + return m_start_address; + } void - SetStartAddress(const Address& start_address); + SetStartAddress(const Address& start_address) + { + m_start_address = start_address; + } lldb::addr_t - GetCallFrameAddress() const; - + GetCallFrameAddress() const + { + return m_cfa; + } + + uint32_t + GetInlineHeight () const + { + return m_inline_height; + } //------------------------------------------------------------------ // Operators //------------------------------------------------------------------ @@ -53,7 +67,10 @@ Address m_start_address; // The address range for the function for this frame lldb::addr_t m_cfa; // The call frame address (stack pointer) value // at the beginning of the function that uniquely - // identifies this frame + // identifies this frame (along with m_inline_height below) + uint32_t m_inline_height; // The inline height of a stack frame. Zero is the actual + // value for the place where a thread stops, 1 and above + // are for the inlined frames above the concrete base frame. }; bool operator== (const StackID& lhs, const StackID& rhs); Modified: lldb/trunk/include/lldb/Target/Thread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Thread.h (original) +++ lldb/trunk/include/lldb/Target/Thread.h Mon Aug 23 19:45:41 2010 @@ -328,7 +328,8 @@ virtual void ClearStackFrames () { - m_frames.Clear(); + m_concrete_frames.Clear(); + m_inlined_frames.Clear(); } void @@ -665,6 +666,13 @@ virtual lldb_private::Unwind * GetUnwinder () = 0; + typedef struct InlinedFrameInfo + { + uint32_t concrete_frame_index; + uint32_t inline_height; + Block *block; + } InlinedFrameInfo; + typedef std::vector InlinedFrameInfoCollection; //------------------------------------------------------------------ // Classes that inherit from Process can see and modify these //------------------------------------------------------------------ @@ -678,9 +686,11 @@ plan_stack m_immediate_plan_stack; ///< The plans that need to get executed before any other work gets done. plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes. plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes. - mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state. - StackFrameList m_frames; ///< The stack frames that get lazily populated after a thread stops. - uint32_t m_current_frame_idx;///< The current frame for this thread + mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state. + StackFrameList m_concrete_frames; ///< The stack frames that get lazily populated after a thread stops. + StackFrameList m_inlined_frames; ///< The stack frames that get lazily populated after a thread stops. + InlinedFrameInfoCollection m_inlined_frame_info; + bool m_show_inlined_frames; int m_resume_signal; ///< The signal that should be used when continuing this thread. lldb::StateType m_resume_state; ///< The state that indicates what this thread should do when the process is resumed. std::auto_ptr m_unwinder_ap; Modified: lldb/trunk/source/API/SBBlock.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBlock.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/API/SBBlock.cpp (original) +++ lldb/trunk/source/API/SBBlock.cpp Mon Aug 23 19:45:41 2010 @@ -39,7 +39,8 @@ { if (IsValid()) { - m_opaque_ptr->AppendVariables (can_create, get_parent_variables, var_list); + bool show_inline = true; + m_opaque_ptr->AppendVariables (can_create, get_parent_variables, show_inline, var_list); } } Modified: lldb/trunk/source/API/SBFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/API/SBFrame.cpp (original) +++ lldb/trunk/source/API/SBFrame.cpp Mon Aug 23 19:45:41 2010 @@ -116,7 +116,7 @@ SBFrame::GetFrameID () const { if (m_opaque_sp) - return m_opaque_sp->GetID(); + return m_opaque_sp->GetFrameIndex (); else return UINT32_MAX; } Modified: lldb/trunk/source/API/SBThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/API/SBThread.cpp (original) +++ lldb/trunk/source/API/SBThread.cpp Mon Aug 23 19:45:41 2010 @@ -288,7 +288,7 @@ frame_idx, GetThreadID(), (long long)pc); - sc->DumpStopContext (&str, &m_opaque_sp->GetProcess(), *frame.GetPCAddress()); + sc->DumpStopContext (&str, &m_opaque_sp->GetProcess(), *frame.GetPCAddress(), true, false); fprintf (out, "\n"); success = true; } Modified: lldb/trunk/source/Breakpoint/BreakpointLocation.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointLocation.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/BreakpointLocation.cpp (original) +++ lldb/trunk/source/Breakpoint/BreakpointLocation.cpp Mon Aug 23 19:45:41 2010 @@ -285,7 +285,7 @@ if (level == lldb::eDescriptionLevelFull) { s->PutCString("where = "); - sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address); + sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, true, false); } else { Modified: lldb/trunk/source/Commands/CommandObjectImage.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectImage.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectImage.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectImage.cpp Mon Aug 23 19:45:41 2010 @@ -341,7 +341,7 @@ strm.PutCString(" in "); } } - sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress()); + sc.DumpStopContext(&strm, interpreter.GetDebugger().GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, false); } } strm.IndentLess (); Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Mon Aug 23 19:45:41 2010 @@ -162,7 +162,7 @@ true, // Dump the stop reason? true, // Dump the thread name? true, // Dump the queue name? - 0); // Dump info for stack frame zero + num_frames > 1 ? UINT32_MAX : first_frame); // Dump info for the first stack frame if we are showing only on frame strm.EOL(); strm.IndentMore(); Modified: lldb/trunk/source/Commands/CommandObjectVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectVariable.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectVariable.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectVariable.cpp Mon Aug 23 19:45:41 2010 @@ -255,7 +255,7 @@ s.Printf ("Variable{0x%8.8x}: ", variable->GetID()); if (!expr_success) - s.Printf ("%s = ERROR (%s)", variable->GetName().AsCString(NULL), expr_error.AsCString()); + s.Printf ("%s = ERROR: %s\n", variable->GetName().AsCString(NULL), expr_error.AsCString()); else { Value::ValueType expr_value_type = expr_result.GetValueType(); @@ -318,8 +318,8 @@ } break; } + s.EOL(); } - s.EOL(); } } @@ -484,9 +484,10 @@ { VariableList variable_list; + bool show_inlined = true; // TODO: Get this from the process SymbolContext frame_sc = exe_ctx.frame->GetSymbolContext (eSymbolContextEverything); if (exe_ctx.frame && frame_sc.block) - frame_sc.block->AppendVariables(true, true, &variable_list); + frame_sc.block->AppendVariables(true, true, show_inlined, &variable_list); VariableSP var_sp; ValueObjectSP valobj_sp; //ValueObjectList &valobj_list = exe_ctx.frame->GetValueObjectList(); Modified: lldb/trunk/source/Core/Address.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Core/Address.cpp (original) +++ lldb/trunk/source/Core/Address.cpp Mon Aug 23 19:45:41 2010 @@ -553,7 +553,7 @@ #endif Address cstr_addr(*this); cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size); - func_sc.DumpStopContext(s, exe_scope, so_addr, true); + func_sc.DumpStopContext(s, exe_scope, so_addr, true, false); if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr)) { #if VERBOSE_OUTPUT @@ -636,7 +636,7 @@ if (pointer_sc.function || pointer_sc.symbol) { s->PutCString(": "); - pointer_sc.DumpStopContext(s, exe_scope, so_addr, false); + pointer_sc.DumpStopContext(s, exe_scope, so_addr, false, false); } } } @@ -675,7 +675,7 @@ { // We have a function or a symbol from the same // sections as this address. - sc.DumpStopContext(s, exe_scope, *this, show_module); + sc.DumpStopContext(s, exe_scope, *this, show_module, false); } else { Modified: lldb/trunk/source/Core/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Core/Disassembler.cpp (original) +++ lldb/trunk/source/Core/Disassembler.cpp Mon Aug 23 19:45:41 2010 @@ -238,7 +238,7 @@ if (offset != 0) strm.EOL(); - sc.DumpStopContext(&strm, process, addr); + sc.DumpStopContext(&strm, process, addr, true, false); if (sc.comp_unit && sc.line_entry.IsValid()) { Modified: lldb/trunk/source/Core/VMRange.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/VMRange.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Core/VMRange.cpp (original) +++ lldb/trunk/source/Core/VMRange.cpp Mon Aug 23 19:45:41 2010 @@ -40,6 +40,17 @@ return false; } +uint32_t +VMRange::FindRangeIndexThatContainsValue (const VMRange::collection& coll, lldb::addr_t value) +{ + ValueInRangeUnaryPredicate in_range_predicate(value); + VMRange::const_iterator begin = coll.begin(); + VMRange::const_iterator end = coll.end(); + VMRange::const_iterator pos = std::find_if (begin, end, in_range_predicate); + if (pos != end) + return std::distance (begin, pos); + return UINT32_MAX; +} void VMRange::Dump(Stream *s, lldb::addr_t offset, uint32_t addr_width) const Modified: lldb/trunk/source/Expression/DWARFExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Expression/DWARFExpression.cpp (original) +++ lldb/trunk/source/Expression/DWARFExpression.cpp Mon Aug 23 19:45:41 2010 @@ -791,7 +791,7 @@ } } if (error_ptr) - error_ptr->SetErrorStringWithFormat("Out of scope.\n", pc); + error_ptr->SetErrorStringWithFormat("Out of scope."); return false; } @@ -995,7 +995,7 @@ // 1 - uint8_t that specifies the size of the data to dereference. // DESCRIPTION: Behaves like the DW_OP_xderef operation: the entry at // the top of the stack is treated as an address. The second stack - // entry is treated as an ???address space identifier??? for those + // entry is treated as an "address space identifier" for those // architectures that support multiple address spaces. The top two // stack elements are popped, a data item is retrieved through an // implementation-defined address calculation and pushed as the new Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/UnwindLibUnwind.cpp Mon Aug 23 19:45:41 2010 @@ -65,7 +65,7 @@ RegisterContext * UnwindLibUnwind::CreateRegisterContextForFrame (StackFrame *frame) { - uint32_t idx = frame->GetID(); + uint32_t idx = frame->GetConcreteFrameIndex (); const uint32_t frame_count = GetFrameCount(); if (idx < frame_count) return new LibUnwindRegisterContext (m_thread, frame, m_cursors[idx]); Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp Mon Aug 23 19:45:41 2010 @@ -66,7 +66,7 @@ RegisterContext * UnwindMacOSXFrameBackchain::CreateRegisterContextForFrame (StackFrame *frame) { - uint32_t idx = frame->GetID(); + uint32_t idx = frame->GetConcreteFrameIndex (); const uint32_t frame_count = GetFrameCount(); if (idx < frame_count) return new RegisterContextMacOSXFrameBackchain (m_thread, frame, m_cursors[idx]); Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Mon Aug 23 19:45:41 2010 @@ -177,11 +177,11 @@ uint32_t frame_idx = 0; if (frame) - frame_idx = frame->GetID(); + frame_idx = frame->GetFrameIndex (); if (frame_idx == 0) return new GDBRemoteRegisterContext (*this, frame, GetGDBProcess().m_register_info, read_all_registers_at_once); - else if (m_unwinder_ap.get() && frame_idx < m_unwinder_ap->GetFrameCount()) + else if (m_unwinder_ap.get()) return m_unwinder_ap->CreateRegisterContextForFrame (frame); return NULL; } Modified: lldb/trunk/source/Symbol/Block.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Block.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Block.cpp (original) +++ lldb/trunk/source/Symbol/Block.cpp Mon Aug 23 19:45:41 2010 @@ -225,6 +225,52 @@ return NULL; } +Block * +Block::GetInlinedParent () const +{ + Block *parent_block = GetParent (); + if (parent_block) + { + if (parent_block->InlinedFunctionInfo()) + return parent_block; + else + return parent_block->GetInlinedParent(); + } + return NULL; +} + + +bool +Block::GetRangeContainingAddress (const Address& addr, AddressRange &range) +{ + SymbolContext sc; + CalculateSymbolContext(&sc); + if (sc.function) + { + const AddressRange &func_range = sc.function->GetAddressRange(); + if (addr.GetSection() == func_range.GetBaseAddress().GetSection()) + { + const addr_t addr_offset = addr.GetOffset(); + const addr_t func_offset = func_range.GetBaseAddress().GetOffset(); + if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize()) + { + addr_t offset = addr_offset - func_offset; + + uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset); + if (range_idx < m_ranges.size()) + { + range.GetBaseAddress() = func_range.GetBaseAddress(); + range.GetBaseAddress().SetOffset(func_offset + m_ranges[range_idx].GetBaseAddress()); + range.SetByteSize(m_ranges[range_idx].GetByteSize()); + return true; + } + } + } + } + range.Clear(); + return false; +} + void Block::AddRange(addr_t start_offset, addr_t end_offset) { @@ -330,22 +376,32 @@ } uint32_t -Block::AppendVariables (bool can_create, bool get_parent_variables, VariableList *variable_list) +Block::AppendVariables +( + bool can_create, + bool get_parent_variables, + bool stop_if_block_is_inlined_function, + VariableList *variable_list +) { uint32_t num_variables_added = 0; VariableListSP variable_list_sp(GetVariableList(false, can_create)); + bool is_inlined_function = InlinedFunctionInfo() != NULL; if (variable_list_sp.get()) { num_variables_added = variable_list_sp->GetSize(); variable_list->AddVariables(variable_list_sp.get()); } - + if (get_parent_variables) { + if (stop_if_block_is_inlined_function && is_inlined_function) + return num_variables_added; + Block* parent_block = GetParent(); if (parent_block) - num_variables_added += parent_block->AppendVariables (can_create, get_parent_variables, variable_list); + num_variables_added += parent_block->AppendVariables (can_create, get_parent_variables, stop_if_block_is_inlined_function, variable_list); } return num_variables_added; } Modified: lldb/trunk/source/Symbol/Function.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Function.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Function.cpp (original) +++ lldb/trunk/source/Symbol/Function.cpp Mon Aug 23 19:45:41 2010 @@ -148,6 +148,16 @@ s->PutCString (m_name.AsCString()); } + +const ConstString & +InlineFunctionInfo::GetName () const +{ + if (m_mangled) + return m_mangled.GetName(); + return m_name; +} + + Declaration & InlineFunctionInfo::GetCallSite () { Modified: lldb/trunk/source/Symbol/SymbolContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Symbol/SymbolContext.cpp (original) +++ lldb/trunk/source/Symbol/SymbolContext.cpp Mon Aug 23 19:45:41 2010 @@ -114,7 +114,8 @@ Stream *s, ExecutionContextScope *exe_scope, const Address &addr, - bool show_module + bool show_module, + bool show_inlined_frames ) const { if (show_module && module_sp) @@ -127,6 +128,30 @@ if (function->GetMangled().GetName()) function->GetMangled().GetName().Dump(s); + + if (show_inlined_frames && block) + { + InlineFunctionInfo *inline_info = block->InlinedFunctionInfo(); + if (inline_info == NULL) + { + Block *parent_inline_block = block->GetInlinedParent(); + if (parent_inline_block) + inline_info = parent_inline_block->InlinedFunctionInfo(); + } + + if (inline_info) + { + s->PutCString(" [inlined] "); + inline_info->GetName().Dump(s); + + if (line_entry.IsValid()) + { + s->PutCString(" at "); + line_entry.DumpStopContext(s); + } + return; + } + } const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset(); if (function_offset) s->Printf(" + %llu", function_offset); @@ -237,6 +262,19 @@ } } +uint32_t +SymbolContext::GetResolvedMask () const +{ + uint32_t resolved_mask = 0; + if (target_sp) resolved_mask |= eSymbolContextTarget; + if (module_sp) resolved_mask |= eSymbolContextModule; + if (comp_unit) resolved_mask |= eSymbolContextCompUnit; + if (function) resolved_mask |= eSymbolContextFunction; + if (block) resolved_mask |= eSymbolContextBlock; + if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry; + if (symbol) resolved_mask |= eSymbolContextSymbol; + return resolved_mask; +} void Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Mon Aug 23 19:45:41 2010 @@ -35,38 +35,118 @@ #define FRAME_IS_OBSOLETE (GOT_FRAME_BASE << 1) #define RESOLVED_VARIABLES (FRAME_IS_OBSOLETE << 1) -StackFrame::StackFrame (lldb::user_id_t frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr) : - UserID (frame_idx), +StackFrame::StackFrame +( + lldb::user_id_t frame_idx, + lldb::user_id_t concrete_frame_index, + Thread &thread, + lldb::addr_t cfa, + uint32_t inline_height, + lldb::addr_t pc, + const SymbolContext *sc_ptr +) : + m_frame_index (frame_idx), + m_concrete_frame_index (concrete_frame_index), m_thread (thread), - m_reg_context_sp(), - m_id(cfa), - m_pc(NULL, pc), - m_sc(), - m_flags(), - m_frame_base(), - m_frame_base_error(), + m_reg_context_sp (), + m_id (cfa, inline_height), + m_pc (NULL, pc), + m_sc (), + m_flags (), + m_frame_base (), + m_frame_base_error (), m_variable_list_sp (), m_value_object_list () { if (sc_ptr != NULL) + { m_sc = *sc_ptr; + m_flags.Set(m_sc.GetResolvedMask ()); + } } -StackFrame::StackFrame (lldb::user_id_t frame_idx, Thread &thread, RegisterContextSP ®_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr) : - UserID (frame_idx), +StackFrame::StackFrame +( + lldb::user_id_t frame_idx, + lldb::user_id_t concrete_frame_index, + Thread &thread, + const RegisterContextSP ®_context_sp, + lldb::addr_t cfa, + uint32_t inline_height, + lldb::addr_t pc, + const SymbolContext *sc_ptr +) : + m_frame_index (frame_idx), + m_concrete_frame_index (concrete_frame_index), m_thread (thread), - m_reg_context_sp(reg_context_sp), - m_id(cfa), - m_pc(NULL, pc), - m_sc(), - m_flags(), - m_frame_base(), - m_frame_base_error(), + m_reg_context_sp (reg_context_sp), + m_id (cfa, inline_height), + m_pc (NULL, pc), + m_sc (), + m_flags (), + m_frame_base (), + m_frame_base_error (), m_variable_list_sp (), m_value_object_list () { if (sc_ptr != NULL) + { m_sc = *sc_ptr; + m_flags.Set(m_sc.GetResolvedMask ()); + } + + if (reg_context_sp && !m_sc.target_sp) + { + m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP(); + m_flags.Set (eSymbolContextTarget); + } +} + +StackFrame::StackFrame +( + lldb::user_id_t frame_idx, + lldb::user_id_t concrete_frame_index, + Thread &thread, + const RegisterContextSP ®_context_sp, + lldb::addr_t cfa, + uint32_t inline_height, + const Address& pc_addr, + const SymbolContext *sc_ptr +) : + m_frame_index (frame_idx), + m_concrete_frame_index (concrete_frame_index), + m_thread (thread), + m_reg_context_sp (reg_context_sp), + m_id (cfa, inline_height), + m_pc (pc_addr), + m_sc (), + m_flags (), + m_frame_base (), + m_frame_base_error (), + m_variable_list_sp (), + m_value_object_list () +{ + if (sc_ptr != NULL) + { + m_sc = *sc_ptr; + m_flags.Set(m_sc.GetResolvedMask ()); + } + + if (m_sc.target_sp.get() == NULL && reg_context_sp) + { + m_sc.target_sp = reg_context_sp->GetThread().GetProcess().GetTarget().GetSP(); + m_flags.Set (eSymbolContextTarget); + } + + if (m_sc.module_sp.get() == NULL && pc_addr.GetSection()) + { + Module *pc_module = pc_addr.GetSection()->GetModule(); + if (pc_module) + { + m_sc.module_sp = pc_module->GetSP(); + m_flags.Set (eSymbolContextModule); + } + } } @@ -213,7 +293,7 @@ // instruction following the function call instruction... Address lookup_addr(GetPC()); - if (GetID() > 0 && lookup_addr.IsValid()) + if (m_frame_index > 0 && lookup_addr.IsValid()) { addr_t offset = lookup_addr.GetOffset(); if (offset > 0) @@ -225,11 +305,65 @@ // We have something in our stack frame symbol context, lets check // if we haven't already tried to lookup one of those things. If we // haven't then we will do the query. - if ((m_sc.comp_unit == NULL && (resolve_scope & eSymbolContextCompUnit ) && m_flags.IsClear(eSymbolContextCompUnit )) || - (m_sc.function == NULL && (resolve_scope & eSymbolContextFunction ) && m_flags.IsClear(eSymbolContextFunction )) || - (m_sc.block == NULL && (resolve_scope & eSymbolContextBlock ) && m_flags.IsClear(eSymbolContextBlock )) || - (m_sc.symbol == NULL && (resolve_scope & eSymbolContextSymbol ) && m_flags.IsClear(eSymbolContextSymbol )) || - (!m_sc.line_entry.IsValid() && (resolve_scope & eSymbolContextLineEntry) && m_flags.IsClear(eSymbolContextLineEntry ))) + + uint32_t actual_resolve_scope = 0; + + if (resolve_scope & eSymbolContextCompUnit) + { + if (m_flags.IsClear (eSymbolContextCompUnit)) + { + if (m_sc.comp_unit) + m_flags.Set (eSymbolContextCompUnit); + else + actual_resolve_scope |= eSymbolContextCompUnit; + } + } + + if (resolve_scope & eSymbolContextFunction) + { + if (m_flags.IsClear (eSymbolContextFunction)) + { + if (m_sc.function) + m_flags.Set (eSymbolContextFunction); + else + actual_resolve_scope |= eSymbolContextFunction; + } + } + + if (resolve_scope & eSymbolContextBlock) + { + if (m_flags.IsClear (eSymbolContextBlock)) + { + if (m_sc.block) + m_flags.Set (eSymbolContextBlock); + else + actual_resolve_scope |= eSymbolContextBlock; + } + } + + if (resolve_scope & eSymbolContextSymbol) + { + if (m_flags.IsClear (eSymbolContextSymbol)) + { + if (m_sc.symbol) + m_flags.Set (eSymbolContextSymbol); + else + actual_resolve_scope |= eSymbolContextSymbol; + } + } + + if (resolve_scope & eSymbolContextLineEntry) + { + if (m_flags.IsClear (eSymbolContextLineEntry)) + { + if (m_sc.line_entry.IsValid()) + m_flags.Set (eSymbolContextLineEntry); + else + actual_resolve_scope |= eSymbolContextLineEntry; + } + } + + if (actual_resolve_scope) { // We might be resolving less information than what is already // in our current symbol context so resolve into a temporary @@ -237,7 +371,10 @@ // already found in "m_sc" SymbolContext sc; // Set flags that indicate what we have tried to resolve - const uint32_t resolved = m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, resolve_scope, sc); + const uint32_t resolved = m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); + // Only replace what we didn't already have as we may have + // information for an inlined function scope that won't match + // what a standard lookup by address would match if (resolved & eSymbolContextCompUnit) m_sc.comp_unit = sc.comp_unit; if (resolved & eSymbolContextFunction) m_sc.function = sc.function; if (resolved & eSymbolContextBlock) m_sc.block = sc.block; @@ -387,10 +524,13 @@ return; if (show_frame_index) - strm->Printf("frame #%u: ", GetID()); + strm->Printf("frame #%u: ", m_frame_index); strm->Printf("pc = 0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetRegisterContext()->GetPC()); SymbolContext sc (GetSymbolContext(eSymbolContextEverything)); strm->PutCString(", where = "); - sc.DumpStopContext(strm, &m_thread.GetProcess(), GetPC()); + // TODO: need to get the + const bool show_module = true; + const bool show_inline = true; + sc.DumpStopContext(strm, &m_thread.GetProcess(), GetPC(), show_module, show_inline); } Modified: lldb/trunk/source/Target/StackID.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackID.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Target/StackID.cpp (original) +++ lldb/trunk/source/Target/StackID.cpp Mon Aug 23 19:45:41 2010 @@ -21,22 +21,25 @@ //---------------------------------------------------------------------- StackID::StackID() : m_start_address(), - m_cfa() + m_cfa (0), + m_inline_height (0) { } //---------------------------------------------------------------------- // StackID constructor with args //---------------------------------------------------------------------- -StackID::StackID (const Address& start_address, lldb::addr_t cfa) : +StackID::StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_id) : m_start_address (start_address), - m_cfa (cfa) + m_cfa (cfa), + m_inline_height (inline_id) { } -StackID::StackID (lldb::addr_t cfa) : +StackID::StackID (lldb::addr_t cfa, uint32_t inline_id) : m_start_address (), - m_cfa (cfa) + m_cfa (cfa), + m_inline_height (inline_id) { } @@ -45,7 +48,8 @@ //---------------------------------------------------------------------- StackID::StackID(const StackID& rhs) : m_start_address (rhs.m_start_address), - m_cfa (rhs.m_cfa) + m_cfa (rhs.m_cfa), + m_inline_height (rhs.m_inline_height) { } @@ -59,6 +63,7 @@ { m_start_address = rhs.m_start_address; m_cfa = rhs.m_cfa; + m_inline_height = rhs.m_inline_height; } return *this; } @@ -70,36 +75,20 @@ { } - -const Address& -StackID::GetStartAddress() const -{ - return m_start_address; -} - -void -StackID::SetStartAddress(const Address& start_address) -{ - m_start_address = start_address; -} - -lldb::addr_t -StackID::GetCallFrameAddress() const -{ - return m_cfa; -} - - bool lldb_private::operator== (const StackID& lhs, const StackID& rhs) { - return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() && lhs.GetStartAddress() == rhs.GetStartAddress(); + return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() && + lhs.GetInlineHeight() == rhs.GetInlineHeight() && + lhs.GetStartAddress() == rhs.GetStartAddress(); } bool lldb_private::operator!= (const StackID& lhs, const StackID& rhs) { - return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() || lhs.GetStartAddress() != rhs.GetStartAddress(); + return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() || + lhs.GetInlineHeight() != rhs.GetInlineHeight() || + lhs.GetStartAddress() != rhs.GetStartAddress(); } bool Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Mon Aug 23 19:45:41 2010 @@ -156,16 +156,22 @@ BreakpointSP -Target::CreateBreakpoint (lldb::addr_t load_addr, bool internal) +Target::CreateBreakpoint (lldb::addr_t addr, bool internal) { - BreakpointSP bp_sp; Address so_addr; // Attempt to resolve our load address if possible, though it is ok if // it doesn't resolve to section/offset. Process *process = GetProcessSP().get(); - if (process && process->ResolveLoadAddress(load_addr, so_addr)) - bp_sp = CreateBreakpoint(so_addr, internal); + // Try and resolve as a load address if possible + if (process) + process->ResolveLoadAddress(addr, so_addr); + if (!so_addr.IsValid()) + { + // The address didn't resolve, so just set this as an absolute address + so_addr.SetOffset (addr); + } + BreakpointSP bp_sp (CreateBreakpoint(so_addr, internal)); return bp_sp; } Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=111877&r1=111876&r2=111877&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Mon Aug 23 19:45:41 2010 @@ -49,8 +49,10 @@ m_immediate_plan_stack(), m_completed_plan_stack(), m_state_mutex (Mutex::eMutexTypeRecursive), - m_frames (), - m_current_frame_idx (0), + m_concrete_frames (), + m_inlined_frames (), + m_inlined_frame_info (), + m_show_inlined_frames (true), m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER), m_resume_state (eStateRunning), m_unwinder_ap () @@ -798,7 +800,69 @@ { Unwind *unwinder = GetUnwinder (); if (unwinder) - return unwinder->GetFrameCount(); + { + if (m_show_inlined_frames) + { + if (m_inlined_frame_info.empty()) + { + // If we are going to show inlined stack frames as actual frames, + // we need to calculate all concrete frames first, then iterate + // through all of them and count up how many inlined functions are + // in each frame. We can then fill in m_inlined_frame_info with + // the concrete frame index and inlined depth + const uint32_t concrete_frame_count = unwinder->GetFrameCount(); + + addr_t pc, cfa; + InlinedFrameInfo inlined_frame_info; + + StackFrameSP frame_sp; + for (uint32_t idx=0; idxGetSP(), 0, m_reg_context_sp->GetPC(), NULL)); + } + else + { + const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc); + assert (success); + frame_sp.reset (new StackFrame (m_inlined_frame_info.size(), idx, *this, cfa, 0, pc, NULL)); + } + m_concrete_frames.SetFrameAtIndex(idx, frame_sp); + Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block; + + inlined_frame_info.concrete_frame_index = idx; + inlined_frame_info.inline_height = 0; + inlined_frame_info.block = block; + m_inlined_frame_info.push_back (inlined_frame_info); + + if (block) + { + Block *inlined_block; + if (block->InlinedFunctionInfo()) + inlined_block = block; + else + inlined_block = block->GetInlinedParent (); + + while (inlined_block) + { + inlined_frame_info.block = inlined_block; + inlined_frame_info.inline_height++; + m_inlined_frame_info.push_back (inlined_frame_info); + inlined_block = inlined_block->GetInlinedParent (); + } + } + } + } + return m_inlined_frame_info.size(); + } + else + { + return unwinder->GetFrameCount(); + } + } return 0; } @@ -806,7 +870,12 @@ Thread::GetStackFrameAtIndex (uint32_t idx) { - StackFrameSP frame_sp (m_frames.GetFrameAtIndex(idx)); + StackFrameSP frame_sp; + + if (m_show_inlined_frames) + frame_sp = m_inlined_frames.GetFrameAtIndex(idx); + else + frame_sp = m_concrete_frames.GetFrameAtIndex(idx); if (frame_sp.get()) return frame_sp; @@ -827,38 +896,95 @@ // context with the stack frame at index zero. GetRegisterContext(); assert (m_reg_context_sp.get()); - frame_sp.reset (new StackFrame (idx, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), m_reg_context_sp->GetPC())); + frame_sp.reset (new StackFrame (0, 0, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), 0, m_reg_context_sp->GetPC(), NULL)); } else if (idx < GetStackFrameCount()) { - Unwind *unwinder = GetUnwinder (); - if (unwinder) + if (m_show_inlined_frames) { - addr_t pc, cfa; - if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) - frame_sp.reset (new StackFrame (idx, *this, cfa, pc)); + if (m_inlined_frame_info[idx].inline_height == 0) + { + // Same as the concrete stack frame if block is NULL + frame_sp = m_concrete_frames.GetFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index); + } + else + { + // We have blocks that were above an inlined function. Inlined + // functions are represented as blocks with non-NULL inline + // function info. Here we must reconstruct a frame by looking + // at the block + StackFrameSP previous_frame_sp (GetStackFrameAtIndex (idx-1)); + + SymbolContext inline_sc; + + Block *inlined_parent_block = m_inlined_frame_info[idx].block->GetInlinedParent(); + + if (inlined_parent_block) + inlined_parent_block->CalculateSymbolContext (&inline_sc); + else + { + Block *parent_block = m_inlined_frame_info[idx].block->GetParent(); + parent_block->CalculateSymbolContext(&inline_sc); + } + + InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo(); + assert (inline_info); + inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetPC(); + inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); + inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); + inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); + + StackFrameSP concrete_frame_sp (m_concrete_frames.GetFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index)); + assert (previous_frame_sp.get()); + AddressRange range; + m_inlined_frame_info[idx].block->GetRangeContainingAddress (previous_frame_sp->GetPC(), range); + + frame_sp.reset (new StackFrame (idx, + m_inlined_frame_info[idx].concrete_frame_index, + *this, + concrete_frame_sp->GetRegisterContextSP (), + concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA + m_inlined_frame_info[idx].inline_height, // Inline height + range.GetBaseAddress(), + &inline_sc)); // The symbol context for this inline frame + + } + + } + else + { + Unwind *unwinder = GetUnwinder (); + if (unwinder) + { + addr_t pc, cfa; + if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) + frame_sp.reset (new StackFrame (idx, idx, *this, cfa, 0, pc, NULL)); + } } } - m_frames.SetFrameAtIndex(idx, frame_sp); + if (m_show_inlined_frames) + m_inlined_frames.SetFrameAtIndex(idx, frame_sp); + else + m_concrete_frames.SetFrameAtIndex(idx, frame_sp); return frame_sp; } lldb::StackFrameSP Thread::GetCurrentFrame () { - return GetStackFrameAtIndex (m_frames.GetCurrentFrameIndex()); + return GetStackFrameAtIndex (m_concrete_frames.GetCurrentFrameIndex()); } uint32_t Thread::SetCurrentFrame (lldb_private::StackFrame *frame) { - return m_frames.SetCurrentFrame(frame); + return m_concrete_frames.SetCurrentFrame(frame); } void -Thread::SetCurrentFrameByIndex (uint32_t frame_idx) +Thread::SetCurrentFrameByIndex (uint32_t idx) { - m_frames.SetCurrentFrameByIndex(frame_idx); + m_concrete_frames.SetCurrentFrameByIndex(idx); } void @@ -868,14 +994,14 @@ bool show_stop_reason, bool show_name, bool show_queue, - uint32_t frame_idx + uint32_t idx ) { strm.Printf("thread #%u: tid = 0x%4.4x", GetIndexID(), GetID()); - if (frame_idx != LLDB_INVALID_INDEX32) + if (idx != LLDB_INVALID_INDEX32) { - StackFrameSP frame_sp(GetStackFrameAtIndex (frame_idx)); + StackFrameSP frame_sp(GetStackFrameAtIndex (idx)); if (frame_sp) { strm.PutCString(", "); From gclayton at apple.com Mon Aug 23 20:28:00 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 24 Aug 2010 01:28:00 -0000 Subject: [Lldb-commits] [lldb] r111891 - /lldb/trunk/include/lldb/Target/Thread.h Message-ID: <20100824012800.93A462A6C12C@llvm.org> Author: gclayton Date: Mon Aug 23 20:28:00 2010 New Revision: 111891 URL: http://llvm.org/viewvc/llvm-project?rev=111891&view=rev Log: Clear the inline stack frame info when we clean all stack frames. Modified: lldb/trunk/include/lldb/Target/Thread.h Modified: lldb/trunk/include/lldb/Target/Thread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=111891&r1=111890&r2=111891&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Thread.h (original) +++ lldb/trunk/include/lldb/Target/Thread.h Mon Aug 23 20:28:00 2010 @@ -330,6 +330,7 @@ { m_concrete_frames.Clear(); m_inlined_frames.Clear(); + m_inlined_frame_info.clear(); } void From johnny.chen at apple.com Tue Aug 24 11:35:00 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 16:35:00 -0000 Subject: [Lldb-commits] [lldb] r111920 - /lldb/trunk/test/make/Makefile.rules Message-ID: <20100824163500.6EFE32A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 11:35:00 2010 New Revision: 111920 URL: http://llvm.org/viewvc/llvm-project?rev=111920&view=rev Log: Generates the .d prerequisite file for dylib as well. Modified: lldb/trunk/test/make/Makefile.rules Modified: lldb/trunk/test/make/Makefile.rules URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/make/Makefile.rules?rev=111920&r1=111919&r2=111920&view=diff ============================================================================== --- lldb/trunk/test/make/Makefile.rules (original) +++ lldb/trunk/test/make/Makefile.rules Tue Aug 24 11:35:00 2010 @@ -100,6 +100,9 @@ # files by replacing all .c files with .d. #---------------------------------------------------------------------- PREREQS := $(OBJECTS:.o=.d) +ifneq "$(DYLIB_NAME)" "" + DYLIB_PREREQS := $(DYLIB_OBJECTS:.o=.d) +endif #---------------------------------------------------------------------- # Rule for Generating Prerequisites Automatically using .d files and @@ -135,6 +138,9 @@ # to manually track all of the prerequisites for each source file. #---------------------------------------------------------------------- sinclude $(PREREQS) +ifneq "$(DYLIB_NAME)" "" + sinclude $(DYLIB_PREREQS) +endif .PHONY: clean dsym: $(DSYM) From johnny.chen at apple.com Tue Aug 24 12:43:34 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 17:43:34 -0000 Subject: [Lldb-commits] [lldb] r111928 - /lldb/trunk/test/bitfields/Makefile Message-ID: <20100824174334.A5EB32A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 12:43:34 2010 New Revision: 111928 URL: http://llvm.org/viewvc/llvm-project?rev=111928&view=rev Log: Converted to Makefile.rules. Modified: lldb/trunk/test/bitfields/Makefile Modified: lldb/trunk/test/bitfields/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/Makefile?rev=111928&r1=111927&r2=111928&view=diff ============================================================================== --- lldb/trunk/test/bitfields/Makefile (original) +++ lldb/trunk/test/bitfields/Makefile Tue Aug 24 12:43:34 2010 @@ -1,125 +1,5 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES :=main.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../make +C_SOURCES := main.c +include $(LEVEL)/Makefile.rules From johnny.chen at apple.com Tue Aug 24 13:21:23 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 18:21:23 -0000 Subject: [Lldb-commits] [lldb] r111937 - /lldb/trunk/test/bitfields/TestBitfields.py Message-ID: <20100824182123.2ACD72A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 13:21:23 2010 New Revision: 111937 URL: http://llvm.org/viewvc/llvm-project?rev=111937&view=rev Log: Added test case TestBitfields.py for rdar://problem/8348251, where "variable list bits" display bits variable correctly, but not "variable list". Added: lldb/trunk/test/bitfields/TestBitfields.py Added: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=111937&view=auto ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (added) +++ lldb/trunk/test/bitfields/TestBitfields.py Tue Aug 24 13:21:23 2010 @@ -0,0 +1,61 @@ +"""Show bitfields and check that they display correctly.""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class TestBitfields(TestBase): + + mydir = "bitfields" + + @unittest2.expectedFailure + def test_global_variables(self): + """Test 'variable list ...' and check for correct display.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + self.expect("breakpoint set -f main.c -l 42", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.c', line = 42, locations = 1") + + self.runCmd("run", RUN_STOPPED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['state is Stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + # This should display correctly. + self.expect("variable list bits", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(uint32_t:1) b1 = 0x00000001,', + '(uint32_t:2) b2 = 0x00000003,', + '(uint32_t:3) b3 = 0x00000007,', + '(uint32_t:4) b4 = 0x0000000f,', + '(uint32_t:5) b5 = 0x0000001f,', + '(uint32_t:6) b6 = 0x0000003f,', + '(uint32_t:7) b7 = 0x0000007f,', + '(uint32_t:4) four = 0x0000000f']) + + # And so should this. + # rdar://problem/8348251 + self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(uint32_t:1) b1 = 0x00000001,', + '(uint32_t:2) b2 = 0x00000003,', + '(uint32_t:3) b3 = 0x00000007,', + '(uint32_t:4) b4 = 0x0000000f,', + '(uint32_t:5) b5 = 0x0000001f,', + '(uint32_t:6) b6 = 0x0000003f,', + '(uint32_t:7) b7 = 0x0000007f,', + '(uint32_t:4) four = 0x0000000f']) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() From johnny.chen at apple.com Tue Aug 24 13:41:53 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 18:41:53 -0000 Subject: [Lldb-commits] [lldb] r111938 - /lldb/trunk/test/enum_types/Makefile Message-ID: <20100824184153.1FB6F2A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 13:41:52 2010 New Revision: 111938 URL: http://llvm.org/viewvc/llvm-project?rev=111938&view=rev Log: Converted to Makefile.rules. Modified: lldb/trunk/test/enum_types/Makefile Modified: lldb/trunk/test/enum_types/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/enum_types/Makefile?rev=111938&r1=111937&r2=111938&view=diff ============================================================================== --- lldb/trunk/test/enum_types/Makefile (original) +++ lldb/trunk/test/enum_types/Makefile Tue Aug 24 13:41:52 2010 @@ -1,125 +1,5 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES :=main.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) - +LEVEL = ../make +C_SOURCES := main.c +include $(LEVEL)/Makefile.rules From johnny.chen at apple.com Tue Aug 24 13:46:00 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 18:46:00 -0000 Subject: [Lldb-commits] [lldb] r111939 - /lldb/trunk/test/bitfields/TestBitfields.py Message-ID: <20100824184600.2D0452A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 13:46:00 2010 New Revision: 111939 URL: http://llvm.org/viewvc/llvm-project?rev=111939&view=rev Log: Need a better method name. Modified: lldb/trunk/test/bitfields/TestBitfields.py Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=111939&r1=111938&r2=111939&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Tue Aug 24 13:46:00 2010 @@ -10,7 +10,7 @@ mydir = "bitfields" @unittest2.expectedFailure - def test_global_variables(self): + def test_variable_list_for_bitfields(self): """Test 'variable list ...' and check for correct display.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) From johnny.chen at apple.com Tue Aug 24 15:44:33 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 20:44:33 -0000 Subject: [Lldb-commits] [lldb] r111958 - /lldb/trunk/test/enum_types/TestEnumTypes.py Message-ID: <20100824204433.BD76A2A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 15:44:33 2010 New Revision: 111958 URL: http://llvm.org/viewvc/llvm-project?rev=111958&view=rev Log: Added a test case which uses "image lookup" command on an enum data type. Added: lldb/trunk/test/enum_types/TestEnumTypes.py Added: lldb/trunk/test/enum_types/TestEnumTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/enum_types/TestEnumTypes.py?rev=111958&view=auto ============================================================================== --- lldb/trunk/test/enum_types/TestEnumTypes.py (added) +++ lldb/trunk/test/enum_types/TestEnumTypes.py Tue Aug 24 15:44:33 2010 @@ -0,0 +1,51 @@ +"""Look up enum type information and check for correct display.""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class TestEnumTypes(TestBase): + + mydir = "enum_types" + + def test_image_lookup_for_enum_type(self): + """Test 'image lookup -t days' and check for correct display.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + self.expect("breakpoint set -f main.c -l 26", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.c', line = 26, locations = 1") + + self.runCmd("run", RUN_STOPPED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['state is Stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + # Look up information about the 'days' enum type. + # Check for correct display. + self.expect("image lookup -t days", DATA_TYPES_DISPLAYED_CORRECTLY, + substrs = ['enum days {', + 'Monday,', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday,', + 'kNumDays', + '}']) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() From johnny.chen at apple.com Tue Aug 24 15:48:28 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 20:48:28 -0000 Subject: [Lldb-commits] [lldb] r111960 - /lldb/trunk/test/bitfields/TestBitfields.py Message-ID: <20100824204828.44AE12A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 15:48:28 2010 New Revision: 111960 URL: http://llvm.org/viewvc/llvm-project?rev=111960&view=rev Log: More descriptive method doc string. Modified: lldb/trunk/test/bitfields/TestBitfields.py Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=111960&r1=111959&r2=111960&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Tue Aug 24 15:48:28 2010 @@ -11,7 +11,7 @@ @unittest2.expectedFailure def test_variable_list_for_bitfields(self): - """Test 'variable list ...' and check for correct display.""" + """Test 'variable list ...' on a variable with bitfields.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) From johnny.chen at apple.com Tue Aug 24 15:54:26 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 20:54:26 -0000 Subject: [Lldb-commits] [lldb] r111961 - /lldb/trunk/test/inlines/Makefile Message-ID: <20100824205426.53E112A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 15:54:26 2010 New Revision: 111961 URL: http://llvm.org/viewvc/llvm-project?rev=111961&view=rev Log: Converted to Makefile.rules. Modified: lldb/trunk/test/inlines/Makefile Modified: lldb/trunk/test/inlines/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/inlines/Makefile?rev=111961&r1=111960&r2=111961&view=diff ============================================================================== --- lldb/trunk/test/inlines/Makefile (original) +++ lldb/trunk/test/inlines/Makefile Tue Aug 24 15:54:26 2010 @@ -1,125 +1,5 @@ -#---------------------------------------------------------------------- -# Fill in the source files to build -#---------------------------------------------------------------------- -C_SOURCES := inlines.c -CXX_SOURCES := -OBJC_SOURCES := -OBJCXX_SOURCES := - -# Uncomment line below for debugging shell commands -# SHELL = /bin/sh -x - -#---------------------------------------------------------------------- -# Change any build/tool options needed -#---------------------------------------------------------------------- -DS := /usr/bin/dsymutil -DSFLAGS = -CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 -CPLUSPLUSFLAGS +=$(CFLAGS) -CPPFLAGS +=$(CFLAGS) -LD = gcc -LDFLAGS = $(CFLAGS) -OBJECTS = -EXE=a.out -DSYM=$(EXE).dSYM - -#---------------------------------------------------------------------- -# Check if we have any C source files -#---------------------------------------------------------------------- -ifneq "$(strip $(C_SOURCES))" "" - OBJECTS +=$(strip $(C_SOURCES:.c=.o)) -endif - -#---------------------------------------------------------------------- -# Check if we have any C++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(CXX_SOURCES))" "" - OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) - LD = g++ -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJC_SOURCES))" "" - OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) - LDFLAGS +=-lobjc -endif - -#---------------------------------------------------------------------- -# Check if we have any ObjC++ source files -#---------------------------------------------------------------------- -ifneq "$(strip $(OBJCXX_SOURCES))" "" - OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) - LD = g++ - ifeq $(findstring lobjc,$(LDFLAGS)) "" - LDFLAGS +=-lobjc - endif -endif - - -#---------------------------------------------------------------------- -# Make the dSYM file from the executable -#---------------------------------------------------------------------- -$(DSYM) : $(EXE) - $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" - -#---------------------------------------------------------------------- -# Compile the executable from all the objects (default rule) with no -# dsym file. -#---------------------------------------------------------------------- -$(EXE) : $(OBJECTS) - $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" - - -#---------------------------------------------------------------------- -# Automatic variables based on items already entered. Below we create -# an objects lists from the list of sources by replacing all entries -# that end with .c with .o, and we also create a list of prerequisite -# files by replacing all .c files with .d. -#---------------------------------------------------------------------- -PREREQS := $(OBJECTS:.o=.d) - -#---------------------------------------------------------------------- -# Rule for Generating Prerequisites Automatically using .d files and -# the compiler -MM option. The -M option will list all system headers, -# and the -MM option will list all non-system dependencies. -#---------------------------------------------------------------------- -%.d: %.c - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.cpp - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.m - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -%.d: %.mm - @set -e; rm -f $@; \ - $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ - -#---------------------------------------------------------------------- -# Include all of the makefiles for each source file so we don't have -# to manually track all of the prerequisites for each source file. -#---------------------------------------------------------------------- -sinclude $(PREREQS) - -.PHONY: clean -dsym: $(DSYM) -all: $(EXE) $(DSYM) -clean: - rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) *~ - +LEVEL = ../make +C_SOURCES := inlines.c +include $(LEVEL)/Makefile.rules From gclayton at apple.com Tue Aug 24 16:05:24 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 24 Aug 2010 21:05:24 -0000 Subject: [Lldb-commits] [lldb] r111964 - in /lldb/trunk: include/lldb/Core/ include/lldb/Expression/ include/lldb/Symbol/ include/lldb/Target/ source/API/ source/Commands/ source/Core/ source/Expression/ source/Plugins/Process/MacOSX-User/source/MacOSX/ source/Plugins/Process/Utility/ source/Symbol/ source/Target/ Message-ID: <20100824210525.29FBC2A6C12C@llvm.org> Author: gclayton Date: Tue Aug 24 16:05:24 2010 New Revision: 111964 URL: http://llvm.org/viewvc/llvm-project?rev=111964&view=rev Log: Got a lot of the kinks worked out in the inline support after debugging more complex inlined examples. StackFrame classes don't have a "GetPC" anymore, they have "GetFrameCodeAddress()". This is because inlined frames will have a PC value that is the same as the concrete frame that owns the inlined frame, yet the code locations for the frame can be different. We also need to be able to get the real PC value for a given frame so that variables evaluate correctly. To get the actual PC value for a frame you can use: addr_t pc = frame->GetRegisterContext()->GetPC(); Some issues with the StackFrame stomping on its own symbol context were resolved which were causing the information to change for a frame when the stack ID was calculated. Also the StackFrame will now correctly store the symbol context resolve flags for any extra bits of information that were looked up (if you ask for a block only and you find one, you will alwasy have the compile unit and function). Modified: lldb/trunk/include/lldb/Core/ModuleList.h lldb/trunk/include/lldb/Core/VMRange.h lldb/trunk/include/lldb/Expression/DWARFExpression.h lldb/trunk/include/lldb/Symbol/Block.h lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/source/API/SBFrame.cpp lldb/trunk/source/Commands/CommandObjectArgs.cpp lldb/trunk/source/Commands/CommandObjectDisassemble.cpp lldb/trunk/source/Core/Disassembler.cpp lldb/trunk/source/Core/ModuleList.cpp lldb/trunk/source/Expression/DWARFExpression.cpp lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.cpp lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.cpp lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp lldb/trunk/source/Symbol/Block.cpp lldb/trunk/source/Symbol/SymbolContext.cpp lldb/trunk/source/Symbol/Variable.cpp lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/Thread.cpp lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp lldb/trunk/source/Target/ThreadPlanStepOut.cpp lldb/trunk/source/Target/ThreadPlanStepUntil.cpp Modified: lldb/trunk/include/lldb/Core/ModuleList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ModuleList.h?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ModuleList.h (original) +++ lldb/trunk/include/lldb/Core/ModuleList.h Tue Aug 24 16:05:24 2010 @@ -259,7 +259,7 @@ ModuleList& matching_module_list) const; lldb::ModuleSP - FindModule (lldb_private::Module *module_ptr); + FindModule (const Module *module_ptr); lldb::ModuleSP FindFirstModuleForFileSpec (const FileSpec &file_spec, @@ -355,7 +355,7 @@ GetSize () const; static const lldb::ModuleSP - GetModuleSP (lldb_private::Module *module_ptr); + GetModuleSP (const Module *module_ptr); static Error GetSharedModule (const FileSpec& file_spec, Modified: lldb/trunk/include/lldb/Core/VMRange.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/VMRange.h?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/VMRange.h (original) +++ lldb/trunk/include/lldb/Core/VMRange.h Tue Aug 24 16:05:24 2010 @@ -43,20 +43,30 @@ { } + void + Clear () + { + m_base_addr = 0; + m_byte_size = 0; + } + // Set the start and end values - void Reset (lldb::addr_t start_addr, lldb::addr_t end_addr) + void + Reset (lldb::addr_t start_addr, lldb::addr_t end_addr) { SetBaseAddress (start_addr); SetEndAddress (end_addr); } // Set the start value for the range, and keep the same size - void SetBaseAddress (lldb::addr_t base_addr) + void + SetBaseAddress (lldb::addr_t base_addr) { m_base_addr = base_addr; } - void SetEndAddress (lldb::addr_t end_addr) + void + SetEndAddress (lldb::addr_t end_addr) { const lldb::addr_t base_addr = GetBaseAddress(); if (end_addr > base_addr) @@ -92,7 +102,7 @@ bool IsValid() const { - return GetByteSize() > 0; + return m_byte_size > 0; } bool @@ -101,7 +111,8 @@ return (GetBaseAddress() <= addr) && (addr < GetEndAddress()); } - bool Contains (const VMRange& range) const + bool + Contains (const VMRange& range) const { if (Contains(range.GetBaseAddress())) { Modified: lldb/trunk/include/lldb/Expression/DWARFExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/DWARFExpression.h?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/DWARFExpression.h (original) +++ lldb/trunk/include/lldb/Expression/DWARFExpression.h Tue Aug 24 16:05:24 2010 @@ -118,6 +118,9 @@ bool LocationListContainsLoadAddress (Process* process, const Address &addr) const; + bool + LocationListContainsLoadAddress (Process* process, lldb::addr_t load_addr) const; + //------------------------------------------------------------------ /// Make the expression parser read its location information from a /// given data source. Does not change the offset and length Modified: lldb/trunk/include/lldb/Symbol/Block.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Block.h?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Block.h (original) +++ lldb/trunk/include/lldb/Symbol/Block.h Tue Aug 24 16:05:24 2010 @@ -182,8 +182,28 @@ Block * GetParent () const; + + //------------------------------------------------------------------ + /// Get the inlined block that contains this block. + /// + /// @return + /// If this block contains inlined function info, it will return + /// this block, else parent blocks will be searched to see if + /// any contain this block. NULL will be returned if this block + /// nor any parent blocks are inlined function blocks. + //------------------------------------------------------------------ Block * - GetInlinedParent () const; + GetContainingInlinedBlock (); + + //------------------------------------------------------------------ + /// Get the inlined parent block for this block. + /// + /// @return + /// The parent block pointer, or NULL if this block has no + /// parent. + //------------------------------------------------------------------ + Block * + GetInlinedParent (); //------------------------------------------------------------------ /// Get the sibling block for this block. @@ -206,7 +226,12 @@ /// children. //------------------------------------------------------------------ Block * - GetFirstChild () const; + GetFirstChild () const + { + if (m_children.empty()) + return NULL; + return m_children.front().get(); + } //------------------------------------------------------------------ /// Get the variable list for this block and optionally all child @@ -266,16 +291,6 @@ VariableList *variable_list); //------------------------------------------------------------------ - /// Get accessor for any inlined function information. - /// - /// @return - /// A pointer to any inlined function information, or NULL if - /// this is a regular block. - //------------------------------------------------------------------ - InlineFunctionInfo* - InlinedFunctionInfo (); - - //------------------------------------------------------------------ /// Get const accessor for any inlined function information. /// /// @return @@ -283,7 +298,10 @@ /// if this is a regular block. //------------------------------------------------------------------ const InlineFunctionInfo* - InlinedFunctionInfo () const; + InlinedFunctionInfo () const + { + return m_inlineInfoSP.get(); + } //------------------------------------------------------------------ /// Get the memory cost of this object. @@ -348,7 +366,11 @@ /// A shared pointer to a VariableList. //------------------------------------------------------------------ void - SetVariableList (lldb::VariableListSP& variable_list_sp); + SetVariableList (lldb::VariableListSP& variable_list_sp) + { + m_variable_list_sp = variable_list_sp; + } + bool @@ -364,6 +386,9 @@ FindBlockByID (lldb::user_id_t block_id); bool + GetRangeContainingOffset (const lldb::addr_t offset, VMRange &range); + + bool GetRangeContainingAddress (const Address& addr, AddressRange &range); @@ -377,7 +402,7 @@ collection m_children; VMRange::collection m_ranges; ///< A list of address offset ranges relative to the function's section/offset address. lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information. - lldb::VariableListSP m_variables; ///< The variable list for all local, static and paramter variables scoped to this block. + lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, static and paramter variables scoped to this block. bool m_parsed_block_info:1, ///< Set to true if this block and it's children have all been parsed m_parsed_block_variables:1, m_parsed_child_blocks:1; Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Tue Aug 24 16:05:24 2010 @@ -50,7 +50,7 @@ GetStackID(); Address& - GetPC(); + GetFrameCodeAddress(); void ChangePC (lldb::addr_t pc); Modified: lldb/trunk/source/API/SBFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/API/SBFrame.cpp (original) +++ lldb/trunk/source/API/SBFrame.cpp Tue Aug 24 16:05:24 2010 @@ -121,12 +121,11 @@ return UINT32_MAX; } - lldb::addr_t SBFrame::GetPC () const { if (m_opaque_sp) - return m_opaque_sp->GetPC().GetLoadAddress (&m_opaque_sp->GetThread().GetProcess()); + return m_opaque_sp->GetFrameCodeAddress().GetLoadAddress (&m_opaque_sp->GetThread().GetProcess()); return LLDB_INVALID_ADDRESS; } @@ -161,7 +160,7 @@ { SBAddress sb_addr; if (m_opaque_sp) - sb_addr.SetAddress (&m_opaque_sp->GetPC()); + sb_addr.SetAddress (&m_opaque_sp->GetFrameCodeAddress()); return sb_addr; } Modified: lldb/trunk/source/Commands/CommandObjectArgs.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectArgs.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectArgs.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectArgs.cpp Tue Aug 24 16:05:24 2010 @@ -148,7 +148,7 @@ return false; } - Module *thread_module = thread_cur_frame->GetPC ().GetModule (); + Module *thread_module = thread_cur_frame->GetFrameCodeAddress ().GetModule (); if (!thread_module) { result.AppendError ("The PC has no associated module."); Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Tue Aug 24 16:05:24 2010 @@ -248,7 +248,7 @@ else if (sc.symbol && sc.symbol->GetAddressRangePtr()) range = *sc.symbol->GetAddressRangePtr(); else - range.GetBaseAddress() = exe_ctx.frame->GetPC(); + range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress(); } else { Modified: lldb/trunk/source/Core/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Core/Disassembler.cpp (original) +++ lldb/trunk/source/Core/Disassembler.cpp Tue Aug 24 16:05:24 2010 @@ -311,7 +311,7 @@ } else { - range.GetBaseAddress() = exe_ctx.frame->GetPC(); + range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress(); } if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) Modified: lldb/trunk/source/Core/ModuleList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Core/ModuleList.cpp (original) +++ lldb/trunk/source/Core/ModuleList.cpp Tue Aug 24 16:05:24 2010 @@ -267,7 +267,7 @@ } ModuleSP -ModuleList::FindModule (lldb_private::Module *module_ptr) +ModuleList::FindModule (const Module *module_ptr) { ModuleSP module_sp; @@ -450,7 +450,7 @@ } const lldb::ModuleSP -ModuleList::GetModuleSP (lldb_private::Module *module_ptr) +ModuleList::GetModuleSP (const Module *module_ptr) { lldb::ModuleSP module_sp; if (module_ptr) Modified: lldb/trunk/source/Expression/DWARFExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Expression/DWARFExpression.cpp (original) +++ lldb/trunk/source/Expression/DWARFExpression.cpp Tue Aug 24 16:05:24 2010 @@ -688,13 +688,18 @@ bool DWARFExpression::LocationListContainsLoadAddress (Process* process, const Address &addr) const { + return LocationListContainsLoadAddress(process, addr.GetLoadAddress(process)); +} + +bool +DWARFExpression::LocationListContainsLoadAddress (Process* process, addr_t load_addr) const +{ + if (load_addr == LLDB_INVALID_ADDRESS) + return false; + if (IsLocationList()) { uint32_t offset = 0; - const addr_t load_addr = addr.GetLoadAddress(process); - - if (load_addr == LLDB_INVALID_ADDRESS) - return false; addr_t loc_list_base_addr = m_loclist_base_addr.GetLoadAddress(process); @@ -722,6 +727,7 @@ } return false; } + bool DWARFExpression::Evaluate ( @@ -749,7 +755,7 @@ if (IsLocationList()) { uint32_t offset = 0; - addr_t pc = exe_ctx->frame->GetPC().GetLoadAddress(exe_ctx->process); + addr_t pc = exe_ctx->frame->GetRegisterContext()->GetPC(); if (pc == LLDB_INVALID_ADDRESS) { Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.cpp (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_i386.cpp Tue Aug 24 16:05:24 2010 @@ -210,7 +210,7 @@ if (addr_range_ptr) { - if (first_frame->GetPC() == addr_range_ptr->GetBaseAddress()) + if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) { // We are at the first instruction, so we can recover the // previous PC by dereferencing the SP Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.cpp (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/MacOSX/MachThreadContext_x86_64.cpp Tue Aug 24 16:05:24 2010 @@ -221,7 +221,7 @@ if (addr_range_ptr) { - if (first_frame->GetPC() == addr_range_ptr->GetBaseAddress()) + if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) { // We are at the first instruction, so we can recover the // previous PC by dereferencing the SP Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp Tue Aug 24 16:05:24 2010 @@ -130,7 +130,7 @@ if (addr_range_ptr) { - if (first_frame->GetPC() == addr_range_ptr->GetBaseAddress()) + if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) { // We are at the first instruction, so we can recover the // previous PC by dereferencing the SP @@ -218,7 +218,7 @@ if (addr_range_ptr) { - if (first_frame->GetPC() == addr_range_ptr->GetBaseAddress()) + if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) { // We are at the first instruction, so we can recover the // previous PC by dereferencing the SP Modified: lldb/trunk/source/Symbol/Block.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Block.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Block.cpp (original) +++ lldb/trunk/source/Symbol/Block.cpp Tue Aug 24 16:05:24 2010 @@ -24,7 +24,7 @@ m_children (), m_ranges (), m_inlineInfoSP (), - m_variables (), + m_variable_list_sp (), m_parsed_block_info (false), m_parsed_block_variables (false), m_parsed_child_blocks (false) @@ -104,9 +104,9 @@ { s->IndentMore(); - if (m_variables.get()) + if (m_variable_list_sp.get()) { - m_variables->Dump(s, show_context); + m_variable_list_sp->Dump(s, show_context); } for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling()) @@ -137,7 +137,7 @@ } void -Block::CalculateSymbolContext(SymbolContext* sc) +Block::CalculateSymbolContext (SymbolContext* sc) { if (m_parent_scope) m_parent_scope->CalculateSymbolContext(sc); @@ -149,7 +149,7 @@ { Block* parent_block = GetParent(); - InlineFunctionInfo* inline_info = InlinedFunctionInfo (); + const InlineFunctionInfo* inline_info = InlinedFunctionInfo (); if (inline_info) { const Declaration &call_site = inline_info->GetCallSite(); @@ -226,7 +226,15 @@ } Block * -Block::GetInlinedParent () const +Block::GetContainingInlinedBlock () +{ + if (InlinedFunctionInfo()) + return this; + return GetInlinedParent (); +} + +Block * +Block::GetInlinedParent () { Block *parent_block = GetParent (); if (parent_block) @@ -241,6 +249,20 @@ bool +Block::GetRangeContainingOffset (const addr_t offset, VMRange &range) +{ + uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset); + if (range_idx < m_ranges.size()) + { + range = m_ranges[range_idx]; + return true; + } + range.Clear(); + return false; +} + + +bool Block::GetRangeContainingAddress (const Address& addr, AddressRange &range) { SymbolContext sc; @@ -278,18 +300,6 @@ m_ranges.back().Reset(start_offset, end_offset); } -InlineFunctionInfo* -Block::InlinedFunctionInfo () -{ - return m_inlineInfoSP.get(); -} - -const InlineFunctionInfo* -Block::InlinedFunctionInfo () const -{ - return m_inlineInfoSP.get(); -} - // Return the current number of bytes that this object occupies in memory size_t Block::MemorySize() const @@ -297,20 +307,12 @@ size_t mem_size = sizeof(Block) + m_ranges.size() * sizeof(VMRange); if (m_inlineInfoSP.get()) mem_size += m_inlineInfoSP->MemorySize(); - if (m_variables.get()) - mem_size += m_variables->MemorySize(); + if (m_variable_list_sp.get()) + mem_size += m_variable_list_sp->MemorySize(); return mem_size; } -Block * -Block::GetFirstChild () const -{ - if (m_children.empty()) - return NULL; - return m_children.front().get(); -} - void Block::AddChild(const BlockSP &child_block_sp) { @@ -343,7 +345,7 @@ VariableListSP variable_list_sp; if (m_parsed_block_variables == false) { - if (m_variables.get() == NULL && can_create) + if (m_variable_list_sp.get() == NULL && can_create) { m_parsed_block_variables = true; SymbolContext sc; @@ -353,11 +355,11 @@ } } - if (m_variables.get()) + if (m_variable_list_sp.get()) { variable_list_sp.reset(new VariableList()); if (variable_list_sp.get()) - variable_list_sp->AddVariables(m_variables.get()); + variable_list_sp->AddVariables(m_variable_list_sp.get()); if (get_child_variables) { @@ -406,13 +408,6 @@ return num_variables_added; } - -void -Block::SetVariableList(VariableListSP& variables) -{ - m_variables = variables; -} - void Block::SetBlockInfoHasBeenParsed (bool b, bool set_children) { Modified: lldb/trunk/source/Symbol/SymbolContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Symbol/SymbolContext.cpp (original) +++ lldb/trunk/source/Symbol/SymbolContext.cpp Tue Aug 24 16:05:24 2010 @@ -131,10 +131,10 @@ if (show_inlined_frames && block) { - InlineFunctionInfo *inline_info = block->InlinedFunctionInfo(); + const InlineFunctionInfo *inline_info = block->InlinedFunctionInfo(); if (inline_info == NULL) { - Block *parent_inline_block = block->GetInlinedParent(); + const Block *parent_inline_block = block->GetInlinedParent(); if (parent_inline_block) inline_info = parent_inline_block->InlinedFunctionInfo(); } Modified: lldb/trunk/source/Symbol/Variable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Variable.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Variable.cpp (original) +++ lldb/trunk/source/Symbol/Variable.cpp Tue Aug 24 16:05:24 2010 @@ -14,6 +14,7 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" @@ -142,7 +143,7 @@ // It is a location list. We just need to tell if the location // list contains the current address when converted to a load // address - return m_location.LocationListContainsLoadAddress (&frame->GetThread().GetProcess(), frame->GetPC()); + return m_location.LocationListContainsLoadAddress (&frame->GetThread().GetProcess(), frame->GetRegisterContext()->GetPC()); } else { Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Tue Aug 24 16:05:24 2010 @@ -29,8 +29,8 @@ // The first bits in the flags are reserved for the SymbolContext::Scope bits // so we know if we have tried to look up information in our internal symbol // context (m_sc) already. -#define RESOLVED_PC_SO_ADDR (uint32_t(eSymbolContextEverything + 1)) -#define RESOLVED_FRAME_ID (RESOLVED_PC_SO_ADDR << 1) +#define RESOLVED_FRAME_ADDR (uint32_t(eSymbolContextEverything + 1)) +#define RESOLVED_FRAME_ID (RESOLVED_FRAME_ADDR << 1) #define GOT_FRAME_BASE (RESOLVED_FRAME_ID << 1) #define FRAME_IS_OBSOLETE (GOT_FRAME_BASE << 1) #define RESOLVED_VARIABLES (FRAME_IS_OBSOLETE << 1) @@ -169,53 +169,29 @@ // Resolve our PC to section offset if we haven't alreday done so // and if we don't have a module. The resolved address section will // contain the module to which it belongs. - if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR)) - GetPC(); + if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR)) + GetFrameCodeAddress(); - const uint32_t resolve_scope = eSymbolContextModule | - eSymbolContextCompUnit | - eSymbolContextFunction; - - if (m_sc.module_sp) + if (GetSymbolContext (eSymbolContextFunction).function) { - if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction) - { - assert (m_sc.function); - m_id.SetStartAddress(m_sc.function->GetAddressRange().GetBaseAddress()); - } - else if (m_sc.module_sp->ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol) - { - assert (m_sc.symbol); - AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); - if (symbol_range_ptr) - m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress()); - } + m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress()); + } + else if (GetSymbolContext (eSymbolContextSymbol).symbol) + { + AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); + if (symbol_range_ptr) + m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress()); } -// else if (m_sc.target != NULL) -// { -// if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextFunction) -// { -// assert (m_sc.function); -// m_id.GetAddressRange() = m_sc.function->GetAddressRange(); -// } -// else if (m_sc.target->GetImages().ResolveSymbolContextForAddress (GetPC(), resolve_scope, m_sc) & eSymbolContextSymbol) -// { -// assert (m_sc.symbol); -// AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRange(); -// if (symbol_range_ptr) -// m_id.GetAddressRange() = *symbol_range_ptr; -// } -// } } return m_id; } Address& -StackFrame::GetPC() +StackFrame::GetFrameCodeAddress() { - if (m_flags.IsClear(RESOLVED_PC_SO_ADDR) && !m_pc.IsSectionOffset()) + if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_pc.IsSectionOffset()) { - m_flags.Set (RESOLVED_PC_SO_ADDR); + m_flags.Set (RESOLVED_FRAME_ADDR); // Resolve the PC into a temporary address because if ResolveLoadAddress // fails to resolve the address, it will clear the address object... @@ -279,20 +255,19 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope) { // Copy our internal symbol context into "sc". - if ((m_flags.GetAllFlagBits() & resolve_scope) != resolve_scope) { // Resolve our PC to section offset if we haven't alreday done so // and if we don't have a module. The resolved address section will // contain the module to which it belongs - if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_PC_SO_ADDR)) - GetPC(); + if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR)) + GetFrameCodeAddress(); // If this is not frame zero, then we need to subtract 1 from the PC // value when doing address lookups since the PC will be on the // instruction following the function call instruction... - Address lookup_addr(GetPC()); + Address lookup_addr(GetFrameCodeAddress()); if (m_frame_index > 0 && lookup_addr.IsValid()) { addr_t offset = lookup_addr.GetOffset(); @@ -300,6 +275,8 @@ lookup_addr.SetOffset(offset - 1); } + + uint32_t resolved = 0; if (m_sc.module_sp) { // We have something in our stack frame symbol context, lets check @@ -313,7 +290,7 @@ if (m_flags.IsClear (eSymbolContextCompUnit)) { if (m_sc.comp_unit) - m_flags.Set (eSymbolContextCompUnit); + resolved |= eSymbolContextCompUnit; else actual_resolve_scope |= eSymbolContextCompUnit; } @@ -324,7 +301,7 @@ if (m_flags.IsClear (eSymbolContextFunction)) { if (m_sc.function) - m_flags.Set (eSymbolContextFunction); + resolved |= eSymbolContextFunction; else actual_resolve_scope |= eSymbolContextFunction; } @@ -335,7 +312,7 @@ if (m_flags.IsClear (eSymbolContextBlock)) { if (m_sc.block) - m_flags.Set (eSymbolContextBlock); + resolved |= eSymbolContextBlock; else actual_resolve_scope |= eSymbolContextBlock; } @@ -346,7 +323,7 @@ if (m_flags.IsClear (eSymbolContextSymbol)) { if (m_sc.symbol) - m_flags.Set (eSymbolContextSymbol); + resolved |= eSymbolContextSymbol; else actual_resolve_scope |= eSymbolContextSymbol; } @@ -357,7 +334,7 @@ if (m_flags.IsClear (eSymbolContextLineEntry)) { if (m_sc.line_entry.IsValid()) - m_flags.Set (eSymbolContextLineEntry); + resolved |= eSymbolContextLineEntry; else actual_resolve_scope |= eSymbolContextLineEntry; } @@ -371,15 +348,21 @@ // already found in "m_sc" SymbolContext sc; // Set flags that indicate what we have tried to resolve - const uint32_t resolved = m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); + resolved |= m_sc.module_sp->ResolveSymbolContextForAddress (lookup_addr, actual_resolve_scope, sc); // Only replace what we didn't already have as we may have // information for an inlined function scope that won't match // what a standard lookup by address would match - if (resolved & eSymbolContextCompUnit) m_sc.comp_unit = sc.comp_unit; - if (resolved & eSymbolContextFunction) m_sc.function = sc.function; - if (resolved & eSymbolContextBlock) m_sc.block = sc.block; - if (resolved & eSymbolContextSymbol) m_sc.symbol = sc.symbol; - if (resolved & eSymbolContextLineEntry) m_sc.line_entry = sc.line_entry; + if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == NULL) + m_sc.comp_unit = sc.comp_unit; + if ((resolved & eSymbolContextFunction) && m_sc.function == NULL) + m_sc.function = sc.function; + if ((resolved & eSymbolContextBlock) && m_sc.block == NULL) + m_sc.block = sc.block; + if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL) + m_sc.symbol = sc.symbol; + if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid()) + m_sc.line_entry = sc.line_entry; + } } else @@ -387,16 +370,23 @@ // If we don't have a module, then we can't have the compile unit, // function, block, line entry or symbol, so we can safely call // ResolveSymbolContextForAddress with our symbol context member m_sc. - m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); + resolved |= m_thread.GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc); } // If the target was requested add that: if (m_sc.target_sp.get() == NULL) + { m_sc.target_sp = CalculateProcess()->GetTarget().GetSP(); + if (m_sc.target_sp) + resolved |= eSymbolContextTarget; + } // Update our internal flags so we remember what we have tried to locate so // we don't have to keep trying when more calls to this function are made. - m_flags.Set(resolve_scope); + // We might have dug up more information that was requested (for example + // if we were asked to only get the block, we will have gotten the + // compile unit, and function) so set any additional bits that we resolved + m_flags.Set (resolve_scope | resolved); } // Return the symbol context with everything that was possible to resolve @@ -412,8 +402,7 @@ { m_flags.Set(RESOLVED_VARIABLES); - GetSymbolContext(eSymbolContextFunction); - if (m_sc.function) + if (GetSymbolContext (eSymbolContextFunction).function) { bool get_child_variables = true; bool can_create = true; @@ -474,7 +463,7 @@ bool StackFrame::HasDebugInformation () { - GetSymbolContext(eSymbolContextLineEntry); + GetSymbolContext (eSymbolContextLineEntry); return m_sc.line_entry.IsValid(); } @@ -525,12 +514,12 @@ if (show_frame_index) strm->Printf("frame #%u: ", m_frame_index); - strm->Printf("pc = 0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetRegisterContext()->GetPC()); - SymbolContext sc (GetSymbolContext(eSymbolContextEverything)); + strm->Printf("0x%0*llx", m_thread.GetProcess().GetAddressByteSize() * 2, GetFrameCodeAddress().GetLoadAddress(&m_thread.GetProcess())); + GetSymbolContext(eSymbolContextEverything); strm->PutCString(", where = "); // TODO: need to get the const bool show_module = true; const bool show_inline = true; - sc.DumpStopContext(strm, &m_thread.GetProcess(), GetPC(), show_module, show_inline); + m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline); } Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Tue Aug 24 16:05:24 2010 @@ -926,18 +926,21 @@ Block *parent_block = m_inlined_frame_info[idx].block->GetParent(); parent_block->CalculateSymbolContext(&inline_sc); } + + Address backed_up_pc (previous_frame_sp->GetFrameCodeAddress()); + backed_up_pc.SetOffset(backed_up_pc.GetOffset()-1); + AddressRange range; + m_inlined_frame_info[idx].block->GetRangeContainingAddress (backed_up_pc, range); - InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo(); + const InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo(); assert (inline_info); - inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetPC(); + inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress(); inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); StackFrameSP concrete_frame_sp (m_concrete_frames.GetFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index)); assert (previous_frame_sp.get()); - AddressRange range; - m_inlined_frame_info[idx].block->GetRangeContainingAddress (previous_frame_sp->GetPC(), range); frame_sp.reset (new StackFrame (idx, m_inlined_frame_info[idx].concrete_frame_index, @@ -949,7 +952,6 @@ &inline_sc)); // The symbol context for this inline frame } - } else { Modified: lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp (original) +++ lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp Tue Aug 24 16:05:24 2010 @@ -122,10 +122,10 @@ { StreamString s; s.PutCString ("Stepped in to: "); - addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetPC().GetLoadAddress(&m_thread.GetProcess()); + addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); s.Address (stop_addr, m_thread.GetProcess().GetAddressByteSize()); s.PutCString (" stepping out to: "); - addr_t return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess()); + addr_t return_addr = return_frame->GetRegisterContext()->GetPC(); s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize()); log->Printf("%s.", s.GetData()); } Modified: lldb/trunk/source/Target/ThreadPlanStepOut.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOut.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlanStepOut.cpp (original) +++ lldb/trunk/source/Target/ThreadPlanStepOut.cpp Tue Aug 24 16:05:24 2010 @@ -53,7 +53,8 @@ StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); if (return_frame) { - m_return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess()); + // TODO: check for inlined frames and do the right thing... + m_return_addr = return_frame->GetRegisterContext()->GetPC(); Breakpoint *return_bp = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_return_addr, true).get(); if (return_bp != NULL) { Modified: lldb/trunk/source/Target/ThreadPlanStepUntil.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepUntil.cpp?rev=111964&r1=111963&r2=111964&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadPlanStepUntil.cpp (original) +++ lldb/trunk/source/Target/ThreadPlanStepUntil.cpp Tue Aug 24 16:05:24 2010 @@ -63,7 +63,8 @@ // FIXME - can we do this more securely if we know first_insn? StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); - m_return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess()); + // TODO: add inline functionality + m_return_addr = return_frame->GetRegisterContext()->GetPC(); Breakpoint *return_bp = target.CreateBreakpoint (m_return_addr, true).get(); if (return_bp != NULL) { From johnny.chen at apple.com Tue Aug 24 17:07:56 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 22:07:56 -0000 Subject: [Lldb-commits] [lldb] r111975 - in /lldb/trunk/test: lldbtest.py macosx/universal/TestUniversal.py Message-ID: <20100824220756.4EC412A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 17:07:56 2010 New Revision: 111975 URL: http://llvm.org/viewvc/llvm-project?rev=111975&view=rev Log: Added a test for launching a universal binary. Launch of i386 architecture currently fails: rdar://problem/8349784. Forgot to check in lldbtest.py in the previous commit r111958. Added: lldb/trunk/test/macosx/universal/TestUniversal.py 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=111975&r1=111974&r2=111975&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Tue Aug 24 17:07:56 2010 @@ -130,6 +130,8 @@ STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in" +DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly" + VARIABLES_DISPLAYED_CORRECTLY = "Show specified variable(s) correctly" # Added: lldb/trunk/test/macosx/universal/TestUniversal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/TestUniversal.py?rev=111975&view=auto ============================================================================== --- lldb/trunk/test/macosx/universal/TestUniversal.py (added) +++ lldb/trunk/test/macosx/universal/TestUniversal.py Tue Aug 24 17:07:56 2010 @@ -0,0 +1,52 @@ +"""Test aspects of lldb commands on universal binaries.""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class TestUniversal(TestBase): + + mydir = "macosx/universal" + + @unittest2.expectedFailure + def test_process_launch_for_universal(self): + """Test process launch of a universal binary.""" + + # Note that "testit" is a universal binary. + exe = os.path.join(os.getcwd(), "testit") + + # By default, x86_64 is assumed if no architecture is specified. + self.expect("file " + exe, CURRENT_EXECUTABLE_SET, + startstr = "Current executable set to ", + substrs = ["testit' (x86_64)."]) + + # Break inside the main. + self.expect("breakpoint set -f main.c -l 5", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.c', line = 5, locations = 1") + + # We should be able to launch the x86_64 executable. + self.runCmd("run", RUN_STOPPED) + self.runCmd("continue") + + # Now specify i386 as the architecture for "testit". + self.expect("file " + exe + " -a i386", CURRENT_EXECUTABLE_SET, + startstr = "Current executable set to ", + substrs = ["testit' (i386)."]) + + # Break inside the main. + self.expect("breakpoint set -f main.c -l 5", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.c', line = 5, locations = 1") + + # We should be able to launch the i386 executable. + # Process launch for i386 architecture currently fails. + # rdar://problem/8349784 + self.runCmd("run", RUN_STOPPED) + self.runCmd("continue") + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() From gclayton at apple.com Tue Aug 24 17:59:52 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 24 Aug 2010 22:59:52 -0000 Subject: [Lldb-commits] [lldb] r111989 - in /lldb/trunk: include/lldb/Core/Address.h include/lldb/Target/StackFrame.h include/lldb/Target/Thread.h source/Core/Address.cpp source/Target/StackFrame.cpp source/Target/Thread.cpp Message-ID: <20100824225952.645A72A6C12C@llvm.org> Author: gclayton Date: Tue Aug 24 17:59:52 2010 New Revision: 111989 URL: http://llvm.org/viewvc/llvm-project?rev=111989&view=rev Log: Fixed another issue with the inline stack frames where if the first frame has inlined functions that all started at the same address, then the inlined backtrace would not produce correct stack frames. Also cleaned up and inlined a lot of stuff in lldb_private::Address. Added a function to StackFrame to detect if the frame is a concrete frame so we can detect the difference between actual frames and inlined frames. Modified: lldb/trunk/include/lldb/Core/Address.h lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/Target/Thread.h lldb/trunk/source/Core/Address.cpp lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/Thread.cpp Modified: lldb/trunk/include/lldb/Core/Address.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Address.h?rev=111989&r1=111988&r2=111989&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Address.h (original) +++ lldb/trunk/include/lldb/Core/Address.h Tue Aug 24 17:59:52 2010 @@ -97,7 +97,13 @@ /// Initialize with a invalid section (NULL) and an invalid /// offset (LLDB_INVALID_ADDRESS). //------------------------------------------------------------------ - Address (); + Address () : + SymbolContextScope(), + m_section (NULL), + m_offset (LLDB_INVALID_ADDRESS) + { + } + //------------------------------------------------------------------ /// Copy constructor @@ -107,7 +113,12 @@ /// @param[in] rhs /// A const Address object reference to copy. //------------------------------------------------------------------ - Address (const Address& rhs); + Address (const Address& rhs) : + SymbolContextScope(rhs), + m_section (rhs.m_section), + m_offset (rhs.m_offset) + { + } //------------------------------------------------------------------ /// Construct with a section pointer and offset. @@ -122,7 +133,12 @@ /// @param[in] offset /// The offset in bytes into \a section. //------------------------------------------------------------------ - Address (const Section* section, lldb::addr_t offset); + Address (const Section* section, lldb::addr_t offset) : + SymbolContextScope(), + m_section (section), + m_offset (offset) + { + } //------------------------------------------------------------------ /// Construct with a virtual address and section list. @@ -161,7 +177,11 @@ /// offset (LLDB_INVALID_ADDRESS). //------------------------------------------------------------------ void - Clear (); + Clear () + { + m_section = NULL; + m_offset = LLDB_INVALID_ADDRESS; + } //------------------------------------------------------------------ /// Compare two Address objects. @@ -301,7 +321,10 @@ /// offset, \b false otherwise. //------------------------------------------------------------------ bool - IsSectionOffset() const; + IsSectionOffset() const + { + return m_section != NULL && IsValid(); + } //------------------------------------------------------------------ /// Check if the object state is valid. @@ -315,7 +338,11 @@ /// otherwise. //------------------------------------------------------------------ bool - IsValid() const; + IsValid() const + { + return m_offset != LLDB_INVALID_ADDRESS; + } + //------------------------------------------------------------------ /// Get the memory cost of this object. @@ -376,7 +403,23 @@ /// Returns \b true if the offset changed, \b false otherwise. //------------------------------------------------------------------ bool - SetOffset (lldb::addr_t offset); + SetOffset (lldb::addr_t offset) + { + bool changed = m_offset != offset; + m_offset = offset; + return changed; + } + + bool + Slide (int64_t offset) + { + if (m_offset != LLDB_INVALID_ADDRESS) + { + m_offset += offset; + return true; + } + return false; + } //------------------------------------------------------------------ /// Set accessor for the section. Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=111989&r1=111988&r2=111989&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Tue Aug 24 17:59:52 2010 @@ -96,6 +96,10 @@ { return m_concrete_frame_index; } + + bool + IsConcrete () const; + //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Target/Thread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=111989&r1=111988&r2=111989&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Thread.h (original) +++ lldb/trunk/include/lldb/Target/Thread.h Tue Aug 24 17:59:52 2010 @@ -28,135 +28,7 @@ public UserID, public ExecutionContextScope { -friend class ThreadPlan; public: -// //---------------------------------------------------------------------- -// // StopInfo -// // -// // Describes the reason the thread it was created with stopped. -// //---------------------------------------------------------------------- -// class StopInfo -// { -// public: -// StopInfo(Thread *thread = NULL); -// -// ~StopInfo(); -// -// // Clear clears the stop reason, but it does not clear the thread this -// // StopInfo is tied to. -// void -// Clear(); -// -// lldb::StopReason -// GetStopReason() const; -// -// void -// SetThread (Thread *thread); -// -// Thread * -// GetThread (); -// -// void -// SetStopReasonWithBreakpointSiteID (lldb::user_id_t break_id); -// -// void -// SetStopReasonWithWatchpointID (lldb::user_id_t watch_id); -// -// void -// SetStopReasonWithSignal (int signo); -// -// void -// SetStopReasonToTrace (); -// -// void -// SetStopReasonWithGenericException (uint32_t exc_type, size_t exc_data_count); -// -// void -// SetStopReasonWithPlan (lldb::ThreadPlanSP &plan); -// -// void -// SetStopReasonToNone (); -// -// const char * -// GetStopDescription() const; -// -// void -// SetStopDescription(const char *desc); -// -// void -// SetStopReasonWithMachException (uint32_t exc_type, -// size_t exc_data_count, -// const lldb::addr_t *exc_data); -// -// lldb::user_id_t -// GetBreakpointSiteID() const; -// -// lldb::user_id_t -// GetWatchpointID() const; -// -// int -// GetSignal() const; -// -// lldb::user_id_t -// GetPlanID () const; -// -// uint32_t -// GetExceptionType() const; -// -// size_t -// GetExceptionDataCount() const; -// -// lldb::addr_t -// GetExceptionDataAtIndex (uint32_t idx) const; -// -// bool -// SetExceptionDataAtIndex (uint32_t idx, lldb::addr_t data); -// -// void -// Dump (Stream *s) const; -// -// protected: -// lldb::StopReason m_reason; -// //-------------------------------------------------------------- -// // For eStopReasonPlan the completed plan is stored in this shared pointer. -// //-------------------------------------------------------------- -// lldb::ThreadPlanSP m_completed_plan_sp; -// Thread *m_thread; -// char m_description[256]; -// union -// { -// //-------------------------------------------------------------- -// // eStopReasonBreakpoint -// //-------------------------------------------------------------- -// struct -// { -// lldb::user_id_t bp_site_id; -// } breakpoint; -// //-------------------------------------------------------------- -// // eStopReasonWatchpoint -// //-------------------------------------------------------------- -// struct -// { -// lldb::user_id_t watch_id; -// } watchpoint; -// //-------------------------------------------------------------- -// // eStopReasonSignal -// //-------------------------------------------------------------- -// struct -// { -// int signo; -// } signal; -// //-------------------------------------------------------------- -// // eStopReasonException -// //-------------------------------------------------------------- -// struct -// { -// uint32_t type; -// size_t data_count; -// lldb::addr_t data[LLDB_THREAD_MAX_STOP_EXC_DATA]; -// } exception; -// } m_details; -// }; class RegisterCheckpoint { @@ -648,6 +520,9 @@ Calculate (ExecutionContext &exe_ctx); protected: + + friend class ThreadPlan; + void PushPlan (lldb::ThreadPlanSP &plan_sp); Modified: lldb/trunk/source/Core/Address.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=111989&r1=111988&r2=111989&view=diff ============================================================================== --- lldb/trunk/source/Core/Address.cpp (original) +++ lldb/trunk/source/Core/Address.cpp Tue Aug 24 17:59:52 2010 @@ -240,27 +240,6 @@ return total_len; } -Address::Address () : - SymbolContextScope(), - m_section (NULL), - m_offset (LLDB_INVALID_ADDRESS) -{ -} - -Address::Address (const Address& rhs) : - SymbolContextScope(rhs), - m_section (rhs.m_section), - m_offset (rhs.m_offset) -{ -} - -Address::Address (const Section* section, addr_t offset) : - SymbolContextScope(), - m_section (section), - m_offset (offset) -{ -} - Address::Address (addr_t address, const SectionList * sections) : SymbolContextScope(), m_section (NULL), @@ -281,18 +260,6 @@ } bool -Address::IsValid() const -{ - return m_offset != LLDB_INVALID_ADDRESS; -} - -bool -Address::IsSectionOffset() const -{ - return m_section != NULL && IsValid(); -} - -bool Address::ResolveAddressUsingFileSections (addr_t addr, const SectionList *sections) { if (sections) @@ -392,22 +359,6 @@ } bool -Address::SetOffset (addr_t offset) -{ - bool changed = m_offset != offset; - m_offset = offset; - return changed; -} - -void -Address::Clear() -{ - m_section = NULL; - m_offset = LLDB_INVALID_ADDRESS; -} - - -bool Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const { // If the section was NULL, only load address is going to work. Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=111989&r1=111988&r2=111989&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Tue Aug 24 17:59:52 2010 @@ -473,6 +473,11 @@ return m_value_object_list; } +bool +StackFrame::IsConcrete () const +{ + return m_id.GetInlineHeight () == 0; +} Target * StackFrame::CalculateTarget () Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=111989&r1=111988&r2=111989&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Tue Aug 24 17:59:52 2010 @@ -926,11 +926,13 @@ Block *parent_block = m_inlined_frame_info[idx].block->GetParent(); parent_block->CalculateSymbolContext(&inline_sc); } + + Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress()); + if (previous_frame_sp->IsConcrete () && previous_frame_sp->GetFrameIndex() > 0) + previous_frame_lookup_addr.Slide (-1); - Address backed_up_pc (previous_frame_sp->GetFrameCodeAddress()); - backed_up_pc.SetOffset(backed_up_pc.GetOffset()-1); AddressRange range; - m_inlined_frame_info[idx].block->GetRangeContainingAddress (backed_up_pc, range); + m_inlined_frame_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range); const InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo(); assert (inline_info); From johnny.chen at apple.com Tue Aug 24 18:14:47 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 23:14:47 -0000 Subject: [Lldb-commits] [lldb] r111992 - /lldb/trunk/test/macosx/universal/TestUniversal.py Message-ID: <20100824231447.B9A462A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 18:14:47 2010 New Revision: 111992 URL: http://llvm.org/viewvc/llvm-project?rev=111992&view=rev Log: Removed the @unitest2.expectedFailure decorator. The i386 process launch works correctly after all. It was my own configuration error (I was building x86_64 only). Modified: lldb/trunk/test/macosx/universal/TestUniversal.py Modified: lldb/trunk/test/macosx/universal/TestUniversal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/TestUniversal.py?rev=111992&r1=111991&r2=111992&view=diff ============================================================================== --- lldb/trunk/test/macosx/universal/TestUniversal.py (original) +++ lldb/trunk/test/macosx/universal/TestUniversal.py Tue Aug 24 18:14:47 2010 @@ -9,7 +9,6 @@ mydir = "macosx/universal" - @unittest2.expectedFailure def test_process_launch_for_universal(self): """Test process launch of a universal binary.""" @@ -38,9 +37,7 @@ self.expect("breakpoint set -f main.c -l 5", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.c', line = 5, locations = 1") - # We should be able to launch the i386 executable. - # Process launch for i386 architecture currently fails. - # rdar://problem/8349784 + # We should be able to launch the i386 executable as well. self.runCmd("run", RUN_STOPPED) self.runCmd("continue") From johnny.chen at apple.com Tue Aug 24 18:48:10 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 24 Aug 2010 23:48:10 -0000 Subject: [Lldb-commits] [lldb] r112000 - /lldb/trunk/test/lldbtest.py Message-ID: <20100824234810.3C3122A6C12C@llvm.org> Author: johnny Date: Tue Aug 24 18:48:10 2010 New Revision: 112000 URL: http://llvm.org/viewvc/llvm-project?rev=112000&view=rev Log: More descriptive trace messages for the matchings of start and sub strings. 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=112000&r1=111999&r2=112000&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Tue Aug 24 18:48:10 2010 @@ -250,16 +250,21 @@ output = self.res.GetOutput() matched = output.startswith(startstr) if startstr else True - if not matched and startstr and trace: - print >> sys.stderr, "Startstr not matched:", startstr + if startstr and trace: + print >> sys.stderr, "Expecting start string:", startstr + print >> sys.stderr, "Matched" if matched else "Not matched" + print >> sys.stderr if substrs: for str in substrs: matched = output.find(str) > 0 + if trace: + print >> sys.stderr, "Expecting sub string:", str + print >> sys.stderr, "Matched" if matched else "Not matched" if not matched: - if trace: - print >> sys.stderr, "Substring not matched:", str break + if trace: + print >> sys.stderr self.assertTrue(matched, msg if msg else CMD_MSG(cmd)) From gclayton at apple.com Tue Aug 24 19:35:26 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 25 Aug 2010 00:35:26 -0000 Subject: [Lldb-commits] [lldb] r112007 - in /lldb/trunk: include/lldb/Target/StackFrameList.h include/lldb/Target/Thread.h include/lldb/lldb-forward-rtti.h source/Target/StackFrameList.cpp source/Target/Thread.cpp Message-ID: <20100825003527.0E4EF2A6C12C@llvm.org> Author: gclayton Date: Tue Aug 24 19:35:26 2010 New Revision: 112007 URL: http://llvm.org/viewvc/llvm-project?rev=112007&view=rev Log: Cleaned up the inline backtrace code even more by moving all stack backtracing functionality into StackFrameList. This will allow us to copy the previous stack backtrace from the previous stop into another variable so we can re-use as much as possible from the previous stack backtrace. Modified: lldb/trunk/include/lldb/Target/StackFrameList.h lldb/trunk/include/lldb/Target/Thread.h lldb/trunk/include/lldb/lldb-forward-rtti.h lldb/trunk/source/Target/StackFrameList.cpp lldb/trunk/source/Target/Thread.cpp Modified: lldb/trunk/include/lldb/Target/StackFrameList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=112007&r1=112006&r2=112007&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrameList.h (original) +++ lldb/trunk/include/lldb/Target/StackFrameList.h Tue Aug 24 19:35:26 2010 @@ -28,19 +28,16 @@ //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - StackFrameList(); + StackFrameList (Thread &thread, bool show_inline_frames); virtual ~StackFrameList(); uint32_t - GetNumFrames() const; + GetNumFrames(); lldb::StackFrameSP - GetFrameAtIndex (uint32_t idx) const; - - bool - SetFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); + GetFrameAtIndex (uint32_t idx); // Mark a stack frame as the current frame uint32_t @@ -56,15 +53,31 @@ void Clear (); - // After we have determined the number of frames, we can set the count here - // and have the frame info be generated on demand. - void - SetNumFrames(uint32_t count); - void InvalidateFrames (uint32_t start_idx); protected: + bool + SetActualFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); + + bool + SetInlineFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); + + + lldb::StackFrameSP + GetActualFrameAtIndex (uint32_t idx) const; + + lldb::StackFrameSP + GetInlineFrameAtIndex (uint32_t idx) const; + + typedef struct InlinedFrameInfo + { + uint32_t concrete_frame_index; + uint32_t inline_height; + Block *block; + } InlinedFrameInfo; + typedef std::vector InlinedFrameInfoCollection; + //------------------------------------------------------------------ // Classes that inherit from StackFrameList can see and modify these //------------------------------------------------------------------ @@ -72,9 +85,13 @@ typedef collection::iterator iterator; typedef collection::const_iterator const_iterator; + Thread &m_thread; mutable Mutex m_mutex; - collection m_frames; + collection m_actual_frames; + collection m_inline_frames; + InlinedFrameInfoCollection m_inlined_frame_info; uint32_t m_current_frame_idx; + bool m_show_inlined_frames; private: //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Target/Thread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=112007&r1=112006&r2=112007&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Thread.h (original) +++ lldb/trunk/include/lldb/Target/Thread.h Tue Aug 24 19:35:26 2010 @@ -198,12 +198,7 @@ CreateRegisterContextForFrame (StackFrame *frame) = 0; virtual void - ClearStackFrames () - { - m_concrete_frames.Clear(); - m_inlined_frames.Clear(); - m_inlined_frame_info.clear(); - } + ClearStackFrames (); void DumpInfo (Stream &strm, @@ -522,6 +517,7 @@ protected: friend class ThreadPlan; + friend class StackFrameList; void PushPlan (lldb::ThreadPlanSP &plan_sp); @@ -542,13 +538,9 @@ virtual lldb_private::Unwind * GetUnwinder () = 0; - typedef struct InlinedFrameInfo - { - uint32_t concrete_frame_index; - uint32_t inline_height; - Block *block; - } InlinedFrameInfo; - typedef std::vector InlinedFrameInfoCollection; + StackFrameList & + GetStackFrameList (); + //------------------------------------------------------------------ // Classes that inherit from Process can see and modify these //------------------------------------------------------------------ @@ -558,15 +550,12 @@ const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread for easy UI/command line access. lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this thread's current register state. lldb::StateType m_state; ///< The state of our process. + mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state. plan_stack m_plan_stack; ///< The stack of plans this thread is executing. plan_stack m_immediate_plan_stack; ///< The plans that need to get executed before any other work gets done. plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes. plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes. - mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state. - StackFrameList m_concrete_frames; ///< The stack frames that get lazily populated after a thread stops. - StackFrameList m_inlined_frames; ///< The stack frames that get lazily populated after a thread stops. - InlinedFrameInfoCollection m_inlined_frame_info; - bool m_show_inlined_frames; + lldb::StackFrameListSP m_frames_sp; ///< The stack frames that get lazily populated after a thread stops. int m_resume_signal; ///< The signal that should be used when continuing this thread. lldb::StateType m_resume_state; ///< The state that indicates what this thread should do when the process is resumed. std::auto_ptr m_unwinder_ap; Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=112007&r1=112006&r2=112007&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward-rtti.h (original) +++ lldb/trunk/include/lldb/lldb-forward-rtti.h Tue Aug 24 19:35:26 2010 @@ -49,6 +49,7 @@ typedef SharedPtr::Type SectionSP; typedef SharedPtr::Type SearchFilterSP; typedef SharedPtr::Type StackFrameSP; + typedef SharedPtr::Type StackFrameListSP; typedef SharedPtr::Type StateVariableSP; typedef SharedPtr::Type StopInfoSP; typedef SharedPtr::Type StoppointLocationSP; Modified: lldb/trunk/source/Target/StackFrameList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=112007&r1=112006&r2=112007&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrameList.cpp (original) +++ lldb/trunk/source/Target/StackFrameList.cpp Tue Aug 24 19:35:26 2010 @@ -7,12 +7,18 @@ // //===----------------------------------------------------------------------===// +#include "lldb/Target/StackFrameList.h" + // C Includes // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Target/StackFrameList.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/Unwind.h" using namespace lldb; using namespace lldb_private; @@ -20,9 +26,12 @@ //---------------------------------------------------------------------- // StackFrameList constructor //---------------------------------------------------------------------- -StackFrameList::StackFrameList() : +StackFrameList::StackFrameList(Thread &thread, bool show_inline_frames) : + m_thread (thread), + m_show_inlined_frames (show_inline_frames), m_mutex (Mutex::eMutexTypeRecursive), - m_frames (), + m_actual_frames (), + m_inline_frames (), m_current_frame_idx (0) { } @@ -36,43 +45,242 @@ uint32_t -StackFrameList::GetNumFrames() const +StackFrameList::GetNumFrames() { Mutex::Locker locker (m_mutex); - return m_frames.size(); + + if (m_show_inlined_frames) + { + if (m_inlined_frame_info.empty()) + { + Unwind *unwinder = m_thread.GetUnwinder (); + // If we are going to show inlined stack frames as actual frames, + // we need to calculate all concrete frames first, then iterate + // through all of them and count up how many inlined functions are + // in each frame. We can then fill in m_inlined_frame_info with + // the concrete frame index and inlined depth + const uint32_t concrete_frame_count = unwinder->GetFrameCount(); + + addr_t pc, cfa; + InlinedFrameInfo inlined_frame_info; + + StackFrameSP frame_sp; + for (uint32_t idx=0; idxGetSP(), + 0, + m_thread.m_reg_context_sp->GetPC(), + NULL)); + } + else + { + const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc); + assert (success); + frame_sp.reset (new StackFrame (m_inlined_frame_info.size(), idx, m_thread, cfa, 0, pc, NULL)); + } + SetActualFrameAtIndex (idx, frame_sp); + Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block; + + inlined_frame_info.concrete_frame_index = idx; + inlined_frame_info.inline_height = 0; + inlined_frame_info.block = block; + m_inlined_frame_info.push_back (inlined_frame_info); + + if (block) + { + Block *inlined_block; + if (block->InlinedFunctionInfo()) + inlined_block = block; + else + inlined_block = block->GetInlinedParent (); + + while (inlined_block) + { + inlined_frame_info.block = inlined_block; + inlined_frame_info.inline_height++; + m_inlined_frame_info.push_back (inlined_frame_info); + inlined_block = inlined_block->GetInlinedParent (); + } + } + } + } + return m_inlined_frame_info.size(); + } + else + { + if (m_actual_frames.empty()) + m_actual_frames.resize(m_thread.GetUnwinder()->GetFrameCount()); + + return m_actual_frames.size(); + } + return 0; } -// After we have determined the number of frames, we can set the count here -// and have the frame info be generated on demand. -void -StackFrameList::SetNumFrames(uint32_t count) +lldb::StackFrameSP +StackFrameList::GetActualFrameAtIndex (uint32_t idx) const { - Mutex::Locker locker (m_mutex); - return m_frames.resize(count); + StackFrameSP frame_sp; + if (idx < m_actual_frames.size()) + frame_sp = m_actual_frames[idx]; + return frame_sp; +} + +lldb::StackFrameSP +StackFrameList::GetInlineFrameAtIndex (uint32_t idx) const +{ + StackFrameSP frame_sp; + if (idx < m_inline_frames.size()) + frame_sp = m_inline_frames[idx]; + return frame_sp; } + StackFrameSP -StackFrameList::GetFrameAtIndex (uint32_t idx) const +StackFrameList::GetFrameAtIndex (uint32_t idx) { StackFrameSP frame_sp; { Mutex::Locker locker (m_mutex); - if (idx < m_frames.size()) - frame_sp = m_frames[idx]; + + if (m_show_inlined_frames) + { + frame_sp = GetInlineFrameAtIndex (idx); + } + else + { + frame_sp = GetActualFrameAtIndex (idx); + } + + if (frame_sp.get()) + return frame_sp; + + // Special case the first frame (idx == 0) so that we don't need to + // know how many stack frames there are to get it. If we need any other + // frames, then we do need to know if "idx" is a valid index. + if (idx == 0) + { + // If this is the first frame, we want to share the thread register + // context with the stack frame at index zero. + m_thread.GetRegisterContext(); + assert (m_thread.m_reg_context_sp.get()); + frame_sp.reset (new StackFrame (0, + 0, + m_thread, + m_thread.m_reg_context_sp, + m_thread.m_reg_context_sp->GetSP(), + 0, + m_thread.m_reg_context_sp->GetPC(), + NULL)); + } + else if (idx < GetNumFrames()) + { + if (m_show_inlined_frames) + { + if (m_inlined_frame_info[idx].inline_height == 0) + { + // Same as the concrete stack frame if block is NULL + assert (m_inlined_frame_info[idx].concrete_frame_index < m_actual_frames.size()); + frame_sp = GetActualFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index); + } + else + { + // We have blocks that were above an inlined function. Inlined + // functions are represented as blocks with non-NULL inline + // function info. Here we must reconstruct a frame by looking + // at the block + StackFrameSP previous_frame_sp (m_thread.GetStackFrameAtIndex (idx-1)); + + SymbolContext inline_sc; + + Block *inlined_parent_block = m_inlined_frame_info[idx].block->GetInlinedParent(); + + if (inlined_parent_block) + inlined_parent_block->CalculateSymbolContext (&inline_sc); + else + { + Block *parent_block = m_inlined_frame_info[idx].block->GetParent(); + parent_block->CalculateSymbolContext(&inline_sc); + } + + Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress()); + if (previous_frame_sp->IsConcrete () && previous_frame_sp->GetFrameIndex() > 0) + previous_frame_lookup_addr.Slide (-1); + + AddressRange range; + m_inlined_frame_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range); + + const InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo(); + assert (inline_info); + inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress(); + inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); + inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); + inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); + + StackFrameSP concrete_frame_sp (GetActualFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index)); + assert (previous_frame_sp.get()); + + frame_sp.reset (new StackFrame (idx, + m_inlined_frame_info[idx].concrete_frame_index, + m_thread, + concrete_frame_sp->GetRegisterContextSP (), + concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA + m_inlined_frame_info[idx].inline_height, // Inline height + range.GetBaseAddress(), + &inline_sc)); // The symbol context for this inline frame + + } + } + else + { + Unwind *unwinder = m_thread.GetUnwinder (); + if (unwinder) + { + addr_t pc, cfa; + if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) + frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, 0, pc, NULL)); + } + } + } + if (m_show_inlined_frames) + SetInlineFrameAtIndex(idx, frame_sp); + else + SetActualFrameAtIndex(idx, frame_sp); + return frame_sp; + } return frame_sp; } bool -StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) +StackFrameList::SetActualFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) { - Mutex::Locker locker (m_mutex); - if (idx >= m_frames.size()) - m_frames.resize(idx + 1); + if (idx >= m_actual_frames.size()) + m_actual_frames.resize(idx + 1); + // Make sure allocation succeeded by checking bounds again + if (idx < m_actual_frames.size()) + { + m_actual_frames[idx] = frame_sp; + return true; + } + return false; // resize failed, out of memory? +} + +bool +StackFrameList::SetInlineFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) +{ + if (idx >= m_inline_frames.size()) + m_inline_frames.resize(idx + 1); // Make sure allocation succeeded by checking bounds again - if (idx < m_frames.size()) + if (idx < m_inline_frames.size()) { - m_frames[idx] = frame_sp; + m_inline_frames[idx] = frame_sp; return true; } return false; // resize failed, out of memory? @@ -90,9 +298,9 @@ StackFrameList::SetCurrentFrame (lldb_private::StackFrame *frame) { Mutex::Locker locker (m_mutex); - const_iterator pos, - begin = m_frames.begin(), - end = m_frames.end(); + const_iterator pos; + const_iterator begin = m_show_inlined_frames ? m_inline_frames.begin() : m_actual_frames.begin(); + const_iterator end = m_show_inlined_frames ? m_inline_frames.end() : m_actual_frames.end(); for (pos = begin; pos != end; ++pos) { if (pos->get() == frame) @@ -119,17 +327,26 @@ StackFrameList::Clear () { Mutex::Locker locker (m_mutex); - m_frames.clear(); + m_actual_frames.clear(); + m_inline_frames.clear(); + m_inlined_frame_info.clear(); } void StackFrameList::InvalidateFrames (uint32_t start_idx) { Mutex::Locker locker (m_mutex); - size_t num_frames = m_frames.size(); - while (start_idx < num_frames) + if (m_show_inlined_frames) + { + Clear(); + } + else { - m_frames[start_idx].reset(); - ++start_idx; + const size_t num_frames = m_actual_frames.size(); + while (start_idx < num_frames) + { + m_actual_frames[start_idx].reset(); + ++start_idx; + } } } Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=112007&r1=112006&r2=112007&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Tue Aug 24 19:35:26 2010 @@ -45,14 +45,11 @@ m_index_id (process.GetNextThreadIndexID ()), m_reg_context_sp (), m_state (eStateUnloaded), + m_state_mutex (Mutex::eMutexTypeRecursive), m_plan_stack (), m_immediate_plan_stack(), m_completed_plan_stack(), - m_state_mutex (Mutex::eMutexTypeRecursive), - m_concrete_frames (), - m_inlined_frames (), - m_inlined_frame_info (), - m_show_inlined_frames (true), + m_frames_sp (), m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER), m_resume_state (eStateRunning), m_unwinder_ap () @@ -795,200 +792,53 @@ exe_ctx.frame = NULL; } + +StackFrameList & +Thread::GetStackFrameList () +{ + if (m_frames_sp.get() == NULL) + m_frames_sp.reset (new StackFrameList (*this, true)); + return *m_frames_sp; +} + + + uint32_t Thread::GetStackFrameCount() { - Unwind *unwinder = GetUnwinder (); - if (unwinder) - { - if (m_show_inlined_frames) - { - if (m_inlined_frame_info.empty()) - { - // If we are going to show inlined stack frames as actual frames, - // we need to calculate all concrete frames first, then iterate - // through all of them and count up how many inlined functions are - // in each frame. We can then fill in m_inlined_frame_info with - // the concrete frame index and inlined depth - const uint32_t concrete_frame_count = unwinder->GetFrameCount(); - - addr_t pc, cfa; - InlinedFrameInfo inlined_frame_info; - - StackFrameSP frame_sp; - for (uint32_t idx=0; idxGetSP(), 0, m_reg_context_sp->GetPC(), NULL)); - } - else - { - const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc); - assert (success); - frame_sp.reset (new StackFrame (m_inlined_frame_info.size(), idx, *this, cfa, 0, pc, NULL)); - } - m_concrete_frames.SetFrameAtIndex(idx, frame_sp); - Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block; + return GetStackFrameList().GetNumFrames(); +} - inlined_frame_info.concrete_frame_index = idx; - inlined_frame_info.inline_height = 0; - inlined_frame_info.block = block; - m_inlined_frame_info.push_back (inlined_frame_info); - if (block) - { - Block *inlined_block; - if (block->InlinedFunctionInfo()) - inlined_block = block; - else - inlined_block = block->GetInlinedParent (); - - while (inlined_block) - { - inlined_frame_info.block = inlined_block; - inlined_frame_info.inline_height++; - m_inlined_frame_info.push_back (inlined_frame_info); - inlined_block = inlined_block->GetInlinedParent (); - } - } - } - } - return m_inlined_frame_info.size(); - } - else - { - return unwinder->GetFrameCount(); - } - } - return 0; +void +Thread::ClearStackFrames () +{ + if (m_frames_sp) + m_frames_sp->Clear(); } lldb::StackFrameSP Thread::GetStackFrameAtIndex (uint32_t idx) { - - StackFrameSP frame_sp; - - if (m_show_inlined_frames) - frame_sp = m_inlined_frames.GetFrameAtIndex(idx); - else - frame_sp = m_concrete_frames.GetFrameAtIndex(idx); - - if (frame_sp.get()) - return frame_sp; - - // Don't try and fetch a frame while process is running -// FIXME: This check isn't right because IsRunning checks the Public state, but this -// is work you need to do - for instance in ShouldStop & friends - before the public -// state has been changed. -// if (m_process.IsRunning()) -// return frame_sp; - - // Special case the first frame (idx == 0) so that we don't need to - // know how many stack frames there are to get it. If we need any other - // frames, then we do need to know if "idx" is a valid index. - if (idx == 0) - { - // If this is the first frame, we want to share the thread register - // context with the stack frame at index zero. - GetRegisterContext(); - assert (m_reg_context_sp.get()); - frame_sp.reset (new StackFrame (0, 0, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), 0, m_reg_context_sp->GetPC(), NULL)); - } - else if (idx < GetStackFrameCount()) - { - if (m_show_inlined_frames) - { - if (m_inlined_frame_info[idx].inline_height == 0) - { - // Same as the concrete stack frame if block is NULL - frame_sp = m_concrete_frames.GetFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index); - } - else - { - // We have blocks that were above an inlined function. Inlined - // functions are represented as blocks with non-NULL inline - // function info. Here we must reconstruct a frame by looking - // at the block - StackFrameSP previous_frame_sp (GetStackFrameAtIndex (idx-1)); - - SymbolContext inline_sc; - - Block *inlined_parent_block = m_inlined_frame_info[idx].block->GetInlinedParent(); - - if (inlined_parent_block) - inlined_parent_block->CalculateSymbolContext (&inline_sc); - else - { - Block *parent_block = m_inlined_frame_info[idx].block->GetParent(); - parent_block->CalculateSymbolContext(&inline_sc); - } - - Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress()); - if (previous_frame_sp->IsConcrete () && previous_frame_sp->GetFrameIndex() > 0) - previous_frame_lookup_addr.Slide (-1); - - AddressRange range; - m_inlined_frame_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range); - - const InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo(); - assert (inline_info); - inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress(); - inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); - inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); - inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); - - StackFrameSP concrete_frame_sp (m_concrete_frames.GetFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index)); - assert (previous_frame_sp.get()); - - frame_sp.reset (new StackFrame (idx, - m_inlined_frame_info[idx].concrete_frame_index, - *this, - concrete_frame_sp->GetRegisterContextSP (), - concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA - m_inlined_frame_info[idx].inline_height, // Inline height - range.GetBaseAddress(), - &inline_sc)); // The symbol context for this inline frame - - } - } - else - { - Unwind *unwinder = GetUnwinder (); - if (unwinder) - { - addr_t pc, cfa; - if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) - frame_sp.reset (new StackFrame (idx, idx, *this, cfa, 0, pc, NULL)); - } - } - } - if (m_show_inlined_frames) - m_inlined_frames.SetFrameAtIndex(idx, frame_sp); - else - m_concrete_frames.SetFrameAtIndex(idx, frame_sp); - return frame_sp; + return StackFrameSP (GetStackFrameList().GetFrameAtIndex(idx)); } lldb::StackFrameSP Thread::GetCurrentFrame () { - return GetStackFrameAtIndex (m_concrete_frames.GetCurrentFrameIndex()); + return GetStackFrameAtIndex (GetStackFrameList().GetCurrentFrameIndex()); } uint32_t Thread::SetCurrentFrame (lldb_private::StackFrame *frame) { - return m_concrete_frames.SetCurrentFrame(frame); + return GetStackFrameList().SetCurrentFrame(frame); } void Thread::SetCurrentFrameByIndex (uint32_t idx) { - m_concrete_frames.SetCurrentFrameByIndex(idx); + GetStackFrameList().SetCurrentFrameByIndex(idx); } void From gclayton at apple.com Tue Aug 24 19:58:59 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 25 Aug 2010 00:58:59 -0000 Subject: [Lldb-commits] [lldb] r112009 - /lldb/trunk/include/lldb/Target/StackFrameList.h Message-ID: <20100825005859.480A92A6C12C@llvm.org> Author: gclayton Date: Tue Aug 24 19:58:59 2010 New Revision: 112009 URL: http://llvm.org/viewvc/llvm-project?rev=112009&view=rev Log: Thread no longer needs to be a friend in StackFrameList now that StackFrameList contains the entire stack backtrace. Modified: lldb/trunk/include/lldb/Target/StackFrameList.h Modified: lldb/trunk/include/lldb/Target/StackFrameList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=112009&r1=112008&r2=112009&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrameList.h (original) +++ lldb/trunk/include/lldb/Target/StackFrameList.h Tue Aug 24 19:58:59 2010 @@ -24,7 +24,6 @@ class StackFrameList { public: - friend class Thread; //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ From gclayton at apple.com Tue Aug 24 20:01:30 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 25 Aug 2010 01:01:30 -0000 Subject: [Lldb-commits] [lldb] r112010 - /lldb/trunk/include/lldb/Target/StackFrameList.h Message-ID: <20100825010130.D97402A6C12C@llvm.org> Author: gclayton Date: Tue Aug 24 20:01:30 2010 New Revision: 112010 URL: http://llvm.org/viewvc/llvm-project?rev=112010&view=rev Log: The destructor for StackFrameList doesn't need to be virtual as we aren't subclassing it anywhere. Modified: lldb/trunk/include/lldb/Target/StackFrameList.h Modified: lldb/trunk/include/lldb/Target/StackFrameList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=112010&r1=112009&r2=112010&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrameList.h (original) +++ lldb/trunk/include/lldb/Target/StackFrameList.h Tue Aug 24 20:01:30 2010 @@ -29,7 +29,6 @@ //------------------------------------------------------------------ StackFrameList (Thread &thread, bool show_inline_frames); - virtual ~StackFrameList(); uint32_t From johnny.chen at apple.com Wed Aug 25 13:49:48 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 25 Aug 2010 18:49:48 -0000 Subject: [Lldb-commits] [lldb] r112071 - /lldb/trunk/test/lldbtest.py Message-ID: <20100825184948.2B5AF2A6C12C@llvm.org> Author: johnny Date: Wed Aug 25 13:49:48 2010 New Revision: 112071 URL: http://llvm.org/viewvc/llvm-project?rev=112071&view=rev Log: Allow command retries in case of process launch failures. This recovery mechanism seems to work fine on my MacBook Pro in some limited test cases. The default maxLaunchCount and timeWait variables used in the scheme can be overridden by the env variables LLDB_MAX_LAUNCH_COUNT and LLDB_TIME_WAIT. 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=112071&r1=112070&r2=112071&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Wed Aug 25 13:49:48 2010 @@ -107,6 +107,7 @@ import os import sys +import time import unittest2 import lldb @@ -150,6 +151,14 @@ # State pertaining to the inferior process, if any. runStarted = False + # Maximum allowed attempts when launching the inferior process. + # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable. + maxLaunchCount = 3; + + # Time to wait before the next launching attempt in second(s). + # Can be overridden by the LLDB_TIME_WAIT environment variable. + timeWait = 1.0; + # os.environ["LLDB_COMMAND_TRACE"], if set to "YES", will turn on this flag. traceAlways = False; @@ -168,6 +177,12 @@ if ("LLDB_TEST" in os.environ): os.chdir(os.path.join(os.environ["LLDB_TEST"], self.mydir)); + if "LLDB_MAX_LAUNCH_COUNT" in os.environ: + self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"]) + + if "LLDB_TIME_WAIT" in os.environ: + self.timeWait = float(os.environ["LLDB_TIME_WAIT"]) + if ("LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"] == "YES"): self.traceAlways = True @@ -213,19 +228,25 @@ trace = (True if self.traceAlways else trace) - if trace: - print >> sys.stderr, "runCmd:", cmd + self.runStarted = (cmd.startswith("run") or + cmd.startswith("process launch")) - self.ci.HandleCommand(cmd, self.res) + for i in range(self.maxLaunchCount if self.runStarted else 1): + self.ci.HandleCommand(cmd, self.res) - if cmd.startswith("run"): - self.runStarted = True + if trace: + print >> sys.stderr, "runCmd:", cmd + if self.res.Succeeded(): + print >> sys.stderr, "output:", self.res.GetOutput() + else: + print >> sys.stderr, self.res.GetError() - if trace: if self.res.Succeeded(): - print >> sys.stderr, "output:", self.res.GetOutput() + break else: - print >> sys.stderr, self.res.GetError() + if self.runStarted: + # Process launch failed, wait some time before the next try. + time.sleep(self.timeWait) if check: self.assertTrue(self.res.Succeeded(), From johnny.chen at apple.com Wed Aug 25 14:00:04 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 25 Aug 2010 19:00:04 -0000 Subject: [Lldb-commits] [lldb] r112074 - /lldb/trunk/test/lldbtest.py Message-ID: <20100825190004.5B1F42A6C12D@llvm.org> Author: johnny Date: Wed Aug 25 14:00:04 2010 New Revision: 112074 URL: http://llvm.org/viewvc/llvm-project?rev=112074&view=rev Log: Fixed a logic error in the expect() method. If the start string does not match, there's no point matching further sub strings; the expect() already fails. Also cleaned up the assert message for VARIABLES_DISPLAYED_CORRECTLY. 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=112074&r1=112073&r2=112074&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Wed Aug 25 14:00:04 2010 @@ -133,7 +133,7 @@ DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly" -VARIABLES_DISPLAYED_CORRECTLY = "Show specified variable(s) correctly" +VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly" # # And a generic "Command '%s' returns successfully" message generator. @@ -276,7 +276,7 @@ print >> sys.stderr, "Matched" if matched else "Not matched" print >> sys.stderr - if substrs: + if substrs and matched: for str in substrs: matched = output.find(str) > 0 if trace: From johnny.chen at apple.com Wed Aug 25 17:52:45 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 25 Aug 2010 22:52:45 -0000 Subject: [Lldb-commits] [lldb] r112102 - in /lldb/trunk/test: lldbtest.py macosx/universal/TestUniversal.py Message-ID: <20100825225245.D7DA72A6C12C@llvm.org> Author: johnny Date: Wed Aug 25 17:52:45 2010 New Revision: 112102 URL: http://llvm.org/viewvc/llvm-project?rev=112102&view=rev Log: Added logic to TestUniversal.py to exercise the python APIs: o SBDebugger.GetCurrentTarget() o SBTarget.GetProcess() o SBProcess.GetAddressByteSize() in order to make sure that, indeed, 64-bit, followed by 32-bit processes have been launched. Added invoke() method to TestBase to factor in the tracing logic in one place. This method allows an object to call a method with no arg reflectively. Modified: lldb/trunk/test/lldbtest.py lldb/trunk/test/macosx/universal/TestUniversal.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112102&r1=112101&r2=112102&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Wed Aug 25 17:52:45 2010 @@ -289,3 +289,16 @@ self.assertTrue(matched, msg if msg else CMD_MSG(cmd)) + def invoke(self, obj, name, trace=False): + """Use reflection to call a method dynamically without any argument.""" + + trace = (True if self.traceAlways else trace) + + method = getattr(obj, name) + import inspect + self.assertTrue(inspect.ismethod(method), + name + "is a method name of object: " + str(obj)) + result = method() + if self.traceAlways: + print str(method) + ":", result + return result Modified: lldb/trunk/test/macosx/universal/TestUniversal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/TestUniversal.py?rev=112102&r1=112101&r2=112102&view=diff ============================================================================== --- lldb/trunk/test/macosx/universal/TestUniversal.py (original) +++ lldb/trunk/test/macosx/universal/TestUniversal.py Wed Aug 25 17:52:45 2010 @@ -26,6 +26,14 @@ # We should be able to launch the x86_64 executable. self.runCmd("run", RUN_STOPPED) + + # Check whether we have a 64-bit process launched. + target = self.dbg.GetCurrentTarget() + process = target.GetProcess() + self.assertTrue(target.IsValid() and process.IsValid() and + self.invoke(process, 'GetAddressByteSize') == 8, + "64-bit process launched") + self.runCmd("continue") # Now specify i386 as the architecture for "testit". @@ -39,6 +47,14 @@ # We should be able to launch the i386 executable as well. self.runCmd("run", RUN_STOPPED) + + # Check whether we have a 32-bit process launched. + target = self.dbg.GetCurrentTarget() + process = target.GetProcess() + self.assertTrue(target.IsValid() and process.IsValid() and + self.invoke(process, 'GetAddressByteSize') == 4, + "32-bit process launched") + self.runCmd("continue") From johnny.chen at apple.com Wed Aug 25 17:56:10 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 25 Aug 2010 22:56:10 -0000 Subject: [Lldb-commits] [lldb] r112103 - /lldb/trunk/test/lldbtest.py Message-ID: <20100825225610.66C8F2A6C12C@llvm.org> Author: johnny Date: Wed Aug 25 17:56:10 2010 New Revision: 112103 URL: http://llvm.org/viewvc/llvm-project?rev=112103&view=rev Log: Minor doc string modification. 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=112103&r1=112102&r2=112103&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Wed Aug 25 17:56:10 2010 @@ -290,7 +290,7 @@ self.assertTrue(matched, msg if msg else CMD_MSG(cmd)) def invoke(self, obj, name, trace=False): - """Use reflection to call a method dynamically without any argument.""" + """Use reflection to call a method dynamically with no argument.""" trace = (True if self.traceAlways else trace) From gclayton at apple.com Wed Aug 25 21:28:22 2010 From: gclayton at apple.com (Greg Clayton) Date: Thu, 26 Aug 2010 02:28:22 -0000 Subject: [Lldb-commits] [lldb] r112152 - in /lldb/trunk: include/lldb/Target/StackFrame.h include/lldb/Target/StackFrameList.h include/lldb/Target/StackID.h include/lldb/Target/Thread.h source/Target/StackFrame.cpp source/Target/StackFrameList.cpp source/Target/StackID.cpp source/Target/Thread.cpp Message-ID: <20100826022822.9F0492A6C12C@llvm.org> Author: gclayton Date: Wed Aug 25 21:28:22 2010 New Revision: 112152 URL: http://llvm.org/viewvc/llvm-project?rev=112152&view=rev Log: Cleaned up the inline stack frame code one more time to prepare for inlined code stepping. Also we now store the stack frames for the current and previous stops in the thread in std::auto_ptr objects. When we create a thread stack frame list we pass the previous frame into it so it can re-use the frames and maintain will allow for variable changes to be detected. I will implement the stack frame reuse next. Modified: lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/Target/StackFrameList.h lldb/trunk/include/lldb/Target/StackID.h lldb/trunk/include/lldb/Target/Thread.h lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/StackFrameList.cpp lldb/trunk/source/Target/StackID.cpp lldb/trunk/source/Target/Thread.cpp Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=112152&r1=112151&r2=112152&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Wed Aug 25 21:28:22 2010 @@ -33,9 +33,9 @@ //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, lldb::addr_t cfa, uint32_t inline_height, lldb::addr_t pc, const SymbolContext *sc_ptr); - StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, uint32_t inline_height, lldb::addr_t pc, const SymbolContext *sc_ptr); - StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, uint32_t inline_height, const Address& pc, const SymbolContext *sc_ptr); + StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr); + StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr); + StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, const Address& pc, const SymbolContext *sc_ptr); virtual ~StackFrame (); Thread & @@ -97,9 +97,6 @@ return m_concrete_frame_index; } - bool - IsConcrete () const; - //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions //------------------------------------------------------------------ @@ -119,10 +116,16 @@ Calculate (ExecutionContext &exe_ctx); protected: + friend class StackFrameList; + //------------------------------------------------------------------ // Classes that inherit from StackFrame can see and modify these //------------------------------------------------------------------ - + void + SetInlineBlockID (lldb::user_id_t inline_block_id) + { + m_id.SetInlineBlockID(inline_block_id); + } private: //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Target/StackFrameList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=112152&r1=112151&r2=112152&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrameList.h (original) +++ lldb/trunk/include/lldb/Target/StackFrameList.h Wed Aug 25 21:28:22 2010 @@ -27,7 +27,9 @@ //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - StackFrameList (Thread &thread, bool show_inline_frames); + StackFrameList (Thread &thread, + StackFrameList *prev_frames, + bool show_inline_frames); ~StackFrameList(); @@ -56,22 +58,21 @@ protected: bool - SetActualFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); + SetUnwindFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); bool SetInlineFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); lldb::StackFrameSP - GetActualFrameAtIndex (uint32_t idx) const; + GetUnwindFrameAtIndex (uint32_t idx) const; lldb::StackFrameSP GetInlineFrameAtIndex (uint32_t idx) const; typedef struct InlinedFrameInfo { - uint32_t concrete_frame_index; - uint32_t inline_height; + uint32_t unwind_frame_index; Block *block; } InlinedFrameInfo; typedef std::vector InlinedFrameInfoCollection; @@ -84,10 +85,11 @@ typedef collection::const_iterator const_iterator; Thread &m_thread; + std::auto_ptr m_prev_frames_ap; mutable Mutex m_mutex; - collection m_actual_frames; + collection m_unwind_frames; collection m_inline_frames; - InlinedFrameInfoCollection m_inlined_frame_info; + InlinedFrameInfoCollection m_inlined_info; uint32_t m_current_frame_idx; bool m_show_inlined_frames; Modified: lldb/trunk/include/lldb/Target/StackID.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackID.h?rev=112152&r1=112151&r2=112152&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackID.h (original) +++ lldb/trunk/include/lldb/Target/StackID.h Wed Aug 25 21:28:22 2010 @@ -25,11 +25,38 @@ //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - StackID (); - explicit StackID (lldb::addr_t cfa, uint32_t inline_id); - StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_id); - StackID (const StackID& rhs); - virtual ~StackID(); + StackID () : + m_start_address(), + m_cfa (0), + m_inline_block_id (0) + { + } + + explicit + StackID (lldb::addr_t cfa, lldb::user_id_t inline_block_id) : + m_start_address (), + m_cfa (cfa), + m_inline_block_id (inline_block_id) + { + } + + StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_block_id) : + m_start_address (start_address), + m_cfa (cfa), + m_inline_block_id (inline_block_id) + { + } + + StackID (const StackID& rhs) : + m_start_address (rhs.m_start_address), + m_cfa (rhs.m_cfa), + m_inline_block_id (rhs.m_inline_block_id) + { + } + + ~StackID() + { + } const Address& GetStartAddress() const @@ -49,28 +76,44 @@ return m_cfa; } - uint32_t - GetInlineHeight () const + lldb::user_id_t + GetInlineBlockID () const + { + return m_inline_block_id; + } + + void + SetInlineBlockID (lldb::user_id_t inline_block_id) { - return m_inline_height; + m_inline_block_id = inline_block_id; } + //------------------------------------------------------------------ // Operators //------------------------------------------------------------------ const StackID& - operator=(const StackID& rhs); + operator=(const StackID& rhs) + { + if (this != &rhs) + { + m_start_address = rhs.m_start_address; + m_cfa = rhs.m_cfa; + m_inline_block_id = rhs.m_inline_block_id; + } + return *this; + } protected: //------------------------------------------------------------------ // Classes that inherit from StackID can see and modify these //------------------------------------------------------------------ - Address m_start_address; // The address range for the function for this frame - lldb::addr_t m_cfa; // The call frame address (stack pointer) value - // at the beginning of the function that uniquely - // identifies this frame (along with m_inline_height below) - uint32_t m_inline_height; // The inline height of a stack frame. Zero is the actual - // value for the place where a thread stops, 1 and above - // are for the inlined frames above the concrete base frame. + Address m_start_address; // The address range for the function for this frame + lldb::addr_t m_cfa; // The call frame address (stack pointer) value + // at the beginning of the function that uniquely + // identifies this frame (along with m_inline_block_id below) + lldb::user_id_t m_inline_block_id; // The inline height of a stack frame. Zero is the actual + // value for the place where a thread stops, 1 and above + // are for the inlined frames above the concrete base frame. }; bool operator== (const StackID& lhs, const StackID& rhs); Modified: lldb/trunk/include/lldb/Target/Thread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=112152&r1=112151&r2=112152&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Thread.h (original) +++ lldb/trunk/include/lldb/Target/Thread.h Wed Aug 25 21:28:22 2010 @@ -555,7 +555,8 @@ plan_stack m_immediate_plan_stack; ///< The plans that need to get executed before any other work gets done. plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes. plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes. - lldb::StackFrameListSP m_frames_sp; ///< The stack frames that get lazily populated after a thread stops. + std::auto_ptr m_curr_frames_ap; ///< The stack frames that get lazily populated after a thread stops. + std::auto_ptr m_prev_frames_ap; ///< The previous stack frames from the last time this thread stopped. int m_resume_signal; ///< The signal that should be used when continuing this thread. lldb::StateType m_resume_state; ///< The state that indicates what this thread should do when the process is resumed. std::auto_ptr m_unwinder_ap; Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=112152&r1=112151&r2=112152&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Wed Aug 25 21:28:22 2010 @@ -41,7 +41,6 @@ lldb::user_id_t concrete_frame_index, Thread &thread, lldb::addr_t cfa, - uint32_t inline_height, lldb::addr_t pc, const SymbolContext *sc_ptr ) : @@ -49,7 +48,7 @@ m_concrete_frame_index (concrete_frame_index), m_thread (thread), m_reg_context_sp (), - m_id (cfa, inline_height), + m_id (cfa, 0), m_pc (NULL, pc), m_sc (), m_flags (), @@ -72,7 +71,6 @@ Thread &thread, const RegisterContextSP ®_context_sp, lldb::addr_t cfa, - uint32_t inline_height, lldb::addr_t pc, const SymbolContext *sc_ptr ) : @@ -80,7 +78,7 @@ m_concrete_frame_index (concrete_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (cfa, inline_height), + m_id (cfa, 0), m_pc (NULL, pc), m_sc (), m_flags (), @@ -109,7 +107,6 @@ Thread &thread, const RegisterContextSP ®_context_sp, lldb::addr_t cfa, - uint32_t inline_height, const Address& pc_addr, const SymbolContext *sc_ptr ) : @@ -117,7 +114,7 @@ m_concrete_frame_index (concrete_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (cfa, inline_height), + m_id (cfa, 0), m_pc (pc_addr), m_sc (), m_flags (), @@ -473,12 +470,6 @@ return m_value_object_list; } -bool -StackFrame::IsConcrete () const -{ - return m_id.GetInlineHeight () == 0; -} - Target * StackFrame::CalculateTarget () { Modified: lldb/trunk/source/Target/StackFrameList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=112152&r1=112151&r2=112152&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrameList.cpp (original) +++ lldb/trunk/source/Target/StackFrameList.cpp Wed Aug 25 21:28:22 2010 @@ -26,11 +26,12 @@ //---------------------------------------------------------------------- // StackFrameList constructor //---------------------------------------------------------------------- -StackFrameList::StackFrameList(Thread &thread, bool show_inline_frames) : +StackFrameList::StackFrameList(Thread &thread, StackFrameList *prev_frames, bool show_inline_frames) : m_thread (thread), + m_prev_frames_ap (prev_frames), m_show_inlined_frames (show_inline_frames), m_mutex (Mutex::eMutexTypeRecursive), - m_actual_frames (), + m_unwind_frames (), m_inline_frames (), m_current_frame_idx (0) { @@ -51,13 +52,13 @@ if (m_show_inlined_frames) { - if (m_inlined_frame_info.empty()) + if (m_inlined_info.empty()) { Unwind *unwinder = m_thread.GetUnwinder (); // If we are going to show inlined stack frames as actual frames, // we need to calculate all concrete frames first, then iterate // through all of them and count up how many inlined functions are - // in each frame. We can then fill in m_inlined_frame_info with + // in each frame. We can then fill in m_inlined_info with // the concrete frame index and inlined depth const uint32_t concrete_frame_count = unwinder->GetFrameCount(); @@ -75,7 +76,6 @@ m_thread, m_thread.m_reg_context_sp, m_thread.m_reg_context_sp->GetSP(), - 0, m_thread.m_reg_context_sp->GetPC(), NULL)); } @@ -83,52 +83,51 @@ { const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc); assert (success); - frame_sp.reset (new StackFrame (m_inlined_frame_info.size(), idx, m_thread, cfa, 0, pc, NULL)); + frame_sp.reset (new StackFrame (m_inlined_info.size(), idx, m_thread, cfa, pc, NULL)); } - SetActualFrameAtIndex (idx, frame_sp); + SetUnwindFrameAtIndex (idx, frame_sp); Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block; - inlined_frame_info.concrete_frame_index = idx; - inlined_frame_info.inline_height = 0; - inlined_frame_info.block = block; - m_inlined_frame_info.push_back (inlined_frame_info); + inlined_frame_info.unwind_frame_index = idx; + inlined_frame_info.block = NULL; + m_inlined_info.push_back (inlined_frame_info); if (block) { - Block *inlined_block; - if (block->InlinedFunctionInfo()) - inlined_block = block; - else - inlined_block = block->GetInlinedParent (); - - while (inlined_block) + Block *inlined_block = block->GetContainingInlinedBlock(); + + if (inlined_block) { - inlined_frame_info.block = inlined_block; - inlined_frame_info.inline_height++; - m_inlined_frame_info.push_back (inlined_frame_info); - inlined_block = inlined_block->GetInlinedParent (); + frame_sp->SetInlineBlockID (inlined_block->GetID()); + + while (inlined_block) + { + inlined_frame_info.block = inlined_block; + m_inlined_info.push_back (inlined_frame_info); + inlined_block = inlined_block->GetInlinedParent (); + } } } } } - return m_inlined_frame_info.size(); + return m_inlined_info.size(); } else { - if (m_actual_frames.empty()) - m_actual_frames.resize(m_thread.GetUnwinder()->GetFrameCount()); + if (m_unwind_frames.empty()) + m_unwind_frames.resize(m_thread.GetUnwinder()->GetFrameCount()); - return m_actual_frames.size(); + return m_unwind_frames.size(); } return 0; } lldb::StackFrameSP -StackFrameList::GetActualFrameAtIndex (uint32_t idx) const +StackFrameList::GetUnwindFrameAtIndex (uint32_t idx) const { StackFrameSP frame_sp; - if (idx < m_actual_frames.size()) - frame_sp = m_actual_frames[idx]; + if (idx < m_unwind_frames.size()) + frame_sp = m_unwind_frames[idx]; return frame_sp; } @@ -155,118 +154,138 @@ } else { - frame_sp = GetActualFrameAtIndex (idx); + frame_sp = GetUnwindFrameAtIndex (idx); } if (frame_sp.get()) - return frame_sp; + return frame_sp; - // Special case the first frame (idx == 0) so that we don't need to - // know how many stack frames there are to get it. If we need any other - // frames, then we do need to know if "idx" is a valid index. - if (idx == 0) - { - // If this is the first frame, we want to share the thread register - // context with the stack frame at index zero. - m_thread.GetRegisterContext(); - assert (m_thread.m_reg_context_sp.get()); - frame_sp.reset (new StackFrame (0, - 0, - m_thread, - m_thread.m_reg_context_sp, - m_thread.m_reg_context_sp->GetSP(), - 0, - m_thread.m_reg_context_sp->GetPC(), - NULL)); - } - else if (idx < GetNumFrames()) - { - if (m_show_inlined_frames) + // Special case the first frame (idx == 0) so that we don't need to + // know how many stack frames there are to get it. If we need any other + // frames, then we do need to know if "idx" is a valid index. + if (idx == 0) { - if (m_inlined_frame_info[idx].inline_height == 0) + // If this is the first frame, we want to share the thread register + // context with the stack frame at index zero. + m_thread.GetRegisterContext(); + assert (m_thread.m_reg_context_sp.get()); + frame_sp.reset (new StackFrame (0, + 0, + m_thread, + m_thread.m_reg_context_sp, + m_thread.m_reg_context_sp->GetSP(), + m_thread.m_reg_context_sp->GetPC(), + NULL)); + + if (m_show_inlined_frames && idx + 1 < m_inlined_info.size()) { - // Same as the concrete stack frame if block is NULL - assert (m_inlined_frame_info[idx].concrete_frame_index < m_actual_frames.size()); - frame_sp = GetActualFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index); + if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index) + frame_sp->SetInlineBlockID (frame_sp->GetSymbolContext (eSymbolContextBlock).block->GetID()); } - else + + } + else if (idx < GetNumFrames()) + { + if (m_show_inlined_frames) { - // We have blocks that were above an inlined function. Inlined - // functions are represented as blocks with non-NULL inline - // function info. Here we must reconstruct a frame by looking - // at the block - StackFrameSP previous_frame_sp (m_thread.GetStackFrameAtIndex (idx-1)); - - SymbolContext inline_sc; - - Block *inlined_parent_block = m_inlined_frame_info[idx].block->GetInlinedParent(); - - if (inlined_parent_block) - inlined_parent_block->CalculateSymbolContext (&inline_sc); - else + if (m_inlined_info[idx].block == NULL) { - Block *parent_block = m_inlined_frame_info[idx].block->GetParent(); - parent_block->CalculateSymbolContext(&inline_sc); + // Same as the concrete stack frame if block is NULL + assert (m_inlined_info[idx].unwind_frame_index < m_unwind_frames.size()); + frame_sp = GetUnwindFrameAtIndex (m_inlined_info[idx].unwind_frame_index); + if (idx + 1 < m_inlined_info.size()) + { + if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index) + frame_sp->SetInlineBlockID (frame_sp->GetSymbolContext (eSymbolContextBlock).block->GetID()); + } } - - Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress()); - if (previous_frame_sp->IsConcrete () && previous_frame_sp->GetFrameIndex() > 0) - previous_frame_lookup_addr.Slide (-1); - - AddressRange range; - m_inlined_frame_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range); + else + { + // We have blocks that were above an inlined function. Inlined + // functions are represented as blocks with non-NULL inline + // function info. Here we must reconstruct a frame by looking + // at the block + StackFrameSP previous_frame_sp (m_thread.GetStackFrameAtIndex (idx-1)); + + SymbolContext inline_sc; + + Block *inlined_parent_block = m_inlined_info[idx].block->GetInlinedParent(); + + if (inlined_parent_block) + inlined_parent_block->CalculateSymbolContext (&inline_sc); + else + { + Block *parent_block = m_inlined_info[idx].block->GetParent(); + parent_block->CalculateSymbolContext(&inline_sc); + } - const InlineFunctionInfo* inline_info = m_inlined_frame_info[idx].block->InlinedFunctionInfo(); - assert (inline_info); - inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress(); - inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); - inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); - inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); - - StackFrameSP concrete_frame_sp (GetActualFrameAtIndex (m_inlined_frame_info[idx].concrete_frame_index)); - assert (previous_frame_sp.get()); - - frame_sp.reset (new StackFrame (idx, - m_inlined_frame_info[idx].concrete_frame_index, - m_thread, - concrete_frame_sp->GetRegisterContextSP (), - concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA - m_inlined_frame_info[idx].inline_height, // Inline height - range.GetBaseAddress(), - &inline_sc)); // The symbol context for this inline frame - + Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress()); + if (previous_frame_sp->GetFrameIndex() > 0 && m_inlined_info[idx-1].block == NULL) + previous_frame_lookup_addr.Slide (-1); + + AddressRange range; + m_inlined_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range); + + const InlineFunctionInfo* inline_info = m_inlined_info[idx].block->InlinedFunctionInfo(); + assert (inline_info); + inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress(); + inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); + inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); + inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); + + StackFrameSP concrete_frame_sp (GetUnwindFrameAtIndex (m_inlined_info[idx].unwind_frame_index)); + assert (previous_frame_sp.get()); + + frame_sp.reset (new StackFrame (idx, + m_inlined_info[idx].unwind_frame_index, + m_thread, + concrete_frame_sp->GetRegisterContextSP (), + concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA + range.GetBaseAddress(), + &inline_sc)); // The symbol context for this inline frame + + if (idx + 1 < m_inlined_info.size()) + { + if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index) + frame_sp->SetInlineBlockID (m_inlined_info[idx].block->GetID()); + } + } + } + else + { + Unwind *unwinder = m_thread.GetUnwinder (); + if (unwinder) + { + addr_t pc, cfa; + if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) + frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, pc, NULL)); + } } } + + if (m_show_inlined_frames) + { + SetInlineFrameAtIndex(idx, frame_sp); + } else { - Unwind *unwinder = m_thread.GetUnwinder (); - if (unwinder) - { - addr_t pc, cfa; - if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) - frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, 0, pc, NULL)); - } + SetUnwindFrameAtIndex(idx, frame_sp); } - } - if (m_show_inlined_frames) - SetInlineFrameAtIndex(idx, frame_sp); - else - SetActualFrameAtIndex(idx, frame_sp); - return frame_sp; - + return frame_sp; + } return frame_sp; } bool -StackFrameList::SetActualFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) +StackFrameList::SetUnwindFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) { - if (idx >= m_actual_frames.size()) - m_actual_frames.resize(idx + 1); + if (idx >= m_unwind_frames.size()) + m_unwind_frames.resize(idx + 1); // Make sure allocation succeeded by checking bounds again - if (idx < m_actual_frames.size()) + if (idx < m_unwind_frames.size()) { - m_actual_frames[idx] = frame_sp; + m_unwind_frames[idx] = frame_sp; return true; } return false; // resize failed, out of memory? @@ -299,8 +318,8 @@ { Mutex::Locker locker (m_mutex); const_iterator pos; - const_iterator begin = m_show_inlined_frames ? m_inline_frames.begin() : m_actual_frames.begin(); - const_iterator end = m_show_inlined_frames ? m_inline_frames.end() : m_actual_frames.end(); + const_iterator begin = m_show_inlined_frames ? m_inline_frames.begin() : m_unwind_frames.begin(); + const_iterator end = m_show_inlined_frames ? m_inline_frames.end() : m_unwind_frames.end(); for (pos = begin; pos != end; ++pos) { if (pos->get() == frame) @@ -327,9 +346,9 @@ StackFrameList::Clear () { Mutex::Locker locker (m_mutex); - m_actual_frames.clear(); + m_unwind_frames.clear(); m_inline_frames.clear(); - m_inlined_frame_info.clear(); + m_inlined_info.clear(); } void @@ -342,10 +361,10 @@ } else { - const size_t num_frames = m_actual_frames.size(); + const size_t num_frames = m_unwind_frames.size(); while (start_idx < num_frames) { - m_actual_frames[start_idx].reset(); + m_unwind_frames[start_idx].reset(); ++start_idx; } } Modified: lldb/trunk/source/Target/StackID.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackID.cpp?rev=112152&r1=112151&r2=112152&view=diff ============================================================================== --- lldb/trunk/source/Target/StackID.cpp (original) +++ lldb/trunk/source/Target/StackID.cpp Wed Aug 25 21:28:22 2010 @@ -16,84 +16,27 @@ using namespace lldb_private; -//---------------------------------------------------------------------- -// StackID constructor -//---------------------------------------------------------------------- -StackID::StackID() : - m_start_address(), - m_cfa (0), - m_inline_height (0) -{ -} - -//---------------------------------------------------------------------- -// StackID constructor with args -//---------------------------------------------------------------------- -StackID::StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_id) : - m_start_address (start_address), - m_cfa (cfa), - m_inline_height (inline_id) -{ -} - -StackID::StackID (lldb::addr_t cfa, uint32_t inline_id) : - m_start_address (), - m_cfa (cfa), - m_inline_height (inline_id) -{ -} - -//---------------------------------------------------------------------- -// StackID copy constructor -//---------------------------------------------------------------------- -StackID::StackID(const StackID& rhs) : - m_start_address (rhs.m_start_address), - m_cfa (rhs.m_cfa), - m_inline_height (rhs.m_inline_height) -{ -} - -//---------------------------------------------------------------------- -// StackID assignment operator -//---------------------------------------------------------------------- -const StackID& -StackID::operator=(const StackID& rhs) -{ - if (this != &rhs) - { - m_start_address = rhs.m_start_address; - m_cfa = rhs.m_cfa; - m_inline_height = rhs.m_inline_height; - } - return *this; -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -StackID::~StackID() -{ -} bool lldb_private::operator== (const StackID& lhs, const StackID& rhs) { - return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() && - lhs.GetInlineHeight() == rhs.GetInlineHeight() && - lhs.GetStartAddress() == rhs.GetStartAddress(); + return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() && + lhs.GetInlineBlockID() == rhs.GetInlineBlockID() && + lhs.GetStartAddress() == rhs.GetStartAddress(); } bool lldb_private::operator!= (const StackID& lhs, const StackID& rhs) { - return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() || - lhs.GetInlineHeight() != rhs.GetInlineHeight() || - lhs.GetStartAddress() != rhs.GetStartAddress(); + return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() || + lhs.GetInlineBlockID() != rhs.GetInlineBlockID() || + lhs.GetStartAddress() != rhs.GetStartAddress(); } bool lldb_private::operator< (const StackID& lhs, const StackID& rhs) { - return lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress(); + if (lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress()) + return true; + return lhs.GetInlineBlockID() < rhs.GetInlineBlockID(); } - Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=112152&r1=112151&r2=112152&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Wed Aug 25 21:28:22 2010 @@ -49,7 +49,7 @@ m_plan_stack (), m_immediate_plan_stack(), m_completed_plan_stack(), - m_frames_sp (), + m_curr_frames_ap (), m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER), m_resume_state (eStateRunning), m_unwinder_ap () @@ -796,9 +796,9 @@ StackFrameList & Thread::GetStackFrameList () { - if (m_frames_sp.get() == NULL) - m_frames_sp.reset (new StackFrameList (*this, true)); - return *m_frames_sp; + if (m_curr_frames_ap.get() == NULL) + m_curr_frames_ap.reset (new StackFrameList (*this, m_prev_frames_ap.release(), true)); + return *m_curr_frames_ap; } @@ -813,8 +813,7 @@ void Thread::ClearStackFrames () { - if (m_frames_sp) - m_frames_sp->Clear(); + m_prev_frames_ap = m_curr_frames_ap; } lldb::StackFrameSP From johnny.chen at apple.com Thu Aug 26 15:04:17 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 26 Aug 2010 20:04:17 -0000 Subject: [Lldb-commits] [lldb] r112210 - in /lldb/trunk: scripts/Python/build-swig-Python.sh scripts/lldb.swig test/array_types/TestArrayTypes.py test/lldbtest.py Message-ID: <20100826200417.4894D2A6C12C@llvm.org> Author: johnny Date: Thu Aug 26 15:04:17 2010 New Revision: 112210 URL: http://llvm.org/viewvc/llvm-project?rev=112210&view=rev Log: o Added a test case for array_types which uses the Python APIs from lldb.py, with the only exception of launching the process from SBTarget which is under investigation. o build-swig-Python.sh should also checks the timestamp of ${swig_input_file} for update eligibility. Also, once an update is in order, there's no need to check the remaining header files for timestamps. o Coaches swig to treat StopReason as an int type, instead of a C++ class. Modified: lldb/trunk/scripts/Python/build-swig-Python.sh lldb/trunk/scripts/lldb.swig lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/scripts/Python/build-swig-Python.sh URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/build-swig-Python.sh?rev=112210&r1=112209&r2=112210&view=diff ============================================================================== --- lldb/trunk/scripts/Python/build-swig-Python.sh (original) +++ lldb/trunk/scripts/Python/build-swig-Python.sh Thu Aug 26 15:04:17 2010 @@ -67,7 +67,7 @@ NeedToUpdate=0 -if [ ! -f $swig_output_file ] +if [ ! -f ${swig_output_file} ] then NeedToUpdate=1 if [ $Debug == 1 ] @@ -80,7 +80,7 @@ then for hdrfile in ${HEADER_FILES} do - if [ $hdrfile -nt $swig_output_file ] + if [ $hdrfile -nt ${swig_output_file} ] then NeedToUpdate=1 if [ $Debug == 1 ] @@ -88,10 +88,24 @@ echo "${hdrfile} is newer than ${swig_output_file}" echo "swig file will need to be re-built." fi + break fi done fi +if [ $NeedToUpdate == 0 ] +then + if [ ${swig_input_file} -nt ${swig_output_file} ] + then + NeedToUpdate=1 + if [ $Debug == 1 ] + then + echo "${swig_input_file} is newer than ${swig_output_file}" + echo "swig file will need to be re-built." + fi + fi +fi + os_name=`uname -s` python_version=`/usr/bin/python --version 2>&1 | sed -e 's,Python ,,' -e 's,[.][0-9],,2' -e 's,[a-z][a-z][0-9],,'` Modified: lldb/trunk/scripts/lldb.swig URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=112210&r1=112209&r2=112210&view=diff ============================================================================== --- lldb/trunk/scripts/lldb.swig (original) +++ lldb/trunk/scripts/lldb.swig Thu Aug 26 15:04:17 2010 @@ -121,6 +121,7 @@ typedef lldb::SBStringList SBStringList; typedef lldb::RegisterKind RegisterKind; const RegisterKind kNumRegisterKinds = lldb::kNumRegisterKinds ; +typedef int StopReason; %include "lldb/API/SBAddress.h" Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112210&r1=112209&r2=112210&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Aug 26 15:04:17 2010 @@ -52,6 +52,64 @@ self.expect("variable list long_6", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(long [6])') + def test_array_types_python(self): + """ + Test 'variable list var_name' on some variables with array types. + + Use the Python APIs from lldb.py. + """ + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.c", 42) + self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) + + self.runCmd("run", RUN_STOPPED) + + # The stop reason of the thread should be breakpoint. + thread = target.GetProcess().GetThreadAtIndex(0) + self.assertTrue(thread.GetStopReason() == Enum("Breakpoint"), + STOPPED_DUE_TO_BREAKPOINT) + + # The breakpoint should have a hit count of 1. + self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) + + # Lookup the "strings" string array variable. + frame = thread.GetFrameAtIndex(0) + variable = frame.LookupVar("strings") + self.assertTrue(variable.GetNumChildren() == 4, + "Variable 'strings' should have 4 children") + + child3 = variable.GetChildAtIndex(3) + self.assertTrue(child3.GetSummary(frame) == '"Guten Tag"', + 'strings[3] == "Guten Tag"') + + # Lookup the "char_16" char array variable. + variable = frame.LookupVar("char_16") + self.assertTrue(variable.GetNumChildren() == 16, + "Variable 'char_16' should have 16 children") + + # Lookup the "ushort_matrix" ushort[] array variable. + variable = frame.LookupVar("ushort_matrix") + self.assertTrue(variable.GetNumChildren() == 2, + "Variable 'ushort_matrix' should have 2 children") + child0 = variable.GetChildAtIndex(0) + self.assertTrue(child0.GetNumChildren() == 3, + "Variable 'ushort_matrix[0]' should have 3 children") + child0_2 = child0.GetChildAtIndex(2) + self.assertTrue(int(child0_2.GetValue(frame), 16) == 3, + "ushort_matrix[0][2] == 3") + + # Lookup the "long_6" char array variable. + variable = frame.LookupVar("long_6") + self.assertTrue(variable.GetNumChildren() == 6, + "Variable 'long_6' should have 6 children") + child5 = variable.GetChildAtIndex(5) + self.assertTrue(long(child5.GetValue(frame)) == 6, + "long_6[5] == 6") + if __name__ == '__main__': import atexit Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112210&r1=112209&r2=112210&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu Aug 26 15:04:17 2010 @@ -133,14 +133,43 @@ DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly" +VALID_BREAKPOINT = "Got a valid breakpoint" + +VALID_PROCESS = "Got a valid process" + +VALID_TARGET = "Got a valid target" + VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly" + # # And a generic "Command '%s' returns successfully" message generator. # def CMD_MSG(command): return "Command '%s' returns successfully" % (command) +# +# Returns the enum from the input string stopReason. +# +def Enum(stopReason): + if stopReason == "Invalid": + return 0 + elif stopReason == "None": + return 1 + elif stopReason == "Trace": + return 2 + elif stopReason == "Breakpoint": + return 3 + elif stopReason == "Watchpoint": + return 4 + elif stopReason == "Signal": + return 5 + elif stopReason == "Exception": + return 6 + elif stopReason == "PlanComplete": + return 7 + else: + raise Exception("Unknown stopReason string") class TestBase(unittest2.TestCase): """This LLDB abstract base class is meant to be subclassed.""" From jingham at apple.com Thu Aug 26 15:44:46 2010 From: jingham at apple.com (Jim Ingham) Date: Thu, 26 Aug 2010 20:44:46 -0000 Subject: [Lldb-commits] [lldb] r112217 - in /lldb/trunk: include/lldb/Target/StackFrame.h source/Target/StackFrame.cpp Message-ID: <20100826204446.17ADF2A6C12C@llvm.org> Author: jingham Date: Thu Aug 26 15:44:45 2010 New Revision: 112217 URL: http://llvm.org/viewvc/llvm-project?rev=112217&view=rev Log: Add StackFrame::IsInlined. Modified: lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/source/Target/StackFrame.cpp Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=112217&r1=112216&r2=112217&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Thu Aug 26 15:44:45 2010 @@ -84,6 +84,9 @@ void Dump (Stream *strm, bool show_frame_index); + + bool + IsInlined (); uint32_t GetFrameIndex () const Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=112217&r1=112216&r2=112217&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Thu Aug 26 15:44:45 2010 @@ -470,6 +470,16 @@ return m_value_object_list; } +bool +StackFrame::IsInlined () +{ + Block *block = GetSymbolContext (eSymbolContextBlock).block; + if (block) + return block->GetContainingInlinedBlock() != NULL; + else + return false; +} + Target * StackFrame::CalculateTarget () { From jingham at apple.com Thu Aug 26 16:32:51 2010 From: jingham at apple.com (Jim Ingham) Date: Thu, 26 Aug 2010 21:32:51 -0000 Subject: [Lldb-commits] [lldb] r112221 - in /lldb/trunk: include/lldb/API/ include/lldb/Core/ include/lldb/Target/ source/API/ source/Commands/ source/Core/ source/Interpreter/ source/Plugins/Process/MacOSX-User/scripts/ source/Target/ tools/driver/ Message-ID: <20100826213251.9D2962A6C12C@llvm.org> Author: jingham Date: Thu Aug 26 16:32:51 2010 New Revision: 112221 URL: http://llvm.org/viewvc/llvm-project?rev=112221&view=rev Log: Change "Current" as in GetCurrentThread, GetCurrentStackFrame, etc, to "Selected" i.e. GetSelectedThread. Selected makes more sense, since these are set by some user action (a selection). I didn't change "CurrentProcess" since this is always controlled by the target, and a given target can only have one process, so it really can't be selected. Modified: lldb/trunk/include/lldb/API/SBDebugger.h lldb/trunk/include/lldb/API/SBProcess.h lldb/trunk/include/lldb/API/SBTarget.h lldb/trunk/include/lldb/API/SBThread.h lldb/trunk/include/lldb/API/SBValue.h lldb/trunk/include/lldb/Core/Debugger.h lldb/trunk/include/lldb/Target/StackFrameList.h lldb/trunk/include/lldb/Target/TargetList.h lldb/trunk/include/lldb/Target/Thread.h lldb/trunk/include/lldb/Target/ThreadList.h lldb/trunk/source/API/SBCommandInterpreter.cpp lldb/trunk/source/API/SBDebugger.cpp lldb/trunk/source/API/SBProcess.cpp lldb/trunk/source/API/SBTarget.cpp lldb/trunk/source/API/SBThread.cpp lldb/trunk/source/API/SBValue.cpp lldb/trunk/source/Commands/CommandCompletions.cpp lldb/trunk/source/Commands/CommandObjectArgs.cpp lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp lldb/trunk/source/Commands/CommandObjectDisassemble.cpp lldb/trunk/source/Commands/CommandObjectFile.cpp lldb/trunk/source/Commands/CommandObjectFrame.cpp lldb/trunk/source/Commands/CommandObjectImage.cpp lldb/trunk/source/Commands/CommandObjectProcess.cpp lldb/trunk/source/Commands/CommandObjectSource.cpp lldb/trunk/source/Commands/CommandObjectTarget.cpp lldb/trunk/source/Commands/CommandObjectThread.cpp lldb/trunk/source/Core/Debugger.cpp lldb/trunk/source/Interpreter/Options.cpp lldb/trunk/source/Plugins/Process/MacOSX-User/scripts/test-ProcessDebug.pl lldb/trunk/source/Target/ExecutionContext.cpp lldb/trunk/source/Target/StackFrameList.cpp lldb/trunk/source/Target/TargetList.cpp lldb/trunk/source/Target/Thread.cpp lldb/trunk/source/Target/ThreadList.cpp lldb/trunk/tools/driver/Driver.cpp lldb/trunk/tools/driver/Driver.h Modified: lldb/trunk/include/lldb/API/SBDebugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBDebugger.h (original) +++ lldb/trunk/include/lldb/API/SBDebugger.h Thu Aug 26 16:32:51 2010 @@ -99,10 +99,10 @@ GetNumTargets (); lldb::SBTarget - GetCurrentTarget (); + GetSelectedTarget (); void - UpdateCurrentThread (lldb::SBProcess &process); + UpdateSelectedThread (lldb::SBProcess &process); lldb::SBSourceManager & GetSourceManager (); Modified: lldb/trunk/include/lldb/API/SBProcess.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBProcess.h (original) +++ lldb/trunk/include/lldb/API/SBProcess.h Thu Aug 26 16:32:51 2010 @@ -58,10 +58,10 @@ GetSTDERR (char *dst, size_t dst_len) const; void - ReportCurrentState (const lldb::SBEvent &event, FILE *out) const; + ReportEventState (const lldb::SBEvent &event, FILE *out) const; void - AppendCurrentStateReport (const lldb::SBEvent &event, lldb::SBCommandReturnObject &result); + AppendEventStateReport (const lldb::SBEvent &event, lldb::SBCommandReturnObject &result); //------------------------------------------------------------------ // Thread related functions @@ -76,13 +76,13 @@ GetThreadByID (lldb::tid_t sb_thread_id); lldb::SBThread - GetCurrentThread () const; + GetSelectedThread () const; bool - SetCurrentThread (const lldb::SBThread &thread); + SetSelectedThread (const lldb::SBThread &thread); bool - SetCurrentThreadByID (uint32_t tid); + SetSelectedThreadByID (uint32_t tid); //------------------------------------------------------------------ // Stepping related functions Modified: lldb/trunk/include/lldb/API/SBTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBTarget.h (original) +++ lldb/trunk/include/lldb/API/SBTarget.h Thu Aug 26 16:32:51 2010 @@ -82,9 +82,6 @@ bool DeleteTargetFromList (lldb_private::TargetList *list); - bool - MakeCurrentTarget (); - lldb::SBBreakpoint BreakpointCreateByLocation (const char *file, uint32_t line); Modified: lldb/trunk/include/lldb/API/SBThread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBThread.h (original) +++ lldb/trunk/include/lldb/API/SBThread.h Thu Aug 26 16:32:51 2010 @@ -52,7 +52,7 @@ GetQueueName() const; void - DisplayFramesForCurrentContext (FILE *out, + DisplayFramesForSelectedContext (FILE *out, FILE *err, uint32_t first_frame, uint32_t num_frames, @@ -62,7 +62,7 @@ uint32_t source_lines_after = 3); bool - DisplaySingleFrameForCurrentContext (FILE *out, + DisplaySingleFrameForSelectedContext (FILE *out, FILE *err, lldb::SBFrame &frame, bool show_frame_info, Modified: lldb/trunk/include/lldb/API/SBValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBValue.h (original) +++ lldb/trunk/include/lldb/API/SBValue.h Thu Aug 26 16:32:51 2010 @@ -112,10 +112,6 @@ #endif private: -// -// lldb_private::ExecutionContext -// GetCurrentExecutionContext (); -// lldb::ValueObjectSP m_opaque_sp; }; Modified: lldb/trunk/include/lldb/Core/Debugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Debugger.h (original) +++ lldb/trunk/include/lldb/Core/Debugger.h Thu Aug 26 16:32:51 2010 @@ -101,10 +101,10 @@ GetSourceManager (); lldb::TargetSP - GetCurrentTarget (); + GetSelectedTarget (); ExecutionContext - GetCurrentExecutionContext(); + GetSelectedExecutionContext(); //------------------------------------------------------------------ /// Get accessor for the target list. /// Modified: lldb/trunk/include/lldb/Target/StackFrameList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrameList.h (original) +++ lldb/trunk/include/lldb/Target/StackFrameList.h Thu Aug 26 16:32:51 2010 @@ -41,14 +41,14 @@ // Mark a stack frame as the current frame uint32_t - SetCurrentFrame (lldb_private::StackFrame *frame); + SetSelectedFrame (lldb_private::StackFrame *frame); uint32_t - GetCurrentFrameIndex () const; + GetSelectedFrameIndex () const; // Mark a stack frame as the current frame using the frame index void - SetCurrentFrameByIndex (uint32_t idx); + SetSelectedFrameByIndex (uint32_t idx); void Clear (); @@ -90,7 +90,7 @@ collection m_unwind_frames; collection m_inline_frames; InlinedFrameInfoCollection m_inlined_info; - uint32_t m_current_frame_idx; + uint32_t m_selected_frame_idx; bool m_show_inlined_frames; private: Modified: lldb/trunk/include/lldb/Target/TargetList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/TargetList.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/TargetList.h (original) +++ lldb/trunk/include/lldb/Target/TargetList.h Thu Aug 26 16:32:51 2010 @@ -181,13 +181,13 @@ SignalIfRunning (lldb::pid_t pid, int signo); uint32_t - SetCurrentTarget (Target *target); + SetSelectedTarget (Target *target); void - SetCurrentTargetWithIndex (uint32_t idx); + SetSelectedTargetWithIndex (uint32_t idx); lldb::TargetSP - GetCurrentTarget (); + GetSelectedTarget (); protected: @@ -197,7 +197,7 @@ //------------------------------------------------------------------ collection m_target_list; mutable Mutex m_target_list_mutex; - uint32_t m_current_target_idx; + uint32_t m_selected_target_idx; private: DISALLOW_COPY_AND_ASSIGN (TargetList); }; Modified: lldb/trunk/include/lldb/Target/Thread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Thread.h (original) +++ lldb/trunk/include/lldb/Target/Thread.h Thu Aug 26 16:32:51 2010 @@ -177,13 +177,13 @@ GetStackFrameAtIndex (uint32_t idx); lldb::StackFrameSP - GetCurrentFrame (); + GetSelectedFrame (); uint32_t - SetCurrentFrame (lldb_private::StackFrame *frame); + SetSelectedFrame (lldb_private::StackFrame *frame); void - SetCurrentFrameByIndex (uint32_t frame_idx); + SetSelectedFrameByIndex (uint32_t frame_idx); virtual RegisterContext * GetRegisterContext () = 0; Modified: lldb/trunk/include/lldb/Target/ThreadList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadList.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/ThreadList.h (original) +++ lldb/trunk/include/lldb/Target/ThreadList.h Thu Aug 26 16:32:51 2010 @@ -46,13 +46,13 @@ AddThread (lldb::ThreadSP &thread_sp); lldb::ThreadSP - GetCurrentThread (); + GetSelectedThread (); bool - SetCurrentThreadByID (lldb::tid_t tid); + SetSelectedThreadByID (lldb::tid_t tid); bool - SetCurrentThreadByIndexID (uint32_t index_id); + SetSelectedThreadByIndexID (uint32_t index_id); void Clear(); @@ -109,7 +109,7 @@ uint32_t m_stop_id; ///< The process stop ID that this thread list is valid for. collection m_threads; ///< The threads for this process. mutable Mutex m_threads_mutex; - lldb::tid_t m_current_tid; ///< For targets that need the notion of a current thread. + lldb::tid_t m_selected_tid; ///< For targets that need the notion of a current thread. private: ThreadList (); Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/API/SBCommandInterpreter.cpp (original) +++ lldb/trunk/source/API/SBCommandInterpreter.cpp Thu Aug 26 16:32:51 2010 @@ -166,7 +166,7 @@ if (m_opaque_ptr) { Debugger &debugger = m_opaque_ptr->GetDebugger(); - Target *target = debugger.GetCurrentTarget().get(); + Target *target = debugger.GetSelectedTarget().get(); if (target) process.SetProcess(target->GetProcessSP()); } Modified: lldb/trunk/source/API/SBDebugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/API/SBDebugger.cpp (original) +++ lldb/trunk/source/API/SBDebugger.cpp Thu Aug 26 16:32:51 2010 @@ -215,16 +215,16 @@ bool is_stopped = StateIsStoppedState (event_state); if (!is_stopped) - process.ReportCurrentState (event, out); + process.ReportEventState (event, out); } } void -SBDebugger::UpdateCurrentThread (SBProcess &process) +SBDebugger::UpdateSelectedThread (SBProcess &process) { if (process.IsValid()) { - SBThread curr_thread = process.GetCurrentThread (); + SBThread curr_thread = process.GetSelectedThread (); SBThread thread; StopReason curr_thread_stop_reason = eStopReasonInvalid; if (curr_thread.IsValid()) @@ -270,9 +270,9 @@ } } if (plan_thread.IsValid()) - process.SetCurrentThreadByID (plan_thread.GetThreadID()); + process.SetSelectedThreadByID (plan_thread.GetThreadID()); else if (other_thread.IsValid()) - process.SetCurrentThreadByID (other_thread.GetThreadID()); + process.SetSelectedThreadByID (other_thread.GetThreadID()); else { if (curr_thread.IsValid()) @@ -281,7 +281,7 @@ thread = process.GetThreadAtIndex(0); if (thread.IsValid()) - process.SetCurrentThreadByID (thread.GetThreadID()); + process.SetSelectedThreadByID (thread.GetThreadID()); } } } @@ -415,7 +415,7 @@ if (error.Success()) { - m_opaque_sp->GetTargetList().SetCurrentTarget (target_sp.get()); + m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get()); target.reset(target_sp); } } @@ -450,7 +450,7 @@ if (error.Success()) { - m_opaque_sp->GetTargetList().SetCurrentTarget (target_sp.get()); + m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get()); target.reset (target_sp); } } @@ -509,11 +509,11 @@ } SBTarget -SBDebugger::GetCurrentTarget () +SBDebugger::GetSelectedTarget () { SBTarget sb_target; if (m_opaque_sp) - sb_target.reset(m_opaque_sp->GetTargetList().GetCurrentTarget ()); + sb_target.reset(m_opaque_sp->GetTargetList().GetSelectedTarget ()); return sb_target; } Modified: lldb/trunk/source/API/SBProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBProcess.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/API/SBProcess.cpp (original) +++ lldb/trunk/source/API/SBProcess.cpp Thu Aug 26 16:32:51 2010 @@ -97,11 +97,11 @@ } SBThread -SBProcess::GetCurrentThread () const +SBProcess::GetSelectedThread () const { SBThread sb_thread; if (m_opaque_sp) - sb_thread.SetThread (m_opaque_sp->GetThreadList().GetCurrentThread()); + sb_thread.SetThread (m_opaque_sp->GetThreadList().GetSelectedThread()); return sb_thread; } @@ -152,7 +152,7 @@ } void -SBProcess::ReportCurrentState (const SBEvent &event, FILE *out) const +SBProcess::ReportEventState (const SBEvent &event, FILE *out) const { if (out == NULL) return; @@ -173,7 +173,7 @@ } void -SBProcess::AppendCurrentStateReport (const SBEvent &event, SBCommandReturnObject &result) +SBProcess::AppendEventStateReport (const SBEvent &event, SBCommandReturnObject &result) { if (m_opaque_sp != NULL) { @@ -190,18 +190,18 @@ } bool -SBProcess::SetCurrentThread (const SBThread &thread) +SBProcess::SetSelectedThread (const SBThread &thread) { if (m_opaque_sp != NULL) - return m_opaque_sp->GetThreadList().SetCurrentThreadByID (thread.GetThreadID()); + return m_opaque_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID()); return false; } bool -SBProcess::SetCurrentThreadByID (uint32_t tid) +SBProcess::SetSelectedThreadByID (uint32_t tid) { if (m_opaque_sp != NULL) - return m_opaque_sp->GetThreadList().SetCurrentThreadByID (tid); + return m_opaque_sp->GetThreadList().SetSelectedThreadByID (tid); return false; } @@ -274,7 +274,7 @@ { state = m_opaque_sp->WaitForStateChangedEvents (NULL, event_sp); SBEvent event (event_sp); - AppendCurrentStateReport (event, result); + AppendEventStateReport (event, result); state_changed = true; } } Modified: lldb/trunk/source/API/SBTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/API/SBTarget.cpp (original) +++ lldb/trunk/source/API/SBTarget.cpp Thu Aug 26 16:32:51 2010 @@ -167,17 +167,6 @@ } bool -SBTarget::MakeCurrentTarget () -{ - if (m_opaque_sp) - { - m_opaque_sp->GetDebugger().GetTargetList().SetCurrentTarget (m_opaque_sp.get()); - return true; - } - return false; -} - -bool SBTarget::operator == (const SBTarget &rhs) const { return m_opaque_sp.get() == rhs.m_opaque_sp.get(); Modified: lldb/trunk/source/API/SBThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/API/SBThread.cpp (original) +++ lldb/trunk/source/API/SBThread.cpp Thu Aug 26 16:32:51 2010 @@ -219,7 +219,7 @@ void -SBThread::DisplayFramesForCurrentContext (FILE *out, +SBThread::DisplayFramesForSelectedContext (FILE *out, FILE *err, uint32_t first_frame, uint32_t num_frames, @@ -247,7 +247,7 @@ break; SBFrame sb_frame (frame_sp); - if (DisplaySingleFrameForCurrentContext (out, + if (DisplaySingleFrameForSelectedContext (out, err, sb_frame, show_frame_info, @@ -260,13 +260,13 @@ } bool -SBThread::DisplaySingleFrameForCurrentContext (FILE *out, - FILE *err, - SBFrame &frame, - bool show_frame_info, - bool show_source, - uint32_t source_lines_after, - uint32_t source_lines_before) +SBThread::DisplaySingleFrameForSelectedContext (FILE *out, + FILE *err, + SBFrame &frame, + bool show_frame_info, + bool show_source, + uint32_t source_lines_after, + uint32_t source_lines_before) { bool success = false; @@ -349,7 +349,7 @@ Process &process = m_opaque_sp->GetProcess(); // Why do we need to set the current thread by ID here??? - process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID()); + process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); process.Resume(); } } @@ -383,7 +383,7 @@ Process &process = m_opaque_sp->GetProcess(); // Why do we need to set the current thread by ID here??? - process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID()); + process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); process.Resume(); } @@ -400,7 +400,7 @@ m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, NULL, false, stop_other_threads, eVoteYes, eVoteNoOpinion); Process &process = m_opaque_sp->GetProcess(); - process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID()); + process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); process.Resume(); } } @@ -412,7 +412,7 @@ { m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true); Process &process = m_opaque_sp->GetProcess(); - process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID()); + process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); process.Resume(); } } @@ -429,7 +429,7 @@ m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads); Process &process = m_opaque_sp->GetProcess(); - process.GetThreadList().SetCurrentThreadByID (m_opaque_sp->GetID()); + process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); process.Resume(); } Modified: lldb/trunk/source/API/SBValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/API/SBValue.cpp (original) +++ lldb/trunk/source/API/SBValue.cpp Thu Aug 26 16:32:51 2010 @@ -302,42 +302,6 @@ return is_ptr_type; } - -//lldb_private::ExecutionContext -//SBValue::GetCurrentExecutionContext () -//{ -// lldb_private::Process *process = NULL; -// lldb_private::Thread *thread = NULL; -// lldb_private::StackFrame *frame = NULL; -// -// SBTarget sb_target = SBDebugger::GetCurrentTarget(); -// if (sb_target.IsValid()) -// { -// SBProcess sb_process = sb_target.GetProcess(); -// if (sb_process.IsValid()) -// { -// process = sb_process.get(); -// SBThread sb_thread = sb_process.GetCurrentThread(); -// if (sb_thread.IsValid()) -// { -// thread = sb_thread.GetLLDBObjectPtr(); -// frame = thread->GetStackFrameAtIndex(0).get(); -// lldb_private::ExecutionContext exe_context (process, thread, frame); -// return exe_context; -// } -// else -// { -// lldb_private::ExecutionContext exe_context (process, NULL, NULL); -// return exe_context; -// } -// } -// } -// -// lldb_private::ExecutionContext exe_context (NULL, NULL, NULL); -// return exe_context; -//} -// -// void * SBValue::GetOpaqueType() { Modified: lldb/trunk/source/Commands/CommandCompletions.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandCompletions.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandCompletions.cpp (original) +++ lldb/trunk/source/Commands/CommandCompletions.cpp Thu Aug 26 16:32:51 2010 @@ -102,7 +102,7 @@ if (searcher == NULL) { - lldb::TargetSP target_sp = interpreter.GetDebugger().GetCurrentTarget(); + lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); SearchFilter null_searcher (target_sp); completer.DoCompletion (&null_searcher); } @@ -368,7 +368,7 @@ if (searcher == NULL) { - lldb::TargetSP target_sp = interpreter.GetDebugger().GetCurrentTarget(); + lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); SearchFilter null_searcher (target_sp); completer.DoCompletion (&null_searcher); } @@ -399,7 +399,7 @@ if (searcher == NULL) { - lldb::TargetSP target_sp = interpreter.GetDebugger().GetCurrentTarget(); + lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); SearchFilter null_searcher (target_sp); completer.DoCompletion (&null_searcher); } Modified: lldb/trunk/source/Commands/CommandObjectArgs.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectArgs.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectArgs.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectArgs.cpp Thu Aug 26 16:32:51 2010 @@ -140,7 +140,7 @@ return false; } - lldb::StackFrameSP thread_cur_frame = thread->GetCurrentFrame (); + lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame (); if (!thread_cur_frame) { result.AppendError ("The current thread has no current frame."); Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Thu Aug 26 16:32:51 2010 @@ -273,7 +273,7 @@ CommandReturnObject &result ) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("Invalid target, set executable file using 'file' command."); @@ -706,7 +706,7 @@ CommandReturnObject &result ) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("Invalid target, set executable file using 'file' command."); @@ -797,7 +797,7 @@ CommandReturnObject &result ) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("Invalid target, set executable file using 'file' command."); @@ -897,7 +897,7 @@ CommandReturnObject &result ) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("Invalid target, set executable file using 'file' command."); @@ -993,7 +993,7 @@ CommandReturnObject &result ) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("Invalid target, set executable file using 'file' command."); @@ -1240,7 +1240,7 @@ return false; } - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("Invalid target, set executable file using 'file' command."); Modified: lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp Thu Aug 26 16:32:51 2010 @@ -213,7 +213,7 @@ CommandReturnObject &result ) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { @@ -417,7 +417,7 @@ CommandReturnObject &result ) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { @@ -503,7 +503,7 @@ CommandReturnObject &result ) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Thu Aug 26 16:32:51 2010 @@ -160,7 +160,7 @@ CommandReturnObject &result ) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("invalid target, set executable file using 'file' command"); Modified: lldb/trunk/source/Commands/CommandObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFile.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFile.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFile.cpp Thu Aug 26 16:32:51 2010 @@ -132,7 +132,7 @@ if (target_sp) { - debugger.GetTargetList().SetCurrentTarget(target_sp.get()); + debugger.GetTargetList().SetSelectedTarget(target_sp.get()); result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().AsCString()); result.SetStatus (eReturnStatusSuccessFinishNoResult); } Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Thu Aug 26 16:32:51 2010 @@ -109,8 +109,8 @@ const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0); if (frame_idx < num_frames) { - exe_ctx.thread->SetCurrentFrameByIndex (frame_idx); - exe_ctx.frame = exe_ctx.thread->GetCurrentFrame ().get(); + exe_ctx.thread->SetSelectedFrameByIndex (frame_idx); + exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get(); if (exe_ctx.frame) { Modified: lldb/trunk/source/Commands/CommandObjectImage.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectImage.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectImage.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectImage.cpp Thu Aug 26 16:32:51 2010 @@ -579,7 +579,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("invalid target, set executable file using 'file' command"); @@ -687,7 +687,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("invalid target, set executable file using 'file' command"); @@ -794,7 +794,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("invalid target, set executable file using 'file' command"); @@ -901,7 +901,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("invalid target, set executable file using 'file' command"); @@ -1070,7 +1070,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("invalid target, set executable file using 'file' command"); @@ -1438,7 +1438,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("invalid target, set executable file using 'file' command"); Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Thu Aug 26 16:32:51 2010 @@ -124,7 +124,7 @@ Args& launch_args, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); bool synchronous_execution = interpreter.GetSynchronous (); // bool launched = false; // bool stopped_after_launch = false; @@ -377,7 +377,7 @@ if (process && process->IsAlive()) return true; - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { // No target has been set yet, for now do host completion. Otherwise I don't know how we would @@ -436,7 +436,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); Process *process = interpreter.GetDebugger().GetExecutionContext().process; if (process) @@ -470,7 +470,7 @@ result.AppendError(error.AsCString("Error creating empty target")); return false; } - interpreter.GetDebugger().GetTargetList().SetCurrentTarget(target); + interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); } // Record the old executable module, we want to issue a warning if the process of attaching changed the Modified: lldb/trunk/source/Commands/CommandObjectSource.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSource.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSource.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectSource.cpp Thu Aug 26 16:32:51 2010 @@ -267,7 +267,7 @@ if (!m_options.symbol_name.empty()) { // Displaying the source for a symbol: - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("invalid target, set executable file using 'file' command"); @@ -441,7 +441,7 @@ else { const char *filename = m_options.file_name.c_str(); - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target == NULL) { result.AppendError ("invalid target, set executable file using 'file' command"); Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Thu Aug 26 16:32:51 2010 @@ -50,7 +50,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target) { uint32_t argc = command.GetArgumentCount(); @@ -113,7 +113,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target) { bool notify = true; @@ -148,7 +148,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target) { uint32_t argc = command.GetArgumentCount(); @@ -231,7 +231,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target) { if (command.GetArgumentCount() != 0) @@ -272,7 +272,7 @@ Args& command, CommandReturnObject &result) { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + Target *target = interpreter.GetDebugger().GetSelectedTarget().get(); if (target) { if (command.GetArgumentCount() != 1) @@ -337,8 +337,8 @@ // const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0); // if (frame_idx < num_frames) // { -// exe_ctx.thread->SetCurrentFrameByIndex (frame_idx); -// exe_ctx.frame = exe_ctx.thread->GetCurrentFrame ().get(); +// exe_ctx.thread->SetSelectedFrameByIndex (frame_idx); +// exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get(); // // if (exe_ctx.frame) // { Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Thu Aug 26 16:32:51 2010 @@ -55,7 +55,7 @@ } strm.Indent(); - strm.Printf("%c ", thread->GetProcess().GetThreadList().GetCurrentThread().get() == thread ? '*' : ' '); + strm.Printf("%c ", thread->GetProcess().GetThreadList().GetSelectedThread().get() == thread ? '*' : ' '); // Show one frame with only the first showing source if (show_source) @@ -465,7 +465,7 @@ if (command.GetArgumentCount() == 0) { - thread = process->GetThreadList().GetCurrentThread().get(); + thread = process->GetThreadList().GetSelectedThread().get(); if (thread == NULL) { result.AppendError ("no current thread in process"); @@ -525,7 +525,7 @@ else new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); - process->GetThreadList().SetCurrentThreadByID (thread->GetID()); + process->GetThreadList().SetSelectedThreadByID (thread->GetID()); process->Resume (); } else if (m_step_type == eStepTypeOver) @@ -549,19 +549,19 @@ // Maybe there should be a parameter to control this. new_plan->SetOkayToDiscard(false); - process->GetThreadList().SetCurrentThreadByID (thread->GetID()); + process->GetThreadList().SetSelectedThreadByID (thread->GetID()); process->Resume (); } else if (m_step_type == eStepTypeTrace) { thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); - process->GetThreadList().SetCurrentThreadByID (thread->GetID()); + process->GetThreadList().SetSelectedThreadByID (thread->GetID()); process->Resume (); } else if (m_step_type == eStepTypeTraceOver) { thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads); - process->GetThreadList().SetCurrentThreadByID (thread->GetID()); + process->GetThreadList().SetSelectedThreadByID (thread->GetID()); process->Resume (); } else if (m_step_type == eStepTypeOut) @@ -573,7 +573,7 @@ // Maybe there should be a parameter to control this. new_plan->SetOkayToDiscard(false); - process->GetThreadList().SetCurrentThreadByID (thread->GetID()); + process->GetThreadList().SetSelectedThreadByID (thread->GetID()); process->Resume (); } else @@ -591,7 +591,7 @@ // { // state = process->WaitForStateChangedEvents (NULL, event_sp); // } - process->GetThreadList().SetCurrentThreadByID (thread->GetID()); + process->GetThreadList().SetSelectedThreadByID (thread->GetID()); result.SetDidChangeProcessState (true); result.AppendMessageWithFormat ("Process %i %s\n", process->GetID(), StateAsCString (state)); result.SetStatus (eReturnStatusSuccessFinishNoResult); @@ -665,7 +665,7 @@ { bool synchronous_execution = interpreter.GetSynchronous (); - if (!interpreter.GetDebugger().GetCurrentTarget().get()) + if (!interpreter.GetDebugger().GetSelectedTarget().get()) { result.AppendError ("invalid target, set executable file using 'file' command"); result.SetStatus (eReturnStatusFailed); @@ -725,7 +725,7 @@ } else { - Thread *current_thread = process->GetThreadList().GetCurrentThread().get(); + Thread *current_thread = process->GetThreadList().GetSelectedThread().get(); if (current_thread == NULL) { result.AppendError ("the process doesn't have a current thread"); @@ -917,7 +917,7 @@ { bool synchronous_execution = interpreter.GetSynchronous (); - if (!interpreter.GetDebugger().GetCurrentTarget().get()) + if (!interpreter.GetDebugger().GetSelectedTarget().get()) { result.AppendError ("invalid target, set executable file using 'file' command"); result.SetStatus (eReturnStatusFailed); @@ -953,7 +953,7 @@ if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) { - thread = process->GetThreadList().GetCurrentThread().get(); + thread = process->GetThreadList().GetSelectedThread().get(); } else { @@ -1033,7 +1033,7 @@ } - process->GetThreadList().SetCurrentThreadByID (m_options.m_thread_idx); + process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx); Error error (process->Resume ()); if (error.Success()) { @@ -1129,7 +1129,7 @@ return false; } - process->GetThreadList().SetCurrentThreadByID(new_thread->GetID()); + process->GetThreadList().SetSelectedThreadByID(new_thread->GetID()); DisplayThreadInfo (interpreter, result.GetOutputStream(), Modified: lldb/trunk/source/Core/Debugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Core/Debugger.cpp (original) +++ lldb/trunk/source/Core/Debugger.cpp Thu Aug 26 16:32:51 2010 @@ -240,18 +240,18 @@ TargetSP -Debugger::GetCurrentTarget () +Debugger::GetSelectedTarget () { - return m_target_list.GetCurrentTarget (); + return m_target_list.GetSelectedTarget (); } ExecutionContext -Debugger::GetCurrentExecutionContext () +Debugger::GetSelectedExecutionContext () { ExecutionContext exe_ctx; exe_ctx.Clear(); - lldb::TargetSP target_sp = GetCurrentTarget(); + lldb::TargetSP target_sp = GetSelectedTarget(); exe_ctx.target = target_sp.get(); if (target_sp) @@ -259,12 +259,12 @@ exe_ctx.process = target_sp->GetProcessSP().get(); if (exe_ctx.process && exe_ctx.process->IsRunning() == false) { - exe_ctx.thread = exe_ctx.process->GetThreadList().GetCurrentThread().get(); + exe_ctx.thread = exe_ctx.process->GetThreadList().GetSelectedThread().get(); if (exe_ctx.thread == NULL) exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); if (exe_ctx.thread) { - exe_ctx.frame = exe_ctx.thread->GetCurrentFrame().get(); + exe_ctx.frame = exe_ctx.thread->GetSelectedFrame().get(); if (exe_ctx.frame == NULL) exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get(); } @@ -301,7 +301,7 @@ return; // TODO: implement the STDIO to the process as an input reader... - TargetSP target = GetCurrentTarget(); + TargetSP target = GetSelectedTarget(); if (target.get() != NULL) { ProcessSP process_sp = target->GetProcessSP(); @@ -473,19 +473,19 @@ } else { - TargetSP target_sp (GetCurrentTarget()); + TargetSP target_sp (GetSelectedTarget()); if (target_sp) { m_exe_ctx.target = target_sp.get(); m_exe_ctx.process = target_sp->GetProcessSP().get(); if (m_exe_ctx.process && m_exe_ctx.process->IsRunning() == false) { - m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetCurrentThread().get(); + m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetSelectedThread().get(); if (m_exe_ctx.thread == NULL) m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); if (m_exe_ctx.thread) { - m_exe_ctx.frame = m_exe_ctx.thread->GetCurrentFrame().get(); + m_exe_ctx.frame = m_exe_ctx.thread->GetSelectedFrame().get(); if (m_exe_ctx.frame == NULL) m_exe_ctx.frame = m_exe_ctx.thread->GetStackFrameAtIndex (0).get(); } Modified: lldb/trunk/source/Interpreter/Options.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Options.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/Options.cpp (original) +++ lldb/trunk/source/Interpreter/Options.cpp Thu Aug 26 16:32:51 2010 @@ -746,7 +746,7 @@ if (module_name) { FileSpec module_spec(module_name); - lldb::TargetSP target_sp = interpreter.GetDebugger().GetCurrentTarget(); + lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); // Search filters require a target... if (target_sp != NULL) filter_ap.reset (new SearchFilterByModule (target_sp, module_spec)); Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/scripts/test-ProcessDebug.pl URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/scripts/test-ProcessDebug.pl?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/scripts/test-ProcessDebug.pl (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/scripts/test-ProcessDebug.pl Thu Aug 26 16:32:51 2010 @@ -338,7 +338,7 @@ } elsif ( $pid_state == $lldb::eStateStopped ) { - my $tid = lldb::PDProcessGetCurrentThread ( $pid ); + my $tid = lldb::PDProcessGetSelectedThread ( $pid ); my $pc = lldb::PDThreadGetRegisterHexValueByName($pid, $tid, $lldb::PD_REGISTER_SET_ALL, "eip", 0); $pc != 0 and printf("pc = 0x%8.8x ", $pc); # my $sp = lldb::PDThreadGetRegisterHexValueByName($pid, $tid, $lldb::PD_REGISTER_SET_ALL, "esp", 0); Modified: lldb/trunk/source/Target/ExecutionContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ExecutionContext.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Target/ExecutionContext.cpp (original) +++ lldb/trunk/source/Target/ExecutionContext.cpp Thu Aug 26 16:32:51 2010 @@ -41,9 +41,9 @@ process = t->GetProcessSP().get(); if (process) { - thread = process->GetThreadList().GetCurrentThread().get(); + thread = process->GetThreadList().GetSelectedThread().get(); if (thread) - frame = thread->GetCurrentFrame().get(); + frame = thread->GetSelectedFrame().get(); } } } Modified: lldb/trunk/source/Target/StackFrameList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrameList.cpp (original) +++ lldb/trunk/source/Target/StackFrameList.cpp Thu Aug 26 16:32:51 2010 @@ -33,7 +33,7 @@ m_mutex (Mutex::eMutexTypeRecursive), m_unwind_frames (), m_inline_frames (), - m_current_frame_idx (0) + m_selected_frame_idx (0) { } @@ -306,15 +306,15 @@ } uint32_t -StackFrameList::GetCurrentFrameIndex () const +StackFrameList::GetSelectedFrameIndex () const { Mutex::Locker locker (m_mutex); - return m_current_frame_idx; + return m_selected_frame_idx; } uint32_t -StackFrameList::SetCurrentFrame (lldb_private::StackFrame *frame) +StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame) { Mutex::Locker locker (m_mutex); const_iterator pos; @@ -324,20 +324,20 @@ { if (pos->get() == frame) { - m_current_frame_idx = std::distance (begin, pos); - return m_current_frame_idx; + m_selected_frame_idx = std::distance (begin, pos); + return m_selected_frame_idx; } } - m_current_frame_idx = 0; - return m_current_frame_idx; + m_selected_frame_idx = 0; + return m_selected_frame_idx; } // Mark a stack frame as the current frame using the frame index void -StackFrameList::SetCurrentFrameByIndex (uint32_t idx) +StackFrameList::SetSelectedFrameByIndex (uint32_t idx) { Mutex::Locker locker (m_mutex); - m_current_frame_idx = idx; + m_selected_frame_idx = idx; } // The thread has been run, reset the number stack frames to zero so we can Modified: lldb/trunk/source/Target/TargetList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/TargetList.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Target/TargetList.cpp (original) +++ lldb/trunk/source/Target/TargetList.cpp Thu Aug 26 16:32:51 2010 @@ -30,7 +30,7 @@ Broadcaster("TargetList"), m_target_list(), m_target_list_mutex (Mutex::eMutexTypeRecursive), - m_current_target_idx (0) + m_selected_target_idx (0) { } @@ -101,7 +101,7 @@ if (target_sp.get()) { Mutex::Locker locker(m_target_list_mutex); - m_current_target_idx = m_target_list.size(); + m_selected_target_idx = m_target_list.size(); m_target_list.push_back(target_sp); } @@ -123,7 +123,7 @@ // { // error.Clear(); // Mutex::Locker locker(m_target_list_mutex); -// m_current_target_idx = m_target_list.size(); +// m_selected_target_idx = m_target_list.size(); // m_target_list.push_back(target_sp); // } // } @@ -334,7 +334,7 @@ } uint32_t -TargetList::SetCurrentTarget (Target* target) +TargetList::SetSelectedTarget (Target* target) { Mutex::Locker locker (m_target_list_mutex); collection::const_iterator pos, @@ -344,19 +344,19 @@ { if (pos->get() == target) { - m_current_target_idx = std::distance (begin, pos); - return m_current_target_idx; + m_selected_target_idx = std::distance (begin, pos); + return m_selected_target_idx; } } - m_current_target_idx = 0; - return m_current_target_idx; + m_selected_target_idx = 0; + return m_selected_target_idx; } lldb::TargetSP -TargetList::GetCurrentTarget () +TargetList::GetSelectedTarget () { Mutex::Locker locker (m_target_list_mutex); - if (m_current_target_idx >= m_target_list.size()) - m_current_target_idx = 0; - return GetTargetAtIndex (m_current_target_idx); + if (m_selected_target_idx >= m_target_list.size()) + m_selected_target_idx = 0; + return GetTargetAtIndex (m_selected_target_idx); } Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Thu Aug 26 16:32:51 2010 @@ -823,21 +823,21 @@ } lldb::StackFrameSP -Thread::GetCurrentFrame () +Thread::GetSelectedFrame () { - return GetStackFrameAtIndex (GetStackFrameList().GetCurrentFrameIndex()); + return GetStackFrameAtIndex (GetStackFrameList().GetSelectedFrameIndex()); } uint32_t -Thread::SetCurrentFrame (lldb_private::StackFrame *frame) +Thread::SetSelectedFrame (lldb_private::StackFrame *frame) { - return GetStackFrameList().SetCurrentFrame(frame); + return GetStackFrameList().SetSelectedFrame(frame); } void -Thread::SetCurrentFrameByIndex (uint32_t idx) +Thread::SetSelectedFrameByIndex (uint32_t idx) { - GetStackFrameList().SetCurrentFrameByIndex(idx); + GetStackFrameList().SetSelectedFrameByIndex(idx); } void Modified: lldb/trunk/source/Target/ThreadList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadList.cpp (original) +++ lldb/trunk/source/Target/ThreadList.cpp Thu Aug 26 16:32:51 2010 @@ -23,7 +23,7 @@ m_stop_id (0), m_threads(), m_threads_mutex (Mutex::eMutexTypeRecursive), - m_current_tid (LLDB_INVALID_THREAD_ID) + m_selected_tid (LLDB_INVALID_THREAD_ID) { } @@ -32,7 +32,7 @@ m_stop_id (), m_threads (), m_threads_mutex (Mutex::eMutexTypeRecursive), - m_current_tid () + m_selected_tid () { // Use the assignment operator since it uses the mutex *this = rhs; @@ -50,7 +50,7 @@ m_process = rhs.m_process; m_stop_id = rhs.m_stop_id; m_threads = rhs.m_threads; - m_current_tid = rhs.m_current_tid; + m_selected_tid = rhs.m_selected_tid; } return *this; } @@ -274,7 +274,7 @@ { m_stop_id = 0; m_threads.clear(); - m_current_tid = LLDB_INVALID_THREAD_ID; + m_selected_tid = LLDB_INVALID_THREAD_ID; } void @@ -376,7 +376,7 @@ // You can't say "stop others" and also want yourself to be suspended. assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended); - if (thread_sp == GetCurrentThread()) + if (thread_sp == GetSelectedThread()) { run_only_current_thread = true; run_me_only_list.Clear(); @@ -415,7 +415,7 @@ if (run_only_current_thread) { - thread_to_run = GetCurrentThread(); + thread_to_run = GetSelectedThread(); } else if (run_me_only_list.GetSize (false) == 1) { @@ -456,34 +456,34 @@ } ThreadSP -ThreadList::GetCurrentThread () +ThreadList::GetSelectedThread () { Mutex::Locker locker(m_threads_mutex); - return FindThreadByID(m_current_tid); + return FindThreadByID(m_selected_tid); } bool -ThreadList::SetCurrentThreadByID (lldb::tid_t tid) +ThreadList::SetSelectedThreadByID (lldb::tid_t tid) { Mutex::Locker locker(m_threads_mutex); if (FindThreadByID(tid).get()) - m_current_tid = tid; + m_selected_tid = tid; else - m_current_tid = LLDB_INVALID_THREAD_ID; + m_selected_tid = LLDB_INVALID_THREAD_ID; - return m_current_tid != LLDB_INVALID_THREAD_ID; + return m_selected_tid != LLDB_INVALID_THREAD_ID; } bool -ThreadList::SetCurrentThreadByIndexID (uint32_t index_id) +ThreadList::SetSelectedThreadByIndexID (uint32_t index_id) { Mutex::Locker locker(m_threads_mutex); ThreadSP thread_sp (FindThreadByIndexID(index_id)); if (thread_sp.get()) - m_current_tid = thread_sp->GetID(); + m_selected_tid = thread_sp->GetID(); else - m_current_tid = LLDB_INVALID_THREAD_ID; + m_selected_tid = LLDB_INVALID_THREAD_ID; - return m_current_tid != LLDB_INVALID_THREAD_ID; + return m_selected_tid != LLDB_INVALID_THREAD_ID; } Modified: lldb/trunk/tools/driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.cpp (original) +++ lldb/trunk/tools/driver/Driver.cpp Thu Aug 26 16:32:51 2010 @@ -603,7 +603,7 @@ // The process has stuff waiting for stdout; get it and write it out to the appropriate place. char stdio_buffer[1024]; size_t len; - while ((len = m_debugger.GetCurrentTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0) + while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0) m_io_channel_ap->OutWrite (stdio_buffer, len); } @@ -613,18 +613,18 @@ // The process has stuff waiting for stderr; get it and write it out to the appropriate place. char stdio_buffer[1024]; size_t len; - while ((len = m_debugger.GetCurrentTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0) + while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0) m_io_channel_ap->ErrWrite (stdio_buffer, len); } void -Driver::UpdateCurrentThread () +Driver::UpdateSelectedThread () { using namespace lldb; - SBProcess process(m_debugger.GetCurrentTarget().GetProcess()); + SBProcess process(m_debugger.GetSelectedTarget().GetProcess()); if (process.IsValid()) { - SBThread curr_thread (process.GetCurrentThread()); + SBThread curr_thread (process.GetSelectedThread()); SBThread thread; StopReason curr_thread_stop_reason = eStopReasonInvalid; curr_thread_stop_reason = curr_thread.GetStopReason(); @@ -664,9 +664,9 @@ } } if (plan_thread.IsValid()) - process.SetCurrentThread (plan_thread); + process.SetSelectedThread (plan_thread); else if (other_thread.IsValid()) - process.SetCurrentThread (other_thread); + process.SetSelectedThread (other_thread); else { if (curr_thread.IsValid()) @@ -675,7 +675,7 @@ thread = process.GetThreadAtIndex(0); if (thread.IsValid()) - process.SetCurrentThread (thread); + process.SetSelectedThread (thread); } } } @@ -756,7 +756,7 @@ } else { - UpdateCurrentThread (); + UpdateSelectedThread (); m_debugger.HandleCommand("process status"); m_io_channel_ap->RefreshPrompt(); } @@ -1201,7 +1201,7 @@ else done = HandleIOEvent (event); } - else if (event.BroadcasterMatchesRef (m_debugger.GetCurrentTarget().GetProcess().GetBroadcaster())) + else if (event.BroadcasterMatchesRef (m_debugger.GetSelectedTarget().GetProcess().GetBroadcaster())) { HandleProcessEvent (event); } @@ -1231,7 +1231,7 @@ } } - SBProcess process = m_debugger.GetCurrentTarget().GetProcess(); + SBProcess process = m_debugger.GetSelectedTarget().GetProcess(); if (process.IsValid()) process.Destroy(); } Modified: lldb/trunk/tools/driver/Driver.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.h?rev=112221&r1=112220&r2=112221&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.h (original) +++ lldb/trunk/tools/driver/Driver.h Thu Aug 26 16:32:51 2010 @@ -139,7 +139,7 @@ GetProcessSTDERR (); void - UpdateCurrentThread (); + UpdateSelectedThread (); void CloseIOChannelFile (); From johnny.chen at apple.com Thu Aug 26 16:49:29 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 26 Aug 2010 21:49:29 -0000 Subject: [Lldb-commits] [lldb] r112223 - in /lldb/trunk/test: array_types/TestArrayTypes.py lldbtest.py Message-ID: <20100826214929.BFD532A6C12C@llvm.org> Author: johnny Date: Thu Aug 26 16:49:29 2010 New Revision: 112223 URL: http://llvm.org/viewvc/llvm-project?rev=112223&view=rev Log: Added a utility function EnvArray() to lldbtest.py. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112223&r1=112222&r2=112223&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Aug 26 16:49:29 2010 @@ -67,6 +67,7 @@ self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) self.runCmd("run", RUN_STOPPED) + #process = target.LaunchProcess([''], [''], os.ctermid(), False) # The stop reason of the thread should be breakpoint. thread = target.GetProcess().GetThreadAtIndex(0) Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112223&r1=112222&r2=112223&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu Aug 26 16:49:29 2010 @@ -171,6 +171,12 @@ else: raise Exception("Unknown stopReason string") +# +# Returns an env variable array from the os.environ map object. +# +def EnvArray(): + return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values()) + class TestBase(unittest2.TestCase): """This LLDB abstract base class is meant to be subclassed.""" From johnny.chen at apple.com Thu Aug 26 16:53:26 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 26 Aug 2010 21:53:26 -0000 Subject: [Lldb-commits] [lldb] r112226 - /lldb/trunk/test/array_types/TestArrayTypes.py Message-ID: <20100826215326.5D8AB2A6C12C@llvm.org> Author: johnny Date: Thu Aug 26 16:53:26 2010 New Revision: 112226 URL: http://llvm.org/viewvc/llvm-project?rev=112226&view=rev Log: Added comment about target.LaunchProcess() not working. Modified: lldb/trunk/test/array_types/TestArrayTypes.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112226&r1=112225&r2=112226&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Aug 26 16:53:26 2010 @@ -67,6 +67,7 @@ self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) self.runCmd("run", RUN_STOPPED) + # This does not work, and results in the process stopped at dyld_start? #process = target.LaunchProcess([''], [''], os.ctermid(), False) # The stop reason of the thread should be breakpoint. From gclayton at apple.com Thu Aug 26 17:05:43 2010 From: gclayton at apple.com (Greg Clayton) Date: Thu, 26 Aug 2010 22:05:43 -0000 Subject: [Lldb-commits] [lldb] r112230 - in /lldb/trunk: include/lldb/Interpreter/CommandInterpreter.h include/lldb/Target/StackFrame.h include/lldb/Target/StackID.h source/Commands/CommandObjectMultiword.cpp source/Interpreter/CommandInterpreter.cpp source/Target/StackFrame.cpp Message-ID: <20100826220543.8C6912A6C12C@llvm.org> Author: gclayton Date: Thu Aug 26 17:05:43 2010 New Revision: 112230 URL: http://llvm.org/viewvc/llvm-project?rev=112230&view=rev Log: Changed the StackID to store its start PC address as a load address instead of a section offset address. Fixed up some very inefficient STL code. Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/Target/StackID.h lldb/trunk/source/Commands/CommandObjectMultiword.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/source/Target/StackFrame.cpp Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=112230&r1=112229&r2=112230&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Thu Aug 26 17:05:43 2010 @@ -230,7 +230,7 @@ RemoveLogChannel (const char *name); #endif - std::string + size_t FindLongestCommandWord (CommandObject::CommandMap &dict); void Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=112230&r1=112229&r2=112230&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Thu Aug 26 17:05:43 2010 @@ -139,7 +139,7 @@ uint32_t m_concrete_frame_index; lldb::RegisterContextSP m_reg_context_sp; StackID m_id; - Address m_pc; // PC as a section/offset address + Address m_frame_code_addr; // The frame code address (might not be the same as the actual PC for inlined frames) as a section/offset address SymbolContext m_sc; Flags m_flags; Scalar m_frame_base; Modified: lldb/trunk/include/lldb/Target/StackID.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackID.h?rev=112230&r1=112229&r2=112230&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackID.h (original) +++ lldb/trunk/include/lldb/Target/StackID.h Thu Aug 26 17:05:43 2010 @@ -26,29 +26,22 @@ // Constructors and Destructors //------------------------------------------------------------------ StackID () : - m_start_address(), - m_cfa (0), - m_inline_block_id (0) + m_start_pc (LLDB_INVALID_ADDRESS), + m_cfa (LLDB_INVALID_ADDRESS), + m_inline_block_id (LLDB_INVALID_UID) { } explicit - StackID (lldb::addr_t cfa, lldb::user_id_t inline_block_id) : - m_start_address (), - m_cfa (cfa), - m_inline_block_id (inline_block_id) - { - } - - StackID (const Address& start_address, lldb::addr_t cfa, uint32_t inline_block_id) : - m_start_address (start_address), + StackID (lldb::addr_t start_pc, lldb::addr_t cfa, lldb::user_id_t inline_block_id) : + m_start_pc (), m_cfa (cfa), m_inline_block_id (inline_block_id) { } StackID (const StackID& rhs) : - m_start_address (rhs.m_start_address), + m_start_pc (rhs.m_start_pc), m_cfa (rhs.m_cfa), m_inline_block_id (rhs.m_inline_block_id) { @@ -58,16 +51,16 @@ { } - const Address& + const lldb::addr_t GetStartAddress() const { - return m_start_address; + return m_start_pc; } void - SetStartAddress(const Address& start_address) + SetStartAddress(lldb::addr_t start_pc) { - m_start_address = start_address; + m_start_pc = start_pc; } lldb::addr_t @@ -96,7 +89,7 @@ { if (this != &rhs) { - m_start_address = rhs.m_start_address; + m_start_pc = rhs.m_start_pc; m_cfa = rhs.m_cfa; m_inline_block_id = rhs.m_inline_block_id; } @@ -107,7 +100,7 @@ //------------------------------------------------------------------ // Classes that inherit from StackID can see and modify these //------------------------------------------------------------------ - Address m_start_address; // The address range for the function for this frame + lldb::addr_t m_start_pc; // The start address for the function/symbol for this frame lldb::addr_t m_cfa; // The call frame address (stack pointer) value // at the beginning of the function that uniquely // identifies this frame (along with m_inline_block_id below) Modified: lldb/trunk/source/Commands/CommandObjectMultiword.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMultiword.cpp?rev=112230&r1=112229&r2=112230&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectMultiword.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectMultiword.cpp Thu Aug 26 17:05:43 2010 @@ -188,11 +188,10 @@ output_stream.PutCString ("The following subcommands are supported:\n\n"); CommandMap::iterator pos; - std::string longest_word = interpreter.FindLongestCommandWord (m_subcommand_dict); - uint32_t max_len = 0; + uint32_t max_len = interpreter.FindLongestCommandWord (m_subcommand_dict); - if (! longest_word.empty()) - max_len = strlen (longest_word.c_str()) + 4; // Indent the output by 4 spaces. + if (max_len) + max_len += 4; // Indent the output by 4 spaces. for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos) { Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=112230&r1=112229&r2=112230&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Thu Aug 26 17:05:43 2010 @@ -494,25 +494,20 @@ help_string.Printf ("'"); } -std::string +size_t CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict) { CommandObject::CommandMap::const_iterator pos; - int max_len = 0; - CommandObjectSP cmd_sp; - std::string longest_word; - - for (pos = dict.begin(); pos != dict.end(); ++pos) - { - if ((max_len == 0) - || (strlen (pos->first.c_str()) > max_len)) - { - longest_word = pos->first; - max_len = strlen (longest_word.c_str()); - } - } + CommandObject::CommandMap::const_iterator end = dict.end(); + size_t max_len = 0; - return longest_word; + for (pos = dict.begin(); pos != end; ++pos) + { + size_t len = pos->first.size(); + if (max_len < len) + max_len = len; + } + return max_len; } void @@ -521,8 +516,7 @@ CommandObject::CommandMap::const_iterator pos; result.AppendMessage("The following is a list of built-in, permanent debugger commands:"); result.AppendMessage(""); - std::string longest_word = FindLongestCommandWord (m_command_dict); - uint32_t max_len = strlen (longest_word.c_str()); + uint32_t max_len = FindLongestCommandWord (m_command_dict); for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) { @@ -535,8 +529,8 @@ { result.AppendMessage("The following is a list of your current command abbreviations (see 'commands alias' for more info):"); result.AppendMessage(""); - longest_word = FindLongestCommandWord (m_alias_dict); - max_len = strlen (longest_word.c_str()); + max_len = FindLongestCommandWord (m_alias_dict); + for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos) { StreamString sstr; Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=112230&r1=112229&r2=112230&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Thu Aug 26 17:05:43 2010 @@ -48,8 +48,8 @@ m_concrete_frame_index (concrete_frame_index), m_thread (thread), m_reg_context_sp (), - m_id (cfa, 0), - m_pc (NULL, pc), + m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), + m_frame_code_addr (NULL, pc), m_sc (), m_flags (), m_frame_base (), @@ -78,8 +78,8 @@ m_concrete_frame_index (concrete_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (cfa, 0), - m_pc (NULL, pc), + m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), + m_frame_code_addr (NULL, pc), m_sc (), m_flags (), m_frame_base (), @@ -114,8 +114,8 @@ m_concrete_frame_index (concrete_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (cfa, 0), - m_pc (pc_addr), + m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), + m_frame_code_addr (pc_addr), m_sc (), m_flags (), m_frame_base (), @@ -157,9 +157,10 @@ StackID& StackFrame::GetStackID() { - // Make sure we have resolved our stack ID's address range before we give - // it out to any external clients - if (m_id.GetStartAddress().IsValid() == 0 && m_flags.IsClear(RESOLVED_FRAME_ID)) + // Make sure we have resolved our stack ID's start PC before we give + // it out to any external clients. This allows us to not have to lookup + // this information if it is never asked for. + if (m_flags.IsClear(RESOLVED_FRAME_ID) && m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) { m_flags.Set (RESOLVED_FRAME_ID); @@ -171,14 +172,19 @@ if (GetSymbolContext (eSymbolContextFunction).function) { - m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress()); + m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); } else if (GetSymbolContext (eSymbolContextSymbol).symbol) { AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); if (symbol_range_ptr) - m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress()); + m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); } + + // We didn't find a function or symbol, just use the frame code address + // which will be the same as the PC in the frame. + if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) + m_id.SetStartAddress (m_frame_code_addr.GetLoadAddress (&m_thread.GetProcess())); } return m_id; } @@ -186,17 +192,17 @@ Address& StackFrame::GetFrameCodeAddress() { - if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_pc.IsSectionOffset()) + if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_frame_code_addr.IsSectionOffset()) { m_flags.Set (RESOLVED_FRAME_ADDR); // Resolve the PC into a temporary address because if ResolveLoadAddress // fails to resolve the address, it will clear the address object... Address resolved_pc; - if (m_thread.GetProcess().ResolveLoadAddress(m_pc.GetOffset(), resolved_pc)) + if (m_thread.GetProcess().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc)) { - m_pc = resolved_pc; - const Section *section = m_pc.GetSection(); + m_frame_code_addr = resolved_pc; + const Section *section = m_frame_code_addr.GetSection(); if (section) { Module *module = section->GetModule(); @@ -209,14 +215,14 @@ } } } - return m_pc; + return m_frame_code_addr; } void StackFrame::ChangePC (addr_t pc) { - m_pc.SetOffset(pc); - m_pc.SetSection(NULL); + m_frame_code_addr.SetOffset(pc); + m_frame_code_addr.SetSection(NULL); m_sc.Clear(); m_flags.SetAllFlagBits(0); m_thread.ClearStackFrames (); @@ -473,11 +479,7 @@ bool StackFrame::IsInlined () { - Block *block = GetSymbolContext (eSymbolContextBlock).block; - if (block) - return block->GetContainingInlinedBlock() != NULL; - else - return false; + return m_id.GetInlineBlockID() != LLDB_INVALID_UID; } Target * From johnny.chen at apple.com Thu Aug 26 17:06:03 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 26 Aug 2010 22:06:03 -0000 Subject: [Lldb-commits] [lldb] r112231 - /lldb/trunk/test/macosx/universal/TestUniversal.py Message-ID: <20100826220603.5D2B12A6C12C@llvm.org> Author: johnny Date: Thu Aug 26 17:06:03 2010 New Revision: 112231 URL: http://llvm.org/viewvc/llvm-project?rev=112231&view=rev Log: Changed from dbg.GetCurrentTarget() to dbg.GetSelectedTarget(). Modified: lldb/trunk/test/macosx/universal/TestUniversal.py Modified: lldb/trunk/test/macosx/universal/TestUniversal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/TestUniversal.py?rev=112231&r1=112230&r2=112231&view=diff ============================================================================== --- lldb/trunk/test/macosx/universal/TestUniversal.py (original) +++ lldb/trunk/test/macosx/universal/TestUniversal.py Thu Aug 26 17:06:03 2010 @@ -28,7 +28,7 @@ self.runCmd("run", RUN_STOPPED) # Check whether we have a 64-bit process launched. - target = self.dbg.GetCurrentTarget() + target = self.dbg.GetSelectedTarget() process = target.GetProcess() self.assertTrue(target.IsValid() and process.IsValid() and self.invoke(process, 'GetAddressByteSize') == 8, @@ -49,7 +49,7 @@ self.runCmd("run", RUN_STOPPED) # Check whether we have a 32-bit process launched. - target = self.dbg.GetCurrentTarget() + target = self.dbg.GetSelectedTarget() process = target.GetProcess() self.assertTrue(target.IsValid() and process.IsValid() and self.invoke(process, 'GetAddressByteSize') == 4, From johnny.chen at apple.com Thu Aug 26 17:38:51 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 26 Aug 2010 22:38:51 -0000 Subject: [Lldb-commits] [lldb] r112236 - /lldb/trunk/test/array_types/TestArrayTypes.py Message-ID: <20100826223851.68B562A6C12C@llvm.org> Author: johnny Date: Thu Aug 26 17:38:51 2010 New Revision: 112236 URL: http://llvm.org/viewvc/llvm-project?rev=112236&view=rev Log: Modified method doc string for verbose test description output. Modified: lldb/trunk/test/array_types/TestArrayTypes.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112236&r1=112235&r2=112236&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Aug 26 17:38:51 2010 @@ -53,11 +53,7 @@ startstr = '(long [6])') def test_array_types_python(self): - """ - Test 'variable list var_name' on some variables with array types. - - Use the Python APIs from lldb.py. - """ + """Use Python APIs to test variables with array types.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) From jingham at apple.com Thu Aug 26 18:36:03 2010 From: jingham at apple.com (Jim Ingham) Date: Thu, 26 Aug 2010 23:36:03 -0000 Subject: [Lldb-commits] [lldb] r112243 - in /lldb/trunk/source/Commands: CommandObjectThread.cpp CommandObjectThread.h Message-ID: <20100826233603.CDA192A6C12C@llvm.org> Author: jingham Date: Thu Aug 26 18:36:03 2010 New Revision: 112243 URL: http://llvm.org/viewvc/llvm-project?rev=112243&view=rev Log: Add -c (count - i.e. number of frames to show) and -s (start frame.) Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp lldb/trunk/source/Commands/CommandObjectThread.h Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=112243&r1=112242&r2=112243&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Thu Aug 26 18:36:03 2010 @@ -63,7 +63,6 @@ DisplayFramesForExecutionContext (thread, interpreter, strm, - true, 0, // Start at first frame 1, // Number of frames to show false,// Don't show the frame info since we already displayed most of it above... @@ -141,7 +140,6 @@ Thread *thread, CommandInterpreter &interpreter, Stream& strm, - bool ascending, uint32_t first_frame, uint32_t num_frames, bool show_frame_info, @@ -168,49 +166,33 @@ StackFrameSP frame_sp; uint32_t frame_idx = 0; - - if (ascending) - { - for (frame_idx = first_frame; frame_idx < first_frame + num_frames; ++frame_idx) - { - frame_sp = thread->GetStackFrameAtIndex (frame_idx); - if (frame_sp.get() == NULL) - break; - - if (DisplayFrameForExecutionContext (thread, - frame_sp.get(), - interpreter, - strm, - show_frame_info, - num_frames_with_source > first_frame - frame_idx, - source_lines_before, - source_lines_after) == false) - break; - - ++num_frames_displayed; - } - } + uint32_t last_frame; + + // Don't let the last frame wrap around... + if (num_frames == UINT32_MAX) + last_frame = UINT32_MAX; else + last_frame = first_frame + num_frames; + + for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx) { - for (frame_idx = first_frame + num_frames - 1; frame_idx >= first_frame; --frame_idx) - { - frame_sp = thread->GetStackFrameAtIndex (frame_idx); - if (frame_sp == NULL) - break; - - if (DisplayFrameForExecutionContext (thread, - frame_sp.get(), - interpreter, - strm, - show_frame_info, - num_frames_with_source > first_frame - frame_idx, - source_lines_before, - source_lines_after) == false) - break; + frame_sp = thread->GetStackFrameAtIndex (frame_idx); + if (frame_sp.get() == NULL) + break; + + if (DisplayFrameForExecutionContext (thread, + frame_sp.get(), + interpreter, + strm, + show_frame_info, + num_frames_with_source > first_frame - frame_idx, + source_lines_before, + source_lines_after) == false) + break; - ++num_frames_displayed; - } + ++num_frames_displayed; } + strm.IndentLess(); return num_frames_displayed; } @@ -265,12 +247,87 @@ { public: + class CommandOptions : public Options + { + public: + + CommandOptions () : + Options() + { + // Keep default values of all options in one place: ResetOptionValues () + ResetOptionValues (); + } + + virtual + ~CommandOptions () + { + } + + virtual Error + SetOptionValue (int option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'c': + { + bool success; + int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid integer value for option '%c'.\n", short_option); + if (input_count < -1) + m_count = UINT32_MAX; + else + m_count = input_count; + } + break; + case 's': + { + bool success; + m_start = Args::StringToUInt32 (option_arg, 0, 0, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid integer value for option '%c'.\n", short_option); + } + break; + default: + error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); + break; + + } + return error; + } + + void + ResetOptionValues () + { + Options::ResetOptionValues(); + m_count = -1; + m_start = 0; + } + + const lldb::OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static lldb::OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + uint32_t m_count; + uint32_t m_start; + }; + CommandObjectThreadBacktrace () : CommandObject ("thread backtrace", "Shows the stack for one or more threads.", "thread backtrace [] ...", eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), - m_ascending (true) + m_options() { } @@ -278,6 +335,11 @@ { } + virtual Options * + GetOptions () + { + return &m_options; + } virtual bool Execute @@ -297,9 +359,8 @@ if (DisplayFramesForExecutionContext (exe_ctx.thread, interpreter, result.GetOutputStream(), - m_ascending, - 0, - UINT32_MAX, + m_options.m_start, + m_options.m_count, show_frame_info, num_frames_with_source, 3, @@ -322,9 +383,16 @@ return result.Succeeded(); } protected: - bool m_ascending; + CommandOptions m_options; }; +lldb::OptionDefinition +CommandObjectThreadBacktrace::CommandOptions::g_option_table[] = +{ +{ LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, "", "How many frames to display (-1 for all)"}, +{ LLDB_OPT_SET_1, false, "start", 's', required_argument, NULL, 0, "", "Where to start the backtrace"}, +{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } +}; enum StepScope { @@ -468,7 +536,7 @@ thread = process->GetThreadList().GetSelectedThread().get(); if (thread == NULL) { - result.AppendError ("no current thread in process"); + result.AppendError ("no selected thread in process"); result.SetStatus (eReturnStatusFailed); return false; } Modified: lldb/trunk/source/Commands/CommandObjectThread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.h?rev=112243&r1=112242&r2=112243&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.h (original) +++ lldb/trunk/source/Commands/CommandObjectThread.h Thu Aug 26 18:36:03 2010 @@ -48,7 +48,6 @@ DisplayFramesForExecutionContext (Thread *thread, CommandInterpreter &interpreter, Stream& strm, - bool ascending, uint32_t first_frame, uint32_t num_frames, bool show_frame_info, From jingham at apple.com Thu Aug 26 18:56:11 2010 From: jingham at apple.com (Jim Ingham) Date: Thu, 26 Aug 2010 23:56:11 -0000 Subject: [Lldb-commits] [lldb] r112245 - /lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Message-ID: <20100826235612.015122A6C12C@llvm.org> Author: jingham Date: Thu Aug 26 18:56:11 2010 New Revision: 112245 URL: http://llvm.org/viewvc/llvm-project?rev=112245&view=rev Log: Change the "-S", "-F" and "-M" options to take their arguments directly, rather than requiring the -n option. This means you can't "or" together the types (i.e. set a breakpoint on a method or selector called "whatever". But that is a pretty uncommon operation, and having to provide two flags for the more common "set a breakpoint on this selector" is annoying. Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=112245&r1=112244&r2=112245&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Thu Aug 26 18:56:11 2010 @@ -104,21 +104,19 @@ "Set the breakpoint by address, at the specified address."}, { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "", - "Set the breakpoint by function name." }, + "Set the breakpoint by function name - for C++ this means namespaces and arguments will be ignored." }, - { LLDB_OPT_SET_3, false, "basename", 'b', no_argument, NULL, 0, NULL, - "Used in conjuction with --name to search function basenames." }, + { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, 0, "", + "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguemnts, and " + "for Objective C this means a full function prototype with class and selector." }, - { LLDB_OPT_SET_3, false, "fullname", 'F', no_argument, NULL, 0, NULL, - "Used in conjuction with --name to search fully qualified function names. For C++ this means namespaces and all arguemnts, and for Objective C this means a full function prototype with class and selector." }, + { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, "", + "Set the breakpoint by ObjC selector name." }, - { LLDB_OPT_SET_3, false, "selector", 'S', no_argument, NULL, 0, NULL, - "Used in conjuction with --name to search objective C selector names." }, + { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, "", + "Set the breakpoint by C++ method names." }, - { LLDB_OPT_SET_3, false, "method", 'm', no_argument, NULL, 0, NULL, - "Used in conjuction with --name to search objective C selector C++ method names." }, - - { LLDB_OPT_SET_4, true, "func_regex", 'r', required_argument, NULL, 0, "", + { LLDB_OPT_SET_7, true, "func_regex", 'r', required_argument, NULL, 0, "", "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." }, { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } @@ -161,21 +159,21 @@ case 'n': m_func_name = option_arg; - break; - - case 'b': m_func_name_type_mask |= eFunctionNameTypeBase; break; case 'F': + m_func_name = option_arg; m_func_name_type_mask |= eFunctionNameTypeFull; break; case 'S': + m_func_name = option_arg; m_func_name_type_mask |= eFunctionNameTypeSelector; break; - case 'm': + case 'M': + m_func_name = option_arg; m_func_name_type_mask |= eFunctionNameTypeMethod; break; From johnny.chen at apple.com Thu Aug 26 19:15:48 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 27 Aug 2010 00:15:48 -0000 Subject: [Lldb-commits] [lldb] r112247 - in /lldb/trunk/test: array_types/TestArrayTypes.py bitfields/TestBitfields.py lldbtest.py Message-ID: <20100827001548.5E3B02A6C12C@llvm.org> Author: johnny Date: Thu Aug 26 19:15:48 2010 New Revision: 112247 URL: http://llvm.org/viewvc/llvm-project?rev=112247&view=rev Log: Added a test case to bitfields which uses the Python APIs from lldb.py. Added a utility method to TestBase class to debug print an SBValue object. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112247&r1=112246&r2=112247&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Aug 26 19:15:48 2010 @@ -77,34 +77,42 @@ # Lookup the "strings" string array variable. frame = thread.GetFrameAtIndex(0) variable = frame.LookupVar("strings") + self.DebugSBValue(frame, variable) self.assertTrue(variable.GetNumChildren() == 4, "Variable 'strings' should have 4 children") child3 = variable.GetChildAtIndex(3) + self.DebugSBValue(frame, child3) self.assertTrue(child3.GetSummary(frame) == '"Guten Tag"', 'strings[3] == "Guten Tag"') # Lookup the "char_16" char array variable. variable = frame.LookupVar("char_16") + self.DebugSBValue(frame, variable) self.assertTrue(variable.GetNumChildren() == 16, "Variable 'char_16' should have 16 children") # Lookup the "ushort_matrix" ushort[] array variable. variable = frame.LookupVar("ushort_matrix") + self.DebugSBValue(frame, variable) self.assertTrue(variable.GetNumChildren() == 2, "Variable 'ushort_matrix' should have 2 children") child0 = variable.GetChildAtIndex(0) + self.DebugSBValue(frame, child0) self.assertTrue(child0.GetNumChildren() == 3, "Variable 'ushort_matrix[0]' should have 3 children") child0_2 = child0.GetChildAtIndex(2) + self.DebugSBValue(frame, child0_2) self.assertTrue(int(child0_2.GetValue(frame), 16) == 3, "ushort_matrix[0][2] == 3") # Lookup the "long_6" char array variable. variable = frame.LookupVar("long_6") + self.DebugSBValue(frame, variable) self.assertTrue(variable.GetNumChildren() == 6, "Variable 'long_6' should have 6 children") child5 = variable.GetChildAtIndex(5) + self.DebugSBValue(frame, child5) self.assertTrue(long(child5.GetValue(frame)) == 6, "long_6[5] == 6") Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=112247&r1=112246&r2=112247&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Thu Aug 26 19:15:48 2010 @@ -53,6 +53,61 @@ '(uint32_t:7) b7 = 0x0000007f,', '(uint32_t:4) four = 0x0000000f']) + def test_bitfields_variable_python(self): + """Use Python APIs to inspect a bitfields variable.""" + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.c", 42) + self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) + + self.runCmd("run", RUN_STOPPED) + # This does not work, and results in the process stopped at dyld_start? + #process = target.LaunchProcess([''], [''], os.ctermid(), False) + + # The stop reason of the thread should be breakpoint. + thread = target.GetProcess().GetThreadAtIndex(0) + self.assertTrue(thread.GetStopReason() == Enum("Breakpoint"), + STOPPED_DUE_TO_BREAKPOINT) + + # The breakpoint should have a hit count of 1. + self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) + + # Lookup the "bits" variable which contains 8 bitfields. + frame = thread.GetFrameAtIndex(0) + bits = frame.LookupVar("bits") + self.DebugSBValue(frame, bits) + self.assertTrue(bits.GetTypeName() == "Bits" and + bits.GetNumChildren() == 8 and + bits.GetByteSize() == 4, + "(Bits)bits with byte size of 4 and 8 children") + + b1 = bits.GetChildAtIndex(0) + self.DebugSBValue(frame, b1) + self.assertTrue(b1.GetName() == "b1" and + b1.GetTypeName() == "uint32_t:1" and + b1.IsInScope(frame) and + int(b1.GetValue(frame), 16) == 0x01, + 'bits.b1 has type uint32_t:1, is in scope, and == 0x01') + + b7 = bits.GetChildAtIndex(6) + self.DebugSBValue(frame, b7) + self.assertTrue(b7.GetName() == "b7" and + b7.GetTypeName() == "uint32_t:7" and + b7.IsInScope(frame) and + int(b7.GetValue(frame), 16) == 0x7f, + 'bits.b7 has type uint32_t:7, is in scope, and == 0x7f') + + four = bits.GetChildAtIndex(7) + self.DebugSBValue(frame, four) + self.assertTrue(four.GetName() == "four" and + four.GetTypeName() == "uint32_t:4" and + four.IsInScope(frame) and + int(four.GetValue(frame), 16) == 0x0f, + 'bits.four has type uint32_t:4, is in scope, and == 0x0f') + if __name__ == '__main__': import atexit Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112247&r1=112246&r2=112247&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu Aug 26 19:15:48 2010 @@ -177,6 +177,7 @@ def EnvArray(): return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values()) + class TestBase(unittest2.TestCase): """This LLDB abstract base class is meant to be subclassed.""" @@ -337,3 +338,20 @@ if self.traceAlways: print str(method) + ":", result return result + + def DebugSBValue(self, frame, val): + """Debug print a SBValue object, if self.traceAlways is True.""" + if not self.traceAlways: + return + + err = sys.stderr + err.write(val.GetName() + ":\n") + err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n') + err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n') + err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n') + err.write('\t' + "Value -> " + str(val.GetValue(frame)) + '\n') + err.write('\t' + "Summary -> " + str(val.GetSummary(frame)) + '\n') + err.write('\t' + "IsPtrType -> " + str(val.TypeIsPtrType()) + '\n') + err.write('\t' + "Location -> " + val.GetLocation(frame) + '\n') + + From jingham at apple.com Thu Aug 26 19:58:05 2010 From: jingham at apple.com (Jim Ingham) Date: Fri, 27 Aug 2010 00:58:05 -0000 Subject: [Lldb-commits] [lldb] r112248 - /lldb/trunk/source/Commands/CommandObjectThread.cpp Message-ID: <20100827005805.658582A6C12C@llvm.org> Author: jingham Date: Thu Aug 26 19:58:05 2010 New Revision: 112248 URL: http://llvm.org/viewvc/llvm-project?rev=112248&view=rev Log: Make: bt all show the backtrace for all threads, and: bt 1 3 4 show the backtrace for threads 1, 3 and 4. If we want to come up with some fancier syntax for thread lists later, that will be great, but this will do for now. Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=112248&r1=112247&r2=112248&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectThread.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectThread.cpp Thu Aug 26 19:58:05 2010 @@ -324,8 +324,8 @@ CommandObjectThreadBacktrace () : CommandObject ("thread backtrace", - "Shows the stack for one or more threads.", - "thread backtrace [] ...", + "Shows the stack for one or more threads. If no threads are specified, shows the currently selected thread. \nUse the thread-index \"all\" to see all threads.", + "thread backtrace [] ...", eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), m_options() { @@ -349,13 +349,17 @@ CommandReturnObject &result ) { + + bool show_frame_info = true; + uint32_t num_frames_with_source = 0; // Don't show any frames with source when backtracing + + result.SetStatus (eReturnStatusSuccessFinishResult); + if (command.GetArgumentCount() == 0) { ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext()); if (exe_ctx.thread) { - bool show_frame_info = true; - uint32_t num_frames_with_source = 0; // Don't show any frasmes with source when backtracing if (DisplayFramesForExecutionContext (exe_ctx.thread, interpreter, result.GetOutputStream(), @@ -375,10 +379,80 @@ result.SetStatus (eReturnStatusFailed); } } + else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) + { + Process *process = interpreter.GetDebugger().GetExecutionContext().process; + uint32_t num_threads = process->GetThreadList().GetSize(); + for (uint32_t i = 0; i < num_threads; i++) + { + ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i); + if (!DisplayFramesForExecutionContext (thread_sp.get(), + interpreter, + result.GetOutputStream(), + m_options.m_start, + m_options.m_count, + show_frame_info, + num_frames_with_source, + 3, + 3)) + { + result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%d\"\n", i); + result.SetStatus (eReturnStatusFailed); + return false; + } + if (i < num_threads - 1) + result.AppendMessage(""); + } + } else { - result.AppendError ("backtrace doesn't take arguments (for now)"); - result.SetStatus (eReturnStatusFailed); + uint32_t num_args = command.GetArgumentCount(); + Process *process = interpreter.GetDebugger().GetExecutionContext().process; + std::vector thread_sps; + + for (uint32_t i = 0; i < num_args; i++) + { + bool success; + + uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success); + if (!success) + { + result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i)); + result.SetStatus (eReturnStatusFailed); + return false; + } + + thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx)); + + if (!thread_sps[i]) + { + result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i)); + result.SetStatus (eReturnStatusFailed); + return false; + } + + } + + for (uint32_t i = 0; i < num_args; i++) + { + if (!DisplayFramesForExecutionContext (thread_sps[i].get(), + interpreter, + result.GetOutputStream(), + m_options.m_start, + m_options.m_count, + show_frame_info, + num_frames_with_source, + 3, + 3)) + { + result.AppendErrorWithFormat ("error displaying backtrace for thread: \"%s\"\n", command.GetArgumentAtIndex(i)); + result.SetStatus (eReturnStatusFailed); + return false; + } + + if (i < num_args - 1) + result.AppendMessage(""); + } } return result.Succeeded(); } From scallanan at apple.com Thu Aug 26 20:01:45 2010 From: scallanan at apple.com (Sean Callanan) Date: Fri, 27 Aug 2010 01:01:45 -0000 Subject: [Lldb-commits] [lldb] r112249 - in /lldb/trunk: include/lldb/ include/lldb/Core/ include/lldb/Expression/ lldb.xcodeproj/ source/Commands/ source/Expression/ source/Interpreter/ Message-ID: <20100827010145.545872A6C12C@llvm.org> Author: spyffe Date: Thu Aug 26 20:01:44 2010 New Revision: 112249 URL: http://llvm.org/viewvc/llvm-project?rev=112249&view=rev Log: This is a major refactoring of the expression parser. The goal is to separate the parser's data from the data belonging to the parser's clients. This allows clients to use the parser to obtain (for example) a JIT compiled function or some DWARF code, and then discard the parser state. Previously, parser state was held in ClangExpression and used liberally by ClangFunction, which inherited from ClangExpression. The main effects of this refactoring are: - reducing ClangExpression to an abstract class that declares methods that any client must expose to the expression parser, - moving the code specific to implementing the "expr" command from ClangExpression and CommandObjectExpression into ClangUserExpression, a new class, - moving the common parser interaction code from ClangExpression into ClangExpressionParser, a new class, and - making ClangFunction rely only on ClangExpressionParser and not depend on the internal implementation of ClangExpression. Side effects include: - the compiler interaction code has been factored out of ClangFunction and is now in an AST pass (ASTStructExtractor), - the header file for ClangFunction is now fully documented, - several bugs that only popped up when Clang was deallocated (which never happened, since the lifetime of the compiler was essentially infinite) are now fixed, and - the developer-only "call" command has been disabled. I have tested the expr command and the Objective-C step-into code, which use ClangUserExpression and ClangFunction, respectively, and verified that they work. Please let me know if you encounter bugs or poor documentation. Added: lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h - copied, changed from r112086, lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h lldb/trunk/include/lldb/Expression/ASTStructExtractor.h lldb/trunk/include/lldb/Expression/ClangExpressionParser.h lldb/trunk/include/lldb/Expression/ClangUserExpression.h lldb/trunk/source/Expression/ASTResultSynthesizer.cpp - copied, changed from r112086, lldb/trunk/source/Expression/ClangResultSynthesizer.cpp lldb/trunk/source/Expression/ASTStructExtractor.cpp lldb/trunk/source/Expression/ClangExpressionParser.cpp lldb/trunk/source/Expression/ClangUserExpression.cpp - copied, changed from r111952, lldb/trunk/source/Expression/ClangExpression.cpp Removed: lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h lldb/trunk/source/Expression/ClangExpression.cpp lldb/trunk/source/Expression/ClangResultSynthesizer.cpp Modified: lldb/trunk/include/lldb/Core/ClangForward.h lldb/trunk/include/lldb/Expression/ClangExpression.h lldb/trunk/include/lldb/Expression/ClangFunction.h lldb/trunk/include/lldb/Expression/IRForTarget.h lldb/trunk/include/lldb/Expression/IRToDWARF.h lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h lldb/trunk/include/lldb/lldb-forward.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Commands/CommandObjectCall.cpp lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Expression/ClangFunction.cpp lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Expression/IRToDWARF.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp Modified: lldb/trunk/include/lldb/Core/ClangForward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ClangForward.h?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ClangForward.h (original) +++ lldb/trunk/include/lldb/Core/ClangForward.h Thu Aug 26 20:01:44 2010 @@ -25,6 +25,7 @@ } class Action; + class ASTConsumer; class ASTContext; class ASTRecordLayout; class AddrLabelExpr; @@ -52,6 +53,7 @@ class DiagnosticOptions; class EnumDecl; class Expr; + class ExternalASTSource; class ExtVectorElementExpr; class FieldDecl; class FloatingLiteral; Copied: lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h (from r112086, lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h) URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h?p2=lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h&p1=lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h&r1=112086&r2=112249&rev=112249&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h (original) +++ lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h Thu Aug 26 20:01:44 2010 @@ -1,4 +1,4 @@ -//===-- ClangResultSynthesizer.h --------------------------------*- C++ -*-===// +//===-- ASTResultSynthesizer.h ----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangResultSynthesizer_h_ -#define liblldb_ClangResultSynthesizer_h_ +#ifndef liblldb_ASTResultSynthesizer_h_ +#define liblldb_ASTResultSynthesizer_h_ #include "clang/Sema/SemaConsumer.h" #include "lldb/Core/ClangForward.h" @@ -16,7 +16,7 @@ namespace lldb_private { //---------------------------------------------------------------------- -/// @class ClangResultSynthesizer ClangResultSynthesizer.h "lldb/Expression/ClangResultSynthesizer.h" +/// @class ASTResultSynthesizer ASTResultSynthesizer.h "lldb/Expression/ASTResultSynthesizer.h" /// @brief Adds a result variable declaration to the ASTs for an expression. /// /// Users expect the expression "i + 3" to return a result, even if a result @@ -24,11 +24,11 @@ /// a result variable to the expression, transforming it to /// "int ___clang_expr_result = i + 3." The IR transformers ensure that the /// resulting variable is mapped to the right piece of memory. -/// ClangResultSynthesizer's job is to add the variable and its initialization to +/// ASTResultSynthesizer's job is to add the variable and its initialization to /// the ASTs for the expression, and it does so by acting as a SemaConsumer for /// Clang. //---------------------------------------------------------------------- -class ClangResultSynthesizer : public clang::SemaConsumer +class ASTResultSynthesizer : public clang::SemaConsumer { public: //---------------------------------------------------------------------- @@ -40,12 +40,12 @@ /// pass to the next step in the chain after processing. Passthrough is /// the next ASTConsumer, or NULL if none is required. //---------------------------------------------------------------------- - ClangResultSynthesizer(clang::ASTConsumer *passthrough); + ASTResultSynthesizer(clang::ASTConsumer *passthrough); //---------------------------------------------------------------------- /// Destructor //---------------------------------------------------------------------- - ~ClangResultSynthesizer(); + ~ASTResultSynthesizer(); //---------------------------------------------------------------------- /// Link this consumer with a particular AST context Added: lldb/trunk/include/lldb/Expression/ASTStructExtractor.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ASTStructExtractor.h?rev=112249&view=auto ============================================================================== --- lldb/trunk/include/lldb/Expression/ASTStructExtractor.h (added) +++ lldb/trunk/include/lldb/Expression/ASTStructExtractor.h Thu Aug 26 20:01:44 2010 @@ -0,0 +1,156 @@ +//===-- ASTStructExtractor.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ASTStructExtractor_h_ +#define liblldb_ASTStructExtractor_h_ + +#include "clang/Sema/SemaConsumer.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Expression/ClangExpressionVariable.h" +#include "lldb/Expression/ClangFunction.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ASTStructExtractor ASTStructExtractor.h "lldb/Expression/ASTStructExtractor.h" +/// @brief Extracts and describes the argument structure for a wrapped function. +/// +/// This pass integrates with ClangFunction, which calls functions with custom +/// sets of arguments. To avoid having to implement the full calling convention +/// for the target's architecture, ClangFunction writes a simple wrapper +/// function that takes a pointer to an argument structure that contains room +/// for the address of the function to be called, the values of all its +/// arguments, and room for the function's return value. +/// +/// The definition of this struct is itself in the body of the wrapper function, +/// so Clang does the structure layout itself. ASTStructExtractor reads through +/// the AST for the wrapper funtion and finds the struct. +//---------------------------------------------------------------------- +class ASTStructExtractor : public clang::SemaConsumer +{ +public: + //---------------------------------------------------------------------- + /// Constructor + /// + /// @param[in] passthrough + /// Since the ASTs must typically go through to the Clang code generator + /// in order to produce LLVM IR, this SemaConsumer must allow them to + /// pass to the next step in the chain after processing. Passthrough is + /// the next ASTConsumer, or NULL if none is required. + /// + /// @param[in] struct_name + /// The name of the structure to extract from the wrapper function. + /// + /// @param[in] function + /// The caller object whose members should be populated with information + /// about the argument struct. ClangFunction friends ASTStructExtractor + /// for this purpose. + //---------------------------------------------------------------------- + ASTStructExtractor(clang::ASTConsumer *passthrough, + const char *struct_name, + ClangFunction &function); + + //---------------------------------------------------------------------- + /// Destructor + //---------------------------------------------------------------------- + ~ASTStructExtractor(); + + //---------------------------------------------------------------------- + /// Link this consumer with a particular AST context + /// + /// @param[in] Context + /// This AST context will be used for types and identifiers, and also + /// forwarded to the passthrough consumer, if one exists. + //---------------------------------------------------------------------- + void Initialize(clang::ASTContext &Context); + + //---------------------------------------------------------------------- + /// Examine a list of Decls to find the function ___clang_expr and + /// transform its code + /// + /// @param[in] D + /// The list of Decls to search. These may contain LinkageSpecDecls, + /// which need to be searched recursively. That job falls to + /// TransformTopLevelDecl. + //---------------------------------------------------------------------- + void HandleTopLevelDecl(clang::DeclGroupRef D); + + //---------------------------------------------------------------------- + /// Passthrough stub + //---------------------------------------------------------------------- + void HandleTranslationUnit(clang::ASTContext &Ctx); + + //---------------------------------------------------------------------- + /// Passthrough stub + //---------------------------------------------------------------------- + void HandleTagDeclDefinition(clang::TagDecl *D); + + //---------------------------------------------------------------------- + /// Passthrough stub + //---------------------------------------------------------------------- + void CompleteTentativeDefinition(clang::VarDecl *D); + + //---------------------------------------------------------------------- + /// Passthrough stub + //---------------------------------------------------------------------- + void HandleVTable(clang::CXXRecordDecl *RD, bool DefinitionRequired); + + //---------------------------------------------------------------------- + /// Passthrough stub + //---------------------------------------------------------------------- + void PrintStats(); + + //---------------------------------------------------------------------- + /// Set the Sema object to use when performing transforms, and pass it on + /// + /// @param[in] S + /// The Sema to use. Because Sema isn't externally visible, this class + /// casts it to an Action for actual use. + //---------------------------------------------------------------------- + void InitializeSema(clang::Sema &S); + + //---------------------------------------------------------------------- + /// Reset the Sema to NULL now that transformations are done + //---------------------------------------------------------------------- + void ForgetSema(); +private: + //---------------------------------------------------------------------- + /// Hunt the given FunctionDecl for the argument struct and place + /// information about it into m_function + /// + /// @param[in] F + /// The FunctionDecl to hunt. + //---------------------------------------------------------------------- + void + ExtractFromFunctionDecl(clang::FunctionDecl* F); + + //---------------------------------------------------------------------- + /// Hunt the given Decl for FunctionDecls named the same as the wrapper + /// function name, recursing as necessary through LinkageSpecDecls, and + /// calling ExtractFromFunctionDecl on anything that was found + /// + /// @param[in] D + /// The Decl to hunt. + //---------------------------------------------------------------------- + void + ExtractFromTopLevelDecl(clang::Decl* D); + + clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types. + clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer. + clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer. + clang::Sema *m_sema; ///< The Sema to use. + clang::Action *m_action; ///< The Sema to use, cast to an Action so it's usable. + + ClangFunction &m_function; ///< The function to populate with information about the argument structure. + std::string m_struct_name; ///< The name of the structure to extract. +}; + +} + +#endif \ No newline at end of file Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpression.h?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpression.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpression.h Thu Aug 26 20:01:44 2010 @@ -25,12 +25,6 @@ #include "lldb/Core/ClangForward.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" -namespace llvm -{ - class ExecutionEngine; - class StringRef; -} - namespace lldb_private { class RecordingMemoryManager; @@ -48,245 +42,51 @@ { public: //------------------------------------------------------------------ - /// Constructor - /// - /// Initializes class variabes. - /// - /// @param[in] target_triple - /// The LLVM-friendly target triple for use in initializing the - /// compiler. - /// - /// @param[in] expr_decl_map - /// The object that looks up externally-defined names in LLDB's - /// debug information. - //------------------------------------------------------------------ - ClangExpression(const char *target_triple, - ClangExpressionDeclMap *expr_decl_map); - - //------------------------------------------------------------------ - /// Destructor + /// Return the string that the parser should parse. Must be a full + /// translation unit. //------------------------------------------------------------------ - ~ClangExpression(); + virtual const char * + Text () = 0; //------------------------------------------------------------------ - /// Parse a single expression and convert it to IR using Clang. Wrap - /// the expression in a function with signature void ___clang_expr(void*). - /// - /// @param[in] expr_text - /// The text of the expression to be parsed. - /// - /// @param[in] stream - /// The stream to print errors to. - /// - /// @param[in] add_result_var - /// True if a special result variable should be generated for - /// the expression. - /// - /// @return - /// The number of errors encountered during parsing. 0 means - /// success. - //------------------------------------------------------------------ - unsigned - ParseExpression (const char *expr_text, - Stream &stream, - bool add_result_var = false); - - //------------------------------------------------------------------ - /// Parse a single expression and convert it to IR using Clang. Don't - /// wrap the expression in anything at all. - /// - /// @param[in] expr_text - /// The text of the expression to be parsed. - /// - /// @param[in] stream - /// The stream to print errors to. - /// - /// @param[in] add_result_var - /// True if a special result variable should be generated for - /// the expression. - /// - /// @return - /// The number of errors encountered during parsing. 0 means - /// success. - //------------------------------------------------------------------ - unsigned - ParseBareExpression (llvm::StringRef expr_text, - Stream &stream, - bool add_result_var = false); - + /// Return the function name that should be used for executing the + /// expression. Text() should contain the definition of this + /// function. //------------------------------------------------------------------ - /// Convert the IR for an already-parsed expression to DWARF if possible. - /// - /// @param[in] expr_local_variable_list - /// The list of local variables the expression uses, with types, for - /// use by the DWARF parser. - /// - /// @param[in] dwarf_opcode_strm - /// The stream to place the resulting DWARF code into. - /// - /// @return - /// True on success; false on failure. On failure, it may be appropriate - /// to call PrepareIRForTarget(). - //------------------------------------------------------------------ - bool - ConvertIRToDWARF (ClangExpressionVariableList &excpr_local_variable_list, - StreamString &dwarf_opcode_strm); + virtual const char * + FunctionName () = 0; //------------------------------------------------------------------ - /// Prepare the IR for an already-parsed expression for execution in the - /// target process by (among other things) making all externally-defined - /// variables point to offsets from the void* argument. - /// - /// @return - /// True on success; false on failure. On failure, this expression - /// cannot be executed by LLDB. - //------------------------------------------------------------------ - bool - PrepareIRForTarget (); - - //------------------------------------------------------------------ - /// Use the JIT to compile an already-prepared expression from IR into - /// machine code, but keep the code in the current process for now. - /// - /// @param[in] func_name - /// The name of the function to be JITted. By default, the function - /// wrapped by ParseExpression(). - /// - /// @return - /// True on success; false otherwise. - //------------------------------------------------------------------ - bool - JITFunction (const char *func_name = "___clang_expr"); - + /// Return the object that the parser should use when resolving external + /// values. May be NULL if everything should be self-contained. //------------------------------------------------------------------ - /// Write the machine code generated by the JIT into the target's memory. - /// - /// @param[in] exc_context - /// The execution context that the JITted code must be copied into. - /// - /// @return - /// True on success; false otherwise. - //------------------------------------------------------------------ - bool - WriteJITCode (const ExecutionContext &exc_context); - - //------------------------------------------------------------------ - /// Write the machine code generated by the JIT into the target process. - /// - /// @param[in] func_name - /// The name of the function whose address is being requested. - /// By default, the function wrapped by ParseExpression(). - /// - /// @return - /// True on success; false otherwise. - //------------------------------------------------------------------ - lldb::addr_t - GetFunctionAddress (const char *func_name = "___clang_expr"); + virtual ClangExpressionDeclMap * + DeclMap () = 0; //------------------------------------------------------------------ - /// Disassemble the machine code for a JITted function from the target - /// process's memory and print the result to a stream. - /// - /// @param[in] stream - /// The stream to print disassembly to. - /// - /// @param[in] exc_context - /// The execution context to get the machine code from. - /// - /// @param[in] func_name - /// The name of the function to be disassembled. By default, the - /// function wrapped by ParseExpression(). - /// - /// @return - /// The error generated. If .Success() is true, disassembly succeeded. - //------------------------------------------------------------------ - Error - DisassembleFunction (Stream &stream, ExecutionContext &exc_context, const char *func_name = "___clang_expr"); - - //------------------------------------------------------------------ - /// Return the Clang compiler instance being used by this expression. + /// Return the object that the parser should use when registering + /// local variables. May be NULL if the Expression doesn't care. //------------------------------------------------------------------ - clang::CompilerInstance * - GetCompilerInstance () - { - return m_clang_ap.get(); - } - - //------------------------------------------------------------------ - /// Return the AST context being used by this expression. - //------------------------------------------------------------------ - clang::ASTContext * - GetASTContext (); - - //------------------------------------------------------------------ - /// Return the mutex being used to serialize access to Clang. - //------------------------------------------------------------------ - static Mutex & - GetClangMutex (); -protected: - //------------------------------------------------------------------ - // Classes that inherit from ClangExpression can see and modify these - //------------------------------------------------------------------ - - //---------------------------------------------------------------------- - /// @class JittedFunction ClangExpression.h "lldb/Expression/ClangExpression.h" - /// @brief Encapsulates a single function that has been generated by the JIT. - /// - /// Functions that have been generated by the JIT are first resident in the - /// local process, and then placed in the target process. JittedFunction - /// represents a function possibly resident in both. - //---------------------------------------------------------------------- - struct JittedFunction { - std::string m_name; ///< The function's name - lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory - lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory - - //------------------------------------------------------------------ - /// Constructor - /// - /// Initializes class variabes. - /// - /// @param[in] name - /// The name of the function. - /// - /// @param[in] local_addr - /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if - /// it is not present in LLDB's memory. - /// - /// @param[in] remote_addr - /// The address of the function in the target, or LLDB_INVALID_ADDRESS - /// if it is not present in the target's memory. - //------------------------------------------------------------------ - JittedFunction (const char *name, - lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, - lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : - m_name (name), - m_local_addr (local_addr), - m_remote_addr (remote_addr) {} - }; - - std::string m_target_triple; ///< The target triple used to initialize LLVM - ClangExpressionDeclMap *m_decl_map; ///< The class used to look up entities defined in the debug info - std::auto_ptr m_clang_ap; ///< The Clang compiler used to parse expressions into IR - clang::CodeGenerator *m_code_generator_ptr; ///< [owned by the Execution Engine] The Clang object that generates IR - RecordingMemoryManager *m_jit_mm_ptr; ///< [owned by the Execution Engine] The memory manager that allocates code pages on the JIT's behalf - std::auto_ptr m_execution_engine; ///< The LLVM JIT - std::vector m_jitted_functions; ///< A vector of all functions that have been JITted into machine code (just one, if ParseExpression() was called) -private: + virtual ClangExpressionVariableStore * + LocalVariables () = 0; + //------------------------------------------------------------------ - /// Initialize m_clang_ap to a compiler instance with all the options - /// required by the expression parser. + /// Return the object that the parser should allow to access ASTs. + /// May be NULL if the ASTs do not need to be transformed. /// - /// @return - /// True on success; false otherwise. + /// @param[in] passthrough + /// The ASTConsumer that the returned transformer should send + /// the ASTs to after transformation. //------------------------------------------------------------------ - bool CreateCompilerInstance(); - + virtual clang::ASTConsumer * + ASTTransformer (clang::ASTConsumer *passthrough) = 0; + //------------------------------------------------------------------ - // For ClangExpression only + /// Return the stream that the parser should use to write DWARF + /// opcodes. //------------------------------------------------------------------ - ClangExpression(const ClangExpression&); - const ClangExpression& operator=(const ClangExpression&); + virtual StreamString & + DwarfOpcodeStream () = 0; }; } // namespace lldb_private Added: lldb/trunk/include/lldb/Expression/ClangExpressionParser.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionParser.h?rev=112249&view=auto ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionParser.h (added) +++ lldb/trunk/include/lldb/Expression/ClangExpressionParser.h Thu Aug 26 20:01:44 2010 @@ -0,0 +1,182 @@ +//===-- ClangExpressionParser.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangExpressionParser_h_ +#define liblldb_ClangExpressionParser_h_ + +#include "lldb/lldb-include.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Core/Error.h" + +#include +#include + +namespace llvm +{ + class ExecutionEngine; +} + +namespace lldb_private +{ + +class RecordingMemoryManager; + +//---------------------------------------------------------------------- +/// @class ClangExpressionParser ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h" +/// @brief Encapsulates an instance of Clang that can parse expressions. +/// +/// ClangExpressionParser is responsible for preparing an instance of +/// ClangExpression for execution. ClangExpressionParser uses ClangExpression +/// as a glorified parameter list, performing the required parsing and +/// conversion to formats (DWARF bytecode, or JIT compiled machine code) +/// that can be executed. +//---------------------------------------------------------------------- +class ClangExpressionParser +{ +public: + //------------------------------------------------------------------ + /// Constructor + /// + /// Initializes class variabes. + /// + /// @param[in] target_triple + /// The LLVM-friendly target triple for use in initializing the + /// compiler. + /// + /// @param[in] expr + /// The expression to be parsed. + //------------------------------------------------------------------ + ClangExpressionParser (const char *target_triple, + ClangExpression &expr); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + ~ClangExpressionParser (); + + //------------------------------------------------------------------ + /// Parse a single expression and convert it to IR using Clang. Don't + /// wrap the expression in anything at all. + /// + /// @param[in] stream + /// The stream to print errors to. + /// + /// @return + /// The number of errors encountered during parsing. 0 means + /// success. + //------------------------------------------------------------------ + unsigned + Parse (Stream &stream); + + //------------------------------------------------------------------ + /// Convert the IR for an already-parsed expression to DWARF if possible. + /// + /// @param[in] dwarf_opcode_strm + /// The stream to place the resulting DWARF code into. + /// + /// @return + /// An error code indicating the success or failure of the operation. + /// Test with Success(). + //------------------------------------------------------------------ + Error + MakeDWARF (); + + //------------------------------------------------------------------ + /// JIT-compile the IR for an already-parsed expression. + /// + /// @param[out] func_addr + /// The address to which the function has been written. + /// + /// @para[in] exe_ctx + /// The execution context to write the function into. + /// + /// @return + /// An error code indicating the success or failure of the operation. + /// Test with Success(). + //------------------------------------------------------------------ + Error + MakeJIT (lldb::addr_t &func_addr, + ExecutionContext &exe_ctx); + + //------------------------------------------------------------------ + /// Disassemble the machine code for a JITted function from the target + /// process's memory and print the result to a stream. + /// + /// @param[in] stream + /// The stream to print disassembly to. + /// + /// @param[in] exc_context + /// The execution context to get the machine code from. + /// + /// @param[in] func_name + /// The name of the function to be disassembled. By default, the + /// function wrapped by ParseExpression(). + /// + /// @return + /// The error generated. If .Success() is true, disassembly succeeded. + //------------------------------------------------------------------ + Error + DisassembleFunction (Stream &stream, ExecutionContext &exc_context); + +private: + //---------------------------------------------------------------------- + /// @class JittedFunction ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h" + /// @brief Encapsulates a single function that has been generated by the JIT. + /// + /// Functions that have been generated by the JIT are first resident in the + /// local process, and then placed in the target process. JittedFunction + /// represents a function possibly resident in both. + //---------------------------------------------------------------------- + struct JittedFunction { + std::string m_name; ///< The function's name + lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory + lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory + + //------------------------------------------------------------------ + /// Constructor + /// + /// Initializes class variabes. + /// + /// @param[in] name + /// The name of the function. + /// + /// @param[in] local_addr + /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if + /// it is not present in LLDB's memory. + /// + /// @param[in] remote_addr + /// The address of the function in the target, or LLDB_INVALID_ADDRESS + /// if it is not present in the target's memory. + //------------------------------------------------------------------ + JittedFunction (const char *name, + lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, + lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : + m_name (name), + m_local_addr (local_addr), + m_remote_addr (remote_addr) + { + } + }; + + ClangExpression &m_expr; ///< The expression to be parsed + + std::string m_target_triple; ///< The target triple used to initialize LLVM + std::auto_ptr m_diagnostic_buffer; ///< The container for errors produced by the compiler + std::auto_ptr m_compiler; ///< The Clang compiler used to parse expressions into IR + std::auto_ptr m_builtin_context; ///< Context for Clang built-ins + std::auto_ptr m_ast_context; ///< The AST context used to hold types and names for the parser + std::auto_ptr m_code_generator; ///< [owned by the Execution Engine] The Clang object that generates IR + RecordingMemoryManager *m_jit_mm; ///< The memory manager for the LLVM JIT + std::auto_ptr m_execution_engine; ///< The LLVM JIT + std::vector m_jitted_functions; ///< A vector of all functions that have been JITted into machine code (just one, if ParseExpression() was called) +}; + +} + +#endif // liblldb_ClangExpressionParser_h_ Modified: lldb/trunk/include/lldb/Expression/ClangFunction.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangFunction.h?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangFunction.h (original) +++ lldb/trunk/include/lldb/Expression/ClangFunction.h Thu Aug 26 20:01:44 2010 @@ -20,7 +20,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectList.h" - #include "lldb/Expression/ClangExpression.h" // Right now, this is just a toy. It calls a set function, with fixed @@ -28,11 +27,47 @@ namespace lldb_private { + +class ASTStructExtractor; +class ClangExpressionParser; -class ClangFunction : private ClangExpression +//---------------------------------------------------------------------- +/// @class ClangFunction ClangFunction.h "lldb/Expression/ClangFunction.h" +/// @brief Encapsulates a function that can be called. +/// +/// A given ClangFunction object can handle a single function signature. +/// Once constructed, it can set up any number of concurrent calls to +/// functions with that signature. +/// +/// It performs the call by synthesizing a structure that contains the pointer +/// to the function and the arguments that should be passed to that function, +/// and producing a special-purpose JIT-compiled function that accepts a void* +/// pointing to this struct as its only argument and calls the function in the +/// struct with the written arguments. This method lets Clang handle the +/// vagaries of function calling conventions. +/// +/// The simplest use of the ClangFunction is to construct it with a +/// function representative of the signature you want to use, then call +/// ExecuteFunction(ExecutionContext &, Stream &, Value &). +/// +/// If you need to reuse the arguments for several calls, you can call +/// InsertFunction() followed by WriteFunctionArguments(), which will return +/// the location of the args struct for the wrapper function in args_addr_ref. +/// +/// If you need to call the function on the thread plan stack, you can also +/// call InsertFunction() followed by GetThreadPlanToCallFunction(). +/// +/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed +/// a pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated +/// and its address returned in that variable. +/// +/// Any of the methods that take arg_addr_ptr can be passed NULL, and the +/// argument space will be managed for you. +//---------------------------------------------------------------------- +class ClangFunction : public ClangExpression { + friend class ASTStructExtractor; public: - enum ExecutionResults { eExecutionSetupError, @@ -43,56 +78,200 @@ }; //------------------------------------------------------------------ - // Constructors and Destructors + /// Constructor + /// + /// @param[in] target_triple + /// The LLVM-style target triple for the target in which the + /// function is to be executed. + /// + /// @param[in] function_ptr + /// The default function to be called. Can be overridden using + /// WriteFunctionArguments(). + /// + /// @param[in] ast_context + /// The AST context to evaluate argument types in. + /// + /// @param[in] arg_value_list + /// The default values to use when calling this function. Can + /// be overridden using WriteFunctionArguments(). + //------------------------------------------------------------------ + ClangFunction(const char *target_triple, + Function &function_ptr, + ClangASTContext *ast_context, + const ValueList &arg_value_list); + + //------------------------------------------------------------------ + /// Constructor + /// + /// @param[in] target_triple + /// The LLVM-style target triple for the target in which the + /// function is to be executed. + /// + /// @param[in] ast_context + /// The AST context to evaluate argument types in. + /// + /// @param[in] return_qualtype + /// An opaque Clang QualType for the function result. Should be + /// defined in ast_context. + /// + /// @param[in] function_address + /// The address of the function to call. + /// + /// @param[in] arg_value_list + /// The default values to use when calling this function. Can + /// be overridden using WriteFunctionArguments(). //------------------------------------------------------------------ - // Usage Note: + ClangFunction(const char *target_triple, + ClangASTContext *ast_context, + void *return_qualtype, + const Address& function_address, + const ValueList &arg_value_list); - // A given ClangFunction object can handle any function with a common signature. It can also be used to - // set up any number of concurrent functions calls once it has been constructed. - // When you construct it you pass in a particular function, information sufficient to determine the function signature - // and value list. - // The simplest use of the ClangFunction is to construct the function, then call ExecuteFunction (context, errors, results). The function - // will be called using the initial arguments, and the results determined for you, and all cleanup done. - // - // However, if you need to use the function caller in Thread Plans, you need to call the function on the plan stack. - // In that case, you call GetThreadPlanToCallFunction, args_addr will be the location of the args struct, and after you are - // done running this thread plan you can recover the results using FetchFunctionResults passing in the same value. - // You are required to call InsertFunction before calling GetThreadPlanToCallFunction. - // - // You can also reuse the struct if you want, by calling ExecuteFunction but passing in args_addr_ptr primed to this value. - // - // You can also reuse the ClangFunction for the same signature but different function or argument values by rewriting the - // Functions arguments with WriteFunctionArguments, and then calling ExecuteFunction passing in the same args_addr. - // - // Note, any of the functions below that take arg_addr_ptr, or arg_addr_ref, can be passed a pointer set to LLDB_INVALID_ADDRESS and - // new structure will be allocated and its address returned in that variable. - // Any of the functions below that take arg_addr_ptr can be passed NULL, and the argument space will be managed for you. - - ClangFunction(const char *target_triple, Function &function_ptr, ClangASTContext *ast_context, const ValueList &arg_value_list); - // This constructor takes its return type as a Clang QualType opaque pointer, and the ast_context it comes from. - // FIXME: We really should be able to easily make a Type from the qualtype, and then just pass that in. - ClangFunction(const char *target_triple, ClangASTContext *ast_context, void *return_qualtype, const Address& functionAddress, const ValueList &arg_value_list); + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ virtual ~ClangFunction(); + //------------------------------------------------------------------ + /// Compile the wrapper function + /// + /// @param[in] errors + /// The stream to print parser errors to. + /// + /// @return + /// The number of errors. + //------------------------------------------------------------------ unsigned CompileFunction (Stream &errors); - // args_addr is a pointer to the address the addr will be filled with. If the value on - // input is LLDB_INVALID_ADDRESS then a new address will be allocated, and returned in args_addr. - // If args_addr is a value already returned from a previous call to InsertFunction, then - // the args structure at that address is overwritten. - // If any other value is returned, then we return false, and do nothing. - bool InsertFunction (ExecutionContext &context, lldb::addr_t &args_addr_ref, Stream &errors); - - bool WriteFunctionWrapper (ExecutionContext &exec_ctx, Stream &errors); + //------------------------------------------------------------------ + /// Insert the default function wrapper and its default argument struct + /// + /// @param[in] exe_ctx + /// The execution context to insert the function and its arguments + /// into. + /// + /// @param[in,out] args_addr_ref + /// The address of the structure to write the arguments into. May + /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated + /// and args_addr_ref is pointed to it. + /// + /// @param[in] errors + /// The stream to write errors to. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + bool InsertFunction (ExecutionContext &exe_ctx, + lldb::addr_t &args_addr_ref, + Stream &errors); + + //------------------------------------------------------------------ + /// Insert the default function wrapper (using the JIT) + /// + /// @param[in] exe_ctx + /// The execution context to insert the function and its arguments + /// into. + /// + /// @param[in] errors + /// The stream to write errors to. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + bool WriteFunctionWrapper (ExecutionContext &exe_ctx, + Stream &errors); - // This variant writes down the original function address and values to args_addr. - bool WriteFunctionArguments (ExecutionContext &exec_ctx, lldb::addr_t &args_addr_ref, Stream &errors); + //------------------------------------------------------------------ + /// Insert the default function argument struct + /// + /// @param[in] exe_ctx + /// The execution context to insert the function and its arguments + /// into. + /// + /// @param[in,out] args_addr_ref + /// The address of the structure to write the arguments into. May + /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated + /// and args_addr_ref is pointed to it. + /// + /// @param[in] errors + /// The stream to write errors to. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + bool WriteFunctionArguments (ExecutionContext &exe_ctx, + lldb::addr_t &args_addr_ref, + Stream &errors); - // This variant writes down function_address and arg_value. - bool WriteFunctionArguments (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors); + //------------------------------------------------------------------ + /// Insert an argument struct with a non-default function address and + /// non-default argument values + /// + /// @param[in] exe_ctx + /// The execution context to insert the function and its arguments + /// into. + /// + /// @param[in,out] args_addr_ref + /// The address of the structure to write the arguments into. May + /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated + /// and args_addr_ref is pointed to it. + /// + /// @param[in] function_address + /// The address of the function to call. + /// + /// @param[in] arg_values + /// The values of the function's arguments. + /// + /// @param[in] errors + /// The stream to write errors to. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + bool WriteFunctionArguments (ExecutionContext &exe_ctx, + lldb::addr_t &args_addr_ref, + Address function_address, + ValueList &arg_values, + Stream &errors); - // Run a function at a particular address, with a given address passed on the stack. - static ExecutionResults ExecuteFunction (ExecutionContext &exe_ctx, lldb::addr_t function_address, lldb::addr_t &void_arg, bool stop_others, bool try_all_threads, uint32_t single_thread_timeout_usec, Stream &errors); + //------------------------------------------------------------------ + /// [Static] Execute a function, passing it a single void* parameter. + /// ClangFunction uses this to call the wrapper function. + /// + /// @param[in] exe_ctx + /// The execution context to insert the function and its arguments + /// into. + /// + /// @param[in] function_address + /// The address of the function in the target process. + /// + /// @param[in] void_arg + /// The value of the void* parameter. + /// + /// @param[in] stop_others + /// True if other threads should pause during execution. + /// + /// @param[in] try_all_threads + /// If the timeout expires, true if other threads should run. If + /// the function may try to take locks, this is useful. + /// + /// @param[in] single_thread_timeout_usec + /// If stop_others is true, the length of time to wait before + /// concluding that the system is deadlocked. + /// + /// @param[in] errors + /// The stream to write errors to. + /// + /// @return + /// Returns one of the ExecutionResults enum indicating function call status. + //------------------------------------------------------------------ + static ExecutionResults ExecuteFunction (ExecutionContext &exe_ctx, + lldb::addr_t function_address, + lldb::addr_t &void_arg, + bool stop_others, + bool try_all_threads, + uint32_t single_thread_timeout_usec, + Stream &errors); //------------------------------------------------------------------ /// Run the function this ClangFunction was created with. @@ -101,7 +280,7 @@ /// for a fixed timeout period (1000 usec) and if it does not complete, /// we halt the process and try with all threads running. /// - /// @param[in] context + /// @param[in] exe_ctx /// The thread & process in which this function will run. /// /// @param[in] errors @@ -113,7 +292,9 @@ /// @return /// Returns one of the ExecutionResults enum indicating function call status. //------------------------------------------------------------------ - ExecutionResults ExecuteFunction(ExecutionContext &context, Stream &errors, Value &results); + ExecutionResults ExecuteFunction(ExecutionContext &exe_ctx, + Stream &errors, + Value &results); //------------------------------------------------------------------ /// Run the function this ClangFunction was created with. @@ -121,7 +302,7 @@ /// This simple version will run the function obeying the stop_others /// argument. There is no timeout. /// - /// @param[in] context + /// @param[in] exe_ctx /// The thread & process in which this function will run. /// /// @param[in] errors @@ -136,7 +317,9 @@ /// @return /// Returns one of the ExecutionResults enum indicating function call status. //------------------------------------------------------------------ - ExecutionResults ExecuteFunction(ExecutionContext &exc_context, Stream &errors, bool stop_others, Value &results); + ExecutionResults ExecuteFunction(ExecutionContext &exe_ctx, + Stream &errors, bool stop_others, + Value &results); //------------------------------------------------------------------ /// Run the function this ClangFunction was created with. @@ -145,7 +328,7 @@ /// is not zero, we time out after that timeout. If \a try_all_threads is true, then we will /// resume with all threads on, otherwise we halt the process, and eExecutionInterrupted will be returned. /// - /// @param[in] context + /// @param[in] exe_ctx /// The thread & process in which this function will run. /// /// @param[in] errors @@ -163,14 +346,18 @@ /// @return /// Returns one of the ExecutionResults enum indicating function call status. //------------------------------------------------------------------ - ExecutionResults ExecuteFunction(ExecutionContext &context, Stream &errors, uint32_t single_thread_timeout_usec, bool try_all_threads, Value &results); + ExecutionResults ExecuteFunction(ExecutionContext &exe_ctx, + Stream &errors, + uint32_t single_thread_timeout_usec, + bool try_all_threads, + Value &results); //------------------------------------------------------------------ /// Run the function this ClangFunction was created with. /// /// This is the full version. /// - /// @param[in] context + /// @param[in] exe_ctx /// The thread & process in which this function will run. /// /// @param[in] args_addr_ptr @@ -198,48 +385,220 @@ /// @return /// Returns one of the ExecutionResults enum indicating function call status. //------------------------------------------------------------------ - ExecutionResults ExecuteFunction(ExecutionContext &context, lldb::addr_t *args_addr_ptr, Stream &errors, bool stop_others, uint32_t single_thread_timeout_usec, bool try_all_threads, Value &results); - ExecutionResults ExecuteFunctionWithABI(ExecutionContext &context, Stream &errors, Value &results); - + ExecutionResults ExecuteFunction(ExecutionContext &exe_ctx, + lldb::addr_t *args_addr_ptr, + Stream &errors, + bool stop_others, + uint32_t single_thread_timeout_usec, + bool try_all_threads, + Value &results); + + //------------------------------------------------------------------ + /// [static] Get a thread plan to run a function. + /// + /// @param[in] exe_ctx + /// The execution context to insert the function and its arguments + /// into. + /// + /// @param[in] func_addr + /// The address of the function in the target process. + /// + /// @param[in] args_addr_ref + /// The value of the void* parameter. + /// + /// @param[in] errors + /// The stream to write errors to. + /// + /// @param[in] stop_others + /// True if other threads should pause during execution. + /// + /// @param[in] discard_on_error + /// True if the thread plan may simply be discarded if an error occurs. + /// + /// @return + /// A ThreadPlan for executing the function. + //------------------------------------------------------------------ static ThreadPlan * - GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t func_addr, lldb::addr_t &args_addr_ref, Stream &errors, bool stop_others, bool discard_on_error = true); + GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, + lldb::addr_t func_addr, + lldb::addr_t &args_addr_ref, + Stream &errors, + bool stop_others, + bool discard_on_error = true); + //------------------------------------------------------------------ + /// Get a thread plan to run the function this ClangFunction was created with. + /// + /// @param[in] exe_ctx + /// The execution context to insert the function and its arguments + /// into. + /// + /// @param[in] func_addr + /// The address of the function in the target process. + /// + /// @param[in] args_addr_ref + /// The value of the void* parameter. + /// + /// @param[in] errors + /// The stream to write errors to. + /// + /// @param[in] stop_others + /// True if other threads should pause during execution. + /// + /// @param[in] discard_on_error + /// True if the thread plan may simply be discarded if an error occurs. + /// + /// @return + /// A ThreadPlan for executing the function. + //------------------------------------------------------------------ ThreadPlan * - GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors, bool stop_others, bool discard_on_error = true) + GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, + lldb::addr_t &args_addr_ref, + Stream &errors, + bool stop_others, + bool discard_on_error = true) { - return ClangFunction::GetThreadPlanToCallFunction (exc_context, m_wrapper_function_addr, args_addr_ref, errors, stop_others, discard_on_error); + return ClangFunction::GetThreadPlanToCallFunction (exe_ctx, + m_wrapper_function_addr, + args_addr_ref, + errors, + stop_others, + discard_on_error); } - bool FetchFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr, Value &ret_value); - void DeallocateFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr); - -protected: + + //------------------------------------------------------------------ + /// Get the result of the function from its struct + /// + /// @param[in] exe_ctx + /// The execution context to retrieve the result from. + /// + /// @param[in] args_addr + /// The address of the argument struct. + /// + /// @param[in] ret_value + /// The value returned by the function. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + bool FetchFunctionResults (ExecutionContext &exe_ctx, + lldb::addr_t args_addr, + Value &ret_value); + //------------------------------------------------------------------ - // Classes that inherit from ClangFunction can see and modify these + /// Deallocate the arguments structure + /// + /// @param[in] exe_ctx + /// The execution context to insert the function and its arguments + /// into. + /// + /// @param[in] args_addr + /// The address of the argument struct. + //------------------------------------------------------------------ + void DeallocateFunctionResults (ExecutionContext &exe_ctx, + lldb::addr_t args_addr); + //------------------------------------------------------------------ - + /// Interface for ClangExpression + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Return the string that the parser should parse. Must be a full + /// translation unit. + //------------------------------------------------------------------ + const char * + Text () + { + return m_wrapper_function_text.c_str(); + } + + //------------------------------------------------------------------ + /// Return the function name that should be used for executing the + /// expression. Text() should contain the definition of this + /// function. + //------------------------------------------------------------------ + const char * + FunctionName () + { + return m_wrapper_function_name.c_str(); + } + + //------------------------------------------------------------------ + /// Return the object that the parser should use when resolving external + /// values. May be NULL if everything should be self-contained. + //------------------------------------------------------------------ + ClangExpressionDeclMap * + DeclMap () + { + return NULL; + } + + //------------------------------------------------------------------ + /// Return the object that the parser should use when registering + /// local variables. May be NULL if the Expression doesn't care. + //------------------------------------------------------------------ + ClangExpressionVariableStore * + LocalVariables () + { + return NULL; + } + + //------------------------------------------------------------------ + /// Return the object that the parser should allow to access ASTs. + /// May be NULL if the ASTs do not need to be transformed. + /// + /// @param[in] passthrough + /// The ASTConsumer that the returned transformer should send + /// the ASTs to after transformation. + //------------------------------------------------------------------ + clang::ASTConsumer * + ASTTransformer (clang::ASTConsumer *passthrough); + + //------------------------------------------------------------------ + /// Return the stream that the parser should use to write DWARF + /// opcodes. + //------------------------------------------------------------------ + StreamString & + DwarfOpcodeStream () + { + return *((StreamString*)0); + } + private: //------------------------------------------------------------------ // For ClangFunction only //------------------------------------------------------------------ + + std::auto_ptr m_parser; ///< The parser responsible for compiling the function. + + Function *m_function_ptr; ///< The function we're going to call. May be NULL if we don't have debug info for the function. + Address m_function_addr; ///< If we don't have the FunctionSP, we at least need the address & return type. + void *m_function_return_qual_type; ///< The opaque clang qual type for the function return type. + ClangASTContext *m_clang_ast_context; ///< This is the clang_ast_context that we're getting types from the and value, and the function return the function pointer is NULL. + std::string m_target_triple; ///< The target triple to compile the wrapper function for. + + std::string m_wrapper_function_name; ///< The name of the wrapper function. + std::string m_wrapper_function_text; ///< The contents of the wrapper function. + std::string m_wrapper_struct_name; ///< The name of the struct that contains the target function address, arguments, and result. + lldb::addr_t m_wrapper_function_addr; ///< The address of the wrapper function. + std::list m_wrapper_args_addrs; ///< The addresses of the arguments to the wrapper function. - Function *m_function_ptr; // The function we're going to call. May be NULL if we don't have debug info for the function. - Address m_function_addr; // If we don't have the FunctionSP, we at least need the address & return type. - void *m_function_return_qual_type; // The opaque clang qual type for the function return type. - ClangASTContext *m_clang_ast_context; // This is the clang_ast_context that we're getting types from the and value, and the function return the function pointer is NULL. - - std::string m_wrapper_function_name; - std::string m_wrapper_struct_name; - lldb::addr_t m_wrapper_function_addr; - std::list m_wrapper_args_addrs; - const clang::ASTRecordLayout *m_struct_layout; - ValueList m_arg_values; - - size_t m_value_struct_size; - size_t m_return_offset; - uint64_t m_return_size; // Not strictly necessary, could get it from the Function... - bool m_compiled; - bool m_JITted; + bool m_struct_valid; ///< True if the ASTStructExtractor has populated the variables below. + + //------------------------------------------------------------------ + /// These values are populated by the ASTStructExtractor + size_t m_struct_size; ///< The size of the argument struct, in bytes. + std::vector m_member_offsets; ///< The offset of each member in the struct, in bytes. + uint64_t m_return_size; ///< The size of the result variable, in bytes. + uint64_t m_return_offset; ///< The offset of the result variable in the struct, in bytes. + //------------------------------------------------------------------ + + ValueList m_arg_values; ///< The default values of the arguments. + + bool m_compiled; ///< True if the wrapper function has already been parsed. + bool m_JITted; ///< True if the wrapper function has already been JIT-compiled. }; } // Namespace lldb_private + #endif // lldb_ClangFunction_h_ Removed: lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h?rev=112248&view=auto ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h (original) +++ lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h (removed) @@ -1,136 +0,0 @@ -//===-- ClangResultSynthesizer.h --------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ClangResultSynthesizer_h_ -#define liblldb_ClangResultSynthesizer_h_ - -#include "clang/Sema/SemaConsumer.h" -#include "lldb/Core/ClangForward.h" - -namespace lldb_private { - -//---------------------------------------------------------------------- -/// @class ClangResultSynthesizer ClangResultSynthesizer.h "lldb/Expression/ClangResultSynthesizer.h" -/// @brief Adds a result variable declaration to the ASTs for an expression. -/// -/// Users expect the expression "i + 3" to return a result, even if a result -/// variable wasn't specifically declared. To fulfil this requirement, LLDB adds -/// a result variable to the expression, transforming it to -/// "int ___clang_expr_result = i + 3." The IR transformers ensure that the -/// resulting variable is mapped to the right piece of memory. -/// ClangResultSynthesizer's job is to add the variable and its initialization to -/// the ASTs for the expression, and it does so by acting as a SemaConsumer for -/// Clang. -//---------------------------------------------------------------------- -class ClangResultSynthesizer : public clang::SemaConsumer -{ -public: - //---------------------------------------------------------------------- - /// Constructor - /// - /// @param[in] passthrough - /// Since the ASTs must typically go through to the Clang code generator - /// in order to produce LLVM IR, this SemaConsumer must allow them to - /// pass to the next step in the chain after processing. Passthrough is - /// the next ASTConsumer, or NULL if none is required. - //---------------------------------------------------------------------- - ClangResultSynthesizer(clang::ASTConsumer *passthrough); - - //---------------------------------------------------------------------- - /// Destructor - //---------------------------------------------------------------------- - ~ClangResultSynthesizer(); - - //---------------------------------------------------------------------- - /// Link this consumer with a particular AST context - /// - /// @param[in] Context - /// This AST context will be used for types and identifiers, and also - /// forwarded to the passthrough consumer, if one exists. - //---------------------------------------------------------------------- - void Initialize(clang::ASTContext &Context); - - //---------------------------------------------------------------------- - /// Examine a list of Decls to find the function ___clang_expr and - /// transform its code - /// - /// @param[in] D - /// The list of Decls to search. These may contain LinkageSpecDecls, - /// which need to be searched recursively. That job falls to - /// TransformTopLevelDecl. - //---------------------------------------------------------------------- - void HandleTopLevelDecl(clang::DeclGroupRef D); - - //---------------------------------------------------------------------- - /// Passthrough stub - //---------------------------------------------------------------------- - void HandleTranslationUnit(clang::ASTContext &Ctx); - - //---------------------------------------------------------------------- - /// Passthrough stub - //---------------------------------------------------------------------- - void HandleTagDeclDefinition(clang::TagDecl *D); - - //---------------------------------------------------------------------- - /// Passthrough stub - //---------------------------------------------------------------------- - void CompleteTentativeDefinition(clang::VarDecl *D); - - //---------------------------------------------------------------------- - /// Passthrough stub - //---------------------------------------------------------------------- - void HandleVTable(clang::CXXRecordDecl *RD, bool DefinitionRequired); - - //---------------------------------------------------------------------- - /// Passthrough stub - //---------------------------------------------------------------------- - void PrintStats(); - - //---------------------------------------------------------------------- - /// Set the Sema object to use when performing transforms, and pass it on - /// - /// @param[in] S - /// The Sema to use. Because Sema isn't externally visible, this class - /// casts it to an Action for actual use. - //---------------------------------------------------------------------- - void InitializeSema(clang::Sema &S); - - //---------------------------------------------------------------------- - /// Reset the Sema to NULL now that transformations are done - //---------------------------------------------------------------------- - void ForgetSema(); -private: - //---------------------------------------------------------------------- - /// Hunt the given Decl for FunctionDecls named ___clang_expr, recursing - /// as necessary through LinkageSpecDecls, and calling SynthesizeResult on - /// anything that was found - /// - /// @param[in] D - /// The Decl to hunt. - //---------------------------------------------------------------------- - void TransformTopLevelDecl(clang::Decl *D); - - //---------------------------------------------------------------------- - /// Process a function and produce the result variable and initialization - /// - /// @param[in] FunDecl - /// The function to process. - //---------------------------------------------------------------------- - bool SynthesizeResult(clang::FunctionDecl *FunDecl); - - clang::ASTContext *m_ast_context; ///< The AST context to use for identifiers and types. - clang::ASTConsumer *m_passthrough; ///< The ASTConsumer down the chain, for passthrough. NULL if it's a SemaConsumer. - clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer. - clang::Sema *m_sema; ///< The Sema to use. - clang::Action *m_action; ///< The Sema to use, cast to an Action so it's usable. -}; - -} - -#endif \ No newline at end of file Added: lldb/trunk/include/lldb/Expression/ClangUserExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUserExpression.h?rev=112249&view=auto ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangUserExpression.h (added) +++ lldb/trunk/include/lldb/Expression/ClangUserExpression.h Thu Aug 26 20:01:44 2010 @@ -0,0 +1,160 @@ +//===-- ClangUserExpression.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangUserExpression_h_ +#define liblldb_ClangUserExpression_h_ + +// C Includes +// C++ Includes +#include +#include +#include +#include + +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Expression/ClangExpression.h" + +#include "llvm/ExecutionEngine/JITMemoryManager.h" + +namespace lldb_private +{ + +//---------------------------------------------------------------------- +/// @class ClangUserExpression ClangUserExpression.h "lldb/Expression/ClangUserExpression.h" +/// @brief Encapsulates a single expression for use with Clang +/// +/// LLDB uses expressions for various purposes, notably to call functions +/// and as a backend for the expr command. ClangUserExpression encapsulates +/// the objects needed to parse and interpret or JIT an expression. It +/// uses the Clang parser to produce LLVM IR from the expression. +//---------------------------------------------------------------------- +class ClangUserExpression : public ClangExpression +{ +public: + //------------------------------------------------------------------ + /// Constructor + //------------------------------------------------------------------ + ClangUserExpression (const char *expr); + + //------------------------------------------------------------------ + /// Parse the expression + /// + /// @param[in] error_stream + /// A stream to print parse errors and warnings to. + /// + /// @param[in] exe_ctx + /// The execution context to use when looking up entities that + /// are needed for parsing (locations of functions, types of + /// variables, persistent variables, etc.) + /// + /// @return + /// True on success (no errors); false otherwise. + //------------------------------------------------------------------ + bool + Parse (Stream &error_stream, ExecutionContext &exe_ctx); + + //------------------------------------------------------------------ + /// Execute the parsed expression + /// + /// @param[in] error_stream + /// A stream to print errors to. + /// + /// @param[in] exe_ctx + /// The execution context to use when looking up entities that + /// are needed for parsing (locations of variables, etc.) + /// + /// @param[in] result + /// A pointer to direct at the persistent variable in which the + /// expression's result is stored. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + bool + Execute (Stream &error_stream, + ExecutionContext &exe_ctx, + ClangExpressionVariable *& result); + + //------------------------------------------------------------------ + /// Return the string that the parser should parse. Must be a full + /// translation unit. + //------------------------------------------------------------------ + const char * + Text () + { + return m_transformed_text.c_str(); + } + + //------------------------------------------------------------------ + /// Return the function name that should be used for executing the + /// expression. Text() should contain the definition of this + /// function. + //------------------------------------------------------------------ + const char * + FunctionName () + { + return "___clang_expr"; + } + + //------------------------------------------------------------------ + /// Return the object that the parser should use when resolving external + /// values. May be NULL if everything should be self-contained. + //------------------------------------------------------------------ + ClangExpressionDeclMap * + DeclMap () + { + return m_expr_decl_map.get(); + } + + //------------------------------------------------------------------ + /// Return the object that the parser should use when registering + /// local variables. May be NULL if the Expression doesn't care. + //------------------------------------------------------------------ + ClangExpressionVariableStore * + LocalVariables () + { + return m_local_variables.get(); + } + + //------------------------------------------------------------------ + /// Return the object that the parser should allow to access ASTs. + /// May be NULL if the ASTs do not need to be transformed. + /// + /// @param[in] passthrough + /// The ASTConsumer that the returned transformer should send + /// the ASTs to after transformation. + //------------------------------------------------------------------ + clang::ASTConsumer * + ASTTransformer (clang::ASTConsumer *passthrough); + + //------------------------------------------------------------------ + /// Return the stream that the parser should use to write DWARF + /// opcodes. + //------------------------------------------------------------------ + StreamString & + DwarfOpcodeStream (); + +private: + std::string m_expr_text; ///< The text of the expression, as typed by the user + std::string m_transformed_text; ///< The text of the expression, as send to the parser + + std::auto_ptr m_expr_decl_map; ///< The map to use when parsing and materializing the expression. + std::auto_ptr m_local_variables; ///< The local expression variables, if the expression is DWARF. + std::auto_ptr m_dwarf_opcodes; ///< The DWARF opcodes for the expression. May be NULL. + lldb::addr_t m_jit_addr; ///< The address of the JITted code. LLDB_INVALID_ADDRESS if invalid. +}; + +} // namespace lldb_private + +#endif // liblldb_ClangUserExpression_h_ Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Thu Aug 26 20:01:44 2010 @@ -60,9 +60,13 @@ /// The data layout information for the target. This information is /// used to determine the sizes of types that have been lowered into /// IR types. + /// + /// @param[in] func_name + /// The name of the function to prepare for execution in the target. //------------------------------------------------------------------ IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, - const llvm::TargetData *target_data); + const llvm::TargetData *target_data, + const char* func_name = "___clang_expr"); //------------------------------------------------------------------ /// Destructor @@ -96,7 +100,7 @@ //------------------------------------------------------------------ /// A function-level pass to take the generated global value /// ___clang_expr_result and make it into a persistent variable. - /// Also see ClangResultSynthesizer. + /// Also see ASTResultSynthesizer. //------------------------------------------------------------------ //------------------------------------------------------------------ @@ -294,6 +298,7 @@ bool replaceVariables(llvm::Module &M, llvm::Function &F); + std::string m_func_name; ///< The name of the function to translate lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls const llvm::TargetData *m_target_data; ///< The TargetData for use in determining type sizes llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type Modified: lldb/trunk/include/lldb/Expression/IRToDWARF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRToDWARF.h?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRToDWARF.h (original) +++ lldb/trunk/include/lldb/Expression/IRToDWARF.h Thu Aug 26 20:01:44 2010 @@ -19,7 +19,7 @@ } namespace lldb_private { - class ClangExpressionVariableList; + class ClangExpressionVariableStore; class ClangExpressionDeclMap; class StreamString; } @@ -50,7 +50,7 @@ //------------------------------------------------------------------ /// Constructor /// - /// @param[in] variable_list + /// @param[in] local_vars /// A list of variables to populate with the local variables this /// expression uses. /// @@ -60,10 +60,14 @@ /// /// @param[in] stream /// The stream to dump DWARF bytecode onto. + /// + /// @param[in] func_name + /// The name of the function to translate to DWARF. //------------------------------------------------------------------ - IRToDWARF(lldb_private::ClangExpressionVariableList &variable_list, + IRToDWARF(lldb_private::ClangExpressionVariableStore &local_vars, lldb_private::ClangExpressionDeclMap *decl_map, - lldb_private::StreamString &strm); + lldb_private::StreamString &strm, + const char* func_name = "___clang_expr"); //------------------------------------------------------------------ /// Destructor @@ -108,7 +112,8 @@ //------------------------------------------------------------------ bool runOnBasicBlock(llvm::BasicBlock &BB, Relocator &Relocator); - lldb_private::ClangExpressionVariableList &m_variable_list; ///< The list of local variables to populate while transforming + std::string m_func_name; ///< The name of the function to translate + lldb_private::ClangExpressionVariableStore &m_local_vars; ///< The list of local variables to populate while transforming lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The list of external variables lldb_private::StreamString &m_strm; ///< The stream to write bytecode to }; Modified: lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h (original) +++ lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h Thu Aug 26 20:01:44 2010 @@ -24,6 +24,7 @@ #include "lldb/Core/Log.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" #include "lldb/Expression/ClangExpression.h" +#include "lldb/Expression/ClangExpressionParser.h" namespace lldb_private { @@ -51,7 +52,7 @@ //---------------------------------------------------------------------- class RecordingMemoryManager : public llvm::JITMemoryManager { -friend bool ClangExpression::WriteJITCode (const ExecutionContext &exc_context); +friend Error ClangExpressionParser::MakeJIT (uint64_t &, ExecutionContext &); public: //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/lldb-forward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward.h (original) +++ lldb/trunk/include/lldb/lldb-forward.h Thu Aug 26 20:01:44 2010 @@ -41,6 +41,7 @@ class ClangExpression; class ClangExpressionDeclMap; class ClangExpressionVariableList; +class ClangExpressionVariableStore; class Debugger; class CommandInterpreter; class CommandObject; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Aug 26 20:01:44 2010 @@ -152,7 +152,7 @@ 26D5B0BA11B07550009A862E /* ValueObjectList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E9C10F1B85900F91463 /* ValueObjectList.cpp */; }; 26D5B0BB11B07550009A862E /* ValueObjectVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E9D10F1B85900F91463 /* ValueObjectVariable.cpp */; }; 26D5B0BC11B07550009A862E /* VMRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E9E10F1B85900F91463 /* VMRange.cpp */; }; - 26D5B0BD11B07550009A862E /* ClangExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7ED510F1B86700F91463 /* ClangExpression.cpp */; }; + 26D5B0BD11B07550009A862E /* ClangUserExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7ED510F1B86700F91463 /* ClangUserExpression.cpp */; }; 26D5B0BE11B07550009A862E /* ClangExpressionVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */; }; 26D5B0C111B07550009A862E /* Condition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EE710F1B88F00F91463 /* Condition.cpp */; }; 26D5B0C211B07550009A862E /* Host.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EE810F1B88F00F91463 /* Host.mm */; }; @@ -287,7 +287,6 @@ 26D5B14711B07550009A862E /* ThreadPlanCallFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49EC3E98118F90AC00B1265E /* ThreadPlanCallFunction.cpp */; }; 26D5B14811B07550009A862E /* ClangFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C98D3DA118FB96F00E575D0 /* ClangFunction.cpp */; }; 26D5B14911B07550009A862E /* RecordingMemoryManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C98D3DB118FB96F00E575D0 /* RecordingMemoryManager.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; }; - 26D5B14A11B07550009A862E /* CommandObjectCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C98D3E4118FB9B100E575D0 /* CommandObjectCall.cpp */; }; 26D5B14B11B07550009A862E /* CommandObjectTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 269416AD119A024800FF2715 /* CommandObjectTarget.cpp */; }; 26D5B14C11B07550009A862E /* PathMappingList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 495BBACB119A0DBE00418BEA /* PathMappingList.cpp */; }; 26D5B14D11B07550009A862E /* StringExtractorGDBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2676A093119C93C8008A98EF /* StringExtractorGDBRemote.cpp */; }; @@ -330,10 +329,15 @@ 26F5C32D10F3DFDD009D5894 /* libtermcap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32B10F3DFDD009D5894 /* libtermcap.dylib */; }; 26F5C37510F3F61B009D5894 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C37410F3F61B009D5894 /* libobjc.dylib */; }; 26F5C39110F3FA26009D5894 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C39010F3FA26009D5894 /* CoreFoundation.framework */; }; + 4911934C1226383D00578B7F /* ASTStructExtractor.h in Headers */ = {isa = PBXBuildFile; fileRef = 4911934B1226383D00578B7F /* ASTStructExtractor.h */; }; + 491193521226386000578B7F /* ASTStructExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491193501226386000578B7F /* ASTStructExtractor.cpp */; }; 49307AAE11DEA4D90081F992 /* IRForTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49307AAD11DEA4D90081F992 /* IRForTarget.cpp */; }; 49307AB211DEA4F20081F992 /* IRForTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 49307AB111DEA4F20081F992 /* IRForTarget.h */; }; - 49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */; }; - 49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */; }; + 49445C2612245E3600C11A81 /* ClangExpressionParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49445C2512245E3600C11A81 /* ClangExpressionParser.cpp */; }; + 49445C2A12245E5500C11A81 /* ClangExpressionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 49445C2912245E5500C11A81 /* ClangExpressionParser.h */; }; + 49445E351225AB6A00C11A81 /* ClangUserExpression.h in Headers */ = {isa = PBXBuildFile; fileRef = 49445E341225AB6A00C11A81 /* ClangUserExpression.h */; }; + 49A8A3A011D568A300AD3B68 /* ASTResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ASTResultSynthesizer.cpp */; }; + 49A8A3A411D568BF00AD3B68 /* ASTResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ASTResultSynthesizer.h */; }; 49BB309611F79450001A4197 /* TaggedASTType.h in Headers */ = {isa = PBXBuildFile; fileRef = 49BB309511F79450001A4197 /* TaggedASTType.h */; }; 49D4FE831210B5FB00CDB854 /* ClangPersistentVariables.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */; }; 49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */; }; @@ -792,7 +796,7 @@ 26BC7E9C10F1B85900F91463 /* ValueObjectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectList.cpp; path = source/Core/ValueObjectList.cpp; sourceTree = ""; }; 26BC7E9D10F1B85900F91463 /* ValueObjectVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectVariable.cpp; path = source/Core/ValueObjectVariable.cpp; sourceTree = ""; }; 26BC7E9E10F1B85900F91463 /* VMRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VMRange.cpp; path = source/Core/VMRange.cpp; sourceTree = ""; }; - 26BC7ED510F1B86700F91463 /* ClangExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExpression.cpp; path = source/Expression/ClangExpression.cpp; sourceTree = ""; }; + 26BC7ED510F1B86700F91463 /* ClangUserExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangUserExpression.cpp; path = source/Expression/ClangUserExpression.cpp; sourceTree = ""; }; 26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExpressionVariable.cpp; path = source/Expression/ClangExpressionVariable.cpp; sourceTree = ""; }; 26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DWARFExpression.cpp; path = source/Expression/DWARFExpression.cpp; sourceTree = ""; }; 26BC7EE710F1B88F00F91463 /* Condition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Condition.cpp; path = source/Host/posix/Condition.cpp; sourceTree = ""; }; @@ -902,10 +906,15 @@ 26F996A8119B79C300412154 /* ARM_GCC_Registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARM_GCC_Registers.h; path = source/Utility/ARM_GCC_Registers.h; sourceTree = ""; }; 26FE25221146CADE00F4085A /* GDBRemoteCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GDBRemoteCommunication.cpp; path = "source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp"; sourceTree = ""; }; 26FE25231146CADE00F4085A /* GDBRemoteCommunication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GDBRemoteCommunication.h; path = "source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h"; sourceTree = ""; }; + 4911934B1226383D00578B7F /* ASTStructExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTStructExtractor.h; path = include/lldb/Expression/ASTStructExtractor.h; sourceTree = ""; }; + 491193501226386000578B7F /* ASTStructExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTStructExtractor.cpp; path = source/Expression/ASTStructExtractor.cpp; sourceTree = ""; }; 49307AAD11DEA4D90081F992 /* IRForTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRForTarget.cpp; path = source/Expression/IRForTarget.cpp; sourceTree = ""; }; 49307AB111DEA4F20081F992 /* IRForTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IRForTarget.h; path = include/lldb/Expression/IRForTarget.h; sourceTree = ""; }; 493C63F01189203300914D5E /* ABISysV_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ABISysV_x86_64.h; path = "ABI/SysV-x86_64/ABISysV_x86_64.h"; sourceTree = ""; }; 493C63F11189203300914D5E /* ABISysV_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ABISysV_x86_64.cpp; path = "ABI/SysV-x86_64/ABISysV_x86_64.cpp"; sourceTree = ""; }; + 49445C2512245E3600C11A81 /* ClangExpressionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExpressionParser.cpp; path = source/Expression/ClangExpressionParser.cpp; sourceTree = ""; }; + 49445C2912245E5500C11A81 /* ClangExpressionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExpressionParser.h; path = include/lldb/Expression/ClangExpressionParser.h; sourceTree = ""; }; + 49445E341225AB6A00C11A81 /* ClangUserExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangUserExpression.h; path = include/lldb/Expression/ClangUserExpression.h; sourceTree = ""; }; 495BBACB119A0DBE00418BEA /* PathMappingList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PathMappingList.cpp; path = source/Target/PathMappingList.cpp; sourceTree = ""; }; 495BBACF119A0DE700418BEA /* PathMappingList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PathMappingList.h; path = include/lldb/Target/PathMappingList.h; sourceTree = ""; }; 497650CE11A21BEE008DDB57 /* ABIMacOSX_i386.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ABIMacOSX_i386.cpp; path = "ABI/MacOSX-i386/ABIMacOSX_i386.cpp"; sourceTree = ""; }; @@ -914,8 +923,8 @@ 497E7B9D1188F6690065CCA1 /* ABI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ABI.cpp; path = source/Target/ABI.cpp; sourceTree = ""; }; 499F381E11A5B3F300F5CE02 /* CommandObjectArgs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectArgs.h; path = source/Commands/CommandObjectArgs.h; sourceTree = ""; }; 499F381F11A5B3F300F5CE02 /* CommandObjectArgs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectArgs.cpp; path = source/Commands/CommandObjectArgs.cpp; sourceTree = ""; }; - 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangResultSynthesizer.cpp; path = source/Expression/ClangResultSynthesizer.cpp; sourceTree = ""; }; - 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangResultSynthesizer.h; path = include/lldb/Expression/ClangResultSynthesizer.h; sourceTree = ""; }; + 49A8A39F11D568A300AD3B68 /* ASTResultSynthesizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTResultSynthesizer.cpp; path = source/Expression/ASTResultSynthesizer.cpp; sourceTree = ""; }; + 49A8A3A311D568BF00AD3B68 /* ASTResultSynthesizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTResultSynthesizer.h; path = include/lldb/Expression/ASTResultSynthesizer.h; sourceTree = ""; }; 49BB309511F79450001A4197 /* TaggedASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedASTType.h; path = include/lldb/Symbol/TaggedASTType.h; sourceTree = ""; }; 49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCObjectPrinter.cpp; path = source/Target/ObjCObjectPrinter.cpp; sourceTree = ""; }; 49BF48E011ADF37D008863BD /* ObjCObjectPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCObjectPrinter.h; path = include/lldb/Target/ObjCObjectPrinter.h; sourceTree = ""; }; @@ -1845,19 +1854,24 @@ 49D7072611B5AD03001AD875 /* ClangASTSource.h */, 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */, 26BC7DC010F1B79500F91463 /* ClangExpression.h */, - 26BC7ED510F1B86700F91463 /* ClangExpression.cpp */, + 49445E341225AB6A00C11A81 /* ClangUserExpression.h */, + 26BC7ED510F1B86700F91463 /* ClangUserExpression.cpp */, 4C98D3E0118FB98F00E575D0 /* ClangFunction.h */, 4C98D3DA118FB96F00E575D0 /* ClangFunction.cpp */, 49F1A74911B338AE003ED505 /* ClangExpressionDeclMap.h */, 49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */, + 49445C2912245E5500C11A81 /* ClangExpressionParser.h */, + 49445C2512245E3600C11A81 /* ClangExpressionParser.cpp */, 26BC7DC110F1B79500F91463 /* ClangExpressionVariable.h */, 26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */, 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */, 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */, - 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */, - 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */, 26BC7DC310F1B79500F91463 /* DWARFExpression.h */, 26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */, + 49A8A3A311D568BF00AD3B68 /* ASTResultSynthesizer.h */, + 49A8A39F11D568A300AD3B68 /* ASTResultSynthesizer.cpp */, + 4911934B1226383D00578B7F /* ASTStructExtractor.h */, + 491193501226386000578B7F /* ASTStructExtractor.cpp */, 49307AB111DEA4F20081F992 /* IRForTarget.h */, 49307AAD11DEA4D90081F992 /* IRForTarget.cpp */, 49DA743411DE6BB2006AEF7E /* IRToDWARF.h */, @@ -2215,7 +2229,7 @@ 49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */, 261B5A5511C3F2AD00AABD0A /* SharingPtr.h in Headers */, 4C08CDEC11C81F1E001610A8 /* ThreadSpec.h in Headers */, - 49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */, + 49A8A3A411D568BF00AD3B68 /* ASTResultSynthesizer.h in Headers */, 49DA743511DE6BB2006AEF7E /* IRToDWARF.h in Headers */, 49307AB211DEA4F20081F992 /* IRForTarget.h in Headers */, 4C5DBBC911E3FEC60035160F /* CommandObjectCommands.h in Headers */, @@ -2226,6 +2240,9 @@ 2615DB851208A9C90021781D /* StopInfo.h in Headers */, 2615DBCB1208B5FC0021781D /* StopInfoMachException.h in Headers */, 49D4FE831210B5FB00CDB854 /* ClangPersistentVariables.h in Headers */, + 49445C2A12245E5500C11A81 /* ClangExpressionParser.h in Headers */, + 49445E351225AB6A00C11A81 /* ClangUserExpression.h in Headers */, + 4911934C1226383D00578B7F /* ASTStructExtractor.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2480,7 +2497,7 @@ 26D5B0BA11B07550009A862E /* ValueObjectList.cpp in Sources */, 26D5B0BB11B07550009A862E /* ValueObjectVariable.cpp in Sources */, 26D5B0BC11B07550009A862E /* VMRange.cpp in Sources */, - 26D5B0BD11B07550009A862E /* ClangExpression.cpp in Sources */, + 26D5B0BD11B07550009A862E /* ClangUserExpression.cpp in Sources */, 26D5B0BE11B07550009A862E /* ClangExpressionVariable.cpp in Sources */, 26D5B0C111B07550009A862E /* Condition.cpp in Sources */, 26D5B0C211B07550009A862E /* Host.mm in Sources */, @@ -2615,7 +2632,6 @@ 26D5B14711B07550009A862E /* ThreadPlanCallFunction.cpp in Sources */, 26D5B14811B07550009A862E /* ClangFunction.cpp in Sources */, 26D5B14911B07550009A862E /* RecordingMemoryManager.cpp in Sources */, - 26D5B14A11B07550009A862E /* CommandObjectCall.cpp in Sources */, 26D5B14B11B07550009A862E /* CommandObjectTarget.cpp in Sources */, 26D5B14C11B07550009A862E /* PathMappingList.cpp in Sources */, 26D5B14D11B07550009A862E /* StringExtractorGDBRemote.cpp in Sources */, @@ -2672,7 +2688,7 @@ AF94005911C03F6500085DB9 /* SymbolVendor.cpp in Sources */, 261B5A5411C3F2AD00AABD0A /* SharingPtr.cpp in Sources */, 4C08CDE811C81EF8001610A8 /* ThreadSpec.cpp in Sources */, - 49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */, + 49A8A3A011D568A300AD3B68 /* ASTResultSynthesizer.cpp in Sources */, 49DA743011DE6A5A006AEF7E /* IRToDWARF.cpp in Sources */, 49307AAE11DEA4D90081F992 /* IRForTarget.cpp in Sources */, 4C5DBBC811E3FEC60035160F /* CommandObjectCommands.cpp in Sources */, @@ -2682,6 +2698,8 @@ 2615DBCA1208B5FC0021781D /* StopInfoMachException.cpp in Sources */, 49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */, 49FB515E121481B000DF8983 /* DWARFExpression.cpp in Sources */, + 49445C2612245E3600C11A81 /* ClangExpressionParser.cpp in Sources */, + 491193521226386000578B7F /* ASTStructExtractor.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Modified: lldb/trunk/source/Commands/CommandObjectCall.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCall.cpp?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectCall.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectCall.cpp Thu Aug 26 20:01:44 2010 @@ -263,15 +263,8 @@ ClangFunction::ExecutionResults return_status; Value return_value; - if (m_options.use_abi) - { - return_status = clang_fun.ExecuteFunctionWithABI(exe_ctx, errors, return_value); - } - else - { - bool stop_others = true; - return_status = clang_fun.ExecuteFunction(exe_ctx, errors, stop_others, NULL, return_value); - } + bool stop_others = true; + return_status = clang_fun.ExecuteFunction(exe_ctx, errors, stop_others, NULL, return_value); // Now figure out what to do with the return value. if (return_status == ClangFunction::eExecutionSetupError) Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Aug 26 20:01:44 2010 @@ -16,10 +16,8 @@ #include "lldb/Interpreter/Args.h" #include "lldb/Core/Value.h" #include "lldb/Core/InputReader.h" -#include "lldb/Expression/ClangExpression.h" -#include "lldb/Expression/ClangExpressionDeclMap.h" #include "lldb/Expression/ClangExpressionVariable.h" -#include "lldb/Expression/ClangPersistentVariables.h" +#include "lldb/Expression/ClangUserExpression.h" #include "lldb/Expression/ClangFunction.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Host/Host.h" @@ -192,192 +190,22 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream &output_stream, Stream &error_stream, CommandReturnObject *result) { - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - //////////////////////////////////// - // Set up the target and compiler - // - - Target *target = m_exe_ctx.target; - - if (!target) - { - error_stream.PutCString ("error: invalid target\n"); - return false; - } + ClangUserExpression user_expression (expr); - ConstString target_triple; - - target->GetTargetTriple (target_triple); - - if (!target_triple) - target_triple = Host::GetTargetTriple (); - - if (!target_triple) + if (!user_expression.Parse (error_stream, m_exe_ctx)) { - error_stream.PutCString ("error: invalid target triple\n"); + error_stream.Printf ("Couldn't parse the expresssion"); return false; } - ClangExpressionDeclMap expr_decl_map (&m_exe_ctx); - ClangExpression clang_expr (target_triple.AsCString (), &expr_decl_map); - - ////////////////////////// - // Parse the expression - // - - unsigned num_errors; - - if (bare) - num_errors = clang_expr.ParseBareExpression (llvm::StringRef (expr), error_stream); - else - num_errors = clang_expr.ParseExpression (expr, error_stream, true); - - if (num_errors) - { - error_stream.Printf ("error: %d errors parsing expression\n", num_errors); - return false; - } - - /////////////////////////////////////////////// - // Convert the output of the parser to DWARF - // - - StreamString dwarf_opcodes; - dwarf_opcodes.SetByteOrder (eByteOrderHost); - dwarf_opcodes.GetFlags ().Set (Stream::eBinary); - - ClangExpressionVariableList expr_local_vars; - - bool success; - bool canInterpret = false; - - ClangExpressionVariable *expr_result = 0; - Error expr_error; - - canInterpret = clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes); - - if (canInterpret) - { - if (log) - log->Printf("Code can be interpreted."); - success = true; - } - else - { - if (log) - log->Printf("Code cannot be interpreted and must be run in the target."); - success = clang_expr.PrepareIRForTarget (); - } - - if (!success) - { - error_stream.PutCString ("error: expression couldn't be converted to IR\n"); - return false; - } + ClangExpressionVariable *expr_result; - if (canInterpret) + if (!user_expression.Execute (error_stream, m_exe_ctx, expr_result)) { - // TODO interpret IR + error_stream.Printf ("Couldn't execute the expresssion"); return false; } - else - { - if (!clang_expr.JITFunction ()) - { - error_stream.PutCString ("error: IR could not be JIT compiled\n"); - return false; - } - if (!clang_expr.WriteJITCode (m_exe_ctx)) - { - error_stream.PutCString ("error: JIT code could not be written to the target\n"); - return false; - } - - lldb::addr_t function_address(clang_expr.GetFunctionAddress ()); - - if (function_address == LLDB_INVALID_ADDRESS) - { - error_stream.PutCString ("JIT compiled code's address couldn't be found\n"); - return false; - } - - lldb::addr_t struct_address; - - if (!expr_decl_map.Materialize(&m_exe_ctx, struct_address, expr_error)) - { - error_stream.Printf ("Couldn't materialize struct: %s\n", expr_error.AsCString("unknown error")); - return false; - } - - if (log) - { - log->Printf("Function address : 0x%llx", (uint64_t)function_address); - log->Printf("Structure address : 0x%llx", (uint64_t)struct_address); - - StreamString insns; - - Error err = clang_expr.DisassembleFunction(insns, m_exe_ctx); - - if (!err.Success()) - { - log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error")); - } - else - { - log->Printf("Function disassembly:\n%s", insns.GetData()); - } - - StreamString args; - - if (!expr_decl_map.DumpMaterializedStruct(&m_exe_ctx, args, err)) - { - log->Printf("Couldn't extract variable values : %s", err.AsCString("unknown error")); - } - else - { - log->Printf("Structure contents:\n%s", args.GetData()); - } - } - - ClangFunction::ExecutionResults execution_result = - ClangFunction::ExecuteFunction (m_exe_ctx, function_address, struct_address, true, true, 10000, error_stream); - - if (execution_result != ClangFunction::eExecutionCompleted) - { - const char *result_name; - - switch (execution_result) - { - case ClangFunction::eExecutionCompleted: - result_name = "eExecutionCompleted"; - break; - case ClangFunction::eExecutionDiscarded: - result_name = "eExecutionDiscarded"; - break; - case ClangFunction::eExecutionInterrupted: - result_name = "eExecutionInterrupted"; - break; - case ClangFunction::eExecutionSetupError: - result_name = "eExecutionSetupError"; - break; - case ClangFunction::eExecutionTimedOut: - result_name = "eExecutionTimedOut"; - break; - } - - error_stream.Printf ("Couldn't execute function; result was %s\n", result_name); - return false; - } - - if (!expr_decl_map.Dematerialize(&m_exe_ctx, expr_result, expr_error)) - { - error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error")); - return false; - } - } - if (expr_result) { StreamString ss; Copied: lldb/trunk/source/Expression/ASTResultSynthesizer.cpp (from r112086, lldb/trunk/source/Expression/ClangResultSynthesizer.cpp) URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ASTResultSynthesizer.cpp?p2=lldb/trunk/source/Expression/ASTResultSynthesizer.cpp&p1=lldb/trunk/source/Expression/ClangResultSynthesizer.cpp&r1=112086&r2=112249&rev=112249&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangResultSynthesizer.cpp (original) +++ lldb/trunk/source/Expression/ASTResultSynthesizer.cpp Thu Aug 26 20:01:44 2010 @@ -1,4 +1,4 @@ -//===-- ClangResultSynthesizer.cpp ------------------------------*- C++ -*-===// +//===-- ASTResultSynthesizer.cpp --------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -20,13 +20,13 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" #include "lldb/Core/Log.h" -#include "lldb/Expression/ClangResultSynthesizer.h" +#include "lldb/Expression/ASTResultSynthesizer.h" using namespace llvm; using namespace clang; using namespace lldb_private; -ClangResultSynthesizer::ClangResultSynthesizer(ASTConsumer *passthrough) : +ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough) : m_ast_context (NULL), m_passthrough (passthrough), m_passthrough_sema (NULL), @@ -39,12 +39,12 @@ m_passthrough_sema = dyn_cast(passthrough); } -ClangResultSynthesizer::~ClangResultSynthesizer() +ASTResultSynthesizer::~ASTResultSynthesizer() { } void -ClangResultSynthesizer::Initialize(ASTContext &Context) +ASTResultSynthesizer::Initialize(ASTContext &Context) { m_ast_context = &Context; @@ -53,7 +53,7 @@ } void -ClangResultSynthesizer::TransformTopLevelDecl(Decl* D) +ASTResultSynthesizer::TransformTopLevelDecl(Decl* D) { LinkageSpecDecl *linkage_spec_decl = dyn_cast(D); @@ -81,7 +81,7 @@ } void -ClangResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D) +ASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D) { DeclGroupRef::iterator decl_iterator; @@ -99,7 +99,7 @@ } bool -ClangResultSynthesizer::SynthesizeResult (FunctionDecl *FunDecl) +ASTResultSynthesizer::SynthesizeResult (FunctionDecl *FunDecl) { ASTContext &Ctx(*m_ast_context); @@ -210,42 +210,42 @@ } void -ClangResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx) +ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx) { if (m_passthrough) m_passthrough->HandleTranslationUnit(Ctx); } void -ClangResultSynthesizer::HandleTagDeclDefinition(TagDecl *D) +ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D) { if (m_passthrough) m_passthrough->HandleTagDeclDefinition(D); } void -ClangResultSynthesizer::CompleteTentativeDefinition(VarDecl *D) +ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D) { if (m_passthrough) m_passthrough->CompleteTentativeDefinition(D); } void -ClangResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) +ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) { if (m_passthrough) m_passthrough->HandleVTable(RD, DefinitionRequired); } void -ClangResultSynthesizer::PrintStats() +ASTResultSynthesizer::PrintStats() { if (m_passthrough) m_passthrough->PrintStats(); } void -ClangResultSynthesizer::InitializeSema(Sema &S) +ASTResultSynthesizer::InitializeSema(Sema &S) { m_sema = &S; m_action = reinterpret_cast(m_sema); @@ -255,7 +255,7 @@ } void -ClangResultSynthesizer::ForgetSema() +ASTResultSynthesizer::ForgetSema() { m_sema = NULL; m_action = NULL; Added: lldb/trunk/source/Expression/ASTStructExtractor.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ASTStructExtractor.cpp?rev=112249&view=auto ============================================================================== --- lldb/trunk/source/Expression/ASTStructExtractor.cpp (added) +++ lldb/trunk/source/Expression/ASTStructExtractor.cpp Thu Aug 26 20:01:44 2010 @@ -0,0 +1,191 @@ +//===-- ASTStructExtractor.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "stdlib.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclGroup.h" +#include "clang/AST/Expr.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/Stmt.h" +#include "clang/Parse/Action.h" +#include "clang/Parse/Parser.h" +#include "clang/Parse/Scope.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/raw_ostream.h" +#include "lldb/Core/Log.h" +#include "lldb/Expression/ASTStructExtractor.h" + +using namespace llvm; +using namespace clang; +using namespace lldb_private; + +ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough, + const char *struct_name, + ClangFunction &function) : + m_ast_context (NULL), + m_passthrough (passthrough), + m_passthrough_sema (NULL), + m_sema (NULL), + m_action (NULL), + m_struct_name (struct_name), + m_function (function) +{ + if (!m_passthrough) + return; + + m_passthrough_sema = dyn_cast(passthrough); +} + +ASTStructExtractor::~ASTStructExtractor() +{ +} + +void +ASTStructExtractor::Initialize(ASTContext &Context) +{ + m_ast_context = &Context; + + if (m_passthrough) + m_passthrough->Initialize(Context); +} + +void +ASTStructExtractor::ExtractFromFunctionDecl(FunctionDecl *F) +{ + DeclarationName struct_name(&m_ast_context->Idents.get(m_struct_name.c_str())); + RecordDecl::lookup_result struct_lookup = F->lookup(struct_name); + + if (struct_lookup.first == struct_lookup.second) + return; + + RecordDecl *struct_decl = dyn_cast(*(struct_lookup.first)); + + if (!struct_decl) + return; + + const ASTRecordLayout* struct_layout(&m_ast_context->getASTRecordLayout (struct_decl)); + + if (!struct_layout) + return; + + m_function.m_struct_size = struct_layout->getSize() / 8; // Clang returns sizes in bits. + m_function.m_return_offset = struct_layout->getFieldOffset(struct_layout->getFieldCount() - 1) / 8; + m_function.m_return_size = (struct_layout->getDataSize() / 8) - m_function.m_return_offset; + + for (unsigned field_index = 0, num_fields = struct_layout->getFieldCount(); + field_index < num_fields; + ++field_index) + { + m_function.m_member_offsets.push_back(struct_layout->getFieldOffset(field_index) / 8); + } + + m_function.m_struct_valid = true; +} + +void +ASTStructExtractor::ExtractFromTopLevelDecl(Decl* D) +{ + LinkageSpecDecl *linkage_spec_decl = dyn_cast(D); + + if (linkage_spec_decl) + { + RecordDecl::decl_iterator decl_iterator; + + for (decl_iterator = linkage_spec_decl->decls_begin(); + decl_iterator != linkage_spec_decl->decls_end(); + ++decl_iterator) + { + ExtractFromTopLevelDecl(*decl_iterator); + } + } + + FunctionDecl *function_decl = dyn_cast(D); + + if (m_ast_context && + function_decl && + !m_function.m_wrapper_function_name.compare(function_decl->getNameAsCString())) + { + ExtractFromFunctionDecl(function_decl); + } +} + +void +ASTStructExtractor::HandleTopLevelDecl(DeclGroupRef D) +{ + DeclGroupRef::iterator decl_iterator; + + for (decl_iterator = D.begin(); + decl_iterator != D.end(); + ++decl_iterator) + { + Decl *decl = *decl_iterator; + + ExtractFromTopLevelDecl(decl); + } + + if (m_passthrough) + m_passthrough->HandleTopLevelDecl(D); +} + +void +ASTStructExtractor::HandleTranslationUnit(ASTContext &Ctx) +{ + if (m_passthrough) + m_passthrough->HandleTranslationUnit(Ctx); +} + +void +ASTStructExtractor::HandleTagDeclDefinition(TagDecl *D) +{ + if (m_passthrough) + m_passthrough->HandleTagDeclDefinition(D); +} + +void +ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D) +{ + if (m_passthrough) + m_passthrough->CompleteTentativeDefinition(D); +} + +void +ASTStructExtractor::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) +{ + if (m_passthrough) + m_passthrough->HandleVTable(RD, DefinitionRequired); +} + +void +ASTStructExtractor::PrintStats() +{ + if (m_passthrough) + m_passthrough->PrintStats(); +} + +void +ASTStructExtractor::InitializeSema(Sema &S) +{ + m_sema = &S; + m_action = reinterpret_cast(m_sema); + + if (m_passthrough_sema) + m_passthrough_sema->InitializeSema(S); +} + +void +ASTStructExtractor::ForgetSema() +{ + m_sema = NULL; + m_action = NULL; + + if (m_passthrough_sema) + m_passthrough_sema->ForgetSema(); +} Removed: lldb/trunk/source/Expression/ClangExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=112248&view=auto ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangExpression.cpp (removed) @@ -1,748 +0,0 @@ -//===-- ClangExpression.cpp -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include -#if HAVE_SYS_TYPES_H -# include -#endif - -// C++ Includes -#include -#include -#include - -// Other libraries and framework includes -#include "clang/AST/ASTContext.h" -#include "clang/AST/ExternalASTSource.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Basic/Version.h" -#include "clang/Checker/FrontendActions.h" -#include "clang/CodeGen/CodeGenAction.h" -#include "clang/CodeGen/ModuleBuilder.h" -#include "clang/Driver/CC1Options.h" -#include "clang/Driver/OptTable.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/CompilerInvocation.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Frontend/FrontendPluginRegistry.h" -#include "clang/Frontend/TextDiagnosticBuffer.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Frontend/VerifyDiagnosticsClient.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Rewrite/FrontendActions.h" -#include "clang/Sema/ParseAST.h" -#include "clang/Sema/SemaConsumer.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/JIT.h" -#include "llvm/Module.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/LLVMContext.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/System/DynamicLibrary.h" -#include "llvm/System/Host.h" -#include "llvm/System/Signals.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" - -// Project includes -#include "lldb/Core/Log.h" -#include "lldb/Core/ClangForward.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Disassembler.h" -#include "lldb/Expression/ClangExpression.h" -#include "lldb/Expression/ClangASTSource.h" -#include "lldb/Expression/ClangResultSynthesizer.h" -#include "lldb/Expression/IRForTarget.h" -#include "lldb/Expression/IRToDWARF.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Expression/RecordingMemoryManager.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" - -#include "lldb/Core/StreamString.h" -#include "lldb/Host/Mutex.h" - - -using namespace lldb_private; -using namespace clang; -using namespace llvm; - - -//===----------------------------------------------------------------------===// -// Utility Methods -//===----------------------------------------------------------------------===// - -std::string GetBuiltinIncludePath(const char *Argv0) { - llvm::sys::Path P = - llvm::sys::Path::GetMainExecutable(Argv0, - (void*)(intptr_t) GetBuiltinIncludePath); - - if (!P.isEmpty()) { - P.eraseComponent(); // Remove /clang from foo/bin/clang - P.eraseComponent(); // Remove /bin from foo/bin - - // Get foo/lib/clang//include - P.appendComponent("lib"); - P.appendComponent("clang"); - P.appendComponent(CLANG_VERSION_STRING); - P.appendComponent("include"); - } - - return P.str(); -} - - -//===----------------------------------------------------------------------===// -// Main driver -//===----------------------------------------------------------------------===// - -static void LLVMErrorHandler(void *UserData, const std::string &Message) { - Diagnostic &Diags = *static_cast(UserData); - - Diags.Report(diag::err_fe_error_backend) << Message; - - // We cannot recover from llvm errors. - exit(1); -} - -static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { - using namespace clang::frontend; - - switch (CI.getFrontendOpts().ProgramAction) { - default: - llvm_unreachable("Invalid program action!"); - - case ASTDump: return new ASTDumpAction(); - case ASTPrint: return new ASTPrintAction(); - case ASTPrintXML: return new ASTPrintXMLAction(); - case ASTView: return new ASTViewAction(); - case BoostCon: return new BoostConAction(); - case DumpRawTokens: return new DumpRawTokensAction(); - case DumpTokens: return new DumpTokensAction(); - case EmitAssembly: return new EmitAssemblyAction(); - case EmitBC: return new EmitBCAction(); - case EmitHTML: return new HTMLPrintAction(); - case EmitLLVM: return new EmitLLVMAction(); - case EmitLLVMOnly: return new EmitLLVMOnlyAction(); - case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); - case EmitObj: return new EmitObjAction(); - case FixIt: return new FixItAction(); - case GeneratePCH: return new GeneratePCHAction(); - case GeneratePTH: return new GeneratePTHAction(); - case InheritanceView: return new InheritanceViewAction(); - case InitOnly: return new InitOnlyAction(); - case ParseSyntaxOnly: return new SyntaxOnlyAction(); - - case PluginAction: { - for (FrontendPluginRegistry::iterator it = - FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); - it != ie; ++it) { - if (it->getName() == CI.getFrontendOpts().ActionName) { - llvm::OwningPtr P(it->instantiate()); - if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) - return 0; - return P.take(); - } - } - - CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) - << CI.getFrontendOpts().ActionName; - return 0; - } - - case PrintDeclContext: return new DeclContextPrintAction(); - case PrintPreamble: return new PrintPreambleAction(); - case PrintPreprocessedInput: return new PrintPreprocessedAction(); - case RewriteMacros: return new RewriteMacrosAction(); - case RewriteObjC: return new RewriteObjCAction(); - case RewriteTest: return new RewriteTestAction(); - case RunAnalysis: return new AnalysisAction(); - case RunPreprocessorOnly: return new PreprocessOnlyAction(); - } -} - -static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { - // Create the underlying action. - FrontendAction *Act = CreateFrontendBaseAction(CI); - if (!Act) - return 0; - - // If there are any AST files to merge, create a frontend action - // adaptor to perform the merge. - if (!CI.getFrontendOpts().ASTMergeFiles.empty()) - Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0], - CI.getFrontendOpts().ASTMergeFiles.size()); - - return Act; -} - -//---------------------------------------------------------------------- -// ClangExpression constructor -//---------------------------------------------------------------------- -ClangExpression::ClangExpression(const char *target_triple, - ClangExpressionDeclMap *decl_map) : - m_target_triple (), - m_decl_map (decl_map), - m_clang_ap (), - m_code_generator_ptr (NULL), - m_jit_mm_ptr (NULL), - m_execution_engine (), - m_jitted_functions () -{ - if (target_triple && target_triple[0]) - m_target_triple = target_triple; - else - m_target_triple = llvm::sys::getHostTriple(); -} - - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -ClangExpression::~ClangExpression() -{ - if (m_code_generator_ptr && !m_execution_engine.get()) - delete m_code_generator_ptr; -} - -bool -ClangExpression::CreateCompilerInstance () -{ - // Initialize targets first, so that --version shows registered targets. - static struct InitializeLLVM { - InitializeLLVM() { - llvm::InitializeAllTargets(); - llvm::InitializeAllAsmPrinters(); - } - } InitializeLLVM; - - // 1. Create a new compiler instance. - m_clang_ap.reset(new CompilerInstance()); - m_clang_ap->setLLVMContext(new LLVMContext()); - - // 2. Set options. - - // Parse expressions as Objective C++ regardless of context. - // Our hook into Clang's lookup mechanism only works in C++. - m_clang_ap->getLangOpts().CPlusPlus = true; - m_clang_ap->getLangOpts().ObjC1 = true; - m_clang_ap->getLangOpts().ThreadsafeStatics = false; - m_clang_ap->getLangOpts().AccessControl = false; // Debuggers get universal access - m_clang_ap->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name - - // Set CodeGen options - m_clang_ap->getCodeGenOpts().EmitDeclMetadata = true; - m_clang_ap->getCodeGenOpts().InstrumentFunctions = false; - - // Disable some warnings. - m_clang_ap->getDiagnosticOpts().Warnings.push_back("no-unused-value"); - - // Set the target triple. - m_clang_ap->getTargetOpts().Triple = m_target_triple; - - // 3. Set up various important bits of infrastructure. - - m_clang_ap->createDiagnostics(0, 0); - - // Create the target instance. - m_clang_ap->setTarget(TargetInfo::CreateTargetInfo(m_clang_ap->getDiagnostics(), - m_clang_ap->getTargetOpts())); - if (!m_clang_ap->hasTarget()) - { - m_clang_ap.reset(); - return false; - } - - // Inform the target of the language options - // - // FIXME: We shouldn't need to do this, the target should be immutable once - // created. This complexity should be lifted elsewhere. - m_clang_ap->getTarget().setForcedLangOptions(m_clang_ap->getLangOpts()); - - return m_clang_ap.get(); -} - -Mutex & -ClangExpression::GetClangMutex () -{ - static Mutex g_clang_mutex(Mutex::eMutexTypeRecursive); // Control access to the clang compiler - return g_clang_mutex; -} - - -clang::ASTContext * -ClangExpression::GetASTContext () -{ - CompilerInstance *compiler_instance = GetCompilerInstance(); - if (compiler_instance) - return &compiler_instance->getASTContext(); - return NULL; -} - -unsigned -ClangExpression::ParseExpression (const char *expr_text, - Stream &stream, - bool add_result_var) -{ - // HACK: for now we have to make a function body around our expression - // since there is no way to parse a single expression line in LLVM/Clang. - std::string func_expr("extern \"C\" void ___clang_expr(void *___clang_arg)\n{\n\t"); - func_expr.append(expr_text); - func_expr.append(";\n}"); - return ParseBareExpression (func_expr, stream, add_result_var); - -} - -unsigned -ClangExpression::ParseBareExpression (llvm::StringRef expr_text, - Stream &stream, - bool add_result_var) -{ - Mutex::Locker locker(GetClangMutex ()); - - TextDiagnosticBuffer text_diagnostic_buffer; - - if (!CreateCompilerInstance ()) - { - stream.Printf("error: couldn't create compiler instance\n"); - return 1; - } - - // This code is matched below by a setClient to NULL. - // We cannot return out of this code without doing that. - m_clang_ap->getDiagnostics().setClient(&text_diagnostic_buffer); - text_diagnostic_buffer.FlushDiagnostics (m_clang_ap->getDiagnostics()); - - MemoryBuffer *memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__); - - if (!m_clang_ap->hasSourceManager()) - m_clang_ap->createSourceManager(); - - m_clang_ap->createFileManager(); - m_clang_ap->createPreprocessor(); - - // Build the ASTContext. Most of this we inherit from the - // CompilerInstance, but we also want to give the context - // an ExternalASTSource. - SelectorTable selector_table; - std::auto_ptr builtin_ap(new Builtin::Context(m_clang_ap->getTarget())); - ASTContext *Context = new ASTContext(m_clang_ap->getLangOpts(), - m_clang_ap->getSourceManager(), - m_clang_ap->getTarget(), - m_clang_ap->getPreprocessor().getIdentifierTable(), - selector_table, - *builtin_ap.get(), - 0); - - llvm::OwningPtr ASTSource(new ClangASTSource(*Context, *m_decl_map)); - - if (m_decl_map) - { - Context->setExternalSource(ASTSource); - } - - m_clang_ap->setASTContext(Context); - - FileID memory_buffer_file_id = m_clang_ap->getSourceManager().createMainFileIDForMemBuffer (memory_buffer); - std::string module_name("test_func"); - text_diagnostic_buffer.BeginSourceFile(m_clang_ap->getLangOpts(), &m_clang_ap->getPreprocessor()); - - if (m_code_generator_ptr) - delete m_code_generator_ptr; - - m_code_generator_ptr = CreateLLVMCodeGen(m_clang_ap->getDiagnostics(), - module_name, - m_clang_ap->getCodeGenOpts(), - m_clang_ap->getLLVMContext()); - - - // - CodeGeneration ASTConsumer (include/clang/ModuleBuilder.h), which will be passed in when you call... - // - Call clang::ParseAST (in lib/Sema/ParseAST.cpp) to parse the buffer. The CodeGenerator will generate code for __dbg_expr. - // - Once ParseAST completes, you can grab the llvm::Module from the CodeGenerator, which will have an llvm::Function you can hand off to the JIT. - - if (add_result_var) - { - ClangResultSynthesizer result_synthesizer(m_code_generator_ptr); - ParseAST(m_clang_ap->getPreprocessor(), &result_synthesizer, m_clang_ap->getASTContext()); - } - else - { - ParseAST(m_clang_ap->getPreprocessor(), m_code_generator_ptr, m_clang_ap->getASTContext()); - } - - - text_diagnostic_buffer.EndSourceFile(); - - //compiler_instance->getASTContext().getTranslationUnitDecl()->dump(); - - //if (compiler_instance->getFrontendOpts().ShowStats) { - // compiler_instance->getFileManager().PrintStats(); - // fprintf(stderr, "\n"); - //} - - // This code resolves the setClient above. - m_clang_ap->getDiagnostics().setClient(0); - - TextDiagnosticBuffer::const_iterator diag_iterator; - - int num_errors = 0; - -#ifdef COUNT_WARNINGS_AND_ERRORS - int num_warnings = 0; - - for (diag_iterator = text_diagnostic_buffer.warn_begin(); - diag_iterator != text_diagnostic_buffer.warn_end(); - ++diag_iterator) - num_warnings++; - - for (diag_iterator = text_diagnostic_buffer.err_begin(); - diag_iterator != text_diagnostic_buffer.err_end(); - ++diag_iterator) - num_errors++; - - if (num_warnings || num_errors) - { - if (num_warnings) - stream.Printf("%u warning%s%s", num_warnings, (num_warnings == 1 ? "" : "s"), (num_errors ? " and " : "")); - if (num_errors) - stream.Printf("%u error%s", num_errors, (num_errors == 1 ? "" : "s")); - stream.Printf("\n"); - } -#endif - - for (diag_iterator = text_diagnostic_buffer.warn_begin(); - diag_iterator != text_diagnostic_buffer.warn_end(); - ++diag_iterator) - stream.Printf("warning: %s\n", (*diag_iterator).second.c_str()); - - num_errors = 0; - - for (diag_iterator = text_diagnostic_buffer.err_begin(); - diag_iterator != text_diagnostic_buffer.err_end(); - ++diag_iterator) - { - num_errors++; - stream.Printf("error: %s\n", (*diag_iterator).second.c_str()); - } - - return num_errors; -} - -bool -ClangExpression::ConvertIRToDWARF (ClangExpressionVariableList &expr_local_variable_list, - StreamString &dwarf_opcode_strm) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - llvm::Module *module = m_code_generator_ptr->GetModule(); - - if (!module) - { - if (log) - log->Printf("IR doesn't contain a module"); - - return 1; - } - - IRToDWARF ir_to_dwarf(expr_local_variable_list, m_decl_map, dwarf_opcode_strm); - - return ir_to_dwarf.runOnModule(*module); -} - -bool -ClangExpression::PrepareIRForTarget () -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - llvm::Module *module = m_code_generator_ptr->GetModule(); - - if (!module) - { - if (log) - log->Printf("IR doesn't contain a module"); - - return 1; - } - - llvm::Triple target_triple = m_clang_ap->getTarget().getTriple(); - - std::string err; - - const llvm::Target *target = llvm::TargetRegistry::lookupTarget(m_target_triple, err); - - if (!target) - { - if (log) - log->Printf("Couldn't find a target for %s", m_target_triple.c_str()); - - return 1; - } - - std::auto_ptr target_machine(target->createTargetMachine(m_target_triple, "")); - - IRForTarget ir_for_target(m_decl_map, target_machine->getTargetData()); - - return ir_for_target.runOnModule(*module); -} - -bool -ClangExpression::JITFunction (const char *name) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - llvm::Module *module = m_code_generator_ptr->GetModule(); - - if (module) - { - std::string error; - - if (m_jit_mm_ptr == NULL) - m_jit_mm_ptr = new RecordingMemoryManager(); - - //llvm::InitializeNativeTarget(); - - if (log) - { - const char *relocation_model_string; - - switch (llvm::TargetMachine::getRelocationModel()) - { - case llvm::Reloc::Default: - relocation_model_string = "Default"; - break; - case llvm::Reloc::Static: - relocation_model_string = "Static"; - break; - case llvm::Reloc::PIC_: - relocation_model_string = "PIC_"; - break; - case llvm::Reloc::DynamicNoPIC: - relocation_model_string = "DynamicNoPIC"; - break; - } - - log->Printf("Target machine's relocation model: %s", relocation_model_string); - } - - if (m_execution_engine.get() == 0) - m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, - &error, - m_jit_mm_ptr, - CodeGenOpt::Default, - true, - CodeModel::Small)); // set to small so RIP-relative relocations work in PIC - - m_execution_engine->DisableLazyCompilation(); - llvm::Function *function = module->getFunction (llvm::StringRef (name)); - - // We don't actually need the function pointer here, this just forces it to get resolved. - void *fun_ptr = m_execution_engine->getPointerToFunction(function); - // Note, you probably won't get here on error, since the LLVM JIT tends to just - // exit on error at present... So be careful. - if (fun_ptr == 0) - return false; - m_jitted_functions.push_back(ClangExpression::JittedFunction(name, (lldb::addr_t) fun_ptr)); - - } - return true; -} - -bool -ClangExpression::WriteJITCode (const ExecutionContext &exc_context) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - if (m_jit_mm_ptr == NULL) - return false; - - if (exc_context.process == NULL) - return false; - - // Look over the regions allocated for the function compiled. The JIT - // tries to allocate the functions & stubs close together, so we should try to - // write them that way too... - // For now I only write functions with no stubs, globals, exception tables, - // etc. So I only need to write the functions. - - size_t alloc_size = 0; - std::map::iterator fun_pos, fun_end = m_jit_mm_ptr->m_functions.end(); - for (fun_pos = m_jit_mm_ptr->m_functions.begin(); fun_pos != fun_end; fun_pos++) - { - alloc_size += (*fun_pos).second - (*fun_pos).first; - } - - Error error; - lldb::addr_t target_addr = exc_context.process->AllocateMemory (alloc_size, lldb::ePermissionsReadable|lldb::ePermissionsExecutable, error); - - if (target_addr == LLDB_INVALID_ADDRESS) - return false; - - lldb::addr_t cursor = target_addr; - for (fun_pos = m_jit_mm_ptr->m_functions.begin(); fun_pos != fun_end; fun_pos++) - { - if (log) - log->Printf("Reading [%p-%p] from m_functions", fun_pos->first, fun_pos->second); - - lldb::addr_t lstart = (lldb::addr_t) (*fun_pos).first; - lldb::addr_t lend = (lldb::addr_t) (*fun_pos).second; - size_t size = lend - lstart; - exc_context.process->WriteMemory(cursor, (void *) lstart, size, error); - m_jit_mm_ptr->AddToLocalToRemoteMap (lstart, size, cursor); - cursor += size; - } - - std::vector::iterator pos, end = m_jitted_functions.end(); - - for (pos = m_jitted_functions.begin(); pos != end; pos++) - { - (*pos).m_remote_addr = m_jit_mm_ptr->GetRemoteAddressForLocal ((*pos).m_local_addr); - } - return true; -} - -lldb::addr_t -ClangExpression::GetFunctionAddress (const char *name) -{ - std::vector::iterator pos, end = m_jitted_functions.end(); - - for (pos = m_jitted_functions.begin(); pos < end; pos++) - { - if (strcmp ((*pos).m_name.c_str(), name) == 0) - return (*pos).m_remote_addr; - } - return LLDB_INVALID_ADDRESS; -} - -Error -ClangExpression::DisassembleFunction (Stream &stream, ExecutionContext &exe_ctx, const char *name) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - Error ret; - - ret.Clear(); - - lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS; - lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS; - - std::vector::iterator pos, end = m_jitted_functions.end(); - - for (pos = m_jitted_functions.begin(); pos < end; pos++) - { - if (strcmp(pos->m_name.c_str(), name) == 0) - { - func_local_addr = pos->m_local_addr; - func_remote_addr = pos->m_remote_addr; - } - } - - if (func_local_addr == LLDB_INVALID_ADDRESS) - { - ret.SetErrorToGenericError(); - ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", name); - return ret; - } - - if(log) - log->Printf("Found function, has local address 0x%llx and remote address 0x%llx", (uint64_t)func_local_addr, (uint64_t)func_remote_addr); - - std::pair func_range; - - func_range = m_jit_mm_ptr->GetRemoteRangeForLocal(func_local_addr); - - if (func_range.first == 0 && func_range.second == 0) - { - ret.SetErrorToGenericError(); - ret.SetErrorStringWithFormat("Couldn't find code range for function %s", name); - return ret; - } - - if(log) - log->Printf("Function's code range is [0x%llx-0x%llx]", func_range.first, func_range.second); - - if (!exe_ctx.target) - { - ret.SetErrorToGenericError(); - ret.SetErrorString("Couldn't find the target"); - } - - lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second - func_remote_addr, 0)); - - Error err; - exe_ctx.process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err); - - if (!err.Success()) - { - ret.SetErrorToGenericError(); - ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error")); - return ret; - } - - ArchSpec arch(exe_ctx.target->GetArchitecture()); - - Disassembler *disassembler = Disassembler::FindPlugin(arch); - - if (disassembler == NULL) - { - ret.SetErrorToGenericError(); - ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.AsCString()); - return ret; - } - - if (!exe_ctx.process) - { - ret.SetErrorToGenericError(); - ret.SetErrorString("Couldn't find the process"); - return ret; - } - - DataExtractor extractor(buffer_sp, - exe_ctx.process->GetByteOrder(), - exe_ctx.target->GetArchitecture().GetAddressByteSize()); - - if(log) - { - log->Printf("Function data has contents:"); - extractor.PutToLog (log, - 0, - extractor.GetByteSize(), - func_remote_addr, - 16, - DataExtractor::TypeUInt8); - } - - disassembler->DecodeInstructions(extractor, 0, UINT32_MAX); - - Disassembler::InstructionList &instruction_list = disassembler->GetInstructionList(); - - uint32_t bytes_offset = 0; - - for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize(); - instruction_index < num_instructions; - ++instruction_index) - { - Disassembler::Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index); - Address addr(NULL, func_remote_addr + bytes_offset); - instruction->Dump (&stream, - &addr, - &extractor, - bytes_offset, - exe_ctx, - true); - stream.PutChar('\n'); - bytes_offset += instruction->GetByteSize(); - } - - return ret; -} Added: lldb/trunk/source/Expression/ClangExpressionParser.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=112249&view=auto ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionParser.cpp (added) +++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Thu Aug 26 20:01:44 2010 @@ -0,0 +1,640 @@ +//===-- ClangExpressionParser.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Expression/ClangExpressionParser.h" + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/Stream.h" +#include "lldb/Expression/ClangASTSource.h" +#include "lldb/Expression/ClangExpression.h" +#include "lldb/Expression/IRForTarget.h" +#include "lldb/Expression/IRToDWARF.h" +#include "lldb/Expression/RecordingMemoryManager.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ExternalASTSource.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Version.h" +#include "clang/Checker/FrontendActions.h" +#include "clang/CodeGen/CodeGenAction.h" +#include "clang/CodeGen/ModuleBuilder.h" +#include "clang/Driver/CC1Options.h" +#include "clang/Driver/OptTable.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/FrontendPluginRegistry.h" +#include "clang/Frontend/TextDiagnosticBuffer.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Frontend/VerifyDiagnosticsClient.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Rewrite/FrontendActions.h" +#include "clang/Sema/ParseAST.h" +#include "clang/Sema/SemaConsumer.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/JIT.h" +#include "llvm/Module.h" +#include "llvm/LLVMContext.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/System/DynamicLibrary.h" +#include "llvm/System/Host.h" +#include "llvm/System/Signals.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/Target/TargetSelect.h" + +using namespace clang; +using namespace llvm; +using namespace lldb_private; + +//===----------------------------------------------------------------------===// +// Utility Methods for Clang +//===----------------------------------------------------------------------===// + +std::string GetBuiltinIncludePath(const char *Argv0) { + llvm::sys::Path P = + llvm::sys::Path::GetMainExecutable(Argv0, + (void*)(intptr_t) GetBuiltinIncludePath); + + if (!P.isEmpty()) { + P.eraseComponent(); // Remove /clang from foo/bin/clang + P.eraseComponent(); // Remove /bin from foo/bin + + // Get foo/lib/clang//include + P.appendComponent("lib"); + P.appendComponent("clang"); + P.appendComponent(CLANG_VERSION_STRING); + P.appendComponent("include"); + } + + return P.str(); +} + + +//===----------------------------------------------------------------------===// +// Main driver for Clang +//===----------------------------------------------------------------------===// + +static void LLVMErrorHandler(void *UserData, const std::string &Message) { + Diagnostic &Diags = *static_cast(UserData); + + Diags.Report(diag::err_fe_error_backend) << Message; + + // We cannot recover from llvm errors. + exit(1); +} + +static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { + using namespace clang::frontend; + + switch (CI.getFrontendOpts().ProgramAction) { + default: + llvm_unreachable("Invalid program action!"); + + case ASTDump: return new ASTDumpAction(); + case ASTPrint: return new ASTPrintAction(); + case ASTPrintXML: return new ASTPrintXMLAction(); + case ASTView: return new ASTViewAction(); + case BoostCon: return new BoostConAction(); + case DumpRawTokens: return new DumpRawTokensAction(); + case DumpTokens: return new DumpTokensAction(); + case EmitAssembly: return new EmitAssemblyAction(); + case EmitBC: return new EmitBCAction(); + case EmitHTML: return new HTMLPrintAction(); + case EmitLLVM: return new EmitLLVMAction(); + case EmitLLVMOnly: return new EmitLLVMOnlyAction(); + case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); + case EmitObj: return new EmitObjAction(); + case FixIt: return new FixItAction(); + case GeneratePCH: return new GeneratePCHAction(); + case GeneratePTH: return new GeneratePTHAction(); + case InheritanceView: return new InheritanceViewAction(); + case InitOnly: return new InitOnlyAction(); + case ParseSyntaxOnly: return new SyntaxOnlyAction(); + + case PluginAction: { + for (FrontendPluginRegistry::iterator it = + FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); + it != ie; ++it) { + if (it->getName() == CI.getFrontendOpts().ActionName) { + llvm::OwningPtr P(it->instantiate()); + if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) + return 0; + return P.take(); + } + } + + CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) + << CI.getFrontendOpts().ActionName; + return 0; + } + + case PrintDeclContext: return new DeclContextPrintAction(); + case PrintPreamble: return new PrintPreambleAction(); + case PrintPreprocessedInput: return new PrintPreprocessedAction(); + case RewriteMacros: return new RewriteMacrosAction(); + case RewriteObjC: return new RewriteObjCAction(); + case RewriteTest: return new RewriteTestAction(); + case RunAnalysis: return new AnalysisAction(); + case RunPreprocessorOnly: return new PreprocessOnlyAction(); + } +} + +static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { + // Create the underlying action. + FrontendAction *Act = CreateFrontendBaseAction(CI); + if (!Act) + return 0; + + // If there are any AST files to merge, create a frontend action + // adaptor to perform the merge. + if (!CI.getFrontendOpts().ASTMergeFiles.empty()) + Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0], + CI.getFrontendOpts().ASTMergeFiles.size()); + + return Act; +} + +//===----------------------------------------------------------------------===// +// Implementation of ClangExpressionParser +//===----------------------------------------------------------------------===// + +ClangExpressionParser::ClangExpressionParser(const char *target_triple, + ClangExpression &expr) : + m_expr(expr), + m_target_triple (), + m_compiler (), + m_code_generator (NULL), + m_execution_engine (), + m_jitted_functions () +{ + // Initialize targets first, so that --version shows registered targets. + static struct InitializeLLVM { + InitializeLLVM() { + llvm::InitializeAllTargets(); + llvm::InitializeAllAsmPrinters(); + } + } InitializeLLVM; + + if (target_triple && target_triple[0]) + m_target_triple = target_triple; + else + m_target_triple = llvm::sys::getHostTriple(); + + // 1. Create a new compiler instance. + m_compiler.reset(new CompilerInstance()); + m_compiler->setLLVMContext(new LLVMContext()); + + // 2. Set options. + + // Parse expressions as Objective C++ regardless of context. + // Our hook into Clang's lookup mechanism only works in C++. + m_compiler->getLangOpts().CPlusPlus = true; + m_compiler->getLangOpts().ObjC1 = true; + m_compiler->getLangOpts().ThreadsafeStatics = false; + m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access + m_compiler->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name + + // Set CodeGen options + m_compiler->getCodeGenOpts().EmitDeclMetadata = true; + m_compiler->getCodeGenOpts().InstrumentFunctions = false; + + // Disable some warnings. + m_compiler->getDiagnosticOpts().Warnings.push_back("no-unused-value"); + + // Set the target triple. + m_compiler->getTargetOpts().Triple = m_target_triple; + + // 3. Set up various important bits of infrastructure. + m_compiler->createDiagnostics(0, 0); + + // Create the target instance. + m_compiler->setTarget(TargetInfo::CreateTargetInfo(m_compiler->getDiagnostics(), + m_compiler->getTargetOpts())); + + assert (m_compiler->hasTarget()); + + // Inform the target of the language options + // + // FIXME: We shouldn't need to do this, the target should be immutable once + // created. This complexity should be lifted elsewhere. + m_compiler->getTarget().setForcedLangOptions(m_compiler->getLangOpts()); + + // 4. Set up the diagnostic buffer for reporting errors + + m_diagnostic_buffer.reset(new clang::TextDiagnosticBuffer); + m_compiler->getDiagnostics().setClient(m_diagnostic_buffer.get()); + + // 5. Set up the source management objects inside the compiler + + if (!m_compiler->hasSourceManager()) + m_compiler->createSourceManager(); + + m_compiler->createFileManager(); + m_compiler->createPreprocessor(); + + // 6. Most of this we get from the CompilerInstance, but we + // also want to give the context an ExternalASTSource. + SelectorTable selector_table; + m_builtin_context.reset(new Builtin::Context(m_compiler->getTarget())); + + std::auto_ptr ast_context(new ASTContext(m_compiler->getLangOpts(), + m_compiler->getSourceManager(), + m_compiler->getTarget(), + m_compiler->getPreprocessor().getIdentifierTable(), + selector_table, + *m_builtin_context.get(), + 0)); + + ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); + + if (decl_map) + { + OwningPtr ast_source(new ClangASTSource(*ast_context, *decl_map)); + ast_context->setExternalSource(ast_source); + } + + m_compiler->setASTContext(ast_context.release()); + + std::string module_name("___clang_module"); + + m_code_generator.reset(CreateLLVMCodeGen(m_compiler->getDiagnostics(), + module_name, + m_compiler->getCodeGenOpts(), + m_compiler->getLLVMContext())); +} + +ClangExpressionParser::~ClangExpressionParser() +{ +} + +unsigned +ClangExpressionParser::Parse (Stream &stream) +{ + m_diagnostic_buffer->FlushDiagnostics (m_compiler->getDiagnostics()); + + MemoryBuffer *memory_buffer = MemoryBuffer::getMemBufferCopy(m_expr.Text(), __FUNCTION__); + FileID memory_buffer_file_id = m_compiler->getSourceManager().createMainFileIDForMemBuffer (memory_buffer); + + m_diagnostic_buffer->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor()); + + ASTConsumer *ast_transformer = m_expr.ASTTransformer(m_code_generator.get()); + + if (ast_transformer) + ParseAST(m_compiler->getPreprocessor(), ast_transformer, m_compiler->getASTContext()); + else + ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), m_compiler->getASTContext()); + + m_diagnostic_buffer->EndSourceFile(); + + TextDiagnosticBuffer::const_iterator diag_iterator; + + int num_errors = 0; + + for (diag_iterator = m_diagnostic_buffer->warn_begin(); + diag_iterator != m_diagnostic_buffer->warn_end(); + ++diag_iterator) + stream.Printf("warning: %s\n", (*diag_iterator).second.c_str()); + + num_errors = 0; + + for (diag_iterator = m_diagnostic_buffer->err_begin(); + diag_iterator != m_diagnostic_buffer->err_end(); + ++diag_iterator) + { + num_errors++; + stream.Printf("error: %s\n", (*diag_iterator).second.c_str()); + } + + return num_errors; +} + +Error +ClangExpressionParser::MakeDWARF () +{ + Error err; + + llvm::Module *module = m_code_generator->GetModule(); + + if (!module) + { + err.SetErrorToGenericError(); + err.SetErrorString("IR doesn't contain a module"); + return err; + } + + ClangExpressionVariableStore *local_variables = m_expr.LocalVariables(); + ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); + + if (!local_variables) + { + err.SetErrorToGenericError(); + err.SetErrorString("Can't convert an expression without a VariableList to DWARF"); + return err; + } + + if (!decl_map) + { + err.SetErrorToGenericError(); + err.SetErrorString("Can't convert an expression without a DeclMap to DWARF"); + return err; + } + + IRToDWARF ir_to_dwarf(*local_variables, decl_map, m_expr.DwarfOpcodeStream()); + + if (!ir_to_dwarf.runOnModule(*module)) + { + err.SetErrorToGenericError(); + err.SetErrorString("Couldn't convert the expression to DWARF"); + return err; + } + + err.Clear(); + return err; +} + +Error +ClangExpressionParser::MakeJIT (lldb::addr_t &func_addr, ExecutionContext &exe_ctx) +{ + Error err; + + llvm::Module *module = m_code_generator->ReleaseModule(); + + if (!module) + { + err.SetErrorToGenericError(); + err.SetErrorString("IR doesn't contain a module"); + return err; + } + + ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL + + if (decl_map) + { + std::string target_error; + + const llvm::Target *target = llvm::TargetRegistry::lookupTarget(m_target_triple, target_error); + + if (!target) + { + err.SetErrorToGenericError(); + err.SetErrorStringWithFormat("Couldn't find a target for %s", m_target_triple.c_str()); + return err; + } + + std::auto_ptr target_machine(target->createTargetMachine(m_target_triple, "")); + + IRForTarget ir_for_target(decl_map, target_machine->getTargetData(), m_expr.FunctionName()); + + if (!ir_for_target.runOnModule(*module)) + { + err.SetErrorToGenericError(); + err.SetErrorString("Couldn't convert the expression to DWARF"); + return err; + } + } + + m_jit_mm = new RecordingMemoryManager(); + + std::string error_string; + + m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, + &error_string, + m_jit_mm, + CodeGenOpt::Default, + true, + CodeModel::Small)); + + if (!m_execution_engine.get()) + { + err.SetErrorToGenericError(); + err.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str()); + return err; + } + + m_execution_engine->DisableLazyCompilation(); + + llvm::Function *function = module->getFunction (m_expr.FunctionName()); + + // We don't actually need the function pointer here, this just forces it to get resolved. + + void *fun_ptr = m_execution_engine->getPointerToFunction(function); + + // Errors usually cause failures in the JIT, but if we're lucky we get here. + + if (!fun_ptr) + { + err.SetErrorToGenericError(); + err.SetErrorString("Couldn't JIT the function"); + return err; + } + + m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(m_expr.FunctionName(), (lldb::addr_t)fun_ptr)); + + ExecutionContext &exc_context(exe_ctx); + + if (exc_context.process == NULL) + { + err.SetErrorToGenericError(); + err.SetErrorString("Couldn't write the JIT compiled code into the target because there is no target"); + return err; + } + + // Look over the regions allocated for the function compiled. The JIT + // tries to allocate the functions & stubs close together, so we should try to + // write them that way too... + // For now I only write functions with no stubs, globals, exception tables, + // etc. So I only need to write the functions. + + size_t alloc_size = 0; + + std::map::iterator fun_pos = m_jit_mm->m_functions.begin(); + std::map::iterator fun_end = m_jit_mm->m_functions.end(); + + for (; fun_pos != fun_end; ++fun_pos) + alloc_size += (*fun_pos).second - (*fun_pos).first; + + Error alloc_error; + lldb::addr_t target_addr = exc_context.process->AllocateMemory (alloc_size, lldb::ePermissionsReadable|lldb::ePermissionsExecutable, alloc_error); + + if (target_addr == LLDB_INVALID_ADDRESS) + { + err.SetErrorToGenericError(); + err.SetErrorStringWithFormat("Couldn't allocate memory for the JITted function: %s", alloc_error.AsCString("unknown error")); + return err; + } + + lldb::addr_t cursor = target_addr; + + for (fun_pos = m_jit_mm->m_functions.begin(); fun_pos != fun_end; fun_pos++) + { + lldb::addr_t lstart = (lldb::addr_t) (*fun_pos).first; + lldb::addr_t lend = (lldb::addr_t) (*fun_pos).second; + size_t size = lend - lstart; + + Error write_error; + + if (exc_context.process->WriteMemory(cursor, (void *) lstart, size, write_error) != size) + { + err.SetErrorToGenericError(); + err.SetErrorStringWithFormat("Couldn't copy JITted function into the target: %s", write_error.AsCString("unknown error")); + return err; + } + + m_jit_mm->AddToLocalToRemoteMap (lstart, size, cursor); + cursor += size; + } + + std::vector::iterator pos, end = m_jitted_functions.end(); + + for (pos = m_jitted_functions.begin(); pos != end; pos++) + { + (*pos).m_remote_addr = m_jit_mm->GetRemoteAddressForLocal ((*pos).m_local_addr); + + if (!(*pos).m_name.compare(m_expr.FunctionName())) + func_addr = (*pos).m_remote_addr; + } + + err.Clear(); + return err; +} + +Error +ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &exe_ctx) +{ + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + const char *name = m_expr.FunctionName(); + + Error ret; + + ret.Clear(); + + lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS; + + std::vector::iterator pos, end = m_jitted_functions.end(); + + for (pos = m_jitted_functions.begin(); pos < end; pos++) + { + if (strcmp(pos->m_name.c_str(), name) == 0) + { + func_local_addr = pos->m_local_addr; + func_remote_addr = pos->m_remote_addr; + } + } + + if (func_local_addr == LLDB_INVALID_ADDRESS) + { + ret.SetErrorToGenericError(); + ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", name); + return ret; + } + + if(log) + log->Printf("Found function, has local address 0x%llx and remote address 0x%llx", (uint64_t)func_local_addr, (uint64_t)func_remote_addr); + + std::pair func_range; + + func_range = m_jit_mm->GetRemoteRangeForLocal(func_local_addr); + + if (func_range.first == 0 && func_range.second == 0) + { + ret.SetErrorToGenericError(); + ret.SetErrorStringWithFormat("Couldn't find code range for function %s", name); + return ret; + } + + if(log) + log->Printf("Function's code range is [0x%llx-0x%llx]", func_range.first, func_range.second); + + if (!exe_ctx.target) + { + ret.SetErrorToGenericError(); + ret.SetErrorString("Couldn't find the target"); + } + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second - func_remote_addr, 0)); + + Error err; + exe_ctx.process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err); + + if (!err.Success()) + { + ret.SetErrorToGenericError(); + ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error")); + return ret; + } + + ArchSpec arch(exe_ctx.target->GetArchitecture()); + + Disassembler *disassembler = Disassembler::FindPlugin(arch); + + if (disassembler == NULL) + { + ret.SetErrorToGenericError(); + ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.AsCString()); + return ret; + } + + if (!exe_ctx.process) + { + ret.SetErrorToGenericError(); + ret.SetErrorString("Couldn't find the process"); + return ret; + } + + DataExtractor extractor(buffer_sp, + exe_ctx.process->GetByteOrder(), + exe_ctx.target->GetArchitecture().GetAddressByteSize()); + + if(log) + { + log->Printf("Function data has contents:"); + extractor.PutToLog (log, + 0, + extractor.GetByteSize(), + func_remote_addr, + 16, + DataExtractor::TypeUInt8); + } + + disassembler->DecodeInstructions(extractor, 0, UINT32_MAX); + + Disassembler::InstructionList &instruction_list = disassembler->GetInstructionList(); + + uint32_t bytes_offset = 0; + + for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize(); + instruction_index < num_instructions; + ++instruction_index) + { + Disassembler::Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index); + Address addr(NULL, func_remote_addr + bytes_offset); + instruction->Dump (&stream, + &addr, + &extractor, + bytes_offset, + exe_ctx, + true); + stream.PutChar('\n'); + bytes_offset += instruction->GetByteSize(); + } + + return ret; +} Modified: lldb/trunk/source/Expression/ClangFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangFunction.cpp (original) +++ lldb/trunk/source/Expression/ClangFunction.cpp Thu Aug 26 20:01:44 2010 @@ -22,6 +22,8 @@ #include "llvm/Module.h" // Project includes +#include "lldb/Expression/ASTStructExtractor.h" +#include "lldb/Expression/ClangExpressionParser.h" #include "lldb/Expression/ClangFunction.h" #include "lldb/Symbol/Type.h" #include "lldb/Core/DataExtractor.h" @@ -40,11 +42,12 @@ #include "lldb/Core/Log.h" using namespace lldb_private; + //---------------------------------------------------------------------- // ClangFunction constructor //---------------------------------------------------------------------- ClangFunction::ClangFunction(const char *target_triple, ClangASTContext *ast_context, void *return_qualtype, const Address& functionAddress, const ValueList &arg_value_list) : - ClangExpression (target_triple, NULL), + m_target_triple (target_triple), m_function_ptr (NULL), m_function_addr (functionAddress), m_function_return_qual_type(return_qualtype), @@ -53,18 +56,14 @@ m_wrapper_struct_name ("__lldb_caller_struct"), m_wrapper_function_addr (), m_wrapper_args_addrs (), - m_struct_layout (NULL), m_arg_values (arg_value_list), - m_value_struct_size (0), - m_return_offset(0), - m_return_size (0), m_compiled (false), m_JITted (false) { } ClangFunction::ClangFunction(const char *target_triple, Function &function, ClangASTContext *ast_context, const ValueList &arg_value_list) : - ClangExpression (target_triple, NULL), + m_target_triple (target_triple), m_function_ptr (&function), m_function_addr (), m_function_return_qual_type (), @@ -73,11 +72,7 @@ m_wrapper_struct_name ("__lldb_caller_struct"), m_wrapper_function_addr (), m_wrapper_args_addrs (), - m_struct_layout (NULL), m_arg_values (arg_value_list), - m_value_struct_size (0), - m_return_offset (0), - m_return_size (0), m_compiled (false), m_JITted (false) { @@ -95,154 +90,125 @@ unsigned ClangFunction::CompileFunction (Stream &errors) { + if (m_compiled) + return 0; + // FIXME: How does clang tell us there's no return value? We need to handle that case. unsigned num_errors = 0; - if (!m_compiled) + std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type); + + // Cons up the function we're going to wrap our call in, then compile it... + // We declare the function "extern "C"" because the compiler might be in C++ + // mode which would mangle the name and then we couldn't find it again... + m_wrapper_function_text.clear(); + m_wrapper_function_text.append ("extern \"C\" void "); + m_wrapper_function_text.append (m_wrapper_function_name); + m_wrapper_function_text.append (" (void *input)\n{\n struct "); + m_wrapper_function_text.append (m_wrapper_struct_name); + m_wrapper_function_text.append (" \n {\n"); + m_wrapper_function_text.append (" "); + m_wrapper_function_text.append (return_type_str); + m_wrapper_function_text.append (" (*fn_ptr) ("); + + // Get the number of arguments. If we have a function type and it is prototyped, + // trust that, otherwise use the values we were given. + + // FIXME: This will need to be extended to handle Variadic functions. We'll need + // to pull the defined arguments out of the function, then add the types from the + // arguments list for the variable arguments. + + uint32_t num_args = UINT32_MAX; + bool trust_function = false; + // GetArgumentCount returns -1 for an unprototyped function. + if (m_function_ptr) + { + int num_func_args = m_function_ptr->GetArgumentCount(); + if (num_func_args >= 0) + trust_function = true; + else + num_args = num_func_args; + } + + if (num_args == UINT32_MAX) + num_args = m_arg_values.GetSize(); + + std::string args_buffer; // This one stores the definition of all the args in "struct caller". + std::string args_list_buffer; // This one stores the argument list called from the structure. + for (size_t i = 0; i < num_args; i++) { - std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type); - - // Cons up the function we're going to wrap our call in, then compile it... - // We declare the function "extern "C"" because the compiler might be in C++ - // mode which would mangle the name and then we couldn't find it again... - std::string expression; - expression.append ("extern \"C\" void "); - expression.append (m_wrapper_function_name); - expression.append (" (void *input)\n{\n struct "); - expression.append (m_wrapper_struct_name); - expression.append (" \n {\n"); - expression.append (" "); - expression.append (return_type_str); - expression.append (" (*fn_ptr) ("); - - // Get the number of arguments. If we have a function type and it is prototyped, - // trust that, otherwise use the values we were given. - - // FIXME: This will need to be extended to handle Variadic functions. We'll need - // to pull the defined arguments out of the function, then add the types from the - // arguments list for the variable arguments. - - uint32_t num_args = UINT32_MAX; - bool trust_function = false; - // GetArgumentCount returns -1 for an unprototyped function. - if (m_function_ptr) + const char *type_string; + std::string type_stdstr; + + if (trust_function) { - int num_func_args = m_function_ptr->GetArgumentCount(); - if (num_func_args >= 0) - trust_function = true; - else - num_args = num_func_args; + type_string = m_function_ptr->GetArgumentTypeAtIndex(i).GetName().AsCString(); } - - if (num_args == UINT32_MAX) - num_args = m_arg_values.GetSize(); - - std::string args_buffer; // This one stores the definition of all the args in "struct caller". - std::string args_list_buffer; // This one stores the argument list called from the structure. - for (size_t i = 0; i < num_args; i++) + else { - const char *type_string; - std::string type_stdstr; - - if (trust_function) + Value *arg_value = m_arg_values.GetValueAtIndex(i); + void *clang_qual_type = arg_value->GetOpaqueClangQualType (); + if (clang_qual_type != NULL) { - type_string = m_function_ptr->GetArgumentTypeAtIndex(i).GetName().AsCString(); + type_stdstr = ClangASTContext::GetTypeName(clang_qual_type); + type_string = type_stdstr.c_str(); } else - { - Value *arg_value = m_arg_values.GetValueAtIndex(i); - void *clang_qual_type = arg_value->GetOpaqueClangQualType (); - if (clang_qual_type != NULL) - { - type_stdstr = ClangASTContext::GetTypeName(clang_qual_type); - type_string = type_stdstr.c_str(); - } - else - { - errors.Printf("Could not determine type of input value %d.", i); - return 1; - } + { + errors.Printf("Could not determine type of input value %d.", i); + return 1; } - - - expression.append (type_string); - if (i < num_args - 1) - expression.append (", "); - - char arg_buf[32]; - args_buffer.append (" "); - args_buffer.append (type_string); - snprintf(arg_buf, 31, "arg_%zd", i); - args_buffer.push_back (' '); - args_buffer.append (arg_buf); - args_buffer.append (";\n"); - - args_list_buffer.append ("__lldb_fn_data->"); - args_list_buffer.append (arg_buf); - if (i < num_args - 1) - args_list_buffer.append (", "); - } - expression.append (");\n"); // Close off the function calling prototype. - expression.append (args_buffer); + m_wrapper_function_text.append (type_string); + if (i < num_args - 1) + m_wrapper_function_text.append (", "); + + char arg_buf[32]; + args_buffer.append (" "); + args_buffer.append (type_string); + snprintf(arg_buf, 31, "arg_%zd", i); + args_buffer.push_back (' '); + args_buffer.append (arg_buf); + args_buffer.append (";\n"); + + args_list_buffer.append ("__lldb_fn_data->"); + args_list_buffer.append (arg_buf); + if (i < num_args - 1) + args_list_buffer.append (", "); + + } + m_wrapper_function_text.append (");\n"); // Close off the function calling prototype. + + m_wrapper_function_text.append (args_buffer); + + m_wrapper_function_text.append (" "); + m_wrapper_function_text.append (return_type_str); + m_wrapper_function_text.append (" return_value;"); + m_wrapper_function_text.append ("\n };\n struct "); + m_wrapper_function_text.append (m_wrapper_struct_name); + m_wrapper_function_text.append ("* __lldb_fn_data = (struct "); + m_wrapper_function_text.append (m_wrapper_struct_name); + m_wrapper_function_text.append (" *) input;\n"); + + m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr ("); + m_wrapper_function_text.append (args_list_buffer); + m_wrapper_function_text.append (");\n}\n"); - expression.append (" "); - expression.append (return_type_str); - expression.append (" return_value;"); - expression.append ("\n };\n struct "); - expression.append (m_wrapper_struct_name); - expression.append ("* __lldb_fn_data = (struct "); - expression.append (m_wrapper_struct_name); - expression.append (" *) input;\n"); - - expression.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr ("); - expression.append (args_list_buffer); - expression.append (");\n}\n"); - - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); - if (log) - log->Printf ("Expression: \n\n%s\n\n", expression.c_str()); - - // Okay, now compile this expression: - num_errors = ParseBareExpression (expression.c_str(), errors); - m_compiled = (num_errors == 0); + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); + if (log) + log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); - if (m_compiled) - { - using namespace clang; - CompilerInstance *compiler_instance = GetCompilerInstance(); - ASTContext &ast_context = compiler_instance->getASTContext(); - - DeclarationName wrapper_func_name(&ast_context.Idents.get(m_wrapper_function_name.c_str())); - FunctionDecl::lookup_result func_lookup = ast_context.getTranslationUnitDecl()->lookup(wrapper_func_name); - if (func_lookup.first == func_lookup.second) - return false; - - FunctionDecl *wrapper_func = dyn_cast (*(func_lookup.first)); - if (!wrapper_func) - return false; - - DeclarationName wrapper_struct_name(&ast_context.Idents.get(m_wrapper_struct_name.c_str())); - RecordDecl::lookup_result struct_lookup = wrapper_func->lookup(wrapper_struct_name); - if (struct_lookup.first == struct_lookup.second) - return false; - - RecordDecl *wrapper_struct = dyn_cast(*(struct_lookup.first)); - - if (!wrapper_struct) - return false; - - m_struct_layout = &ast_context.getASTRecordLayout (wrapper_struct); - if (!m_struct_layout) - { - m_compiled = false; - return 1; - } - m_return_offset = m_struct_layout->getFieldOffset(m_struct_layout->getFieldCount() - 1); - m_return_size = (m_struct_layout->getDataSize() - m_return_offset)/8; - } - } + // Okay, now compile this expression + + m_parser.reset(new ClangExpressionParser(m_target_triple.c_str(), *this)); + + num_errors = m_parser->Parse (errors); + + m_compiled = (num_errors == 0); + + if (!m_compiled) + return num_errors; return num_errors; } @@ -252,24 +218,18 @@ { Process *process = exe_ctx.process; - if (process == NULL) + if (!process) + return false; + + if (!m_compiled) return false; - if (!m_JITted) - { - // Next we should JIT it and insert the result into the target program. - if (!JITFunction (m_wrapper_function_name.c_str())) - return false; - - if (!WriteJITCode (exe_ctx)) - return false; - - m_JITted = true; - } - - // Next get the call address for the function: - m_wrapper_function_addr = GetFunctionAddress (m_wrapper_function_name.c_str()); - if (m_wrapper_function_addr == LLDB_INVALID_ADDRESS) + if (m_JITted) + return true; + + Error jit_error = m_parser->MakeJIT(m_wrapper_function_addr, exe_ctx); + + if (!jit_error.Success()) return false; return true; @@ -286,12 +246,14 @@ bool ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors) { - // Otherwise, allocate space for the argument passing struct, and write it. - // We use the information in the expression parser AST to - // figure out how to do this... - // We should probably transcode this in this object so we can ditch the compiler instance - // and all its associated data, and just keep the JITTed bytes. - + // All the information to reconstruct the struct is provided by the + // StructExtractor. + if (!m_struct_valid) + { + errors.Printf("Argument information was not correctly parsed, so the function cannot be called."); + return false; + } + Error error; using namespace clang; ExecutionResults return_value = eExecutionSetupError; @@ -300,12 +262,10 @@ if (process == NULL) return return_value; - - uint64_t struct_size = m_struct_layout->getSize()/8; // Clang returns sizes in bytes. - + if (args_addr_ref == LLDB_INVALID_ADDRESS) { - args_addr_ref = process->AllocateMemory(struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error); + args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error); if (args_addr_ref == LLDB_INVALID_ADDRESS) return false; m_wrapper_args_addrs.push_back (args_addr_ref); @@ -323,7 +283,7 @@ // Make a data extractor and put the address into the right byte order & size. uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.process); - int first_offset = m_struct_layout->getFieldOffset(0)/8; + int first_offset = m_member_offsets[0]; process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error); // FIXME: We will need to extend this for Variadic functions. @@ -341,7 +301,7 @@ { // FIXME: We should sanity check sizes. - int offset = m_struct_layout->getFieldOffset(i+1)/8; // Clang sizes are in bytes. + int offset = m_member_offsets[i+1]; // Clang sizes are in bytes. Value *arg_value = arg_values.GetValueAtIndex(i); // FIXME: For now just do scalars: @@ -419,7 +379,7 @@ data_buffer.resize(m_return_size); Process *process = exe_ctx.process; Error error; - size_t bytes_read = process->ReadMemory(args_addr + m_return_offset/8, &data_buffer.front(), m_return_size, error); + size_t bytes_read = process->ReadMemory(args_addr + m_return_offset, &data_buffer.front(), m_return_size, error); if (bytes_read == 0) { @@ -717,69 +677,8 @@ return eExecutionCompleted; } -ClangFunction::ExecutionResults -ClangFunction::ExecuteFunctionWithABI(ExecutionContext &exe_ctx, Stream &errors, Value &results) +clang::ASTConsumer * +ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough) { - // FIXME: Use the errors Stream for better error reporting. - using namespace clang; - ExecutionResults return_value = eExecutionSetupError; - - Process *process = exe_ctx.process; - - if (process == NULL) - { - errors.Printf("Can't call a function without a process."); - return return_value; - } - - //unsigned int num_args = m_arg_values.GetSize(); - //unsigned int arg_index; - - //for (arg_index = 0; arg_index < num_args; ++arg_index) - // m_arg_values.GetValueAtIndex(arg_index)->ResolveValue(&exe_ctx, GetASTContext()); - - ThreadPlan *call_plan = exe_ctx.thread->QueueThreadPlanForCallFunction (false, - m_function_addr, - m_arg_values, - true); - if (call_plan == NULL) - return return_value; - - call_plan->SetPrivate(true); - - // We need to call the function synchronously, so spin waiting for it to return. - // If we get interrupted while executing, we're going to lose our context, and - // won't be able to gather the result at this point. - - process->Resume (); - - while (1) - { - lldb::EventSP event_sp; - - // Now wait for the process to stop again: - // FIXME: Probably want a time out. - lldb::StateType stop_state = process->WaitForStateChangedEvents (NULL, event_sp); - if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping) - continue; - - if (exe_ctx.thread->IsThreadPlanDone (call_plan)) - { - return_value = eExecutionCompleted; - break; - } - else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan)) - { - return_value = eExecutionDiscarded; - break; - } - else - { - return_value = eExecutionInterrupted; - break; - } - - } - - return eExecutionCompleted; + return new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this); } Removed: lldb/trunk/source/Expression/ClangResultSynthesizer.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangResultSynthesizer.cpp?rev=112248&view=auto ============================================================================== --- lldb/trunk/source/Expression/ClangResultSynthesizer.cpp (original) +++ lldb/trunk/source/Expression/ClangResultSynthesizer.cpp (removed) @@ -1,265 +0,0 @@ -//===-- ClangResultSynthesizer.cpp ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "stdlib.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclGroup.h" -#include "clang/AST/Expr.h" -#include "clang/AST/Stmt.h" -#include "clang/Parse/Action.h" -#include "clang/Parse/Parser.h" -#include "clang/Parse/Scope.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/raw_ostream.h" -#include "lldb/Core/Log.h" -#include "lldb/Expression/ClangResultSynthesizer.h" - -using namespace llvm; -using namespace clang; -using namespace lldb_private; - -ClangResultSynthesizer::ClangResultSynthesizer(ASTConsumer *passthrough) : - m_ast_context (NULL), - m_passthrough (passthrough), - m_passthrough_sema (NULL), - m_sema (NULL), - m_action (NULL) -{ - if (!m_passthrough) - return; - - m_passthrough_sema = dyn_cast(passthrough); -} - -ClangResultSynthesizer::~ClangResultSynthesizer() -{ -} - -void -ClangResultSynthesizer::Initialize(ASTContext &Context) -{ - m_ast_context = &Context; - - if (m_passthrough) - m_passthrough->Initialize(Context); -} - -void -ClangResultSynthesizer::TransformTopLevelDecl(Decl* D) -{ - LinkageSpecDecl *linkage_spec_decl = dyn_cast(D); - - if (linkage_spec_decl) - { - RecordDecl::decl_iterator decl_iterator; - - for (decl_iterator = linkage_spec_decl->decls_begin(); - decl_iterator != linkage_spec_decl->decls_end(); - ++decl_iterator) - { - TransformTopLevelDecl(*decl_iterator); - } - } - - FunctionDecl *function_decl = dyn_cast(D); - - if (m_ast_context && - function_decl && - !strcmp(function_decl->getNameAsCString(), - "___clang_expr")) - { - SynthesizeResult(function_decl); - } -} - -void -ClangResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D) -{ - DeclGroupRef::iterator decl_iterator; - - for (decl_iterator = D.begin(); - decl_iterator != D.end(); - ++decl_iterator) - { - Decl *decl = *decl_iterator; - - TransformTopLevelDecl(decl); - } - - if (m_passthrough) - m_passthrough->HandleTopLevelDecl(D); -} - -bool -ClangResultSynthesizer::SynthesizeResult (FunctionDecl *FunDecl) -{ - ASTContext &Ctx(*m_ast_context); - - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - if (!m_sema) - return false; - - FunctionDecl *function_decl = FunDecl; - - if (!function_decl) - return false; - - Stmt *function_body = function_decl->getBody(); - CompoundStmt *compound_stmt = dyn_cast(function_body); - - if (!compound_stmt) - return false; - - if (compound_stmt->body_empty()) - return false; - - Stmt **last_stmt_ptr = compound_stmt->body_end() - 1; - Stmt *last_stmt = *last_stmt_ptr; - - Expr *last_expr = dyn_cast(last_stmt); - - if (!last_expr) - // No auxiliary variable necessary; expression returns void - return true; - - QualType expr_qual_type = last_expr->getType(); - clang::Type *expr_type = expr_qual_type.getTypePtr(); - - if (!expr_type) - return false; - - if (expr_type->isVoidType()) - return true; - - if (log) - { - std::string s = expr_qual_type.getAsString(); - - log->Printf("Last statement's type: %s", s.c_str()); - } - - IdentifierInfo &result_id = Ctx.Idents.get("___clang_expr_result"); - - clang::VarDecl *result_decl = VarDecl::Create(Ctx, - function_decl, - SourceLocation(), - &result_id, - expr_qual_type, - NULL, - VarDecl::Static, - VarDecl::Static); - - if (!result_decl) - return false; - - function_decl->addDecl(result_decl); - - /////////////////////////////// - // call AddInitializerToDecl - // - - Parser::DeclPtrTy result_decl_ptr; - result_decl_ptr.set(result_decl); - - m_action->AddInitializerToDecl(result_decl_ptr, Parser::ExprArg(*m_action, last_expr)); - - ///////////////////////////////// - // call ConvertDeclToDeclGroup - // - - Parser::DeclGroupPtrTy result_decl_group_ptr; - - result_decl_group_ptr = m_action->ConvertDeclToDeclGroup(result_decl_ptr); - - //////////////////////// - // call ActOnDeclStmt - // - - Parser::OwningStmtResult result_initialization_stmt_result(m_action->ActOnDeclStmt(result_decl_group_ptr, - SourceLocation(), - SourceLocation())); - - //////////////////////////////////////////////// - // replace the old statement with the new one - // - - *last_stmt_ptr = reinterpret_cast(result_initialization_stmt_result.take()); - - if (log) - { - std::string s; - raw_string_ostream os(s); - - function_decl->print(os); - - os.flush(); - - log->Printf("Transformed function AST:\n%s", s.c_str()); - } - - return true; -} - -void -ClangResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx) -{ - if (m_passthrough) - m_passthrough->HandleTranslationUnit(Ctx); -} - -void -ClangResultSynthesizer::HandleTagDeclDefinition(TagDecl *D) -{ - if (m_passthrough) - m_passthrough->HandleTagDeclDefinition(D); -} - -void -ClangResultSynthesizer::CompleteTentativeDefinition(VarDecl *D) -{ - if (m_passthrough) - m_passthrough->CompleteTentativeDefinition(D); -} - -void -ClangResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) -{ - if (m_passthrough) - m_passthrough->HandleVTable(RD, DefinitionRequired); -} - -void -ClangResultSynthesizer::PrintStats() -{ - if (m_passthrough) - m_passthrough->PrintStats(); -} - -void -ClangResultSynthesizer::InitializeSema(Sema &S) -{ - m_sema = &S; - m_action = reinterpret_cast(m_sema); - - if (m_passthrough_sema) - m_passthrough_sema->InitializeSema(S); -} - -void -ClangResultSynthesizer::ForgetSema() -{ - m_sema = NULL; - m_action = NULL; - - if (m_passthrough_sema) - m_passthrough_sema->ForgetSema(); -} Copied: lldb/trunk/source/Expression/ClangUserExpression.cpp (from r111952, lldb/trunk/source/Expression/ClangExpression.cpp) URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?p2=lldb/trunk/source/Expression/ClangUserExpression.cpp&p1=lldb/trunk/source/Expression/ClangExpression.cpp&r1=111952&r2=112249&rev=112249&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangUserExpression.cpp Thu Aug 26 20:01:44 2010 @@ -1,4 +1,4 @@ -//===-- ClangExpression.cpp -------------------------------------*- C++ -*-===// +//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,731 +18,240 @@ #include #include -// Other libraries and framework includes -#include "clang/AST/ASTContext.h" -#include "clang/AST/ExternalASTSource.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Basic/Version.h" -#include "clang/Checker/FrontendActions.h" -#include "clang/CodeGen/CodeGenAction.h" -#include "clang/CodeGen/ModuleBuilder.h" -#include "clang/Driver/CC1Options.h" -#include "clang/Driver/OptTable.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/CompilerInvocation.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Frontend/FrontendPluginRegistry.h" -#include "clang/Frontend/TextDiagnosticBuffer.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Frontend/VerifyDiagnosticsClient.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Rewrite/FrontendActions.h" -#include "clang/Sema/ParseAST.h" -#include "clang/Sema/SemaConsumer.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/JIT.h" -#include "llvm/Module.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/LLVMContext.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/System/DynamicLibrary.h" -#include "llvm/System/Host.h" -#include "llvm/System/Signals.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" - -// Project includes +#include "lldb/Core/ConstString.h" #include "lldb/Core/Log.h" -#include "lldb/Core/ClangForward.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Disassembler.h" -#include "lldb/Expression/ClangExpression.h" -#include "lldb/Expression/ClangASTSource.h" -#include "lldb/Expression/ClangResultSynthesizer.h" -#include "lldb/Expression/IRForTarget.h" -#include "lldb/Expression/IRToDWARF.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Expression/RecordingMemoryManager.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Expression/ClangExpressionDeclMap.h" +#include "lldb/Expression/ClangExpressionParser.h" +#include "lldb/Expression/ClangFunction.h" +#include "lldb/Expression/ASTResultSynthesizer.h" +#include "lldb/Expression/ClangUserExpression.h" +#include "lldb/Host/Host.h" #include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" #include "lldb/Target/Target.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/Mutex.h" - - using namespace lldb_private; -using namespace clang; -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Utility Methods -//===----------------------------------------------------------------------===// - -std::string GetBuiltinIncludePath(const char *Argv0) { - llvm::sys::Path P = - llvm::sys::Path::GetMainExecutable(Argv0, - (void*)(intptr_t) GetBuiltinIncludePath); - - if (!P.isEmpty()) { - P.eraseComponent(); // Remove /clang from foo/bin/clang - P.eraseComponent(); // Remove /bin from foo/bin - - // Get foo/lib/clang//include - P.appendComponent("lib"); - P.appendComponent("clang"); - P.appendComponent(CLANG_VERSION_STRING); - P.appendComponent("include"); - } - - return P.str(); -} - - -//===----------------------------------------------------------------------===// -// Main driver -//===----------------------------------------------------------------------===// - -static void LLVMErrorHandler(void *UserData, const std::string &Message) { - Diagnostic &Diags = *static_cast(UserData); - - Diags.Report(diag::err_fe_error_backend) << Message; - - // We cannot recover from llvm errors. - exit(1); -} - -static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { - using namespace clang::frontend; - - switch (CI.getFrontendOpts().ProgramAction) { - default: - llvm_unreachable("Invalid program action!"); - - case ASTDump: return new ASTDumpAction(); - case ASTPrint: return new ASTPrintAction(); - case ASTPrintXML: return new ASTPrintXMLAction(); - case ASTView: return new ASTViewAction(); - case BoostCon: return new BoostConAction(); - case DumpRawTokens: return new DumpRawTokensAction(); - case DumpTokens: return new DumpTokensAction(); - case EmitAssembly: return new EmitAssemblyAction(); - case EmitBC: return new EmitBCAction(); - case EmitHTML: return new HTMLPrintAction(); - case EmitLLVM: return new EmitLLVMAction(); - case EmitLLVMOnly: return new EmitLLVMOnlyAction(); - case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); - case EmitObj: return new EmitObjAction(); - case FixIt: return new FixItAction(); - case GeneratePCH: return new GeneratePCHAction(); - case GeneratePTH: return new GeneratePTHAction(); - case InheritanceView: return new InheritanceViewAction(); - case InitOnly: return new InitOnlyAction(); - case ParseSyntaxOnly: return new SyntaxOnlyAction(); - - case PluginAction: { - for (FrontendPluginRegistry::iterator it = - FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); - it != ie; ++it) { - if (it->getName() == CI.getFrontendOpts().ActionName) { - llvm::OwningPtr P(it->instantiate()); - if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) - return 0; - return P.take(); - } - } - - CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) - << CI.getFrontendOpts().ActionName; - return 0; - } - - case PrintDeclContext: return new DeclContextPrintAction(); - case PrintPreamble: return new PrintPreambleAction(); - case PrintPreprocessedInput: return new PrintPreprocessedAction(); - case RewriteMacros: return new RewriteMacrosAction(); - case RewriteObjC: return new RewriteObjCAction(); - case RewriteTest: return new RewriteTestAction(); - case RunAnalysis: return new AnalysisAction(); - case RunPreprocessorOnly: return new PreprocessOnlyAction(); - } -} - -static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { - // Create the underlying action. - FrontendAction *Act = CreateFrontendBaseAction(CI); - if (!Act) - return 0; - - // If there are any AST files to merge, create a frontend action - // adaptor to perform the merge. - if (!CI.getFrontendOpts().ASTMergeFiles.empty()) - Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0], - CI.getFrontendOpts().ASTMergeFiles.size()); - - return Act; -} - -//---------------------------------------------------------------------- -// ClangExpression constructor -//---------------------------------------------------------------------- -ClangExpression::ClangExpression(const char *target_triple, - ClangExpressionDeclMap *decl_map) : - m_target_triple (), - m_decl_map (decl_map), - m_clang_ap (), - m_code_generator_ptr (NULL), - m_jit_mm_ptr (NULL), - m_execution_engine (), - m_jitted_functions () +ClangUserExpression::ClangUserExpression (const char *expr) : + m_expr_text(expr), + m_jit_addr(LLDB_INVALID_ADDRESS) { - if (target_triple && target_triple[0]) - m_target_triple = target_triple; - else - m_target_triple = llvm::sys::getHostTriple(); + StreamString m_transformed_stream; + + m_transformed_stream.Printf("extern \"C\" void %s(void *___clang_arg) { %s; }\n", + FunctionName(), + m_expr_text.c_str()); + + m_transformed_text = m_transformed_stream.GetData(); } - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -ClangExpression::~ClangExpression() +clang::ASTConsumer * +ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough) { - if (m_code_generator_ptr && !m_execution_engine.get()) - delete m_code_generator_ptr; + return new ASTResultSynthesizer(passthrough); } -bool -ClangExpression::CreateCompilerInstance () +bool +ClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx) { - // Initialize targets first, so that --version shows registered targets. - static struct InitializeLLVM { - InitializeLLVM() { - llvm::InitializeAllTargets(); - llvm::InitializeAllAsmPrinters(); - } - } InitializeLLVM; - - // 1. Create a new compiler instance. - m_clang_ap.reset(new CompilerInstance()); - m_clang_ap->setLLVMContext(new LLVMContext()); - - // 2. Set options. - - // Parse expressions as Objective C++ regardless of context. - // Our hook into Clang's lookup mechanism only works in C++. - m_clang_ap->getLangOpts().CPlusPlus = true; - m_clang_ap->getLangOpts().ObjC1 = true; - m_clang_ap->getLangOpts().ThreadsafeStatics = false; - m_clang_ap->getLangOpts().AccessControl = false; // Debuggers get universal access - m_clang_ap->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name - - // Set CodeGen options - m_clang_ap->getCodeGenOpts().EmitDeclMetadata = true; - m_clang_ap->getCodeGenOpts().InstrumentFunctions = false; - - // Disable some warnings. - m_clang_ap->getDiagnosticOpts().Warnings.push_back("no-unused-value"); + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - // Set the target triple. - m_clang_ap->getTargetOpts().Triple = m_target_triple; + //////////////////////////////////// + // Set up the target and compiler + // - // 3. Set up various important bits of infrastructure. + Target *target = exe_ctx.target; - m_clang_ap->createDiagnostics(0, 0); - - // Create the target instance. - m_clang_ap->setTarget(TargetInfo::CreateTargetInfo(m_clang_ap->getDiagnostics(), - m_clang_ap->getTargetOpts())); - if (!m_clang_ap->hasTarget()) + if (!target) { - m_clang_ap.reset(); + error_stream.PutCString ("error: invalid target\n"); return false; } - - // Inform the target of the language options - // - // FIXME: We shouldn't need to do this, the target should be immutable once - // created. This complexity should be lifted elsewhere. - m_clang_ap->getTarget().setForcedLangOptions(m_clang_ap->getLangOpts()); - - return m_clang_ap.get(); -} - -Mutex & -ClangExpression::GetClangMutex () -{ - static Mutex g_clang_mutex(Mutex::eMutexTypeRecursive); // Control access to the clang compiler - return g_clang_mutex; -} - - -clang::ASTContext * -ClangExpression::GetASTContext () -{ - CompilerInstance *compiler_instance = GetCompilerInstance(); - if (compiler_instance) - return &compiler_instance->getASTContext(); - return NULL; -} - -unsigned -ClangExpression::ParseExpression (const char *expr_text, - Stream &stream, - bool add_result_var) -{ - // HACK: for now we have to make a function body around our expression - // since there is no way to parse a single expression line in LLVM/Clang. - std::string func_expr("extern \"C\" void ___clang_expr(void *___clang_arg)\n{\n\t"); - func_expr.append(expr_text); - func_expr.append(";\n}"); - return ParseBareExpression (func_expr, stream, add_result_var); - -} - -unsigned -ClangExpression::ParseBareExpression (llvm::StringRef expr_text, - Stream &stream, - bool add_result_var) -{ - Mutex::Locker locker(GetClangMutex ()); - - TextDiagnosticBuffer text_diagnostic_buffer; - - if (!CreateCompilerInstance ()) - { - stream.Printf("error: couldn't create compiler instance\n"); - return 1; - } - // This code is matched below by a setClient to NULL. - // We cannot return out of this code without doing that. - m_clang_ap->getDiagnostics().setClient(&text_diagnostic_buffer); - text_diagnostic_buffer.FlushDiagnostics (m_clang_ap->getDiagnostics()); - - MemoryBuffer *memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__); - - if (!m_clang_ap->hasSourceManager()) - m_clang_ap->createSourceManager(); - - m_clang_ap->createFileManager(); - m_clang_ap->createPreprocessor(); - - // Build the ASTContext. Most of this we inherit from the - // CompilerInstance, but we also want to give the context - // an ExternalASTSource. - SelectorTable selector_table; - std::auto_ptr builtin_ap(new Builtin::Context(m_clang_ap->getTarget())); - ASTContext *Context = new ASTContext(m_clang_ap->getLangOpts(), - m_clang_ap->getSourceManager(), - m_clang_ap->getTarget(), - m_clang_ap->getPreprocessor().getIdentifierTable(), - selector_table, - *builtin_ap.get(), - 0); + ConstString target_triple; - llvm::OwningPtr ASTSource(new ClangASTSource(*Context, *m_decl_map)); - - if (m_decl_map) - { - Context->setExternalSource(ASTSource); - } + target->GetTargetTriple (target_triple); - m_clang_ap->setASTContext(Context); - - FileID memory_buffer_file_id = m_clang_ap->getSourceManager().createMainFileIDForMemBuffer (memory_buffer); - std::string module_name("test_func"); - text_diagnostic_buffer.BeginSourceFile(m_clang_ap->getLangOpts(), &m_clang_ap->getPreprocessor()); - - if (m_code_generator_ptr) - delete m_code_generator_ptr; + if (!target_triple) + target_triple = Host::GetTargetTriple (); - m_code_generator_ptr = CreateLLVMCodeGen(m_clang_ap->getDiagnostics(), - module_name, - m_clang_ap->getCodeGenOpts(), - m_clang_ap->getLLVMContext()); - - - // - CodeGeneration ASTConsumer (include/clang/ModuleBuilder.h), which will be passed in when you call... - // - Call clang::ParseAST (in lib/Sema/ParseAST.cpp) to parse the buffer. The CodeGenerator will generate code for __dbg_expr. - // - Once ParseAST completes, you can grab the llvm::Module from the CodeGenerator, which will have an llvm::Function you can hand off to the JIT. - - if (add_result_var) + if (!target_triple) { - ClangResultSynthesizer result_synthesizer(m_code_generator_ptr); - ParseAST(m_clang_ap->getPreprocessor(), &result_synthesizer, m_clang_ap->getASTContext()); - } - else - { - ParseAST(m_clang_ap->getPreprocessor(), m_code_generator_ptr, m_clang_ap->getASTContext()); + error_stream.PutCString ("error: invalid target triple\n"); + return false; } - - - text_diagnostic_buffer.EndSourceFile(); - - //compiler_instance->getASTContext().getTranslationUnitDecl()->dump(); - - //if (compiler_instance->getFrontendOpts().ShowStats) { - // compiler_instance->getFileManager().PrintStats(); - // fprintf(stderr, "\n"); - //} - - // This code resolves the setClient above. - m_clang_ap->getDiagnostics().setClient(0); - - TextDiagnosticBuffer::const_iterator diag_iterator; + + ////////////////////////// + // Parse the expression + // - int num_errors = 0; - -#ifdef COUNT_WARNINGS_AND_ERRORS - int num_warnings = 0; + m_expr_decl_map.reset(new ClangExpressionDeclMap(&exe_ctx)); - for (diag_iterator = text_diagnostic_buffer.warn_begin(); - diag_iterator != text_diagnostic_buffer.warn_end(); - ++diag_iterator) - num_warnings++; + ClangExpressionParser parser(target_triple.GetCString(), *this); - for (diag_iterator = text_diagnostic_buffer.err_begin(); - diag_iterator != text_diagnostic_buffer.err_end(); - ++diag_iterator) - num_errors++; + unsigned num_errors = parser.Parse (error_stream); - if (num_warnings || num_errors) + if (num_errors) { - if (num_warnings) - stream.Printf("%u warning%s%s", num_warnings, (num_warnings == 1 ? "" : "s"), (num_errors ? " and " : "")); - if (num_errors) - stream.Printf("%u error%s", num_errors, (num_errors == 1 ? "" : "s")); - stream.Printf("\n"); - } -#endif - - for (diag_iterator = text_diagnostic_buffer.warn_begin(); - diag_iterator != text_diagnostic_buffer.warn_end(); - ++diag_iterator) - stream.Printf("warning: %s\n", (*diag_iterator).second.c_str()); - - num_errors = 0; - - for (diag_iterator = text_diagnostic_buffer.err_begin(); - diag_iterator != text_diagnostic_buffer.err_end(); - ++diag_iterator) - { - num_errors++; - stream.Printf("error: %s\n", (*diag_iterator).second.c_str()); + error_stream.Printf ("error: %d errors parsing expression\n", num_errors); + return false; } - return num_errors; -} + /////////////////////////////////////////////// + // Convert the output of the parser to DWARF + // -bool -ClangExpression::ConvertIRToDWARF (ClangExpressionVariableList &expr_local_variable_list, - StreamString &dwarf_opcode_strm) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + m_dwarf_opcodes.reset(new StreamString); + m_dwarf_opcodes->SetByteOrder (lldb::eByteOrderHost); + m_dwarf_opcodes->GetFlags ().Set (Stream::eBinary); - llvm::Module *module = m_code_generator_ptr->GetModule(); - - if (!module) + m_local_variables.reset(new ClangExpressionVariableStore()); + + Error dwarf_error = parser.MakeDWARF (); + + if (dwarf_error.Success()) { if (log) - log->Printf("IR doesn't contain a module"); + log->Printf("Code can be interpreted."); - return 1; + return true; } - IRToDWARF ir_to_dwarf(expr_local_variable_list, m_decl_map, dwarf_opcode_strm); + ////////////////////////////////// + // JIT the output of the parser + // - return ir_to_dwarf.runOnModule(*module); -} - -bool -ClangExpression::PrepareIRForTarget () -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + m_dwarf_opcodes.reset(); - llvm::Module *module = m_code_generator_ptr->GetModule(); + Error jit_error = parser.MakeJIT (m_jit_addr, exe_ctx); - if (!module) + if (jit_error.Success()) { if (log) - log->Printf("IR doesn't contain a module"); + { + log->Printf("Code can be run in the target."); + + StreamString disassembly_stream; + + Error err = parser.DisassembleFunction(disassembly_stream, exe_ctx); + + if (!err.Success()) + { + log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error")); + } + else + { + log->Printf("Function disassembly:\n%s", disassembly_stream.GetData()); + } + } - return 1; + return true; } - - llvm::Triple target_triple = m_clang_ap->getTarget().getTriple(); - - std::string err; - - const llvm::Target *target = llvm::TargetRegistry::lookupTarget(m_target_triple, err); - - if (!target) + else { - if (log) - log->Printf("Couldn't find a target for %s", m_target_triple.c_str()); - - return 1; + error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors); + return false; } - - std::auto_ptr target_machine(target->createTargetMachine(m_target_triple, "")); - - IRForTarget ir_for_target(m_decl_map, target_machine->getTargetData()); - - return ir_for_target.runOnModule(*module); } bool -ClangExpression::JITFunction (const char *name) +ClangUserExpression::Execute (Stream &error_stream, + ExecutionContext &exe_ctx, + ClangExpressionVariable *&result) { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - llvm::Module *module = m_code_generator_ptr->GetModule(); - - if (module) + if (m_dwarf_opcodes.get()) { - std::string error; - - if (m_jit_mm_ptr == NULL) - m_jit_mm_ptr = new RecordingMemoryManager(); - - //llvm::InitializeNativeTarget(); + // TODO execute the JITted opcodes + + error_stream.Printf("We don't currently support executing DWARF expressions"); + + return false; + } + else if (m_jit_addr != LLDB_INVALID_ADDRESS) + { + lldb::addr_t struct_address; + + Error materialize_error; + + if (!m_expr_decl_map->Materialize(&exe_ctx, struct_address, materialize_error)) + { + error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString("unknown error")); + return false; + } if (log) { - const char *relocation_model_string; + log->Printf("Function address : 0x%llx", (uint64_t)m_jit_addr); + log->Printf("Structure address : 0x%llx", (uint64_t)struct_address); + + StreamString args; - switch (llvm::TargetMachine::getRelocationModel()) + 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 { - case llvm::Reloc::Default: - relocation_model_string = "Default"; + log->Printf("Structure contents:\n%s", args.GetData()); + } + } + + ClangFunction::ExecutionResults execution_result = + ClangFunction::ExecuteFunction (exe_ctx, m_jit_addr, struct_address, true, true, 10000, error_stream); + + if (execution_result != ClangFunction::eExecutionCompleted) + { + const char *result_name; + + switch (execution_result) + { + case ClangFunction::eExecutionCompleted: + result_name = "eExecutionCompleted"; + break; + case ClangFunction::eExecutionDiscarded: + result_name = "eExecutionDiscarded"; break; - case llvm::Reloc::Static: - relocation_model_string = "Static"; + case ClangFunction::eExecutionInterrupted: + result_name = "eExecutionInterrupted"; break; - case llvm::Reloc::PIC_: - relocation_model_string = "PIC_"; + case ClangFunction::eExecutionSetupError: + result_name = "eExecutionSetupError"; break; - case llvm::Reloc::DynamicNoPIC: - relocation_model_string = "DynamicNoPIC"; + case ClangFunction::eExecutionTimedOut: + result_name = "eExecutionTimedOut"; break; } - log->Printf("Target machine's relocation model: %s", relocation_model_string); + error_stream.Printf ("Couldn't execute function; result was %s\n", result_name); + return false; } - - if (m_execution_engine.get() == 0) - m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, - &error, - m_jit_mm_ptr, - CodeGenOpt::Default, - true, - CodeModel::Small)); // set to small so RIP-relative relocations work in PIC - m_execution_engine->DisableLazyCompilation(); - llvm::Function *function = module->getFunction (llvm::StringRef (name)); - - // We don't actually need the function pointer here, this just forces it to get resolved. - void *fun_ptr = m_execution_engine->getPointerToFunction(function); - // Note, you probably won't get here on error, since the LLVM JIT tends to just - // exit on error at present... So be careful. - if (fun_ptr == 0) + Error expr_error; + + 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")); return false; - m_jitted_functions.push_back(ClangExpression::JittedFunction(name, (lldb::addr_t) fun_ptr)); - - } - return true; -} - -bool -ClangExpression::WriteJITCode (const ExecutionContext &exc_context) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - if (m_jit_mm_ptr == NULL) - return false; - - if (exc_context.process == NULL) - return false; - - // Look over the regions allocated for the function compiled. The JIT - // tries to allocate the functions & stubs close together, so we should try to - // write them that way too... - // For now I only write functions with no stubs, globals, exception tables, - // etc. So I only need to write the functions. - - size_t alloc_size = 0; - std::map::iterator fun_pos, fun_end = m_jit_mm_ptr->m_functions.end(); - for (fun_pos = m_jit_mm_ptr->m_functions.begin(); fun_pos != fun_end; fun_pos++) - { - alloc_size += (*fun_pos).second - (*fun_pos).first; - } - - Error error; - lldb::addr_t target_addr = exc_context.process->AllocateMemory (alloc_size, lldb::ePermissionsReadable|lldb::ePermissionsExecutable, error); - - if (target_addr == LLDB_INVALID_ADDRESS) - return false; - - lldb::addr_t cursor = target_addr; - for (fun_pos = m_jit_mm_ptr->m_functions.begin(); fun_pos != fun_end; fun_pos++) - { - if (log) - log->Printf("Reading [%p-%p] from m_functions", fun_pos->first, fun_pos->second); + } - lldb::addr_t lstart = (lldb::addr_t) (*fun_pos).first; - lldb::addr_t lend = (lldb::addr_t) (*fun_pos).second; - size_t size = lend - lstart; - exc_context.process->WriteMemory(cursor, (void *) lstart, size, error); - m_jit_mm_ptr->AddToLocalToRemoteMap (lstart, size, cursor); - cursor += size; - } - - std::vector::iterator pos, end = m_jitted_functions.end(); - - for (pos = m_jitted_functions.begin(); pos != end; pos++) - { - (*pos).m_remote_addr = m_jit_mm_ptr->GetRemoteAddressForLocal ((*pos).m_local_addr); + return true; } - return true; -} - -lldb::addr_t -ClangExpression::GetFunctionAddress (const char *name) -{ - std::vector::iterator pos, end = m_jitted_functions.end(); - - for (pos = m_jitted_functions.begin(); pos < end; pos++) + else { - if (strcmp ((*pos).m_name.c_str(), name) == 0) - return (*pos).m_remote_addr; + error_stream.Printf("Expression can't be run; neither DWARF nor a JIT compiled function are present"); + return false; } - return LLDB_INVALID_ADDRESS; } -Error -ClangExpression::DisassembleFunction (Stream &stream, ExecutionContext &exe_ctx, const char *name) +StreamString & +ClangUserExpression::DwarfOpcodeStream () { - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - - Error ret; - - ret.Clear(); - - lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS; - lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS; - - std::vector::iterator pos, end = m_jitted_functions.end(); - - for (pos = m_jitted_functions.begin(); pos < end; pos++) - { - if (strcmp(pos->m_name.c_str(), name) == 0) - { - func_local_addr = pos->m_local_addr; - func_remote_addr = pos->m_remote_addr; - } - } - - if (func_local_addr == LLDB_INVALID_ADDRESS) - { - ret.SetErrorToGenericError(); - ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", name); - return ret; - } - - if(log) - log->Printf("Found function, has local address 0x%llx and remote address 0x%llx", (uint64_t)func_local_addr, (uint64_t)func_remote_addr); - - std::pair func_range; - - func_range = m_jit_mm_ptr->GetRemoteRangeForLocal(func_local_addr); - - if (func_range.first == 0 && func_range.second == 0) - { - ret.SetErrorToGenericError(); - ret.SetErrorStringWithFormat("Couldn't find code range for function %s", name); - return ret; - } - - if(log) - log->Printf("Function's code range is [0x%llx-0x%llx]", func_range.first, func_range.second); - - if (!exe_ctx.target) - { - ret.SetErrorToGenericError(); - ret.SetErrorString("Couldn't find the target"); - } - - lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second - func_remote_addr, 0)); - - Error err; - exe_ctx.process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err); - - if (!err.Success()) - { - ret.SetErrorToGenericError(); - ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error")); - return ret; - } - - ArchSpec arch(exe_ctx.target->GetArchitecture()); - - Disassembler *disassembler = Disassembler::FindPlugin(arch); - - if (disassembler == NULL) - { - ret.SetErrorToGenericError(); - ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.AsCString()); - return ret; - } - - if (!exe_ctx.process) - { - ret.SetErrorToGenericError(); - ret.SetErrorString("Couldn't find the process"); - return ret; - } - - DataExtractor extractor(buffer_sp, - exe_ctx.process->GetByteOrder(), - exe_ctx.target->GetArchitecture().GetAddressByteSize()); - - if(log) - { - log->Printf("Function data has contents:"); - extractor.PutToLog (log, - 0, - extractor.GetByteSize(), - func_remote_addr, - 16, - DataExtractor::TypeUInt8); - } - - disassembler->DecodeInstructions(extractor, 0, UINT32_MAX); - - Disassembler::InstructionList &instruction_list = disassembler->GetInstructionList(); - - uint32_t bytes_offset = 0; - - for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize(); - instruction_index < num_instructions; - ++instruction_index) - { - Disassembler::Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index); - Address addr(NULL, func_remote_addr + bytes_offset); - instruction->Dump (&stream, - &addr, - &extractor, - bytes_offset, - exe_ctx, - true); - stream.PutChar('\n'); - bytes_offset += instruction->GetByteSize(); - } + if (!m_dwarf_opcodes.get()) + m_dwarf_opcodes.reset(new StreamString()); - return ret; + return *m_dwarf_opcodes.get(); } Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Thu Aug 26 20:01:44 2010 @@ -31,11 +31,13 @@ static char ID; IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, - const TargetData *target_data) : + const TargetData *target_data, + const char *func_name) : ModulePass(&ID), m_decl_map(decl_map), m_target_data(target_data), - m_sel_registerName(NULL) + m_sel_registerName(NULL), + m_func_name(func_name) { } @@ -910,12 +912,12 @@ { lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - Function* function = M.getFunction(StringRef("___clang_expr")); + Function* function = M.getFunction(StringRef(m_func_name.c_str())); if (!function) { if (log) - log->Printf("Couldn't find ___clang_expr() in the module"); + log->Printf("Couldn't find %s() in the module", m_func_name.c_str()); return false; } Modified: lldb/trunk/source/Expression/IRToDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRToDWARF.cpp?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRToDWARF.cpp (original) +++ lldb/trunk/source/Expression/IRToDWARF.cpp Thu Aug 26 20:01:44 2010 @@ -26,13 +26,15 @@ static char ID; -IRToDWARF::IRToDWARF(lldb_private::ClangExpressionVariableList &variable_list, +IRToDWARF::IRToDWARF(lldb_private::ClangExpressionVariableStore &local_vars, lldb_private::ClangExpressionDeclMap *decl_map, - lldb_private::StreamString &strm) : + lldb_private::StreamString &strm, + const char *func_name) : ModulePass(&ID), - m_variable_list(variable_list), + m_local_vars(local_vars), m_decl_map(decl_map), - m_strm(strm) + m_strm(strm), + m_func_name(func_name) { } @@ -171,14 +173,14 @@ { lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - llvm::Function* function = M.getFunction(StringRef("___clang_expr")); + llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str())); if (!function) { if (log) - log->Printf("Couldn't find ___clang_expr() in the module"); + log->Printf("Couldn't find %s() in the module", m_func_name.c_str()); - return 1; + return false; } Relocator relocator; Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=112249&r1=112248&r2=112249&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Thu Aug 26 20:01:44 2010 @@ -16,7 +16,7 @@ #include "../Commands/CommandObjectApropos.h" #include "../Commands/CommandObjectArgs.h" #include "../Commands/CommandObjectBreakpoint.h" -#include "../Commands/CommandObjectCall.h" +//#include "../Commands/CommandObjectCall.h" #include "../Commands/CommandObjectDelete.h" #include "../Commands/CommandObjectDisassemble.h" #include "../Commands/CommandObjectExpression.h" @@ -207,7 +207,7 @@ m_command_dict["append"] = CommandObjectSP (new CommandObjectAppend ()); m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos ()); m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this)); - m_command_dict["call"] = CommandObjectSP (new CommandObjectCall ()); + //m_command_dict["call"] = CommandObjectSP (new CommandObjectCall ()); m_command_dict["commands"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this)); m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble ()); m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression ()); From johnny.chen at apple.com Fri Aug 27 13:08:58 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 27 Aug 2010 18:08:58 -0000 Subject: [Lldb-commits] [lldb] r112276 - in /lldb/trunk/test: array_types/TestArrayTypes.py bitfields/TestBitfields.py hello_world/ hello_world/Makefile hello_world/TestHelloWorld.py hello_world/main.c lldbtest.py Message-ID: <20100827180858.80C7C2A6C12C@llvm.org> Author: johnny Date: Fri Aug 27 13:08:58 2010 New Revision: 112276 URL: http://llvm.org/viewvc/llvm-project?rev=112276&view=rev Log: Added TestHelloWorld.py which exercises the Python APIs for target, breakpoint, and process. Added comment within the file about issues of using LaunchProcess of SBTarget to launch a process (rdar://problem/8364687). Added: lldb/trunk/test/hello_world/ lldb/trunk/test/hello_world/Makefile lldb/trunk/test/hello_world/TestHelloWorld.py lldb/trunk/test/hello_world/main.c Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112276&r1=112275&r2=112276&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Fri Aug 27 13:08:58 2010 @@ -68,7 +68,7 @@ # The stop reason of the thread should be breakpoint. thread = target.GetProcess().GetThreadAtIndex(0) - self.assertTrue(thread.GetStopReason() == Enum("Breakpoint"), + self.assertTrue(thread.GetStopReason() == StopReasonEnum("Breakpoint"), STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=112276&r1=112275&r2=112276&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Fri Aug 27 13:08:58 2010 @@ -69,7 +69,7 @@ # The stop reason of the thread should be breakpoint. thread = target.GetProcess().GetThreadAtIndex(0) - self.assertTrue(thread.GetStopReason() == Enum("Breakpoint"), + self.assertTrue(thread.GetStopReason() == StopReasonEnum("Breakpoint"), STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. Added: lldb/trunk/test/hello_world/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/Makefile?rev=112276&view=auto ============================================================================== --- lldb/trunk/test/hello_world/Makefile (added) +++ lldb/trunk/test/hello_world/Makefile Fri Aug 27 13:08:58 2010 @@ -0,0 +1,5 @@ +LEVEL = ../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=112276&view=auto ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (added) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Fri Aug 27 13:08:58 2010 @@ -0,0 +1,86 @@ +"""Test Python APIs for target, breakpoint, and process.""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class TestHelloWorld(TestBase): + + mydir = "hello_world" + + @unittest2.expectedFailure + def test_hellp_world_python(self): + """Create target, breakpoint, launch a process, and then kill it.""" + + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + + breakpoint = target.BreakpointCreateByLocation("main.c", 4) + + # The default state after breakpoint creation should be enabled. + self.assertTrue(breakpoint.IsEnabled(), + "Breakpoint should be enabled after creation") + + breakpoint.SetEnabled(False) + self.assertTrue(not breakpoint.IsEnabled(), + "Breakpoint.SetEnabled(False) works") + + breakpoint.SetEnabled(True) + self.assertTrue(breakpoint.IsEnabled(), + "Breakpoint.SetEnabled(True) works") + + # rdar://problem/8364687 + # SBTarget.LaunchProcess() issue (or is there some race condition)? + + # The following approach of launching a process looks untidy and only + # works sometimes. + process = target.LaunchProcess([''], [''], os.ctermid(), False) + + SR = process.GetThreadAtIndex(0).GetStopReason() + count = 0 + while SR == StopReasonEnum("Invalid") or SR == StopReasonEnum("Signal"): + print >> sys.stderr, "StopReason =", StopReasonString(SR) + + time.sleep(1.0) + print >> sys.stderr, "Continuing the process:", process + process.Continue() + + count = count + 1 + if count == 10: + print >> sys.stderr, "Reached 10 iterations, giving up..." + break + + SR = process.GetThreadAtIndex(0).GetStopReason() + + # End of section of launching a process. + + # On the other hand, the following two lines of code are more reliable. + #self.runCmd("run") + #process = target.GetProcess() + + self.runCmd("thread backtrace") + self.runCmd("breakpoint list") + self.runCmd("thread list") + + # The stop reason of the thread should be breakpoint. + thread = process.GetThreadAtIndex(0) + + print >> sys.stderr, "StopReason =", StopReasonString(thread.GetStopReason()) + self.assertTrue(thread.GetStopReason() == StopReasonEnum("Breakpoint"), + STOPPED_DUE_TO_BREAKPOINT) + + # The breakpoint should have a hit count of 1. + self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) + + # Now kill the process, and we are done. + rc = process.Kill() + self.assertTrue(rc.Success()) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/hello_world/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/main.c?rev=112276&view=auto ============================================================================== --- lldb/trunk/test/hello_world/main.c (added) +++ lldb/trunk/test/hello_world/main.c Fri Aug 27 13:08:58 2010 @@ -0,0 +1,6 @@ +#include + +int main(int argc, char const *argv[]) { + printf("Hello world.\n"); + return 0; +} Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112276&r1=112275&r2=112276&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Aug 27 13:08:58 2010 @@ -149,29 +149,52 @@ return "Command '%s' returns successfully" % (command) # -# Returns the enum from the input string stopReason. +# Returns the enum from the input string. # -def Enum(stopReason): - if stopReason == "Invalid": +def StopReasonEnum(string): + if string == "Invalid": return 0 - elif stopReason == "None": + elif string == "None": return 1 - elif stopReason == "Trace": + elif string == "Trace": return 2 - elif stopReason == "Breakpoint": + elif string == "Breakpoint": return 3 - elif stopReason == "Watchpoint": + elif string == "Watchpoint": return 4 - elif stopReason == "Signal": + elif string == "Signal": return 5 - elif stopReason == "Exception": + elif string == "Exception": return 6 - elif stopReason == "PlanComplete": + elif string == "PlanComplete": return 7 else: raise Exception("Unknown stopReason string") # +# Returns the stopReason string given an enum. +# +def StopReasonString(enum): + if enum == 0: + return "Invalid" + elif enum == 1: + return "None" + elif enum == 2: + return "Trace" + elif enum == 3: + return "Breakpoint" + elif enum == 4: + return "Watchpoint" + elif enum == 5: + return "Signal" + elif enum == 6: + return "Exception" + elif enum == 7: + return "PlanComplete" + else: + raise Exception("Unknown stopReason enum") + +# # Returns an env variable array from the os.environ map object. # def EnvArray(): From gclayton at apple.com Fri Aug 27 13:24:16 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 27 Aug 2010 18:24:16 -0000 Subject: [Lldb-commits] [lldb] r112277 - in /lldb/trunk: include/lldb/Target/StackFrame.h include/lldb/Target/StackFrameList.h source/Target/StackFrame.cpp source/Target/StackFrameList.cpp source/Target/Thread.cpp Message-ID: <20100827182416.4DB852A6C12C@llvm.org> Author: gclayton Date: Fri Aug 27 13:24:16 2010 New Revision: 112277 URL: http://llvm.org/viewvc/llvm-project?rev=112277&view=rev Log: Simplified the StackFrameList class down to a single frames list again instead of trying to maintain the real frame list (unwind frames) and an inline frame list. The information is cheap to produce when we already have looked up a block and was making stack frame uniquing difficult when trying to use the previous stack when making the current stack. We now maintain the previous value object lists for common frames between a previous and current frames so we will be able to tell when variable values change. Modified: lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/include/lldb/Target/StackFrameList.h lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/StackFrameList.cpp lldb/trunk/source/Target/Thread.cpp Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=112277&r1=112276&r2=112277&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Fri Aug 27 13:24:16 2010 @@ -129,7 +129,15 @@ { m_id.SetInlineBlockID(inline_block_id); } + + void + SetFrameCodeAddress(const Address& frame_code_addr) + { + m_frame_code_addr = frame_code_addr; + } + void + SetSymbolContext (const SymbolContext& sc); private: //------------------------------------------------------------------ // For StackFrame only Modified: lldb/trunk/include/lldb/Target/StackFrameList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=112277&r1=112276&r2=112277&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrameList.h (original) +++ lldb/trunk/include/lldb/Target/StackFrameList.h Fri Aug 27 13:24:16 2010 @@ -55,27 +55,14 @@ void InvalidateFrames (uint32_t start_idx); -protected: + + void + Dump (Stream *s); - bool - SetUnwindFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); +protected: bool - SetInlineFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); - - - lldb::StackFrameSP - GetUnwindFrameAtIndex (uint32_t idx) const; - - lldb::StackFrameSP - GetInlineFrameAtIndex (uint32_t idx) const; - - typedef struct InlinedFrameInfo - { - uint32_t unwind_frame_index; - Block *block; - } InlinedFrameInfo; - typedef std::vector InlinedFrameInfoCollection; + SetFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); //------------------------------------------------------------------ // Classes that inherit from StackFrameList can see and modify these @@ -87,9 +74,7 @@ Thread &m_thread; std::auto_ptr m_prev_frames_ap; mutable Mutex m_mutex; - collection m_unwind_frames; - collection m_inline_frames; - InlinedFrameInfoCollection m_inlined_info; + collection m_frames; uint32_t m_selected_frame_idx; bool m_show_inlined_frames; Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=112277&r1=112276&r2=112277&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Fri Aug 27 13:24:16 2010 @@ -531,3 +531,11 @@ m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline); } + +void +StackFrame::SetSymbolContext (const SymbolContext& sc) +{ + m_sc = sc; + m_flags.Clear(eSymbolContextEverything); + m_flags.Set(m_sc.GetResolvedMask ()); +} Modified: lldb/trunk/source/Target/StackFrameList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=112277&r1=112276&r2=112277&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrameList.cpp (original) +++ lldb/trunk/source/Target/StackFrameList.cpp Fri Aug 27 13:24:16 2010 @@ -13,6 +13,7 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Core/StreamFile.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Function.h" #include "lldb/Target/RegisterContext.h" @@ -20,6 +21,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/Unwind.h" +//#define DEBUG_STACK_FRAMES 1 + using namespace lldb; using namespace lldb_private; @@ -31,8 +34,7 @@ m_prev_frames_ap (prev_frames), m_show_inlined_frames (show_inline_frames), m_mutex (Mutex::eMutexTypeRecursive), - m_unwind_frames (), - m_inline_frames (), + m_frames (), m_selected_frame_idx (0) { } @@ -50,256 +52,298 @@ { Mutex::Locker locker (m_mutex); - if (m_show_inlined_frames) + if (m_frames.size() <= 1) { - if (m_inlined_info.empty()) + if (m_show_inlined_frames) { +#if defined (DEBUG_STACK_FRAMES) + StreamFile s(stdout); +#endif Unwind *unwinder = m_thread.GetUnwinder (); + addr_t pc, cfa; + // If we are going to show inlined stack frames as actual frames, // we need to calculate all concrete frames first, then iterate // through all of them and count up how many inlined functions are - // in each frame. We can then fill in m_inlined_info with - // the concrete frame index and inlined depth - const uint32_t concrete_frame_count = unwinder->GetFrameCount(); + // in each frame. + const uint32_t unwind_frame_count = unwinder->GetFrameCount(); - addr_t pc, cfa; - InlinedFrameInfo inlined_frame_info; - - StackFrameSP frame_sp; - for (uint32_t idx=0; idxGetSP(), - m_thread.m_reg_context_sp->GetPC(), - NULL)); + // We might have already created frame zero, only create it + // if we need to + if (m_frames.empty()) + { + m_thread.GetRegisterContext(); + unwind_frame_sp.reset (new StackFrame (m_frames.size(), + idx, + m_thread, + m_thread.m_reg_context_sp, + m_thread.m_reg_context_sp->GetSP(), + m_thread.m_reg_context_sp->GetPC(), + NULL)); + m_frames.push_back (unwind_frame_sp); + } + else + { + unwind_frame_sp = m_frames.front(); + } } else { const bool success = unwinder->GetFrameInfoAtIndex(idx, cfa, pc); assert (success); - frame_sp.reset (new StackFrame (m_inlined_info.size(), idx, m_thread, cfa, pc, NULL)); + unwind_frame_sp.reset (new StackFrame (m_frames.size(), idx, m_thread, cfa, pc, NULL)); + m_frames.push_back (unwind_frame_sp); } - SetUnwindFrameAtIndex (idx, frame_sp); - Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block; - - inlined_frame_info.unwind_frame_index = idx; - inlined_frame_info.block = NULL; - m_inlined_info.push_back (inlined_frame_info); + Block *block = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock).block; + if (block) { - Block *inlined_block = block->GetContainingInlinedBlock(); - - if (inlined_block) + for (block = block->GetContainingInlinedBlock(); block != NULL; block = block->GetInlinedParent ()) { - frame_sp->SetInlineBlockID (inlined_block->GetID()); + SymbolContext inline_sc; + Block *parent_block = block->GetInlinedParent(); + + const bool is_inlined_frame = parent_block != NULL; + + if (parent_block == NULL) + parent_block = block->GetParent(); + + parent_block->CalculateSymbolContext (&inline_sc); + + Address previous_frame_lookup_addr (m_frames.back()->GetFrameCodeAddress()); + if (unwind_frame_sp->GetFrameIndex() > 0 && m_frames.back().get() == unwind_frame_sp.get()) + previous_frame_lookup_addr.Slide (-1); + + AddressRange range; + block->GetRangeContainingAddress (previous_frame_lookup_addr, range); + + const InlineFunctionInfo* inline_info = block->InlinedFunctionInfo(); + assert (inline_info); + inline_sc.line_entry.range.GetBaseAddress() = m_frames.back()->GetFrameCodeAddress(); + inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); + inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); + inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); + + StackFrameSP frame_sp(new StackFrame (m_frames.size(), + idx, + m_thread, + unwind_frame_sp->GetRegisterContextSP (), + unwind_frame_sp->GetStackID().GetCallFrameAddress(), // CFA + range.GetBaseAddress(), + &inline_sc)); // The symbol context for this inline frame + + if (is_inlined_frame) + frame_sp->SetInlineBlockID (block->GetID()); + + m_frames.push_back (frame_sp); + } + } + } + StackFrameList *prev_frames = m_prev_frames_ap.get(); + if (prev_frames) + { + StackFrameList *curr_frames = this; - while (inlined_block) +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("prev_frames:\n"); + prev_frames->Dump (&s); + s.PutCString("curr_frames:\n"); + curr_frames->Dump (&s); + s.EOL(); +#endif + size_t curr_frame_num, prev_frame_num; + + for (curr_frame_num = curr_frames->m_frames.size(), prev_frame_num = prev_frames->m_frames.size(); + curr_frame_num > 0 && prev_frame_num > 0; + --curr_frame_num, --prev_frame_num) + { + const size_t curr_frame_idx = curr_frame_num-1; + const size_t prev_frame_idx = prev_frame_num-1; + StackFrameSP curr_frame_sp (curr_frames->m_frames[curr_frame_idx]); + StackFrameSP prev_frame_sp (prev_frames->m_frames[prev_frame_idx]); + +#if defined (DEBUG_STACK_FRAMES) + s.Printf("\nCurrent frame #%u ", curr_frame_idx); + if (curr_frame_sp) + curr_frame_sp->Dump (&s, true); + else + s.PutCString("NULL"); + s.Printf("\nPrevious frame #%u ", prev_frame_idx); + if (prev_frame_sp) + prev_frame_sp->Dump (&s, true); + else + s.PutCString("NULL"); + s.EOL(); +#endif + + StackFrame *curr_frame = curr_frame_sp.get(); + StackFrame *prev_frame = prev_frame_sp.get(); + + if (curr_frame == NULL || prev_frame == NULL) + break; + + // Do a quick sanity check to see if the CFA values are the same. + if (curr_frame->m_id.GetCallFrameAddress() != prev_frame->m_id.GetCallFrameAddress()) + break; + + // Now check our function or symbol + SymbolContext curr_sc (curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); + SymbolContext prev_sc (prev_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); + if (curr_sc.function && curr_sc.function == prev_sc.function) + { + // Same function + if (curr_sc.block != prev_sc.block) { - inlined_frame_info.block = inlined_block; - m_inlined_info.push_back (inlined_frame_info); - inlined_block = inlined_block->GetInlinedParent (); + // Same function different block + if (m_show_inlined_frames) + break; + else + prev_frame->SetSymbolContext (curr_frame->m_sc); } } + else if (curr_sc.symbol && curr_sc.symbol == prev_sc.symbol) + { + // Same symbol + } + else if (curr_frame->GetFrameCodeAddress() != prev_frame->GetFrameCodeAddress()) + { + // No symbols for this frame and the PC was different + break; + } + + if (curr_frame->GetFrameCodeAddress() != prev_frame->GetFrameCodeAddress()) + { +#if defined (DEBUG_STACK_FRAMES) + s.Printf("\nUpdating frame code address and symbol context in previous frame #%u to current frame #%u", prev_frame_idx, curr_frame_idx); +#endif + // We have a different code frame address, we might need to copy + // some stuff in prev_frame, yet update the code address... + prev_frame->SetFrameCodeAddress (curr_frame->GetFrameCodeAddress()); + prev_frame->SetSymbolContext (curr_frame->m_sc); + } + + curr_frames->m_frames[curr_frame_idx] = prev_frames->m_frames[prev_frame_idx]; + +#if defined (DEBUG_STACK_FRAMES) + s.Printf("\nCopying previous frame #%u to current frame #%u", prev_frame_idx, curr_frame_idx); +#endif } + // We are done with the old stack frame list, we can release it now + m_prev_frames_ap.release(); + prev_frames = NULL; } } - return m_inlined_info.size(); - } - else - { - if (m_unwind_frames.empty()) - m_unwind_frames.resize(m_thread.GetUnwinder()->GetFrameCount()); - - return m_unwind_frames.size(); + else + { + m_frames.resize(m_thread.GetUnwinder()->GetFrameCount()); + } } - return 0; + return m_frames.size(); } -lldb::StackFrameSP -StackFrameList::GetUnwindFrameAtIndex (uint32_t idx) const +void +StackFrameList::Dump (Stream *s) { - StackFrameSP frame_sp; - if (idx < m_unwind_frames.size()) - frame_sp = m_unwind_frames[idx]; - return frame_sp; -} + if (s == NULL) + return; + Mutex::Locker locker (m_mutex); -lldb::StackFrameSP -StackFrameList::GetInlineFrameAtIndex (uint32_t idx) const -{ - StackFrameSP frame_sp; - if (idx < m_inline_frames.size()) - frame_sp = m_inline_frames[idx]; - return frame_sp; + const_iterator pos, begin = m_frames.begin(), end = m_frames.end(); + for (pos = begin; pos != end; ++pos) + { + StackFrame *frame = (*pos).get(); + s->Printf("%p: ", frame); + if (frame) + frame->Dump(s, true); + else + s->Printf("frame #%u", std::distance (begin, pos)); + s->EOL(); + } + s->EOL(); } - StackFrameSP StackFrameList::GetFrameAtIndex (uint32_t idx) { StackFrameSP frame_sp; - { - Mutex::Locker locker (m_mutex); - - if (m_show_inlined_frames) - { - frame_sp = GetInlineFrameAtIndex (idx); - } - else - { - frame_sp = GetUnwindFrameAtIndex (idx); - } + Mutex::Locker locker (m_mutex); + if (idx < m_frames.size()) + frame_sp = m_frames[idx]; - if (frame_sp.get()) - return frame_sp; + if (frame_sp) + return frame_sp; - // Special case the first frame (idx == 0) so that we don't need to - // know how many stack frames there are to get it. If we need any other - // frames, then we do need to know if "idx" is a valid index. - if (idx == 0) + // Special case the first frame (idx == 0) so that we don't need to + // know how many stack frames there are to get it. If we need any other + // frames, then we do need to know if "idx" is a valid index. + if (idx == 0) + { + // If this is the first frame, we want to share the thread register + // context with the stack frame at index zero. + m_thread.GetRegisterContext(); + assert (m_thread.m_reg_context_sp.get()); + frame_sp.reset (new StackFrame (0, + 0, + m_thread, + m_thread.m_reg_context_sp, + m_thread.m_reg_context_sp->GetSP(), + m_thread.m_reg_context_sp->GetPC(), + NULL)); + + if (m_show_inlined_frames) { - // If this is the first frame, we want to share the thread register - // context with the stack frame at index zero. - m_thread.GetRegisterContext(); - assert (m_thread.m_reg_context_sp.get()); - frame_sp.reset (new StackFrame (0, - 0, - m_thread, - m_thread.m_reg_context_sp, - m_thread.m_reg_context_sp->GetSP(), - m_thread.m_reg_context_sp->GetPC(), - NULL)); + Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block; - if (m_show_inlined_frames && idx + 1 < m_inlined_info.size()) - { - if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index) - frame_sp->SetInlineBlockID (frame_sp->GetSymbolContext (eSymbolContextBlock).block->GetID()); - } - - } - else if (idx < GetNumFrames()) - { - if (m_show_inlined_frames) - { - if (m_inlined_info[idx].block == NULL) - { - // Same as the concrete stack frame if block is NULL - assert (m_inlined_info[idx].unwind_frame_index < m_unwind_frames.size()); - frame_sp = GetUnwindFrameAtIndex (m_inlined_info[idx].unwind_frame_index); - if (idx + 1 < m_inlined_info.size()) - { - if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index) - frame_sp->SetInlineBlockID (frame_sp->GetSymbolContext (eSymbolContextBlock).block->GetID()); - } - } - else - { - // We have blocks that were above an inlined function. Inlined - // functions are represented as blocks with non-NULL inline - // function info. Here we must reconstruct a frame by looking - // at the block - StackFrameSP previous_frame_sp (m_thread.GetStackFrameAtIndex (idx-1)); - - SymbolContext inline_sc; - - Block *inlined_parent_block = m_inlined_info[idx].block->GetInlinedParent(); - - if (inlined_parent_block) - inlined_parent_block->CalculateSymbolContext (&inline_sc); - else - { - Block *parent_block = m_inlined_info[idx].block->GetParent(); - parent_block->CalculateSymbolContext(&inline_sc); - } - - Address previous_frame_lookup_addr (previous_frame_sp->GetFrameCodeAddress()); - if (previous_frame_sp->GetFrameIndex() > 0 && m_inlined_info[idx-1].block == NULL) - previous_frame_lookup_addr.Slide (-1); - - AddressRange range; - m_inlined_info[idx].block->GetRangeContainingAddress (previous_frame_lookup_addr, range); - - const InlineFunctionInfo* inline_info = m_inlined_info[idx].block->InlinedFunctionInfo(); - assert (inline_info); - inline_sc.line_entry.range.GetBaseAddress() = previous_frame_sp->GetFrameCodeAddress(); - inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); - inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); - inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); - - StackFrameSP concrete_frame_sp (GetUnwindFrameAtIndex (m_inlined_info[idx].unwind_frame_index)); - assert (previous_frame_sp.get()); - - frame_sp.reset (new StackFrame (idx, - m_inlined_info[idx].unwind_frame_index, - m_thread, - concrete_frame_sp->GetRegisterContextSP (), - concrete_frame_sp->GetStackID().GetCallFrameAddress(), // CFA - range.GetBaseAddress(), - &inline_sc)); // The symbol context for this inline frame - - if (idx + 1 < m_inlined_info.size()) - { - if (m_inlined_info[idx].unwind_frame_index == m_inlined_info[idx+1].unwind_frame_index) - frame_sp->SetInlineBlockID (m_inlined_info[idx].block->GetID()); - } - } - } - else + if (block) { - Unwind *unwinder = m_thread.GetUnwinder (); - if (unwinder) - { - addr_t pc, cfa; - if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) - frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, pc, NULL)); - } + Block *inline_block = block->GetContainingInlinedBlock(); + if (inline_block) + frame_sp->SetInlineBlockID (inline_block->GetID()); } } - + SetFrameAtIndex(idx, frame_sp); + } + else if (idx < GetNumFrames()) + { if (m_show_inlined_frames) { - SetInlineFrameAtIndex(idx, frame_sp); + // When inline frames are enabled we cache up all frames in GetNumFrames() + frame_sp = m_frames[idx]; } else { - SetUnwindFrameAtIndex(idx, frame_sp); + Unwind *unwinder = m_thread.GetUnwinder (); + if (unwinder) + { + addr_t pc, cfa; + if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) + { + frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, pc, NULL)); + SetFrameAtIndex(idx, frame_sp); + } + } } - return frame_sp; } return frame_sp; } -bool -StackFrameList::SetUnwindFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) -{ - if (idx >= m_unwind_frames.size()) - m_unwind_frames.resize(idx + 1); - // Make sure allocation succeeded by checking bounds again - if (idx < m_unwind_frames.size()) - { - m_unwind_frames[idx] = frame_sp; - return true; - } - return false; // resize failed, out of memory? -} bool -StackFrameList::SetInlineFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) +StackFrameList::SetFrameAtIndex (uint32_t idx, StackFrameSP &frame_sp) { - if (idx >= m_inline_frames.size()) - m_inline_frames.resize(idx + 1); + if (idx >= m_frames.size()) + m_frames.resize(idx + 1); // Make sure allocation succeeded by checking bounds again - if (idx < m_inline_frames.size()) + if (idx < m_frames.size()) { - m_inline_frames[idx] = frame_sp; + m_frames[idx] = frame_sp; return true; } return false; // resize failed, out of memory? @@ -318,8 +362,8 @@ { Mutex::Locker locker (m_mutex); const_iterator pos; - const_iterator begin = m_show_inlined_frames ? m_inline_frames.begin() : m_unwind_frames.begin(); - const_iterator end = m_show_inlined_frames ? m_inline_frames.end() : m_unwind_frames.end(); + const_iterator begin = m_frames.begin(); + const_iterator end = m_frames.end(); for (pos = begin; pos != end; ++pos) { if (pos->get() == frame) @@ -346,9 +390,7 @@ StackFrameList::Clear () { Mutex::Locker locker (m_mutex); - m_unwind_frames.clear(); - m_inline_frames.clear(); - m_inlined_info.clear(); + m_frames.clear(); } void @@ -361,10 +403,10 @@ } else { - const size_t num_frames = m_unwind_frames.size(); + const size_t num_frames = m_frames.size(); while (start_idx < num_frames) { - m_unwind_frames[start_idx].reset(); + m_frames[start_idx].reset(); ++start_idx; } } Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=112277&r1=112276&r2=112277&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Fri Aug 27 13:24:16 2010 @@ -813,7 +813,8 @@ void Thread::ClearStackFrames () { - m_prev_frames_ap = m_curr_frames_ap; + if (m_curr_frames_ap.get()) + m_prev_frames_ap = m_curr_frames_ap; } lldb::StackFrameSP From johnny.chen at apple.com Fri Aug 27 16:15:57 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 27 Aug 2010 21:15:57 -0000 Subject: [Lldb-commits] [lldb] r112293 - /lldb/trunk/test/array_types/TestArrayTypes.py Message-ID: <20100827211557.2B32D2A6C12C@llvm.org> Author: johnny Date: Fri Aug 27 16:15:57 2010 New Revision: 112293 URL: http://llvm.org/viewvc/llvm-project?rev=112293&view=rev Log: Trivial doc string mod. Modified: lldb/trunk/test/array_types/TestArrayTypes.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112293&r1=112292&r2=112293&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Fri Aug 27 16:15:57 2010 @@ -53,7 +53,7 @@ startstr = '(long [6])') def test_array_types_python(self): - """Use Python APIs to test variables with array types.""" + """Use Python APIs to inspect variables with array types.""" exe = os.path.join(os.getcwd(), "a.out") target = self.dbg.CreateTarget(exe) From gclayton at apple.com Fri Aug 27 16:47:55 2010 From: gclayton at apple.com (Greg Clayton) Date: Fri, 27 Aug 2010 21:47:55 -0000 Subject: [Lldb-commits] [lldb] r112301 - in /lldb/trunk: include/lldb/Core/ValueObjectList.h include/lldb/Target/StackFrame.h source/Core/ValueObjectList.cpp source/Target/StackFrame.cpp source/Target/StackFrameList.cpp Message-ID: <20100827214755.20F792A6C12C@llvm.org> Author: gclayton Date: Fri Aug 27 16:47:54 2010 New Revision: 112301 URL: http://llvm.org/viewvc/llvm-project?rev=112301&view=rev Log: Made it so we update the current frames from the previous frames by doing STL swaps on the variable list, value object list, and disassembly. This avoids us having to try and update frame indexes and other things that were getting out of sync. Modified: lldb/trunk/include/lldb/Core/ValueObjectList.h lldb/trunk/include/lldb/Target/StackFrame.h lldb/trunk/source/Core/ValueObjectList.cpp lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/StackFrameList.cpp Modified: lldb/trunk/include/lldb/Core/ValueObjectList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectList.h?rev=112301&r1=112300&r2=112301&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectList.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectList.h Fri Aug 27 16:47:54 2010 @@ -59,6 +59,9 @@ lldb::ValueObjectSP FindValueObjectByUID (lldb::user_id_t uid); + void + Swap (ValueObjectList &value_object_list); + protected: typedef std::vector collection; //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Target/StackFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=112301&r1=112300&r2=112301&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrame.h (original) +++ lldb/trunk/include/lldb/Target/StackFrame.h Fri Aug 27 16:47:54 2010 @@ -131,13 +131,8 @@ } void - SetFrameCodeAddress(const Address& frame_code_addr) - { - m_frame_code_addr = frame_code_addr; - } - - void - SetSymbolContext (const SymbolContext& sc); + UpdateCurrentFrameFromPreviousFrame (StackFrame &frame); + private: //------------------------------------------------------------------ // For StackFrame only Modified: lldb/trunk/source/Core/ValueObjectList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectList.cpp?rev=112301&r1=112300&r2=112301&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectList.cpp (original) +++ lldb/trunk/source/Core/ValueObjectList.cpp Fri Aug 27 16:47:54 2010 @@ -117,3 +117,9 @@ } return valobj_sp; } + +void +ValueObjectList::Swap (ValueObjectList &value_object_list) +{ + m_value_objects.swap (value_object_list.m_value_objects); +} Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=112301&r1=112300&r2=112301&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Fri Aug 27 16:47:54 2010 @@ -531,11 +531,14 @@ m_sc.DumpStopContext(strm, &m_thread.GetProcess(), GetFrameCodeAddress(), show_module, show_inline); } - void -StackFrame::SetSymbolContext (const SymbolContext& sc) +StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &frame) { - m_sc = sc; - m_flags.Clear(eSymbolContextEverything); - m_flags.Set(m_sc.GetResolvedMask ()); + assert (GetStackID() == frame.GetStackID()); // TODO: remove this after some testing + m_variable_list_sp = frame.m_variable_list_sp; + m_value_object_list.Swap (frame.m_value_object_list); + if (!m_disassembly.GetString().empty()) + m_disassembly.GetString().swap (m_disassembly.GetString()); } + + Modified: lldb/trunk/source/Target/StackFrameList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=112301&r1=112300&r2=112301&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrameList.cpp (original) +++ lldb/trunk/source/Target/StackFrameList.cpp Fri Aug 27 16:47:54 2010 @@ -151,9 +151,9 @@ StackFrameList *curr_frames = this; #if defined (DEBUG_STACK_FRAMES) - s.PutCString("prev_frames:\n"); + s.PutCString("\nprev_frames:\n"); prev_frames->Dump (&s); - s.PutCString("curr_frames:\n"); + s.PutCString("\ncurr_frames:\n"); curr_frames->Dump (&s); s.EOL(); #endif @@ -203,8 +203,6 @@ // Same function different block if (m_show_inlined_frames) break; - else - prev_frame->SetSymbolContext (curr_frame->m_sc); } } else if (curr_sc.symbol && curr_sc.symbol == prev_sc.symbol) @@ -217,27 +215,22 @@ break; } - if (curr_frame->GetFrameCodeAddress() != prev_frame->GetFrameCodeAddress()) - { -#if defined (DEBUG_STACK_FRAMES) - s.Printf("\nUpdating frame code address and symbol context in previous frame #%u to current frame #%u", prev_frame_idx, curr_frame_idx); -#endif - // We have a different code frame address, we might need to copy - // some stuff in prev_frame, yet update the code address... - prev_frame->SetFrameCodeAddress (curr_frame->GetFrameCodeAddress()); - prev_frame->SetSymbolContext (curr_frame->m_sc); - } - - curr_frames->m_frames[curr_frame_idx] = prev_frames->m_frames[prev_frame_idx]; + curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame); #if defined (DEBUG_STACK_FRAMES) - s.Printf("\nCopying previous frame #%u to current frame #%u", prev_frame_idx, curr_frame_idx); + s.Printf("\n Copying previous frame to current frame"); #endif } // We are done with the old stack frame list, we can release it now m_prev_frames_ap.release(); prev_frames = NULL; } + +#if defined (DEBUG_STACK_FRAMES) + s.PutCString("\n\nNew frames:\n"); + Dump (&s); + s.EOL(); +#endif } else { From johnny.chen at apple.com Fri Aug 27 17:35:26 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 27 Aug 2010 22:35:26 -0000 Subject: [Lldb-commits] [lldb] r112308 - in /lldb/trunk: include/lldb/API/SBFileSpec.h scripts/Python/build-swig-Python.sh scripts/lldb.swig source/API/SBFileSpec.cpp tools/driver/IOChannel.cpp Message-ID: <20100827223526.C7A372A6C12C@llvm.org> Author: johnny Date: Fri Aug 27 17:35:26 2010 New Revision: 112308 URL: http://llvm.org/viewvc/llvm-project?rev=112308&view=rev Log: o Exposed SBFileSpec to the Python APIs in lldb.py. o Fixed a crasher when getting it via SBTarget.GetExecutable(). >>> filespec = target.GetExecutable() Segmentation fault o And renamed SBFileSpec::GetFileName() to GetFilename() to be consistent with FileSpec::GetFilename(). Modified: lldb/trunk/include/lldb/API/SBFileSpec.h lldb/trunk/scripts/Python/build-swig-Python.sh lldb/trunk/scripts/lldb.swig lldb/trunk/source/API/SBFileSpec.cpp lldb/trunk/tools/driver/IOChannel.cpp Modified: lldb/trunk/include/lldb/API/SBFileSpec.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFileSpec.h?rev=112308&r1=112307&r2=112308&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBFileSpec.h (original) +++ lldb/trunk/include/lldb/API/SBFileSpec.h Fri Aug 27 17:35:26 2010 @@ -37,7 +37,7 @@ Exists () const; const char * - GetFileName() const; + GetFilename() const; const char * GetDirectory() const; Modified: lldb/trunk/scripts/Python/build-swig-Python.sh URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/build-swig-Python.sh?rev=112308&r1=112307&r2=112308&view=diff ============================================================================== --- lldb/trunk/scripts/Python/build-swig-Python.sh (original) +++ lldb/trunk/scripts/Python/build-swig-Python.sh Fri Aug 27 17:35:26 2010 @@ -42,6 +42,7 @@ " ${SRC_ROOT}/include/lldb/API/SBDebugger.h"\ " ${SRC_ROOT}/include/lldb/API/SBError.h"\ " ${SRC_ROOT}/include/lldb/API/SBEvent.h"\ +" ${SRC_ROOT}/include/lldb/API/SBFileSpec.h"\ " ${SRC_ROOT}/include/lldb/API/SBFrame.h"\ " ${SRC_ROOT}/include/lldb/API/SBFunction.h"\ " ${SRC_ROOT}/include/lldb/API/SBLineEntry.h"\ Modified: lldb/trunk/scripts/lldb.swig URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=112308&r1=112307&r2=112308&view=diff ============================================================================== --- lldb/trunk/scripts/lldb.swig (original) +++ lldb/trunk/scripts/lldb.swig Fri Aug 27 17:35:26 2010 @@ -83,6 +83,7 @@ #include "lldb/API/SBDebugger.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" +#include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBFunction.h" #include "lldb/API/SBLineEntry.h" @@ -136,6 +137,7 @@ %include "lldb/API/SBDebugger.h" %include "lldb/API/SBError.h" %include "lldb/API/SBEvent.h" +%include "lldb/API/SBFileSpec.h" %include "lldb/API/SBFrame.h" %include "lldb/API/SBFunction.h" %include "lldb/API/SBLineEntry.h" Modified: lldb/trunk/source/API/SBFileSpec.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFileSpec.cpp?rev=112308&r1=112307&r2=112308&view=diff ============================================================================== --- lldb/trunk/source/API/SBFileSpec.cpp (original) +++ lldb/trunk/source/API/SBFileSpec.cpp Fri Aug 27 17:35:26 2010 @@ -24,7 +24,7 @@ m_opaque_ap() { if (rhs.m_opaque_ap.get()) - m_opaque_ap.reset (new FileSpec (*m_opaque_ap)); + m_opaque_ap.reset (new FileSpec (rhs.get())); } SBFileSpec::SBFileSpec (const char *path) : @@ -69,7 +69,7 @@ } const char * -SBFileSpec::GetFileName() const +SBFileSpec::GetFilename() const { if (m_opaque_ap.get()) return m_opaque_ap->GetFilename().AsCString(); Modified: lldb/trunk/tools/driver/IOChannel.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/IOChannel.cpp?rev=112308&r1=112307&r2=112308&view=diff ============================================================================== --- lldb/trunk/tools/driver/IOChannel.cpp (original) +++ lldb/trunk/tools/driver/IOChannel.cpp Fri Aug 27 17:35:26 2010 @@ -163,7 +163,7 @@ m_err_file (err), m_command_queue (), m_completion_key ("\t"), - m_edit_line (::el_init (SBHostOS::GetProgramFileSpec().GetFileName(), in, out, err)), + m_edit_line (::el_init (SBHostOS::GetProgramFileSpec().GetFilename(), in, out, err)), m_history (history_init()), m_history_event(), m_getting_command (false) @@ -213,7 +213,7 @@ if (m_history != NULL) { char history_path[PATH_MAX]; - ::snprintf (history_path, sizeof(history_path), "~/.%s-history", SBHostOS::GetProgramFileSpec().GetFileName()); + ::snprintf (history_path, sizeof(history_path), "~/.%s-history", SBHostOS::GetProgramFileSpec().GetFilename()); if ((size_t)SBFileSpec::ResolvePath (history_path, history_path, sizeof(history_path)) < sizeof(history_path) - 1) { const char *path_ptr = history_path; From johnny.chen at apple.com Fri Aug 27 17:39:49 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 27 Aug 2010 22:39:49 -0000 Subject: [Lldb-commits] [lldb] r112311 - /lldb/trunk/test/hello_world/TestHelloWorld.py Message-ID: <20100827223949.857452A6C12C@llvm.org> Author: johnny Date: Fri Aug 27 17:39:49 2010 New Revision: 112311 URL: http://llvm.org/viewvc/llvm-project?rev=112311&view=rev Log: Fixed a typo in the method name. Modified: lldb/trunk/test/hello_world/TestHelloWorld.py Modified: lldb/trunk/test/hello_world/TestHelloWorld.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/hello_world/TestHelloWorld.py?rev=112311&r1=112310&r2=112311&view=diff ============================================================================== --- lldb/trunk/test/hello_world/TestHelloWorld.py (original) +++ lldb/trunk/test/hello_world/TestHelloWorld.py Fri Aug 27 17:39:49 2010 @@ -10,7 +10,7 @@ mydir = "hello_world" @unittest2.expectedFailure - def test_hellp_world_python(self): + def test_hello_world_python(self): """Create target, breakpoint, launch a process, and then kill it.""" exe = os.path.join(os.getcwd(), "a.out") From scallanan at apple.com Fri Aug 27 18:31:21 2010 From: scallanan at apple.com (Sean Callanan) Date: Fri, 27 Aug 2010 23:31:21 -0000 Subject: [Lldb-commits] [lldb] r112324 - in /lldb/trunk: include/lldb/Expression/ClangExpression.h include/lldb/Expression/ClangExpressionParser.h include/lldb/Expression/ClangUserExpression.h include/lldb/Expression/ClangUtilityFunction.h include/lldb/Expression/RecordingMemoryManager.h lldb.xcodeproj/project.pbxproj source/Expression/ClangExpressionParser.cpp source/Expression/ClangFunction.cpp source/Expression/ClangUserExpression.cpp source/Expression/ClangUtilityFunction.cpp Message-ID: <20100827233121.D56F22A6C12C@llvm.org> Author: spyffe Date: Fri Aug 27 18:31:21 2010 New Revision: 112324 URL: http://llvm.org/viewvc/llvm-project?rev=112324&view=rev Log: Added a ClangUtilityFunction class that allows the debugger to insert self-contained functions for use by expressions (mainly for error-checking). In order to support detecting whether a crash occurred in one of these helpers -- currently our preferred way of reporting that an error-check failed -- added a bit of support for getting the extent of a JITted function in addition to just its base. Added: lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h lldb/trunk/source/Expression/ClangUtilityFunction.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h lldb/trunk/include/lldb/Expression/ClangExpressionParser.h lldb/trunk/include/lldb/Expression/ClangUserExpression.h lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Expression/ClangExpressionParser.cpp lldb/trunk/source/Expression/ClangFunction.cpp lldb/trunk/source/Expression/ClangUserExpression.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpression.h?rev=112324&r1=112323&r2=112324&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpression.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpression.h Fri Aug 27 18:31:21 2010 @@ -42,6 +42,13 @@ { public: //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + virtual ~ClangExpression () + { + } + + //------------------------------------------------------------------ /// Return the string that the parser should parse. Must be a full /// translation unit. //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Expression/ClangExpressionParser.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionParser.h?rev=112324&r1=112323&r2=112324&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionParser.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionParser.h Fri Aug 27 18:31:21 2010 @@ -93,7 +93,12 @@ /// @param[out] func_addr /// The address to which the function has been written. /// - /// @para[in] exe_ctx + /// @param[out] func_end + /// The end of the function's allocated memory region. (func_addr + /// and func_end do not delimit an allocated region; the allocated + /// region may begin before func_addr.) + /// + /// @param[in] exe_ctx /// The execution context to write the function into. /// /// @return @@ -101,7 +106,8 @@ /// Test with Success(). //------------------------------------------------------------------ Error - MakeJIT (lldb::addr_t &func_addr, + MakeJIT (lldb::addr_t &func_addr, + lldb::addr_t &func_end, ExecutionContext &exe_ctx); //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Expression/ClangUserExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUserExpression.h?rev=112324&r1=112323&r2=112324&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangUserExpression.h (original) +++ lldb/trunk/include/lldb/Expression/ClangUserExpression.h Fri Aug 27 18:31:21 2010 @@ -48,6 +48,11 @@ ClangUserExpression (const char *expr); //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + virtual ~ClangUserExpression (); + + //------------------------------------------------------------------ /// Parse the expression /// /// @param[in] error_stream Added: lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h?rev=112324&view=auto ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h (added) +++ lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h Fri Aug 27 18:31:21 2010 @@ -0,0 +1,176 @@ +//===-- ClangUtilityFunction.h ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangUtilityFunction_h_ +#define liblldb_ClangUtilityFunction_h_ + +// C Includes +// C++ Includes +#include +#include +#include +#include + +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Expression/ClangExpression.h" + +namespace lldb_private +{ + +//---------------------------------------------------------------------- +/// @class ClangUtilityFunction ClangUtilityFunction.h "lldb/Expression/ClangUtilityFunction.h" +/// @brief Encapsulates a single expression for use with Clang +/// +/// LLDB uses expressions for various purposes, notably to call functions +/// and as a backend for the expr command. ClangUtilityFunction encapsulates +/// a self-contained function meant to be used from other code. Utility +/// functions can perform error-checking for ClangUserExpressions, +//---------------------------------------------------------------------- +class ClangUtilityFunction : public ClangExpression +{ +public: + //------------------------------------------------------------------ + /// Constructor + /// + /// @param[in] text + /// The text of the function. Must be a full translation unit. + /// + /// @param[in] name + /// The name of the function, as used in the text. + //------------------------------------------------------------------ + ClangUtilityFunction (const char *text, + const char *name); + + //------------------------------------------------------------------ + /// Install the utility function into a process + /// + /// @param[in] error_stream + /// A stream to print parse errors and warnings to. + /// + /// @param[in] exe_ctx + /// The execution context to install the utility function to. + /// + /// @return + /// True on success (no errors); false otherwise. + //------------------------------------------------------------------ + bool + Install (Stream &error_stream, ExecutionContext &exe_ctx); + + //------------------------------------------------------------------ + /// Check whether the given PC is inside the function + /// + /// Especially useful if the function dereferences NULL to indicate a failed + /// assert. + /// + /// @param[in] pc + /// The program counter to check. + /// + /// @return + /// True if the program counter falls within the function's bounds; + /// false if not (or the function is not JIT compiled) + //------------------------------------------------------------------ + bool + ContainsAddress (lldb::addr_t address) + { + // nothing is both >= LLDB_INVALID_ADDRESS and < LLDB_INVALID_ADDRESS, + // so this always returns false if the function is not JIT compiled yet + return (address >= m_jit_begin && address < m_jit_end); + } + + //------------------------------------------------------------------ + /// Return the address of the function's JIT-compiled code, or + /// LLDB_INVALID_ADDRESS if the function is not JIT compiled + //------------------------------------------------------------------ + lldb::addr_t + StartAddress () + { + return m_jit_begin; + } + + //------------------------------------------------------------------ + /// Return the string that the parser should parse. Must be a full + /// translation unit. + //------------------------------------------------------------------ + const char * + Text () + { + return m_function_text.c_str(); + } + + //------------------------------------------------------------------ + /// Return the function name that should be used for executing the + /// expression. Text() should contain the definition of this + /// function. + //------------------------------------------------------------------ + const char * + FunctionName () + { + return m_function_name.c_str(); + } + + //------------------------------------------------------------------ + /// Return the object that the parser should use when resolving external + /// values. May be NULL if everything should be self-contained. + //------------------------------------------------------------------ + ClangExpressionDeclMap * + DeclMap () + { + return NULL; + } + + //------------------------------------------------------------------ + /// Return the object that the parser should use when registering + /// local variables. May be NULL if the Expression doesn't care. + //------------------------------------------------------------------ + ClangExpressionVariableStore * + LocalVariables () + { + return NULL; + } + + //------------------------------------------------------------------ + /// Return the object that the parser should allow to access ASTs. + /// May be NULL if the ASTs do not need to be transformed. + /// + /// @param[in] passthrough + /// The ASTConsumer that the returned transformer should send + /// the ASTs to after transformation. + //------------------------------------------------------------------ + clang::ASTConsumer * + ASTTransformer (clang::ASTConsumer *passthrough) + { + return NULL; + } + + //------------------------------------------------------------------ + /// Return the stream that the parser should use to write DWARF + /// opcodes. + //------------------------------------------------------------------ + StreamString & + DwarfOpcodeStream () + { + return *((StreamString*)NULL); + } + +private: + std::string m_function_text; ///< The text of the function. Must be a well-formed translation unit. + std::string m_function_name; ///< The name of the function. + + lldb::addr_t m_jit_begin; ///< The address of the JITted code. LLDB_INVALID_ADDRESS if invalid. + lldb::addr_t m_jit_end; ///< The end of the JITted code. LLDB_INVALID_ADDRESS if invalid. +}; + +} // namespace lldb_private + +#endif // liblldb_ClangUtilityFunction_h_ Modified: lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h?rev=112324&r1=112323&r2=112324&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h (original) +++ lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h Fri Aug 27 18:31:21 2010 @@ -52,7 +52,9 @@ //---------------------------------------------------------------------- class RecordingMemoryManager : public llvm::JITMemoryManager { -friend Error ClangExpressionParser::MakeJIT (uint64_t &, ExecutionContext &); +friend Error ClangExpressionParser::MakeJIT (uint64_t &, + uint64_t&, + ExecutionContext &); public: //------------------------------------------------------------------ Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112324&r1=112323&r2=112324&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Aug 27 18:31:21 2010 @@ -336,6 +336,8 @@ 49445C2612245E3600C11A81 /* ClangExpressionParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49445C2512245E3600C11A81 /* ClangExpressionParser.cpp */; }; 49445C2A12245E5500C11A81 /* ClangExpressionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 49445C2912245E5500C11A81 /* ClangExpressionParser.h */; }; 49445E351225AB6A00C11A81 /* ClangUserExpression.h in Headers */ = {isa = PBXBuildFile; fileRef = 49445E341225AB6A00C11A81 /* ClangUserExpression.h */; }; + 497C86BE122823D800B54702 /* ClangUtilityFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 497C86BD122823D800B54702 /* ClangUtilityFunction.cpp */; }; + 497C86C2122823F300B54702 /* ClangUtilityFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 497C86C1122823F300B54702 /* ClangUtilityFunction.h */; }; 49A8A3A011D568A300AD3B68 /* ASTResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ASTResultSynthesizer.cpp */; }; 49A8A3A411D568BF00AD3B68 /* ASTResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ASTResultSynthesizer.h */; }; 49BB309611F79450001A4197 /* TaggedASTType.h in Headers */ = {isa = PBXBuildFile; fileRef = 49BB309511F79450001A4197 /* TaggedASTType.h */; }; @@ -919,6 +921,8 @@ 495BBACF119A0DE700418BEA /* PathMappingList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PathMappingList.h; path = include/lldb/Target/PathMappingList.h; sourceTree = ""; }; 497650CE11A21BEE008DDB57 /* ABIMacOSX_i386.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ABIMacOSX_i386.cpp; path = "ABI/MacOSX-i386/ABIMacOSX_i386.cpp"; sourceTree = ""; }; 497650CF11A21BEE008DDB57 /* ABIMacOSX_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ABIMacOSX_i386.h; path = "ABI/MacOSX-i386/ABIMacOSX_i386.h"; sourceTree = ""; }; + 497C86BD122823D800B54702 /* ClangUtilityFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangUtilityFunction.cpp; path = source/Expression/ClangUtilityFunction.cpp; sourceTree = ""; }; + 497C86C1122823F300B54702 /* ClangUtilityFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangUtilityFunction.h; path = include/lldb/Expression/ClangUtilityFunction.h; sourceTree = ""; }; 497E7B331188ED300065CCA1 /* ABI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ABI.h; path = include/lldb/Target/ABI.h; sourceTree = ""; }; 497E7B9D1188F6690065CCA1 /* ABI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ABI.cpp; path = source/Target/ABI.cpp; sourceTree = ""; }; 499F381E11A5B3F300F5CE02 /* CommandObjectArgs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectArgs.h; path = source/Commands/CommandObjectArgs.h; sourceTree = ""; }; @@ -1854,8 +1858,6 @@ 49D7072611B5AD03001AD875 /* ClangASTSource.h */, 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */, 26BC7DC010F1B79500F91463 /* ClangExpression.h */, - 49445E341225AB6A00C11A81 /* ClangUserExpression.h */, - 26BC7ED510F1B86700F91463 /* ClangUserExpression.cpp */, 4C98D3E0118FB98F00E575D0 /* ClangFunction.h */, 4C98D3DA118FB96F00E575D0 /* ClangFunction.cpp */, 49F1A74911B338AE003ED505 /* ClangExpressionDeclMap.h */, @@ -1866,6 +1868,10 @@ 26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */, 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */, 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */, + 49445E341225AB6A00C11A81 /* ClangUserExpression.h */, + 26BC7ED510F1B86700F91463 /* ClangUserExpression.cpp */, + 497C86C1122823F300B54702 /* ClangUtilityFunction.h */, + 497C86BD122823D800B54702 /* ClangUtilityFunction.cpp */, 26BC7DC310F1B79500F91463 /* DWARFExpression.h */, 26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */, 49A8A3A311D568BF00AD3B68 /* ASTResultSynthesizer.h */, @@ -2243,6 +2249,7 @@ 49445C2A12245E5500C11A81 /* ClangExpressionParser.h in Headers */, 49445E351225AB6A00C11A81 /* ClangUserExpression.h in Headers */, 4911934C1226383D00578B7F /* ASTStructExtractor.h in Headers */, + 497C86C2122823F300B54702 /* ClangUtilityFunction.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2700,6 +2707,7 @@ 49FB515E121481B000DF8983 /* DWARFExpression.cpp in Sources */, 49445C2612245E3600C11A81 /* ClangExpressionParser.cpp in Sources */, 491193521226386000578B7F /* ASTStructExtractor.cpp in Sources */, + 497C86BE122823D800B54702 /* ClangUtilityFunction.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=112324&r1=112323&r2=112324&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Fri Aug 27 18:31:21 2010 @@ -369,7 +369,9 @@ } Error -ClangExpressionParser::MakeJIT (lldb::addr_t &func_addr, ExecutionContext &exe_ctx) +ClangExpressionParser::MakeJIT (lldb::addr_t &func_addr, + lldb::addr_t &func_end, + ExecutionContext &exe_ctx) { Error err; @@ -507,7 +509,10 @@ (*pos).m_remote_addr = m_jit_mm->GetRemoteAddressForLocal ((*pos).m_local_addr); if (!(*pos).m_name.compare(m_expr.FunctionName())) + { + func_end = m_jit_mm->GetRemoteRangeForLocal ((*pos).m_local_addr).second; func_addr = (*pos).m_remote_addr; + } } err.Clear(); Modified: lldb/trunk/source/Expression/ClangFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=112324&r1=112323&r2=112324&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangFunction.cpp (original) +++ lldb/trunk/source/Expression/ClangFunction.cpp Fri Aug 27 18:31:21 2010 @@ -227,7 +227,9 @@ if (m_JITted) return true; - Error jit_error = m_parser->MakeJIT(m_wrapper_function_addr, exe_ctx); + lldb::addr_t wrapper_function_end; + + Error jit_error = m_parser->MakeJIT(m_wrapper_function_addr, wrapper_function_end, exe_ctx); if (!jit_error.Success()) return false; Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=112324&r1=112323&r2=112324&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangUserExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangUserExpression.cpp Fri Aug 27 18:31:21 2010 @@ -45,6 +45,10 @@ m_transformed_text = m_transformed_stream.GetData(); } +ClangUserExpression::~ClangUserExpression () +{ +} + clang::ASTConsumer * ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough) { @@ -123,7 +127,9 @@ m_dwarf_opcodes.reset(); - Error jit_error = parser.MakeJIT (m_jit_addr, exe_ctx); + lldb::addr_t jit_end; + + Error jit_error = parser.MakeJIT (m_jit_addr, jit_end, exe_ctx); if (jit_error.Success()) { Added: lldb/trunk/source/Expression/ClangUtilityFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUtilityFunction.cpp?rev=112324&view=auto ============================================================================== --- lldb/trunk/source/Expression/ClangUtilityFunction.cpp (added) +++ lldb/trunk/source/Expression/ClangUtilityFunction.cpp Fri Aug 27 18:31:21 2010 @@ -0,0 +1,116 @@ +//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C Includes +#include +#if HAVE_SYS_TYPES_H +# include +#endif + +// C++ Includes + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/Stream.h" +#include "lldb/Expression/ClangExpressionParser.h" +#include "lldb/Expression/ClangUtilityFunction.h" +#include "lldb/Host/Host.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Target.h" + +using namespace lldb_private; + +//------------------------------------------------------------------ +/// Constructor +/// +/// @param[in] text +/// The text of the function. Must be a full translation unit. +/// +/// @param[in] name +/// The name of the function, as used in the text. +//------------------------------------------------------------------ +ClangUtilityFunction::ClangUtilityFunction (const char *text, + const char *name) : + m_function_text(text), + m_function_name(name) +{ +} + +//------------------------------------------------------------------ +/// Install the utility function into a process +/// +/// @param[in] error_stream +/// A stream to print parse errors and warnings to. +/// +/// @param[in] exe_ctx +/// The execution context to install the utility function to. +/// +/// @return +/// True on success (no errors); false otherwise. +//------------------------------------------------------------------ +bool +ClangUtilityFunction::Install (Stream &error_stream, + ExecutionContext &exe_ctx) +{ + //////////////////////////////////// + // Set up the target and compiler + // + + Target *target = exe_ctx.target; + + if (!target) + { + error_stream.PutCString ("error: invalid target\n"); + return false; + } + + ConstString target_triple; + + target->GetTargetTriple (target_triple); + + if (!target_triple) + target_triple = Host::GetTargetTriple (); + + if (!target_triple) + { + error_stream.PutCString ("error: invalid target triple\n"); + return false; + } + + ////////////////////////// + // Parse the expression + // + + ClangExpressionParser parser(target_triple.GetCString(), *this); + + unsigned num_errors = parser.Parse (error_stream); + + if (num_errors) + { + error_stream.Printf ("error: %d errors parsing expression\n", num_errors); + return false; + } + + ////////////////////////////////// + // JIT the output of the parser + // + + Error jit_error = parser.MakeJIT (m_jit_begin, m_jit_end, exe_ctx); + + if (jit_error.Success()) + { + return true; + } + else + { + error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors); + return false; + } +} + + From johnny.chen at apple.com Fri Aug 27 18:47:36 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 27 Aug 2010 23:47:36 -0000 Subject: [Lldb-commits] [lldb] r112327 - in /lldb/trunk/test: array_types/TestArrayTypes.py bitfields/TestBitfields.py class_types/TestClassTypes.py dead-strip/TestDeadStrip.py enum_types/TestEnumTypes.py function_types/TestFunctionTypes.py global_variables/TestGlobalVariables.py lldbtest.py load_unload/TestLoadUnload.py macosx/universal/TestUniversal.py persistent_variables/TestPersistentVariables.py set_values/TestSetValues.py stl/TestSTL.py struct_types/TestStructTypes.py unsigned_types/TestUnsignedTypes.py Message-ID: <20100827234736.D3D812A6C12C@llvm.org> Author: johnny Date: Fri Aug 27 18:47:36 2010 New Revision: 112327 URL: http://llvm.org/viewvc/llvm-project?rev=112327&view=rev Log: Added a test case test_breakpoint_creation_by_filespec_python() which creates a breakpoint by FileSpec and line number and exercises some FileSpec APIs. Also, RUN_STOPPED is a bad assert name, RUN_SUCCEEDED is better. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/bitfields/TestBitfields.py lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/dead-strip/TestDeadStrip.py lldb/trunk/test/enum_types/TestEnumTypes.py lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/global_variables/TestGlobalVariables.py lldb/trunk/test/lldbtest.py lldb/trunk/test/load_unload/TestLoadUnload.py lldb/trunk/test/macosx/universal/TestUniversal.py lldb/trunk/test/persistent_variables/TestPersistentVariables.py lldb/trunk/test/set_values/TestSetValues.py lldb/trunk/test/stl/TestSTL.py lldb/trunk/test/struct_types/TestStructTypes.py lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Fri Aug 27 18:47:36 2010 @@ -18,7 +18,7 @@ self.expect("breakpoint set -f main.c -l 42", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.c', line = 42, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, @@ -62,7 +62,7 @@ breakpoint = target.BreakpointCreateByLocation("main.c", 42) self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # This does not work, and results in the process stopped at dyld_start? #process = target.LaunchProcess([''], [''], os.ctermid(), False) Modified: lldb/trunk/test/bitfields/TestBitfields.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/bitfields/TestBitfields.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/bitfields/TestBitfields.py (original) +++ lldb/trunk/test/bitfields/TestBitfields.py Fri Aug 27 18:47:36 2010 @@ -19,7 +19,7 @@ self.expect("breakpoint set -f main.c -l 42", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.c', line = 42, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, @@ -63,7 +63,7 @@ breakpoint = target.BreakpointCreateByLocation("main.c", 42) self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # This does not work, and results in the process stopped at dyld_start? #process = target.LaunchProcess([''], [''], os.ctermid(), False) Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Fri Aug 27 18:47:36 2010 @@ -18,7 +18,7 @@ self.expect("breakpoint set -f main.cpp -l 73", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.cpp', line = 73, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, @@ -33,6 +33,25 @@ self.expect("variable list this", VARIABLES_DISPLAYED_CORRECTLY, startstr = '(class C *const) this = ') + def test_breakpoint_creation_by_filespec_python(self): + """Use Python APIs to create a breakpoint by (filespec, line).""" + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + filespec = target.GetExecutable() + self.assertTrue(filespec.IsValid(), VALID_FILESPEC) + + breakpoint = target.BreakpointCreateByLocation(filespec, 73) + self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) + + fsDir = filespec.GetDirectory() + fsFile = filespec.GetFilename() + + self.assertTrue(fsDir == os.getcwd() and fsFile == "a.out", + "FileSpec matches the executable") + if __name__ == '__main__': import atexit Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/TestDeadStrip.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Fri Aug 27 18:47:36 2010 @@ -28,7 +28,7 @@ self.expect("breakpoint set -s a.out -n f3", BREAKPOINT_CREATED, startstr = "Breakpoint created: 3: name = 'f3', module = a.out, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint (breakpoint #1). self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, Modified: lldb/trunk/test/enum_types/TestEnumTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/enum_types/TestEnumTypes.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/enum_types/TestEnumTypes.py (original) +++ lldb/trunk/test/enum_types/TestEnumTypes.py Fri Aug 27 18:47:36 2010 @@ -18,7 +18,7 @@ self.expect("breakpoint set -f main.c -l 26", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.c', line = 26, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Fri Aug 27 18:47:36 2010 @@ -18,7 +18,7 @@ self.expect("breakpoint set -f main.c -l 21", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.c', line = 21, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/TestGlobalVariables.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Fri Aug 27 18:47:36 2010 @@ -18,7 +18,7 @@ self.expect("breakpoint set -f main.c -l 20", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.c', line = 20, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Aug 27 18:47:36 2010 @@ -117,7 +117,7 @@ CURRENT_EXECUTABLE_SET = "Current executable set successfully" -RUN_STOPPED = "Process is launched and then stopped successfully" +RUN_SUCCEEDED = "Process is launched successfully" RUN_COMPLETED = "Process exited successfully" @@ -135,6 +135,8 @@ VALID_BREAKPOINT = "Got a valid breakpoint" +VALID_FILESPEC = "Got a valid filespec" + VALID_PROCESS = "Got a valid process" VALID_TARGET = "Got a valid target" Modified: lldb/trunk/test/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/TestLoadUnload.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Fri Aug 27 18:47:36 2010 @@ -20,7 +20,7 @@ self.expect("breakpoint set -n a_function", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: name = 'a_function', locations = 0 (pending)") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint and at a_function. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, Modified: lldb/trunk/test/macosx/universal/TestUniversal.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/TestUniversal.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/macosx/universal/TestUniversal.py (original) +++ lldb/trunk/test/macosx/universal/TestUniversal.py Fri Aug 27 18:47:36 2010 @@ -25,7 +25,7 @@ startstr = "Breakpoint created: 1: file ='main.c', line = 5, locations = 1") # We should be able to launch the x86_64 executable. - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # Check whether we have a 64-bit process launched. target = self.dbg.GetSelectedTarget() @@ -46,7 +46,7 @@ startstr = "Breakpoint created: 1: file ='main.c', line = 5, locations = 1") # We should be able to launch the i386 executable as well. - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # Check whether we have a 32-bit process launched. target = self.dbg.GetSelectedTarget() Modified: lldb/trunk/test/persistent_variables/TestPersistentVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/persistent_variables/TestPersistentVariables.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/persistent_variables/TestPersistentVariables.py (original) +++ lldb/trunk/test/persistent_variables/TestPersistentVariables.py Fri Aug 27 18:47:36 2010 @@ -17,7 +17,7 @@ self.runCmd("breakpoint set --name main") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) self.runCmd("expr int $i = 5; $i + 1") # $0 = (int)6 Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Fri Aug 27 18:47:36 2010 @@ -30,7 +30,7 @@ self.expect("breakpoint set -f main.c -l 85", BREAKPOINT_CREATED, startstr = "Breakpoint created: 5: file ='main.c', line = 85, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Fri Aug 27 18:47:36 2010 @@ -26,7 +26,7 @@ self.expect("breakpoint set -f main.cpp -l 13", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.cpp', line = 13, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # Stop at 'std::string hello_world ("Hello World!");'. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, Modified: lldb/trunk/test/struct_types/TestStructTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/struct_types/TestStructTypes.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/struct_types/TestStructTypes.py (original) +++ lldb/trunk/test/struct_types/TestStructTypes.py Fri Aug 27 18:47:36 2010 @@ -22,7 +22,7 @@ self.expect("breakpoint set -f main.c -l 14", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.c', line = 14, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # We should be stopped on the first executable statement within the # function where the original breakpoint was attempted. Modified: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/TestUnsignedTypes.py?rev=112327&r1=112326&r2=112327&view=diff ============================================================================== --- lldb/trunk/test/unsigned_types/TestUnsignedTypes.py (original) +++ lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Fri Aug 27 18:47:36 2010 @@ -21,7 +21,7 @@ self.expect("breakpoint set -f main.cpp -l 19", BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.cpp', line = 19, locations = 1") - self.runCmd("run", RUN_STOPPED) + self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, From johnny.chen at apple.com Fri Aug 27 18:53:00 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 27 Aug 2010 23:53:00 -0000 Subject: [Lldb-commits] [lldb] r112328 - /lldb/trunk/test/persistent_variables/TestPersistentVariables.py Message-ID: <20100827235300.BE0472A6C12C@llvm.org> Author: johnny Date: Fri Aug 27 18:53:00 2010 New Revision: 112328 URL: http://llvm.org/viewvc/llvm-project?rev=112328&view=rev Log: Fail early, fail fast. Modified: lldb/trunk/test/persistent_variables/TestPersistentVariables.py Modified: lldb/trunk/test/persistent_variables/TestPersistentVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/persistent_variables/TestPersistentVariables.py?rev=112328&r1=112327&r2=112328&view=diff ============================================================================== --- lldb/trunk/test/persistent_variables/TestPersistentVariables.py (original) +++ lldb/trunk/test/persistent_variables/TestPersistentVariables.py Fri Aug 27 18:53:00 2010 @@ -19,18 +19,21 @@ self.runCmd("run", RUN_SUCCEEDED) - self.runCmd("expr int $i = 5; $i + 1") - # $0 = (int)6 - - self.runCmd("expr $i + 3") - # $1 = (int)8 - - self.runCmd("expr $1 + $0") - # $2 = (int)14 + self.expect("expr int $i = 5; $i + 1", + startstr = "$0 = (int) 6") + # $0 = (int) 6 + + self.expect("expr $i + 3", + startstr = "$1 = (int) 8") + # $1 = (int) 8 + + self.expect("expr $1 + $0", + startstr = "$2 = (int) 14") + # $2 = (int) 14 self.expect("expr $2", startstr = "$3 = (int) 14") - # $3 = (int)14 + # $3 = (int) 14 if __name__ == '__main__': From gclayton at apple.com Fri Aug 27 19:08:07 2010 From: gclayton at apple.com (Greg Clayton) Date: Sat, 28 Aug 2010 00:08:07 -0000 Subject: [Lldb-commits] [lldb] r112331 - /lldb/trunk/source/Core/ValueObject.cpp Message-ID: <20100828000807.2D6B12A6C12C@llvm.org> Author: gclayton Date: Fri Aug 27 19:08:07 2010 New Revision: 112331 URL: http://llvm.org/viewvc/llvm-project?rev=112331&view=rev Log: Detect when ValueObject values change each time they are evaluated. Modified: lldb/trunk/source/Core/ValueObject.cpp Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=112331&r1=112330&r2=112331&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Fri Aug 27 19:08:07 2010 @@ -77,13 +77,43 @@ const user_id_t stop_id = process->GetStopID(); if (m_update_id != stop_id) { - m_value_str.clear(); + // Save the old value using swap to avoid a string copy which + // also will clear our m_value_str + std::string old_value_str; + old_value_str.swap (m_value_str); m_location_str.clear(); m_summary_str.clear(); + const bool value_was_valid = GetValueIsValid(); + SetValueDidChange (false); + + m_error.Clear(); + + // Call the pure virtual function to update the value UpdateValue (exe_scope); - if (m_error.Success()) - m_update_id = stop_id; + + // Update the fact that we tried to update the value for this + // value object wether or not we succeed + m_update_id = stop_id; + bool success = m_error.Success(); + SetValueIsValid (success); + // If the variable hasn't already been marked as changed do it + // by comparing the old any new value + if (!GetValueDidChange()) + { + if (success) + { + // The value was gotten successfully, so we consider the + // value as changed if the value string differs + SetValueDidChange (old_value_str != m_value_str); + } + else + { + // The value wasn't gotten successfully, so we mark this + // as changed if the value used to be valid and now isn't + SetValueDidChange (value_was_valid); + } + } } } }