From johnny.chen at apple.com Mon Aug 16 16:28:10 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 16 Aug 2010 21:28:10 -0000 Subject: [Lldb-commits] [lldb] r111188 - in /lldb/trunk/test: array_types/TestArrayTypes.py class_types/TestClassTypes.py dead-strip/TestDeadStrip.py function_types/TestFunctionTypes.py global_variables/TestGlobalVariables.py help/TestHelp.py lldbtest.py load_unload/TestLoadUnload.py order/TestOrderFile.py persistent_variables/TestPersistentVariables.py set_values/TestSetValues.py stl/TestSTL.py struct_types/TestStructTypes.py unsigned_types/TestUnsignedTypes.py Message-ID: <20100816212810.726E92A6C12C@llvm.org> Author: johnny Date: Mon Aug 16 16:28:10 2010 New Revision: 111188 URL: http://llvm.org/viewvc/llvm-project?rev=111188&view=rev Log: Factored the "continue" command execution of the inferior process as part of the cleanup before finish into the test fixture in lldbtest.TestBase.tearDown(). Derivatives of TestBase is responsible for setting self.runStarted to True if an inferior process has been started. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/dead-strip/TestDeadStrip.py lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/global_variables/TestGlobalVariables.py lldb/trunk/test/help/TestHelp.py lldb/trunk/test/lldbtest.py lldb/trunk/test/load_unload/TestLoadUnload.py lldb/trunk/test/order/TestOrderFile.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=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Mon Aug 16 16:28:10 2010 @@ -24,7 +24,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. @@ -73,9 +73,6 @@ self.assertTrue(res.GetOutput().startswith('(long [6])'), VARIABLES_DISPLAYED_CORRECTLY) - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Mon Aug 16 16:28:10 2010 @@ -24,7 +24,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. @@ -47,9 +47,6 @@ self.assertTrue(res.GetOutput().startswith('(class C *const) this = '), VARIABLES_DISPLAYED_CORRECTLY) - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) - 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=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Mon Aug 16 16:28:10 2010 @@ -43,7 +43,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint (breakpoint #1). @@ -81,9 +81,6 @@ self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Mon Aug 16 16:28:10 2010 @@ -24,7 +24,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. @@ -64,9 +64,6 @@ output.find('stop reason = breakpoint') > 0, STOPPED_DUE_TO_BREAKPOINT) - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/TestGlobalVariables.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Mon Aug 16 16:28:10 2010 @@ -24,7 +24,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. @@ -53,9 +53,6 @@ output.find('g_file_global_cstr') > 0, VARIABLES_DISPLAYED_CORRECTLY) - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/help/TestHelp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/help/TestHelp.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/help/TestHelp.py (original) +++ lldb/trunk/test/help/TestHelp.py Mon Aug 16 16:28:10 2010 @@ -17,7 +17,6 @@ """A simple test of 'help' command and its output.""" res = lldb.SBCommandReturnObject() self.ci.HandleCommand("help", res) - #time.sleep(0.1) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( 'The following is a list of built-in, permanent debugger commands'), @@ -27,10 +26,8 @@ """Command 'set term-width 0' should not hang the help command.""" res = lldb.SBCommandReturnObject() self.ci.HandleCommand("set term-width 0", res) - #time.sleep(0.1) self.assertTrue(res.Succeeded(), CMD_MSG('set term-width 0')) self.ci.HandleCommand("help", res) - #time.sleep(0.1) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( 'The following is a list of built-in, permanent debugger commands'), Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Aug 16 16:28:10 2010 @@ -64,6 +64,9 @@ # The concrete subclass should override this attribute. mydir = None + # State pertaining to the inferior process, if any. + runStarted = False + def setUp(self): #import traceback #traceback.print_stack() @@ -101,6 +104,10 @@ def tearDown(self): + # Finish the inferior process, if it was "run" previously. + if self.runStarted: + self.ci.HandleCommand("continue", self.res) + del self.dbg # Restore old working directory. Modified: lldb/trunk/test/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/TestLoadUnload.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Mon Aug 16 16:28:10 2010 @@ -28,7 +28,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint and at a_function. @@ -47,9 +47,6 @@ self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) - # # We should stop agaian at a_function. # # The stop reason of the thread should be breakpoint and at a_function. # self.ci.HandleCommand("thread list", res) Modified: lldb/trunk/test/order/TestOrderFile.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/order/TestOrderFile.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/order/TestOrderFile.py (original) +++ lldb/trunk/test/order/TestOrderFile.py Mon Aug 16 16:28:10 2010 @@ -31,6 +31,7 @@ "Symbols have correct order by the order file") self.ci.HandleCommand("run", res) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_COMPLETED) Modified: lldb/trunk/test/persistent_variables/TestPersistentVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/persistent_variables/TestPersistentVariables.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/persistent_variables/TestPersistentVariables.py (original) +++ lldb/trunk/test/persistent_variables/TestPersistentVariables.py Mon Aug 16 16:28:10 2010 @@ -22,6 +22,7 @@ self.assertTrue(res.Succeeded()) self.ci.HandleCommand("run", res) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) self.ci.HandleCommand("expr int $i = 5; $i + 1", res) @@ -48,6 +49,7 @@ self.ci.HandleCommand("continue", res) self.ci.HandleCommand("quit", res) + self.runStarted = False if __name__ == '__main__': Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Mon Aug 16 16:28:10 2010 @@ -44,7 +44,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. @@ -119,9 +119,6 @@ # TODO: # Now set variable 'i' and check that it is correctly displayed. - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Mon Aug 16 16:28:10 2010 @@ -31,7 +31,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # Stop at 'std::string hello_world ("Hello World!");'. @@ -70,9 +70,6 @@ output.find('stop reason = step in,') > 0, "Command 'thread backtrace' shows we stepped in STL") - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/struct_types/TestStructTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/struct_types/TestStructTypes.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/struct_types/TestStructTypes.py (original) +++ lldb/trunk/test/struct_types/TestStructTypes.py Mon Aug 16 16:28:10 2010 @@ -28,7 +28,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # We should be stopped on the first executable statement within the @@ -47,9 +47,6 @@ self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/TestUnsignedTypes.py?rev=111188&r1=111187&r2=111188&view=diff ============================================================================== --- lldb/trunk/test/unsigned_types/TestUnsignedTypes.py (original) +++ lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Mon Aug 16 16:28:10 2010 @@ -28,7 +28,7 @@ BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - #time.sleep(0.1) + self.runStarted = True self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. @@ -66,9 +66,6 @@ VARIABLES_DISPLAYED_CORRECTLY ) - - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) if __name__ == '__main__': From scallanan at apple.com Mon Aug 16 17:14:59 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 16 Aug 2010 22:14:59 -0000 Subject: [Lldb-commits] [lldb] r111194 - /lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Message-ID: <20100816221459.BFA5E2A6C12C@llvm.org> Author: spyffe Date: Mon Aug 16 17:14:59 2010 New Revision: 111194 URL: http://llvm.org/viewvc/llvm-project?rev=111194&view=rev Log: Documented ClangPersistentVariable(s). No API cleanup here, since this is a new and fairly clean class already. Modified: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Modified: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h?rev=111194&r1=111193&r2=111194&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h (original) +++ lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Mon Aug 16 17:14:59 2010 @@ -21,10 +21,23 @@ namespace lldb_private { +//---------------------------------------------------------------------- +/// @class ClangPersistentVariable ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h" +/// @brief Encapsulates a persistent value that need to be preserved between expression invocations. +/// +/// Although expressions can define truly local variables, frequently the user +/// wants to create variables whose values persist between invocations of the +/// expression. These variables are also created each time an expression returns +/// a result. The ClangPersistentVariable class encapsulates such a variable, +/// which contains data and a type. +//---------------------------------------------------------------------- class ClangPersistentVariable { friend class ClangPersistentVariables; public: + //---------------------------------------------------------------------- + /// Constructor + //---------------------------------------------------------------------- ClangPersistentVariable () : m_name(), m_user_type(), @@ -32,6 +45,12 @@ { } + //---------------------------------------------------------------------- + /// Copy constructor + /// + /// @param[in] pv + /// The persistent variable to make a copy of. + //---------------------------------------------------------------------- ClangPersistentVariable (const ClangPersistentVariable &pv) : m_name(pv.m_name), m_user_type(pv.m_user_type), @@ -39,6 +58,9 @@ { } + //---------------------------------------------------------------------- + /// Assignment operator + //---------------------------------------------------------------------- ClangPersistentVariable &operator=(const ClangPersistentVariable &pv) { m_name = pv.m_name; @@ -47,21 +69,58 @@ return *this; } + //---------------------------------------------------------------------- + /// Return the number of bytes required to store the variable + //---------------------------------------------------------------------- size_t Size () { return (m_user_type.GetClangTypeBitWidth () + 7) / 8; } + //---------------------------------------------------------------------- + /// Return the variable's contents, in local memory but stored according + /// to the target's byte order + //---------------------------------------------------------------------- uint8_t *Data () { return m_data->GetBytes(); } + //---------------------------------------------------------------------- + /// Return the variable's contents, in local memory but stored in a form + /// (byte order, etc.) appropriate for copying into the target's memory + //---------------------------------------------------------------------- TypeFromUser Type () { return m_user_type; } + //---------------------------------------------------------------------- + /// Pretty-print the variable + /// + /// @param[in] output_stream + /// The stream to pretty-print on. + /// + /// @param[in] exe_ctx + /// The execution context to use when resolving the contents of the + /// variable. + /// + /// @param[in] format + /// The format to print the variable in + /// + /// @param[in] show_types + /// If true, print the type of the variable + /// + /// @param[in] show_summary + /// If true, print a summary of the variable's type + /// + /// @param[in] verbose + /// If true, be verbose in printing the value of the variable + /// + /// @return + /// An Error describing the result of the operation. If Error::Success() + /// returns true, the pretty printing completed successfully. + //---------------------------------------------------------------------- Error Print(Stream &output_stream, ExecutionContext &exe_ctx, lldb::Format format, @@ -69,32 +128,85 @@ bool show_summary, bool verbose); private: + //---------------------------------------------------------------------- + /// Constructor + /// + /// @param[in] name + /// The name of the variable, usually of the form $foo. + /// + /// @param[in] user_type + /// The type of the variable, in an AST context that will survive + /// as long as the variable. + //---------------------------------------------------------------------- ClangPersistentVariable (ConstString name, TypeFromUser user_type) { m_name = name; m_user_type = user_type; m_data = lldb::DataBufferSP(new DataBufferHeap(Size(), 0)); } - ConstString m_name; - TypeFromUser m_user_type; - lldb::DataBufferSP m_data; -}; + ConstString m_name; ///< The name of the variable, usually $foo. + TypeFromUser m_user_type; ///< The type of the variable. Must be valid as long as the variable exists. + lldb::DataBufferSP m_data; ///< A shared pointer to the variable's data. This is a shared pointer so the variable object can move around without excess copying. +}; + +//---------------------------------------------------------------------- +/// @class ClangPersistentVariables ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h" +/// @brief Manages persistent values that need to be preserved between expression invocations. +/// +/// A list of variables that can be accessed and updated by any expression. See +/// ClangPersistentVariable for more discussion. Also provides an increasing, +/// 0-based counter for naming result variables. +//---------------------------------------------------------------------- class ClangPersistentVariables { public: + //---------------------------------------------------------------------- + /// Create a single named persistent variable + /// + /// @param[in] name + /// The desired name for the newly-created variable. + /// + /// @param[in] user_type + /// The desired type for the variable, in a context that will survive + /// as long as ClangPersistentVariables. + /// + /// @return + /// The newly-created persistent variable or NULL if a variable with the + /// same name already exists. + //---------------------------------------------------------------------- ClangPersistentVariable *CreateVariable (ConstString name, TypeFromUser user_type); + + //---------------------------------------------------------------------- + /// Finds a persistent variable 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. + //---------------------------------------------------------------------- ClangPersistentVariable *GetVariable (ConstString name); + //---------------------------------------------------------------------- + /// Return the next entry in the sequence of strings "$0", "$1", ... for use + /// naming result variables. + /// + /// @param[in] name + /// A string to place the variable name in. + //---------------------------------------------------------------------- void GetNextResultName(std::string &name); + //---------------------------------------------------------------------- + /// Constructor + //---------------------------------------------------------------------- ClangPersistentVariables (); private: - typedef std::map PVarMap; - typedef PVarMap::iterator PVarIterator; + typedef std::map PVarMap; + typedef PVarMap::iterator PVarIterator; - PVarMap m_variables; - uint64_t m_result_counter; + PVarMap m_variables; ///< The backing store for the list of variables. + uint64_t m_result_counter; ///< The counter used by GetNextResultName(). }; } From johnny.chen at apple.com Mon Aug 16 17:37:45 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 16 Aug 2010 22:37:45 -0000 Subject: [Lldb-commits] [lldb] r111198 - /lldb/trunk/test/dotest.py Message-ID: <20100816223745.7E3502A6C12C@llvm.org> Author: johnny Date: Mon Aug 16 17:37:45 2010 New Revision: 111198 URL: http://llvm.org/viewvc/llvm-project?rev=111198&view=rev Log: Added logging for process.gdb-remote by defining an environment variable named GDB_REMOTE_LOG which specifies the log file pathname. Modified: lldb/trunk/test/dotest.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=111198&r1=111197&r2=111198&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Mon Aug 16 17:37:45 2010 @@ -172,7 +172,7 @@ lldb.DBG = lldb.SBDebugger.Create() # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is -# is defined. Use ${LLDB_LOG} to specify the log file. +# defined. Use ${LLDB_LOG} to specify the log file. ci = lldb.DBG.GetCommandInterpreter() res = lldb.SBCommandReturnObject() if ("LLDB_LOG" in os.environ): @@ -180,6 +180,13 @@ "log enable -f " + os.environ["LLDB_LOG"] + " lldb default", res) if not res.Succeeded(): raise Exception('log enable failed (check your LLDB_LOG env variable...') +# Ditto for gdb-remote logging if ${LLDB_LOG} environment variable is defined. +# Use ${GDB_REMOTE_LOG} to specify the log file. +if ("GDB_REMOTE_LOG" in os.environ): + ci.HandleCommand( + "log enable -f " + os.environ["GDB_REMOTE_LOG"] + " process.gdb-remote packets", res) + if not res.Succeeded(): + raise Exception('log enable failed (check your GDB_REMOTE_LOG env variable...') # Install the control-c handler. unittest2.signals.installHandler() From scallanan at apple.com Mon Aug 16 18:01:35 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 16 Aug 2010 23:01:35 -0000 Subject: [Lldb-commits] [lldb] r111202 - in /lldb/trunk: include/lldb/Expression/ClangResultSynthesizer.h source/Expression/ClangResultSynthesizer.cpp Message-ID: <20100816230135.CD4282A6C12C@llvm.org> Author: spyffe Date: Mon Aug 16 18:01:35 2010 New Revision: 111202 URL: http://llvm.org/viewvc/llvm-project?rev=111202&view=rev Log: Documented ClangResultSynthesizer and added very minor API fixes. Modified: lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h lldb/trunk/source/Expression/ClangResultSynthesizer.cpp Modified: lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h?rev=111202&r1=111201&r2=111202&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h (original) +++ lldb/trunk/include/lldb/Expression/ClangResultSynthesizer.h Mon Aug 16 18:01:35 2010 @@ -15,32 +15,120 @@ 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); - bool SynthesizeResult(clang::ASTContext &Ctx, - clang::FunctionDecl *FunDecl); - clang::ASTContext *m_ast_context; - clang::ASTConsumer *m_passthrough; - clang::SemaConsumer *m_passthrough_sema; - clang::Sema *m_sema; - clang::Action *m_action; + //---------------------------------------------------------------------- + /// 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. }; } Modified: lldb/trunk/source/Expression/ClangResultSynthesizer.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangResultSynthesizer.cpp?rev=111202&r1=111201&r2=111202&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangResultSynthesizer.cpp (original) +++ lldb/trunk/source/Expression/ClangResultSynthesizer.cpp Mon Aug 16 18:01:35 2010 @@ -76,7 +76,7 @@ !strcmp(function_decl->getNameAsCString(), "___clang_expr")) { - SynthesizeResult(*m_ast_context, function_decl); + SynthesizeResult(function_decl); } } @@ -99,9 +99,10 @@ } bool -ClangResultSynthesizer::SynthesizeResult (ASTContext &Ctx, - FunctionDecl *FunDecl) +ClangResultSynthesizer::SynthesizeResult (FunctionDecl *FunDecl) { + ASTContext &Ctx(*m_ast_context); + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); if (!m_sema) From gclayton at apple.com Mon Aug 16 19:35:34 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 17 Aug 2010 00:35:34 -0000 Subject: [Lldb-commits] [lldb] r111215 - /lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Message-ID: <20100817003534.A50C92A6C12C@llvm.org> Author: gclayton Date: Mon Aug 16 19:35:34 2010 New Revision: 111215 URL: http://llvm.org/viewvc/llvm-project?rev=111215&view=rev Log: Fixed FindFunctions so it works with all the new name types for the DWARF in object files case. Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=111215&r1=111214&r2=111215&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Mon Aug 16 19:35:34 2010 @@ -769,30 +769,17 @@ "SymbolFileDWARFDebugMap::FindFunctions (name = %s)", name.GetCString()); - - std::vector indexes; uint32_t initial_size = 0; if (append) initial_size = sc_list.GetSize(); else sc_list.Clear(); - const size_t match_count = m_obj_file->GetSymtab()->FindAllSymbolsWithNameAndType (name, eSymbolTypeFunction, indexes); - if (match_count > 0) + uint32_t oso_idx = 0; + SymbolFileDWARF *oso_dwarf; + while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) { - for (size_t i=0; iFindFunctions(name, name_type_mask, true, sc_list); - } - } -// Stream s(stdout); -// sc_list.Dump(&s); + oso_dwarf->FindFunctions(name, name_type_mask, true, sc_list); } return sc_list.GetSize() - initial_size; @@ -806,6 +793,20 @@ "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')", regex.GetText()); + uint32_t initial_size = 0; + if (append) + initial_size = sc_list.GetSize(); + else + sc_list.Clear(); + + uint32_t oso_idx = 0; + SymbolFileDWARF *oso_dwarf; + while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) + { + oso_dwarf->FindFunctions(regex, true, sc_list); + } + + return sc_list.GetSize() - initial_size; return 0; } From jingham at apple.com Mon Aug 16 19:35:35 2010 From: jingham at apple.com (Jim Ingham) Date: Tue, 17 Aug 2010 00:35:35 -0000 Subject: [Lldb-commits] [lldb] r111216 - /lldb/trunk/source/Expression/ClangFunction.cpp Message-ID: <20100817003535.7375E2A6C12D@llvm.org> Author: jingham Date: Mon Aug 16 19:35:35 2010 New Revision: 111216 URL: http://llvm.org/viewvc/llvm-project?rev=111216&view=rev Log: Check for errors in Resume before waiting for the resume to complete. Modified: lldb/trunk/source/Expression/ClangFunction.cpp Modified: lldb/trunk/source/Expression/ClangFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=111216&r1=111215&r2=111216&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangFunction.cpp (original) +++ lldb/trunk/source/Expression/ClangFunction.cpp Mon Aug 16 19:35:35 2010 @@ -515,7 +515,12 @@ timeout_ptr = &real_timeout; } - exe_ctx.process->Resume (); + Error resume_error = exe_ctx.process->Resume (); + if (!resume_error.Success()) + { + errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString()); + return eExecutionSetupError; + } Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP); From scallanan at apple.com Tue Aug 17 15:24:29 2010 From: scallanan at apple.com (Sean Callanan) Date: Tue, 17 Aug 2010 20:24:29 -0000 Subject: [Lldb-commits] [lldb] r111276 - /lldb/trunk/include/lldb/Expression/DWARFExpression.h Message-ID: <20100817202429.68E652A6C12C@llvm.org> Author: spyffe Date: Tue Aug 17 15:24:29 2010 New Revision: 111276 URL: http://llvm.org/viewvc/llvm-project?rev=111276&view=rev Log: Documented DWARFExpression. Modified: lldb/trunk/include/lldb/Expression/DWARFExpression.h Modified: lldb/trunk/include/lldb/Expression/DWARFExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/DWARFExpression.h?rev=111276&r1=111275&r2=111276&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/DWARFExpression.h (original) +++ lldb/trunk/include/lldb/Expression/DWARFExpression.h Tue Aug 17 15:24:29 2010 @@ -25,56 +25,165 @@ class ClangExpressionDeclMap; //---------------------------------------------------------------------- -// A class designed to evaluate the DWARF expression opcodes. We will -// likely augment its abilities to handle features not supported by -// the DWARF expression engine. +/// @class DWARFExpression DWARFExpression.h "lldb/Expression/DWARFExpression.h" +/// @brief Encapsulates a DWARF location expression and interprets it. +/// +/// DWARF location expressions are used in two ways by LLDB. The first +/// use is to find entities specified in the debug information, since +/// their locations are specified in precisely this language. The second +/// is to interpret expressions without having to run the target in cases +/// where the overhead from copying JIT-compiled code into the target is +/// too high or where the target cannot be run. This class encapsulates +/// a single DWARF location expression or a location list and interprets +/// it. //---------------------------------------------------------------------- class DWARFExpression { public: - //------------------------------------------------------------------ - // Constructors and Destructors + /// Constructor //------------------------------------------------------------------ DWARFExpression(); + //------------------------------------------------------------------ + /// Constructor + /// + /// @param[in] data + /// A data extractor configured to read the DWARF location expression's + /// bytecode. + /// + /// @param[in] data_offset + /// The offset of the location expression in the extractor. + /// + /// @param[in] data_length + /// The byte length of the location expression. + /// + /// @param[in] loclist_base_addr_ptr + /// If non-NULL, the address of the location list in the target + /// process's .debug_loc section. + //------------------------------------------------------------------ DWARFExpression(const DataExtractor& data, uint32_t data_offset, uint32_t data_length, const Address* loclist_base_addr_ptr); + //------------------------------------------------------------------ + /// Copy constructor + //------------------------------------------------------------------ DWARFExpression(const DWARFExpression& rhs); + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ virtual ~DWARFExpression(); + //------------------------------------------------------------------ + /// Print the description of the expression to a stream + /// + /// @param[in] s + /// The stream to print to. + /// + /// @param[in] level + /// The level of verbosity to use. + //------------------------------------------------------------------ void GetDescription (Stream *s, lldb::DescriptionLevel level) const; + //------------------------------------------------------------------ + /// Return true if the location expression contains data + //------------------------------------------------------------------ bool IsValid() const; + //------------------------------------------------------------------ + /// Return true if a location list was provided + //------------------------------------------------------------------ bool IsLocationList() const; + //------------------------------------------------------------------ + /// Search for a load address in the location list + /// + /// @param[in] process + /// The process to use when resolving the load address + /// + /// @param[in] addr + /// The address to resolve + /// + /// @return + /// True if IsLocationList() is true and the address was found; + /// false otherwise. + //------------------------------------------------------------------ bool LocationListContainsLoadAddress (Process* process, const Address &addr) const; + //------------------------------------------------------------------ + /// Make the expression parser read its location information from a + /// given data source. Does not change the offset and length + /// + /// @param[in] data + /// A data extractor configured to read the DWARF location expression's + /// bytecode. + /// + /// @param[in] loclist_base_addr_ptr + /// If non-NULL, the address of the location list in the target + /// process's .debug_loc section. + //------------------------------------------------------------------ void SetOpcodeData(const DataExtractor& data, const Address* loclist_base_addr_ptr); + //------------------------------------------------------------------ + /// Make the expression parser read its location information from a + /// given data source + /// + /// @param[in] data + /// A data extractor configured to read the DWARF location expression's + /// bytecode. + /// + /// @param[in] data_offset + /// The offset of the location expression in the extractor. + /// + /// @param[in] data_length + /// The byte length of the location expression. + /// + /// @param[in] loclist_base_addr_ptr + /// If non-NULL, the address of the location list in the target + /// process's .debug_loc section. + //------------------------------------------------------------------ void SetOpcodeData(const DataExtractor& data, uint32_t data_offset, uint32_t data_length, const Address* loclist_base_addr_ptr); + //------------------------------------------------------------------ + /// Make the expression parser refer to a location list + /// + /// @param[in] base_addr + /// The address of the location list in the target process's .debug_loc + /// section. + //------------------------------------------------------------------ void SetLocationListBaseAddress(Address& base_addr); + //------------------------------------------------------------------ + /// Return the call-frame-info style register kind + //------------------------------------------------------------------ int GetRegisterKind (); + //------------------------------------------------------------------ + /// Set the call-frame-info style register kind + /// + /// @param[in] reg_kind + /// The register kind. + //------------------------------------------------------------------ void SetRegisterKind (int reg_kind); + //------------------------------------------------------------------ + /// Wrapper for the static evaluate function that accepts an + /// ExecutionContextScope instead of an ExecutionContext and uses + /// member variables to populate many operands + //------------------------------------------------------------------ bool Evaluate (ExecutionContextScope *exe_scope, clang::ASTContext *ast_context, @@ -82,6 +191,10 @@ Value& result, Error *error_ptr) const; + //------------------------------------------------------------------ + /// Wrapper for the static evaluate function that uses member + /// variables to populate many operands + //------------------------------------------------------------------ bool Evaluate (ExecutionContext *exe_ctx, clang::ASTContext *ast_context, @@ -89,6 +202,58 @@ Value& result, Error *error_ptr) const; + //------------------------------------------------------------------ + /// Evaluate a DWARF location expression in a particular context + /// + /// @param[in] exe_ctx + /// The execution context in which to evaluate the location + /// expression. The location expression may access the target's + /// memory, especially if it comes from the expression parser. + /// + /// @param[in] ast_context + /// The context in which to interpret types. + /// + /// @param[in] opcodes + /// This is a static method so the opcodes need to be provided + /// explicitly. + /// + /// @param[in] expr_locals + /// If the location expression was produced by the expression parser, + /// the list of local variables referenced by the DWARF expression. + /// This list should already have been populated during parsing; + /// the DWARF expression refers to variables by index. Can be NULL if + /// the location expression uses no locals. + /// + /// @param[in] decl_map + /// If the location expression was produced by the expression parser, + /// the list of external variables referenced by the location + /// expression. Can be NULL if the location expression uses no + /// external variables. + /// + /// @param[in] offset + /// The offset of the location expression in the data extractor. + /// + /// @param[in] length + /// The length in bytes of the location expression. + /// + /// @param[in] reg_set + /// The call-frame-info style register kind. + /// + /// @param[in] initial_value_ptr + /// A value to put on top of the interpreter stack before evaluating + /// the expression, if the expression is parametrized. Can be NULL. + /// + /// @param[in] result + /// A value into which the result of evaluating the expression is + /// to be placed. + /// + /// @param[in] error_ptr + /// If non-NULL, used to report errors in expression evaluation. + /// + /// @return + /// True on success; false otherwise. If error_ptr is non-NULL, + /// details of the failure are provided through it. + //------------------------------------------------------------------ static bool Evaluate (ExecutionContext *exe_ctx, clang::ASTContext *ast_context, @@ -102,23 +267,57 @@ Value& result, Error *error_ptr); + //------------------------------------------------------------------ + /// Loads a ClangExpressionVariableList into the object + /// + /// @param[in] locals + /// If non-NULL, the list of locals used by this expression. + /// See Evaluate(). + //------------------------------------------------------------------ void SetExpressionLocalVariableList (ClangExpressionVariableList *locals); + //------------------------------------------------------------------ + /// Loads a ClangExpressionDeclMap into the object + /// + /// @param[in] locals + /// If non-NULL, the list of external variables used by this + /// expression. See Evaluate(). + //------------------------------------------------------------------ void SetExpressionDeclMap (ClangExpressionDeclMap *decl_map); protected: - - void DumpLocation(Stream *s, uint32_t offset, uint32_t length, lldb::DescriptionLevel level) const; //------------------------------------------------------------------ - // Classes that inherit from DWARFExpression can see and modify these + /// Pretty-prints the location expression to a stream + /// + /// @param[in] stream + /// The stream to use for pretty-printing. + /// + /// @param[in] offset + /// The offset into the data buffer of the opcodes to be printed. + /// + /// @param[in] length + /// The length in bytes of the opcodes to be printed. + /// + /// @param[in] level + /// The level of detail to use in pretty-printing. //------------------------------------------------------------------ - DataExtractor m_data; - int m_reg_kind; // One of the defines that starts with LLDB_REGKIND_ - Address m_loclist_base_addr; // Base address needed for location lists - ClangExpressionVariableList *m_expr_locals; - ClangExpressionDeclMap *m_decl_map; + void + DumpLocation(Stream *s, + uint32_t offset, + uint32_t length, + lldb::DescriptionLevel level) const; + + //------------------------------------------------------------------ + /// Classes that inherit from DWARFExpression can see and modify these + //------------------------------------------------------------------ + + DataExtractor m_data; ///< A data extractor capable of reading opcode bytes + int m_reg_kind; ///< One of the defines that starts with LLDB_REGKIND_ + Address m_loclist_base_addr; ///< Base address needed for location lists + ClangExpressionVariableList *m_expr_locals; ///< The locals used by this expression. See Evaluate() + ClangExpressionDeclMap *m_decl_map; ///< The external variables used by this expression. See Evaluate() }; } // namespace lldb_private From johnny.chen at apple.com Tue Aug 17 16:33:31 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 17 Aug 2010 21:33:31 -0000 Subject: [Lldb-commits] [lldb] r111294 - in /lldb/trunk/test: dead-strip/TestDeadStrip.py lldbtest.py Message-ID: <20100817213331.67C662A6C12C@llvm.org> Author: johnny Date: Tue Aug 17 16:33:31 2010 New Revision: 111294 URL: http://llvm.org/viewvc/llvm-project?rev=111294&view=rev Log: Specify a more meaningful assert message for TestDeadStrip.py. Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/TestDeadStrip.py?rev=111294&r1=111293&r2=111294&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Tue Aug 17 16:33:31 2010 @@ -32,7 +32,7 @@ self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 2: name = 'f2', module = a.out, locations = 0 " "(pending)"), - BREAKPOINT_CREATED) + BREAKPOINT_PENDING_CREATED) # Break by function name f3 (live code). self.ci.HandleCommand("breakpoint set -s a.out -n f3", res) Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=111294&r1=111293&r2=111294&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Tue Aug 17 16:33:31 2010 @@ -43,6 +43,8 @@ BREAKPOINT_CREATED = "Breakpoint created successfully" +BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully" + BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1" STOPPED_DUE_TO_BREAKPOINT = "Process state is stopped due to breakpoint" From johnny.chen at apple.com Tue Aug 17 16:36:09 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 17 Aug 2010 21:36:09 -0000 Subject: [Lldb-commits] [lldb] r111295 - /lldb/trunk/test/dotest.py Message-ID: <20100817213609.6D2532A6C12C@llvm.org> Author: johnny Date: Tue Aug 17 16:36:09 2010 New Revision: 111295 URL: http://llvm.org/viewvc/llvm-project?rev=111295&view=rev Log: Add the ability to specify logging options for lldb and gdb-remote through two additional env variables. Modified: lldb/trunk/test/dotest.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=111295&r1=111294&r2=111295&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Tue Aug 17 16:36:09 2010 @@ -176,17 +176,28 @@ ci = lldb.DBG.GetCommandInterpreter() res = lldb.SBCommandReturnObject() if ("LLDB_LOG" in os.environ): + if ("LLDB_LOG_OPTION" in os.environ): + lldb_log_option = os.environ["LLDB_LOG_OPTION"] + else: + lldb_log_option = "event process" ci.HandleCommand( - "log enable -f " + os.environ["LLDB_LOG"] + " lldb default", res) + "log enable -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option, + res) if not res.Succeeded(): - raise Exception('log enable failed (check your LLDB_LOG env variable...') + raise Exception('log enable failed (check LLDB_LOG env variable.') # Ditto for gdb-remote logging if ${LLDB_LOG} environment variable is defined. # Use ${GDB_REMOTE_LOG} to specify the log file. if ("GDB_REMOTE_LOG" in os.environ): + if ("GDB_REMOTE_LOG_OPTION" in os.environ): + gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"] + else: + gdb_remote_log_option = "packets" ci.HandleCommand( - "log enable -f " + os.environ["GDB_REMOTE_LOG"] + " process.gdb-remote packets", res) + "log enable -f " + os.environ["GDB_REMOTE_LOG"] + " process.gdb-remote " + + gdb_remote_log_option, + res) if not res.Succeeded(): - raise Exception('log enable failed (check your GDB_REMOTE_LOG env variable...') + raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.') # Install the control-c handler. unittest2.signals.installHandler() From jingham at apple.com Tue Aug 17 16:54:19 2010 From: jingham at apple.com (Jim Ingham) Date: Tue, 17 Aug 2010 21:54:19 -0000 Subject: [Lldb-commits] [lldb] r111302 - /lldb/trunk/source/Target/Process.cpp Message-ID: <20100817215419.B43E12A6C12C@llvm.org> Author: jingham Date: Tue Aug 17 16:54:19 2010 New Revision: 111302 URL: http://llvm.org/viewvc/llvm-project?rev=111302&view=rev Log: Don't try to get the architecture up front when doing attach -w. Modified: lldb/trunk/source/Target/Process.cpp Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=111302&r1=111301&r2=111302&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Tue Aug 17 16:54:19 2010 @@ -1135,13 +1135,16 @@ // Find the process and its architecture. Make sure it matches the architecture // of the current Target, and if not adjust it. - ArchSpec attach_spec = GetArchSpecForExistingProcess (process_name); - if (attach_spec != GetTarget().GetArchitecture()) + if (!wait_for_launch) { - // Set the architecture on the target. - GetTarget().SetArchitecture(attach_spec); + ArchSpec attach_spec = GetArchSpecForExistingProcess (process_name); + if (attach_spec != GetTarget().GetArchitecture()) + { + // Set the architecture on the target. + GetTarget().SetArchitecture(attach_spec); + } } - + Error error (WillAttachToProcessWithName(process_name, wait_for_launch)); if (error.Success()) { From scallanan at apple.com Tue Aug 17 17:36:13 2010 From: scallanan at apple.com (Sean Callanan) Date: Tue, 17 Aug 2010 22:36:13 -0000 Subject: [Lldb-commits] [lldb] r111313 - /lldb/trunk/include/lldb/Expression/IRForTarget.h Message-ID: <20100817223613.6C0382A6C12E@llvm.org> Author: spyffe Date: Tue Aug 17 17:36:13 2010 New Revision: 111313 URL: http://llvm.org/viewvc/llvm-project?rev=111313&view=rev Log: Documented IRForTarget Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=111313&r1=111312&r2=111313&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Tue Aug 17 17:36:13 2010 @@ -27,61 +27,247 @@ class ClangExpressionDeclMap; } +//---------------------------------------------------------------------- +/// @class IRForTarget IRForTarget.h "lldb/Expression/IRForTarget.h" +/// @brief Transforms the IR for a function to run in the target +/// +/// Once an expression has been parsed and converted to IR, it can run +/// in two contexts: interpreted by LLDB as a DWARF location expression, +/// or compiled by the JIT and inserted into the target process for +/// execution. +/// +/// IRForTarget makes the second possible, by applying a series of +/// transformations to the IR which make it relocatable. These +/// transformations are discussed in more detail next to their relevant +/// functions. +//---------------------------------------------------------------------- class IRForTarget : public llvm::ModulePass { public: + //------------------------------------------------------------------ + /// Constructor + /// + /// @param[in] pid + /// A unique identifier for this pass. I'm not sure what this does; + /// it just gets passed down to ModulePass's constructor. + /// + /// @param[in] decl_map + /// The list of externally-referenced variables for the expression, + /// for use in looking up globals and allocating the argument + /// struct. See the documentation for ClangExpressionDeclMap. + /// + /// @param[in] target_data + /// The data layout information for the target. This information is + /// used to determine the sizes of types that have been lowered into + /// IR types. + //------------------------------------------------------------------ IRForTarget(const void *pid, lldb_private::ClangExpressionDeclMap *decl_map, const llvm::TargetData *target_data); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ ~IRForTarget(); + + //------------------------------------------------------------------ + /// Run this IR transformer on a single module + /// + /// @param[in] M + /// The module to run on. This module is searched for the function + /// ___clang_expr, and that function is passed to the passes one by + /// one. + //------------------------------------------------------------------ bool runOnModule(llvm::Module &M); + + //------------------------------------------------------------------ + /// Interface stub + //------------------------------------------------------------------ void assignPassManager(llvm::PMStack &PMS, llvm::PassManagerType T = llvm::PMT_ModulePassManager); + + //------------------------------------------------------------------ + /// Returns PMT_ModulePassManager + //------------------------------------------------------------------ llvm::PassManagerType getPotentialPassManagerType() const; private: - // pass to find the result variable created in the result synthesizer and - // make a result variable out of it (or a void variable if there is no - // result) + //------------------------------------------------------------------ + /// A function-level pass to take the generated global value + /// ___clang_expr_result and make it into a persistent variable. + /// Also see ClangResultSynthesizer. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] F + /// The function currently being processed. + //------------------------------------------------------------------ bool createResultVariable(llvm::Module &M, llvm::Function &F); - - // pass to rewrite Objective-C method calls to use the runtime function - // sel_registerName + + //------------------------------------------------------------------ + /// A basic block-level pass to find all Objective-C method calls and + /// rewrite them to use sel_registerName instead of statically allocated + /// selectors. The reason is that the selectors are created on the + /// assumption that the Objective-C runtime will scan the appropriate + /// section and prepare them. This doesn't happen when code is copied + /// into the target, though, and there's no easy way to induce the + /// runtime to scan them. So instead we get our selectors from + /// sel_registerName. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Replace a single selector reference + /// + /// @param[in] selector_load + /// The load of the statically-allocated selector. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool RewriteObjCSelector(llvm::Instruction* selector_load, llvm::Module &M); + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool rewriteObjCSelectors(llvm::Module &M, llvm::BasicBlock &BB); - // pass to find declarations of, and references to, persistent variables and - // register them for (de)materialization + //------------------------------------------------------------------ + /// A basic block-level pass to find all newly-declared persistent + /// variables and register them with the ClangExprDeclMap. This + /// allows them to be materialized and dematerialized like normal + /// external variables. Before transformation, these persistent + /// variables look like normal locals, so they have an allocation. + /// This pass excises these allocations and makes references look + /// like external references where they will be resolved -- like all + /// other external references -- by resolveExternals(). + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Handle a single allocation of a persistent variable + /// + /// @param[in] persistent_alloc + /// The allocation of the persistent variable. + /// + /// @param[in] M + /// The module currently being processed. + //------------------------------------------------------------------ bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc, llvm::Module &M); + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool rewritePersistentAllocs(llvm::Module &M, llvm::BasicBlock &BB); - // pass to register referenced variables and redirect functions at their - // targets in the debugged process + //------------------------------------------------------------------ + /// A basic block-level pass to find all external variables and + /// functions used in the IR. Each found external variable is added + /// to the struct, and each external function is resolved in place, + /// its call replaced with a call to a function pointer whose value + /// is the address of the function in the target process. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Handle a single externally-defined variable + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] V + /// The variable. + /// + /// @param[in] Store + /// True if the access is a store. + //------------------------------------------------------------------ bool MaybeHandleVariable(llvm::Module &M, llvm::Value *V, bool Store); + + //------------------------------------------------------------------ + /// Handle a single external function call + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] C + /// The call instruction. + //------------------------------------------------------------------ bool MaybeHandleCall(llvm::Module &M, llvm::CallInst *C); + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool resolveExternals(llvm::Module &M, llvm::BasicBlock &BB); - // pass to find references to guard variables and excise them + //------------------------------------------------------------------ + /// A basic block-level pass to excise guard variables from the code. + /// The result for the function is passed through Clang as a static + /// variable. Static variables normally have guard variables to + /// ensure that they are only initialized once. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool removeGuards(llvm::Module &M, llvm::BasicBlock &BB); - // pass to replace all identified variables with references to members of - // the argument struct + //------------------------------------------------------------------ + /// A function-level pass to make all external variable references + /// point at the correct offsets from the void* passed into the + /// function. ClangExpressionDeclMap::DoStructLayout() must be called + /// beforehand, so that the offsets are valid. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] F + /// The function currently being processed. + //------------------------------------------------------------------ bool replaceVariables(llvm::Module &M, llvm::Function &F); - lldb_private::ClangExpressionDeclMap *m_decl_map; - const llvm::TargetData *m_target_data; - - llvm::Constant *m_sel_registerName; + 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 }; #endif From johnny.chen at apple.com Tue Aug 17 18:00:13 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 17 Aug 2010 23:00:13 -0000 Subject: [Lldb-commits] [lldb] r111319 - in /lldb/trunk/test: README-TestSuite dotest.py Message-ID: <20100817230013.6A8E92A6C12C@llvm.org> Author: johnny Date: Tue Aug 17 18:00:13 2010 New Revision: 111319 URL: http://llvm.org/viewvc/llvm-project?rev=111319&view=rev Log: Write out the informational message about the total number of test cases to be run to stderr, instead of stdout. The same as what the unittest framework uses. Modified: lldb/trunk/test/README-TestSuite lldb/trunk/test/dotest.py Modified: lldb/trunk/test/README-TestSuite URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/README-TestSuite?rev=111319&r1=111318&r2=111319&view=diff ============================================================================== --- lldb/trunk/test/README-TestSuite (original) +++ lldb/trunk/test/README-TestSuite Tue Aug 17 18:00:13 2010 @@ -11,6 +11,15 @@ directory in order to be recognized by 'dotest.py' test driver as a module which implements a test case, namely, Test*.py. + Some example usages: + + 1. ./dotest.py -v . 2> ~/Developer/Log/lldbtest.log0 + This runs the test suite and directs the run log to a file. + + 2. LLDB_LOG=/tmp/lldb.log GDB_REMOTE_LOG=/tmp/gdb-remote.log ./dotest.py -v . 2> ~/Developer/Log/lldbtest.log + This runs the test suite, with logging turned on for the lldb as well as + the process.gdb-remote channels and directs the run log to a file. + o lldbtest.py Provides an abstract base class of lldb test case named 'TestVase', which in Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=111319&r1=111318&r2=111319&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Tue Aug 17 18:00:13 2010 @@ -50,8 +50,8 @@ # Separator string. separator = '-' * 70 -# Decorated sys.stdout. -out = _WritelnDecorator(sys.stdout) +# Decorated sys.stderr for our consumption. +err = _WritelnDecorator(sys.stderr) def usage(): @@ -157,10 +157,10 @@ os.path.walk(testdir, visit, 'Test') # Now that we have loaded all the test cases, run the whole test suite. -out.writeln(separator) -out.writeln("Collected %d test%s" % (suite.countTestCases(), +err.writeln(separator) +err.writeln("Collected %d test%s" % (suite.countTestCases(), suite.countTestCases() != 1 and "s" or "")) -out.writeln() +err.writeln() # For the time being, let's bracket the test runner within the # lldb.SBDebugger.Initialize()/Terminate() pair. From gclayton at apple.com Tue Aug 17 18:16:15 2010 From: gclayton at apple.com (Greg Clayton) Date: Tue, 17 Aug 2010 23:16:15 -0000 Subject: [Lldb-commits] [lldb] r111322 - /lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Message-ID: <20100817231615.717B82A6C12C@llvm.org> Author: gclayton Date: Tue Aug 17 18:16:15 2010 New Revision: 111322 URL: http://llvm.org/viewvc/llvm-project?rev=111322&view=rev Log: Fixed an issue where we would return matches for DWARF in the .o files when the resulting function from the .o file DWARF didn't make it into the final executable. I recently changed the way FindFunctions() worked in the DWARF with debug map case that caused regressions in our test suite for dead stripped functions. The previous changes allowed us to leverage the powerful searching added to the DWARF parser (search by full name, basename, selector, or method name), without having to chop up the symbol names from the symbol table and do any special parsing of the names to extract the basename, selector or method. Previously we would look through the symbol table for matches first, then try and find the .o file with DWARF for that symbol and only search those .o files. Now we let the DWARF for the .o file search using the new search styles, and filter out any functions that didn't make it. Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=111322&r1=111321&r2=111322&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Tue Aug 17 18:16:15 2010 @@ -762,6 +762,33 @@ return comp_unit_info; } +static void +RemoveFunctionsWithModuleNotEqualTo (Module *module, SymbolContextList &sc_list, uint32_t start_idx) +{ + // We found functions in .o files. Not all functions in the .o files + // will have made it into the final output file. The ones that did + // make it into the final output file will have a section whose module + // matches the module from the ObjectFile for this SymbolFile. When + // the modules don't match, then we have something that was in a + // .o file, but doesn't map to anything in the final executable. + uint32_t i=start_idx; + while (i < sc_list.GetSize()) + { + SymbolContext sc; + sc_list.GetContextAtIndex(i, sc); + if (sc.function) + { + const Section *section = sc.function->GetAddressRange().GetBaseAddress().GetSection(); + if (section->GetModule() != module) + { + sc_list.RemoveContextAtIndex(i); + continue; + } + } + ++i; + } +} + uint32_t SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, uint32_t name_type_mask, bool append, SymbolContextList& sc_list) { @@ -779,7 +806,11 @@ SymbolFileDWARF *oso_dwarf; while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) { - oso_dwarf->FindFunctions(name, name_type_mask, true, sc_list); + uint32_t sc_idx = sc_list.GetSize(); + if (oso_dwarf->FindFunctions(name, name_type_mask, true, sc_list)) + { + RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); + } } return sc_list.GetSize() - initial_size; @@ -803,12 +834,15 @@ SymbolFileDWARF *oso_dwarf; while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) { - oso_dwarf->FindFunctions(regex, true, sc_list); + uint32_t sc_idx = sc_list.GetSize(); + + if (oso_dwarf->FindFunctions(regex, true, sc_list)) + { + RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); + } } return sc_list.GetSize() - initial_size; - - return 0; } From scallanan at apple.com Tue Aug 17 18:18:59 2010 From: scallanan at apple.com (Sean Callanan) Date: Tue, 17 Aug 2010 23:18:59 -0000 Subject: [Lldb-commits] [lldb] r111323 - in /lldb/trunk/include/lldb/Expression: IRForTarget.h IRToDWARF.h Message-ID: <20100817231900.06D272A6C12C@llvm.org> Author: spyffe Date: Tue Aug 17 18:18:59 2010 New Revision: 111323 URL: http://llvm.org/viewvc/llvm-project?rev=111323&view=rev Log: Documented IRToDWARF, and added return value documentation to IRForTarget. Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h lldb/trunk/include/lldb/Expression/IRToDWARF.h Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=111323&r1=111322&r2=111323&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Tue Aug 17 18:18:59 2010 @@ -77,6 +77,9 @@ /// The module to run on. This module is searched for the function /// ___clang_expr, and that function is passed to the passes one by /// one. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool runOnModule(llvm::Module &M); @@ -105,6 +108,9 @@ /// /// @param[in] F /// The function currently being processed. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool createResultVariable(llvm::Module &M, llvm::Function &F); @@ -128,6 +134,9 @@ /// /// @param[in] BB /// The basic block currently being processed. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool RewriteObjCSelector(llvm::Instruction* selector_load, llvm::Module &M); @@ -140,6 +149,9 @@ /// /// @param[in] BB /// The basic block currently being processed. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool rewriteObjCSelectors(llvm::Module &M, llvm::BasicBlock &BB); @@ -163,6 +175,9 @@ /// /// @param[in] M /// The module currently being processed. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc, llvm::Module &M); @@ -198,6 +213,9 @@ /// /// @param[in] Store /// True if the access is a store. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool MaybeHandleVariable(llvm::Module &M, llvm::Value *V, @@ -211,6 +229,9 @@ /// /// @param[in] C /// The call instruction. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool MaybeHandleCall(llvm::Module &M, llvm::CallInst *C); @@ -223,6 +244,9 @@ /// /// @param[in] BB /// The basic block currently being processed. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool resolveExternals(llvm::Module &M, llvm::BasicBlock &BB); @@ -242,6 +266,9 @@ /// /// @param[in] BB /// The basic block currently being processed. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool removeGuards(llvm::Module &M, llvm::BasicBlock &BB); @@ -261,6 +288,9 @@ /// /// @param[in] F /// The function currently being processed. + /// + /// @return + /// True on success; false otherwise //------------------------------------------------------------------ bool replaceVariables(llvm::Module &M, llvm::Function &F); Modified: lldb/trunk/include/lldb/Expression/IRToDWARF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRToDWARF.h?rev=111323&r1=111322&r2=111323&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRToDWARF.h (original) +++ lldb/trunk/include/lldb/Expression/IRToDWARF.h Tue Aug 17 18:18:59 2010 @@ -26,24 +26,96 @@ class Relocator; +//---------------------------------------------------------------------- +/// @class IRToDWARF IRToDWARF.h "lldb/Expression/IRToDWARF.h" +/// @brief Transforms the IR for a function into a DWARF location expression +/// +/// Once an expression has been parsed and converted to IR, it can run +/// in two contexts: interpreted by LLDB as a DWARF location expression, +/// or compiled by the JIT and inserted into the target process for +/// execution. +/// +/// IRToDWARF makes the first possible, by traversing the control flow +/// graph and writing the code for each basic block out as location +/// expression bytecode. To ensure that the links between the basic blocks +/// remain intact, it uses a relocator that records the location of every +/// location expression instruction that has a relocatable operand, the +/// target of that operand (as a basic block), and the mapping of each basic +/// block to an actual location. After all code has been written out, the +/// relocator post-processes it and performs all necessary relocations. +//---------------------------------------------------------------------- class IRToDWARF : public llvm::ModulePass { public: + //------------------------------------------------------------------ + /// Constructor + /// + /// @param[in] pid + /// A unique identifier for this pass. I'm not sure what this does; + /// it just gets passed down to ModulePass's constructor. + /// + /// @param[in] variable_list + /// A list of variables to populate with the local variables this + /// expression uses. + /// + /// @param[in] decl_map + /// The list of externally-referenced variables for the expression, + /// for use in looking up globals. + /// + /// @param[in] stream + /// The stream to dump DWARF bytecode onto. + //------------------------------------------------------------------ IRToDWARF(const void *pid, lldb_private::ClangExpressionVariableList &variable_list, lldb_private::ClangExpressionDeclMap *decl_map, lldb_private::StreamString &strm); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ ~IRToDWARF(); + + //------------------------------------------------------------------ + /// Run this IR transformer on a single module + /// + /// @param[in] M + /// The module to run on. This module is searched for the function + /// ___clang_expr, and that function is converted to a location + /// expression. + /// + /// @return + /// True on success; false otherwise + //------------------------------------------------------------------ bool runOnModule(llvm::Module &M); + + //------------------------------------------------------------------ + /// Interface stub + //------------------------------------------------------------------ void assignPassManager(llvm::PMStack &PMS, llvm::PassManagerType T = llvm::PMT_ModulePassManager); + + //------------------------------------------------------------------ + /// Returns PMT_ModulePassManager + //------------------------------------------------------------------ llvm::PassManagerType getPotentialPassManagerType() const; private: + //------------------------------------------------------------------ + /// Run this IR transformer on a single basic block + /// + /// @param[in] BB + /// The basic block to transform. + /// + /// @param[in] Relocator + /// The relocator to use when registering branches. + /// + /// @return + /// True on success; false otherwise + //------------------------------------------------------------------ bool runOnBasicBlock(llvm::BasicBlock &BB, Relocator &Relocator); - lldb_private::ClangExpressionVariableList &m_variable_list; - lldb_private::ClangExpressionDeclMap *m_decl_map; - lldb_private::StreamString &m_strm; + lldb_private::ClangExpressionVariableList &m_variable_list; ///< 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 }; #endif \ No newline at end of file From scallanan at apple.com Tue Aug 17 19:25:09 2010 From: scallanan at apple.com (Sean Callanan) Date: Wed, 18 Aug 2010 00:25:09 -0000 Subject: [Lldb-commits] [lldb] r111335 - /lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h Message-ID: <20100818002509.9FA462A6C12C@llvm.org> Author: spyffe Date: Tue Aug 17 19:25:09 2010 New Revision: 111335 URL: http://llvm.org/viewvc/llvm-project?rev=111335&view=rev Log: Documented RecordingMemoryManager and removed an undefined, unused function from its API. Modified: lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h Modified: lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h?rev=111335&r1=111334&r2=111335&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h (original) +++ lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h Tue Aug 17 19:25:09 2010 @@ -27,67 +27,196 @@ namespace lldb_private { +//---------------------------------------------------------------------- +/// @class RecordingMemoryManager RecordingMemoryManager.h "lldb/Expression/RecordingMemoryManager.h" +/// @brief Passthrough memory manager for the JIT that records what was allocated where +/// +/// The LLVM JIT is built to compile code for execution in the current +/// process, so it needs to be able to allocate memory. Because different +/// clients have different requirements for the locations of JIT compiled +/// code, the interface for allocating memory has been abstracted out and +/// can be implemented by any client. +/// +/// LLDB, however, needs to move JIT-compiled code into the target process. +/// Because writing individual bytes of code hasn't been abstracted out of +/// the JIT, LLDB instead implements a custom memory allocator that records +/// what regions have been allocated for code. When JIT compilation is +/// complete, these regions are then copied as necessary into the target +/// process. +/// +/// Ideally the memory manager would handle this copying, but this class has +/// to be built without RTTI, which means it cannot include Process.h. As a +/// result, ClangExpression::WriteJITCode() accesses the stored mappings +/// directly. +//---------------------------------------------------------------------- class RecordingMemoryManager : public llvm::JITMemoryManager { - -// I can't write the JIT code in this class because this class has to be -// built without RTTI, which means I can't include Process.h. But I don't -// want to write iterators or "do_over_regions" functions right now, so I'm -// just going to let the ClangExpression handle it using our data members directly. - friend bool ClangExpression::WriteJITCode (const ExecutionContext &exc_context); public: + //------------------------------------------------------------------ + /// Constructor + //------------------------------------------------------------------ RecordingMemoryManager (); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ virtual ~RecordingMemoryManager(); + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual void setMemoryWritable (); + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual void setMemoryExecutable (); + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual void setPoisonMemory (bool poison) { m_default_mm_ap->setPoisonMemory (poison); } + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual void AllocateGOT() { m_default_mm_ap->AllocateGOT(); } - + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual uint8_t *getGOTBase() const { return m_default_mm_ap->getGOTBase(); } + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual uint8_t *startFunctionBody(const llvm::Function *F, - uintptr_t &ActualSize); - - virtual uint8_t *allocateStub(const llvm::GlobalValue* F, unsigned StubSize, - unsigned Alignment); - - virtual void endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart, - uint8_t *FunctionEnd); + uintptr_t &ActualSize); + //------------------------------------------------------------------ + /// Allocate room for a dyld stub for a lazy-referenced function, + /// and add it to the m_stubs map + /// + /// @param[in] F + /// The function being referenced. + /// + /// @param[in] StubSize + /// The size of the stub. + /// + /// @param[in] Alignment + /// The required alignment of the stub. + /// + /// @return + /// Allocated space for the stub. + //------------------------------------------------------------------ + virtual uint8_t *allocateStub(const llvm::GlobalValue* F, + unsigned StubSize, + unsigned Alignment); + + //------------------------------------------------------------------ + /// Complete the body of a function, and add it to the m_functions map + /// + /// @param[in] F + /// The function being completed. + /// + /// @param[in] FunctionStart + /// The first instruction of the function. + /// + /// @param[in] FunctionEnd + /// The last byte of the last instruction of the function. + //------------------------------------------------------------------ + virtual void endFunctionBody(const llvm::Function *F, + uint8_t *FunctionStart, + uint8_t *FunctionEnd); + //------------------------------------------------------------------ + /// Allocate space for an unspecified purpose, and add it to the + /// m_spaceBlocks map + /// + /// @param[in] Size + /// The size of the area. + /// + /// @param[in] Alignment + /// The required alignment of the area. + /// + /// @return + /// Allocated space. + //------------------------------------------------------------------ virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment); - virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment); - + //------------------------------------------------------------------ + /// Allocate space for a global variable, and add it to the + /// m_spaceBlocks map + /// + /// @param[in] Size + /// The size of the variable. + /// + /// @param[in] Alignment + /// The required alignment of the variable. + /// + /// @return + /// Allocated space for the global. + //------------------------------------------------------------------ + virtual uint8_t *allocateGlobal(uintptr_t Size, + unsigned Alignment); + + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual void deallocateFunctionBody(void *Body); + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual uint8_t* startExceptionTable(const llvm::Function* F, - uintptr_t &ActualSize); - - virtual void endExceptionTable(const llvm::Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t* FrameRegister); + uintptr_t &ActualSize); + //------------------------------------------------------------------ + /// Complete the exception table for a function, and add it to the + /// m_exception_tables map + /// + /// @param[in] F + /// The function whose exception table is being written. + /// + /// @param[in] TableStart + /// The first byte of the exception table. + /// + /// @param[in] TableEnd + /// The last byte of the exception table. + /// + /// @param[in] FrameRegister + /// I don't know what this does, but it's passed through. + //------------------------------------------------------------------ + virtual void endExceptionTable(const llvm::Function *F, + uint8_t *TableStart, + uint8_t *TableEnd, + uint8_t* FrameRegister); + + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual void deallocateExceptionTable(void *ET); + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual size_t GetDefaultCodeSlabSize() { return m_default_mm_ap->GetDefaultCodeSlabSize(); } + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual size_t GetDefaultDataSlabSize() { return m_default_mm_ap->GetDefaultDataSlabSize(); } @@ -96,48 +225,82 @@ return m_default_mm_ap->GetDefaultStubSlabSize(); } + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual unsigned GetNumCodeSlabs() { return m_default_mm_ap->GetNumCodeSlabs(); } + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual unsigned GetNumDataSlabs() { return m_default_mm_ap->GetNumDataSlabs(); } + //------------------------------------------------------------------ + /// Passthrough interface stub + //------------------------------------------------------------------ virtual unsigned GetNumStubSlabs() { return m_default_mm_ap->GetNumStubSlabs(); } - // These are methods I've added so we can transfer the memory we've remembered down - // to the target program. For now I'm assuming all this code is PIC without fixups, - // so I'll just copy it blind, but if we need to we can do fixups later. - + //------------------------------------------------------------------ + /// [Convenience method for ClangExpression] Look up the object in + /// m_address_map that contains a given address, find where it was + /// copied to, and return the remote address at the same offset into + /// the copied entity + /// + /// @param[in] local_address + /// The address in the debugger. + /// + /// @return + /// The address in the target process. + //------------------------------------------------------------------ lldb::addr_t GetRemoteAddressForLocal (lldb::addr_t local_address); + //------------------------------------------------------------------ + /// [Convenience method for ClangExpression] Look up the object in + /// m_address_map that contains a given address, find where it was + /// copied to, and return its address range in the target process + /// + /// @param[in] local_address + /// The address in the debugger. + /// + /// @return + /// The range of the containing object in the target process. + //------------------------------------------------------------------ std::pair GetRemoteRangeForLocal (lldb::addr_t local_address); - - bool - WriteJITRegions (const ExecutionContext &exc_context); - - private: - std::auto_ptr m_default_mm_ap; - std::map m_functions; - std::map m_spaceBlocks; - std::map m_stubs; - std::map m_globals; - std::map m_exception_tables; + std::auto_ptr m_default_mm_ap; ///< The memory allocator to use in actually creating space. All calls are passed through to it. + std::map m_functions; ///< A map from function base addresses to their end addresses. + std::map m_spaceBlocks; ///< A map from the base addresses of generic allocations to their sizes. + std::map m_stubs; ///< A map from the base addresses of stubs to their sizes. + std::map m_globals; ///< A map from the base addresses of globals to their sizes. + std::map m_exception_tables; ///< A map from the base addresses of exception tables to their end addresses. - lldb_private::Log *m_log; + lldb_private::Log *m_log; ///< The log to use when printing log messages. May be NULL. + //---------------------------------------------------------------------- + /// @class LocalToRemoteAddressRange RecordingMemoryManager.h "lldb/Expression/RecordingMemoryManager.h" + /// @brief A record of an allocated region that has been copied into the target + /// + /// The RecordingMemoryManager makes records of all regions that need copying; + /// then, ClangExpression copies these regions into the target. It records + /// what was copied where in records of type LocalToRemoteAddressRange. + //---------------------------------------------------------------------- struct LocalToRemoteAddressRange { - lldb::addr_t m_local_start; - size_t m_size; - lldb::addr_t m_remote_start; - + lldb::addr_t m_local_start; ///< The base address of the local allocation + size_t m_size; ///< The size of the allocation + lldb::addr_t m_remote_start; ///< The base address of the remote allocation + + //------------------------------------------------------------------ + /// Constructor + //------------------------------------------------------------------ LocalToRemoteAddressRange (lldb::addr_t lstart, size_t size, lldb::addr_t rstart) : m_local_start (lstart), m_size (size), @@ -146,15 +309,24 @@ }; + //------------------------------------------------------------------ + /// Add a range to the list of copied ranges. + /// + /// @param[in] lstart + /// The base address of the local allocation. + /// + /// @param[in] size + /// The size of the allocation. + /// + /// @param[in] rstart + /// The base address of the remote allocation. + //------------------------------------------------------------------ void AddToLocalToRemoteMap (lldb::addr_t lstart, size_t size, lldb::addr_t rstart); - // We should probably store this by address so we can efficiently - // search it but there really won't be many elements in this array - // at present. So we can put that off for now. - std::vector m_address_map; - + std::vector m_address_map; ///< The base address of the remote allocation }; } // namespace lldb_private + #endif // lldb_RecordingMemoryManager_h_ From gclayton at apple.com Wed Aug 18 13:25:20 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 18 Aug 2010 18:25:20 -0000 Subject: [Lldb-commits] [lldb] r111377 - /lldb/trunk/include/lldb/API/SBDebugger.h Message-ID: <20100818182520.4D6062A6C12C@llvm.org> Author: gclayton Date: Wed Aug 18 13:25:20 2010 New Revision: 111377 URL: http://llvm.org/viewvc/llvm-project?rev=111377&view=rev Log: Allow the SBDebugger to construct itself with the default constructor so objects can own one of these objects and assign a valid value at a later point. Modified: lldb/trunk/include/lldb/API/SBDebugger.h Modified: lldb/trunk/include/lldb/API/SBDebugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=111377&r1=111376&r2=111377&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBDebugger.h (original) +++ lldb/trunk/include/lldb/API/SBDebugger.h Wed Aug 18 13:25:20 2010 @@ -28,6 +28,8 @@ static SBDebugger Create(); + SBDebugger(); + ~SBDebugger(); bool @@ -137,9 +139,6 @@ private: - // Use the static function: SBDebugger::Create(); - SBDebugger(); - #ifndef SWIG friend class SBInputReader; From gclayton at apple.com Wed Aug 18 13:25:47 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 18 Aug 2010 18:25:47 -0000 Subject: [Lldb-commits] [lldb] r111378 - /lldb/trunk/include/lldb/Target/RegisterContext.h Message-ID: <20100818182547.6BEF92A6C12C@llvm.org> Author: gclayton Date: Wed Aug 18 13:25:47 2010 New Revision: 111378 URL: http://llvm.org/viewvc/llvm-project?rev=111378&view=rev Log: Added a Thread accessor to the register context. Modified: lldb/trunk/include/lldb/Target/RegisterContext.h Modified: lldb/trunk/include/lldb/Target/RegisterContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/RegisterContext.h?rev=111378&r1=111377&r2=111378&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/RegisterContext.h (original) +++ lldb/trunk/include/lldb/Target/RegisterContext.h Wed Aug 18 13:25:47 2010 @@ -100,6 +100,12 @@ lldb::tid_t GetThreadID() const; + Thread & + GetThread () + { + return m_thread; + } + const lldb::RegisterInfo * GetRegisterInfoByName (const char *reg_name, uint32_t start_idx = 0); From jingham at apple.com Wed Aug 18 13:28:17 2010 From: jingham at apple.com (Jim Ingham) Date: Wed, 18 Aug 2010 18:28:17 -0000 Subject: [Lldb-commits] [lldb] r111379 - in /lldb/trunk/test/inlines: inlines.c inlines.h Message-ID: <20100818182817.B12802A6C12C@llvm.org> Author: jingham Date: Wed Aug 18 13:28:17 2010 New Revision: 111379 URL: http://llvm.org/viewvc/llvm-project?rev=111379&view=rev Log: Added call stacks with inlined functions higher on the stack, and non-inlined functions at the bottom. Added: lldb/trunk/test/inlines/inlines.h Modified: lldb/trunk/test/inlines/inlines.c Modified: lldb/trunk/test/inlines/inlines.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/inlines/inlines.c?rev=111379&r1=111378&r2=111379&view=diff ============================================================================== --- lldb/trunk/test/inlines/inlines.c (original) +++ lldb/trunk/test/inlines/inlines.c Wed Aug 18 13:28:17 2010 @@ -1,14 +1,29 @@ #include +#include "inlines.h" #define INLINE_ME __inline__ __attribute__((always_inline)) +int +not_inlined_2 (int input) +{ + printf ("Called in not_inlined_2 with : %d.\n", input); + return input; +} + +int +not_inlined_1 (int input) +{ + printf ("Called in not_inlined_1 with %d.\n", input); + return not_inlined_2(input); +} + INLINE_ME int inner_inline (int inner_input, int mod_value) { int inner_result; inner_result = inner_input % mod_value; printf ("Returning: %d.\n", inner_result); - return inner_result; + return not_inlined_1 (inner_result); } INLINE_ME int Added: lldb/trunk/test/inlines/inlines.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/inlines/inlines.h?rev=111379&view=auto ============================================================================== --- lldb/trunk/test/inlines/inlines.h (added) +++ lldb/trunk/test/inlines/inlines.h Wed Aug 18 13:28:17 2010 @@ -0,0 +1,4 @@ +int inner_inline (int inner_input, int mod_value); +int outer_inline (int outer_input); +int not_inlined_2 (int input); +int not_inlined_1 (int input); From gclayton at apple.com Wed Aug 18 13:28:52 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 18 Aug 2010 18:28:52 -0000 Subject: [Lldb-commits] [lldb] r111380 - /lldb/trunk/source/Core/Value.cpp Message-ID: <20100818182852.7F8192A6C12C@llvm.org> Author: gclayton Date: Wed Aug 18 13:28:52 2010 New Revision: 111380 URL: http://llvm.org/viewvc/llvm-project?rev=111380&view=rev Log: Changed "Error Value::GetValueAsData (...)" to set the data extractor byte order and address size correctly when the value comes from a file address. Values have "file" addresses when they are globals and the debug information specifies that they live in the object file at a given address (DWARF will represent this as a location "DW_OP_addr "). This causes global pointers to correctly extract their children on 64 bit programs. Modified: lldb/trunk/source/Core/Value.cpp Modified: lldb/trunk/source/Core/Value.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Value.cpp?rev=111380&r1=111379&r2=111380&view=diff ============================================================================== --- lldb/trunk/source/Core/Value.cpp (original) +++ lldb/trunk/source/Core/Value.cpp Wed Aug 18 13:28:52 2010 @@ -560,7 +560,16 @@ Address so_addr(file_addr, objfile->GetSectionList()); address = so_addr.GetLoadAddress (exe_ctx->process); if (address != LLDB_INVALID_ADDRESS) + { address_type = eAddressTypeLoad; + data.SetByteOrder(exe_ctx->process->GetByteOrder()); + data.SetAddressByteSize(exe_ctx->process->GetAddressByteSize()); + } + else + { + data.SetByteOrder(objfile->GetByteOrder()); + data.SetAddressByteSize(objfile->GetAddressByteSize()); + } } if (address_type == eAddressTypeFile) error.SetErrorStringWithFormat ("%s is not loaded.\n", var_sc.module_sp->GetFileSpec().GetFilename().AsCString()); From gclayton at apple.com Wed Aug 18 13:29:55 2010 From: gclayton at apple.com (Greg Clayton) Date: Wed, 18 Aug 2010 18:29:55 -0000 Subject: [Lldb-commits] [lldb] r111381 - /lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Message-ID: <20100818182955.733B72A6C12C@llvm.org> Author: gclayton Date: Wed Aug 18 13:29:55 2010 New Revision: 111381 URL: http://llvm.org/viewvc/llvm-project?rev=111381&view=rev Log: Avoid an assertion crash by avoiding a circular dependency in the objective C builtin type conversion. Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=111381&r1=111380&r2=111381&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Aug 18 13:29:55 2010 @@ -2620,17 +2620,14 @@ if (type_name_dbstr == g_objc_type_name_id) { clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_id(); - ResolveTypeUID (encoding_uid); } else if (type_name_dbstr == g_objc_type_name_Class) { clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_Class(); - ResolveTypeUID (encoding_uid); } else if (type_name_dbstr == g_objc_type_name_selector) { clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_selector(); - ResolveTypeUID (encoding_uid); } } From scallanan at apple.com Wed Aug 18 13:50:52 2010 From: scallanan at apple.com (Sean Callanan) Date: Wed, 18 Aug 2010 18:50:52 -0000 Subject: [Lldb-commits] [lldb] r111388 - in /lldb/trunk: include/lldb/Expression/IRForTarget.h include/lldb/Expression/IRToDWARF.h source/Expression/ClangExpression.cpp source/Expression/IRForTarget.cpp source/Expression/IRToDWARF.cpp Message-ID: <20100818185052.324FF2A6C12C@llvm.org> Author: spyffe Date: Wed Aug 18 13:50:51 2010 New Revision: 111388 URL: http://llvm.org/viewvc/llvm-project?rev=111388&view=rev Log: Patch by Bill Lynch fixing handling of the pid in the IR transformation passes. Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h lldb/trunk/include/lldb/Expression/IRToDWARF.h lldb/trunk/source/Expression/ClangExpression.cpp lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Expression/IRToDWARF.cpp Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=111388&r1=111387&r2=111388&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Wed Aug 18 13:50:51 2010 @@ -61,8 +61,7 @@ /// used to determine the sizes of types that have been lowered into /// IR types. //------------------------------------------------------------------ - IRForTarget(const void *pid, - lldb_private::ClangExpressionDeclMap *decl_map, + IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, const llvm::TargetData *target_data); //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Expression/IRToDWARF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRToDWARF.h?rev=111388&r1=111387&r2=111388&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRToDWARF.h (original) +++ lldb/trunk/include/lldb/Expression/IRToDWARF.h Wed Aug 18 13:50:51 2010 @@ -50,10 +50,6 @@ //------------------------------------------------------------------ /// Constructor /// - /// @param[in] pid - /// A unique identifier for this pass. I'm not sure what this does; - /// it just gets passed down to ModulePass's constructor. - /// /// @param[in] variable_list /// A list of variables to populate with the local variables this /// expression uses. @@ -65,8 +61,7 @@ /// @param[in] stream /// The stream to dump DWARF bytecode onto. //------------------------------------------------------------------ - IRToDWARF(const void *pid, - lldb_private::ClangExpressionVariableList &variable_list, + IRToDWARF(lldb_private::ClangExpressionVariableList &variable_list, lldb_private::ClangExpressionDeclMap *decl_map, lldb_private::StreamString &strm); @@ -118,4 +113,4 @@ lldb_private::StreamString &m_strm; ///< The stream to write bytecode to }; -#endif \ No newline at end of file +#endif Modified: lldb/trunk/source/Expression/ClangExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=111388&r1=111387&r2=111388&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangExpression.cpp Wed Aug 18 13:50:51 2010 @@ -455,7 +455,7 @@ return 1; } - IRToDWARF ir_to_dwarf("IR to DWARF", expr_local_variable_list, m_decl_map, dwarf_opcode_strm); + IRToDWARF ir_to_dwarf(expr_local_variable_list, m_decl_map, dwarf_opcode_strm); return ir_to_dwarf.runOnModule(*module); } @@ -491,7 +491,7 @@ std::auto_ptr target_machine(target->createTargetMachine(m_target_triple, "")); - IRForTarget ir_for_target("IR for target", m_decl_map, target_machine->getTargetData()); + IRForTarget ir_for_target(m_decl_map, target_machine->getTargetData()); return ir_for_target.runOnModule(*module); } Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=111388&r1=111387&r2=111388&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Wed Aug 18 13:50:51 2010 @@ -28,10 +28,11 @@ using namespace llvm; -IRForTarget::IRForTarget(const void *pid, - lldb_private::ClangExpressionDeclMap *decl_map, +static char ID; + +IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, const TargetData *target_data) : - ModulePass(pid), + ModulePass(ID), m_decl_map(decl_map), m_target_data(target_data), m_sel_registerName(NULL) Modified: lldb/trunk/source/Expression/IRToDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRToDWARF.cpp?rev=111388&r1=111387&r2=111388&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRToDWARF.cpp (original) +++ lldb/trunk/source/Expression/IRToDWARF.cpp Wed Aug 18 13:50:51 2010 @@ -24,11 +24,12 @@ using namespace llvm; -IRToDWARF::IRToDWARF(const void *pid, - lldb_private::ClangExpressionVariableList &variable_list, +static char ID; + +IRToDWARF::IRToDWARF(lldb_private::ClangExpressionVariableList &variable_list, lldb_private::ClangExpressionDeclMap *decl_map, lldb_private::StreamString &strm) : - ModulePass(pid), + ModulePass(ID), m_variable_list(variable_list), m_decl_map(decl_map), m_strm(strm) From jingham at apple.com Wed Aug 18 14:29:16 2010 From: jingham at apple.com (Jim Ingham) Date: Wed, 18 Aug 2010 19:29:16 -0000 Subject: [Lldb-commits] [lldb] r111396 - /lldb/trunk/source/Symbol/Block.cpp Message-ID: <20100818192916.CBE742A6C12C@llvm.org> Author: jingham Date: Wed Aug 18 14:29:16 2010 New Revision: 111396 URL: http://llvm.org/viewvc/llvm-project?rev=111396&view=rev Log: Some Block:: methods wandered to the end of the file after the BlockList:: methods. I moved them back. Modified: lldb/trunk/source/Symbol/Block.cpp Modified: lldb/trunk/source/Symbol/Block.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Block.cpp?rev=111396&r1=111395&r2=111396&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Block.cpp (original) +++ lldb/trunk/source/Symbol/Block.cpp Wed Aug 18 14:29:16 2010 @@ -323,6 +323,76 @@ m_inlineInfoSP.reset(new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr)); } + + +VariableListSP +Block::GetVariableList (bool get_child_variables, bool can_create) +{ + VariableListSP variable_list_sp; + if (m_variables.get() == NULL && can_create) + { + SymbolContext sc; + CalculateSymbolContext(&sc); + assert(sc.module_sp); + sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc); + } + + if (m_variables.get()) + { + variable_list_sp.reset(new VariableList()); + if (variable_list_sp.get()) + variable_list_sp->AddVariables(m_variables.get()); + + if (get_child_variables) + { + Block *child_block = GetFirstChild(); + while (child_block) + { + VariableListSP child_block_variable_list(child_block->GetVariableList(get_child_variables, can_create)); + if (child_block_variable_list.get()) + variable_list_sp->AddVariables(child_block_variable_list.get()); + child_block = child_block->GetSibling(); + } + } + } + + return variable_list_sp; +} + +uint32_t +Block::AppendVariables (bool can_create, bool get_parent_variables, VariableList *variable_list) +{ + uint32_t num_variables_added = 0; + VariableListSP variable_list_sp(GetVariableList(false, can_create)); + + if (variable_list_sp.get()) + { + num_variables_added = variable_list_sp->GetSize(); + variable_list->AddVariables(variable_list_sp.get()); + } + + if (get_parent_variables) + { + Block* parent_block = GetParent(); + if (parent_block) + num_variables_added += parent_block->AppendVariables (can_create, get_parent_variables, variable_list); + } + return num_variables_added; +} + + +void +Block::SetVariableList(VariableListSP& variables) +{ + m_variables = variables; +} + +uint32_t +Block::Depth () const +{ + return m_depth; +} + BlockList::BlockList(Function *function, const AddressRange& range) : m_function(function), m_range(range), @@ -599,73 +669,3 @@ return false; } - - -VariableListSP -Block::GetVariableList (bool get_child_variables, bool can_create) -{ - VariableListSP variable_list_sp; - if (m_variables.get() == NULL && can_create) - { - SymbolContext sc; - CalculateSymbolContext(&sc); - assert(sc.module_sp); - sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc); - } - - if (m_variables.get()) - { - variable_list_sp.reset(new VariableList()); - if (variable_list_sp.get()) - variable_list_sp->AddVariables(m_variables.get()); - - if (get_child_variables) - { - Block *child_block = GetFirstChild(); - while (child_block) - { - VariableListSP child_block_variable_list(child_block->GetVariableList(get_child_variables, can_create)); - if (child_block_variable_list.get()) - variable_list_sp->AddVariables(child_block_variable_list.get()); - child_block = child_block->GetSibling(); - } - } - } - - return variable_list_sp; -} - -uint32_t -Block::AppendVariables (bool can_create, bool get_parent_variables, VariableList *variable_list) -{ - uint32_t num_variables_added = 0; - VariableListSP variable_list_sp(GetVariableList(false, can_create)); - - if (variable_list_sp.get()) - { - num_variables_added = variable_list_sp->GetSize(); - variable_list->AddVariables(variable_list_sp.get()); - } - - if (get_parent_variables) - { - Block* parent_block = GetParent(); - if (parent_block) - num_variables_added += parent_block->AppendVariables (can_create, get_parent_variables, variable_list); - } - return num_variables_added; -} - - -void -Block::SetVariableList(VariableListSP& variables) -{ - m_variables = variables; -} - -uint32_t -Block::Depth () const -{ - return m_depth; -} - From johnny.chen at apple.com Wed Aug 18 16:28:35 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 18 Aug 2010 21:28:35 -0000 Subject: [Lldb-commits] [lldb] r111429 - /lldb/trunk/test/stl/TestSTL.py Message-ID: <20100818212835.BB8482A6C12C@llvm.org> Author: johnny Date: Wed Aug 18 16:28:35 2010 New Revision: 111429 URL: http://llvm.org/viewvc/llvm-project?rev=111429&view=rev Log: Simplify the assert matched-string criterion. Modified: lldb/trunk/test/stl/TestSTL.py Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=111429&r1=111428&r2=111429&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Wed Aug 18 16:28:35 2010 @@ -59,15 +59,12 @@ # self.assertTrue(res.Succeeded(), CMD_MSG("thread step-in")) - #self.ci.HandleCommand("process status", res) - #print "process status:", res.GetOutput() self.ci.HandleCommand("thread backtrace", res) print "thread backtrace:", res.GetOutput() self.assertTrue(res.Succeeded()) output = res.GetOutput() self.assertTrue(output.find('[inlined]') > 0 and - output.find('basic_string.h') and - output.find('stop reason = step in,') > 0, + output.find('basic_string.h'), "Command 'thread backtrace' shows we stepped in STL") From johnny.chen at apple.com Thu Aug 19 13:17:48 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 19 Aug 2010 18:17:48 -0000 Subject: [Lldb-commits] [lldb] r111536 - in /lldb/trunk/test: array_types/TestArrayTypes.py class_types/TestClassTypes.py dead-strip/TestDeadStrip.py function_types/TestFunctionTypes.py global_variables/TestGlobalVariables.py help/TestHelp.py load_unload/TestLoadUnload.py order/TestOrderFile.py persistent_variables/TestPersistentVariables.py set_values/TestSetValues.py stl/TestSTL.py struct_types/TestStructTypes.py unsigned_types/TestUnsignedTypes.py Message-ID: <20100819181749.138282A6C12C@llvm.org> Author: johnny Date: Thu Aug 19 13:17:48 2010 New Revision: 111536 URL: http://llvm.org/viewvc/llvm-project?rev=111536&view=rev Log: Added more informational assert message strings. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/dead-strip/TestDeadStrip.py lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/global_variables/TestGlobalVariables.py lldb/trunk/test/help/TestHelp.py lldb/trunk/test/load_unload/TestLoadUnload.py lldb/trunk/test/order/TestOrderFile.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=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Aug 19 13:17:48 2010 @@ -18,7 +18,7 @@ # Break on line 42 inside main(). self.ci.HandleCommand("breakpoint set -f main.c -l 42", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: file ='main.c', line = 42, locations = 1"), BREAKPOINT_CREATED) @@ -44,7 +44,7 @@ # Issue 'variable list' command on several array-type variables. self.ci.HandleCommand("variable list strings", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) output = res.GetOutput() self.assertTrue(output.startswith('(char *[4])') and output.find('(char *) strings[0]') > 0 and @@ -58,18 +58,18 @@ VARIABLES_DISPLAYED_CORRECTLY) self.ci.HandleCommand("variable list char_16", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) self.assertTrue(res.GetOutput().find('(char) char_16[0]') > 0 and res.GetOutput().find('(char) char_16[15]') > 0, VARIABLES_DISPLAYED_CORRECTLY) self.ci.HandleCommand("variable list ushort_matrix", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) self.assertTrue(res.GetOutput().startswith('(unsigned short [2][3])'), VARIABLES_DISPLAYED_CORRECTLY) self.ci.HandleCommand("variable list long_6", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) self.assertTrue(res.GetOutput().startswith('(long [6])'), VARIABLES_DISPLAYED_CORRECTLY) Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Thu Aug 19 13:17:48 2010 @@ -18,7 +18,7 @@ # Break on the ctor function of class C. self.ci.HandleCommand("breakpoint set -f main.cpp -l 73", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: file ='main.cpp', line = 73, locations = 1"), BREAKPOINT_CREATED) @@ -37,13 +37,13 @@ # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) # We should be stopped on the ctor function of class C. self.ci.HandleCommand("variable list this", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) self.assertTrue(res.GetOutput().startswith('(class C *const) this = '), VARIABLES_DISPLAYED_CORRECTLY) Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/TestDeadStrip.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Thu Aug 19 13:17:48 2010 @@ -20,7 +20,7 @@ # Break by function name f1 (live code). self.ci.HandleCommand("breakpoint set -s a.out -n f1", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: name = 'f1', module = a.out, locations = 1" ), @@ -28,7 +28,7 @@ # Break by function name f2 (dead code). self.ci.HandleCommand("breakpoint set -s a.out -n f2", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 2: name = 'f2', module = a.out, locations = 0 " "(pending)"), @@ -36,7 +36,7 @@ # Break by function name f3 (live code). self.ci.HandleCommand("breakpoint set -s a.out -n f3", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 3: name = 'f3', module = a.out, locations = 1" ), @@ -49,7 +49,7 @@ # The stop reason of the thread should be breakpoint (breakpoint #1). self.ci.HandleCommand("thread list", res) output = res.GetOutput() - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) self.assertTrue(output.find('state is Stopped') > 0 and output.find('main.c:20') > 0 and output.find('where = a.out`f1') > 0 and @@ -58,17 +58,17 @@ # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list 1", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('continue')) # The stop reason of the thread should be breakpoint (breakpoint #3). self.ci.HandleCommand("thread list", res) output = res.GetOutput() - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) self.assertTrue(output.find('state is Stopped') > 0 and output.find('main.c:40') > 0 and output.find('where = a.out`f3') > 0 and @@ -77,7 +77,7 @@ # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list 3", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Thu Aug 19 13:17:48 2010 @@ -18,7 +18,7 @@ # Break inside the main. self.ci.HandleCommand("breakpoint set -f main.c -l 21", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: file ='main.c', line = 21, locations = 1"), BREAKPOINT_CREATED) @@ -37,13 +37,13 @@ # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) # Check that the 'callback' variable display properly. self.ci.HandleCommand("variable list callback", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) output = res.GetOutput() self.assertTrue(output.startswith('(int (*)(char const *)) callback ='), VARIABLES_DISPLAYED_CORRECTLY) @@ -52,11 +52,11 @@ self.ci.HandleCommand("breakpoint set -n string_not_empty", res); self.assertTrue(res.Succeeded(), BREAKPOINT_CREATED) self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('continue')) # Check that we do indeed stop on the string_not_empty function. self.ci.HandleCommand("process status", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('process status')) output = res.GetOutput() #print "process status =", output self.assertTrue(output.find('where = a.out`string_not_empty') > 0 and Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/TestGlobalVariables.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Thu Aug 19 13:17:48 2010 @@ -18,7 +18,7 @@ # Break inside the main. self.ci.HandleCommand("breakpoint set -f main.c -l 20", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: file ='main.c', line = 20, locations = 1"), BREAKPOINT_CREATED) @@ -37,13 +37,13 @@ # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) # Check that GLOBAL scopes are indicated for the variables. self.ci.HandleCommand("variable list -s -a", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) output = res.GetOutput() self.assertTrue(output.find('GLOBAL: g_file_static_cstr') > 0 and output.find('g_file_static_cstr') > 0 and Modified: lldb/trunk/test/help/TestHelp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/help/TestHelp.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/help/TestHelp.py (original) +++ lldb/trunk/test/help/TestHelp.py Thu Aug 19 13:17:48 2010 @@ -17,9 +17,9 @@ """A simple test of 'help' command and its output.""" res = lldb.SBCommandReturnObject() self.ci.HandleCommand("help", res) - self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().startswith( - 'The following is a list of built-in, permanent debugger commands'), + self.assertTrue(res.Succeeded() and + res.GetOutput().startswith( + 'The following is a list of built-in, permanent debugger commands'), CMD_MSG('help')) def test_help_should_not_hang_emacsshell(self): @@ -28,9 +28,9 @@ self.ci.HandleCommand("set term-width 0", res) self.assertTrue(res.Succeeded(), CMD_MSG('set term-width 0')) self.ci.HandleCommand("help", res) - self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().startswith( - 'The following is a list of built-in, permanent debugger commands'), + self.assertTrue(res.Succeeded() and + res.GetOutput().startswith( + 'The following is a list of built-in, permanent debugger commands'), CMD_MSG('help')) Modified: lldb/trunk/test/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/TestLoadUnload.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Thu Aug 19 13:17:48 2010 @@ -20,7 +20,7 @@ # Break by function name a_function (not yet loaded). self.ci.HandleCommand("breakpoint set -n a_function", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: name = 'a_function', locations = 0 " "(pending)" @@ -43,7 +43,7 @@ # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) Modified: lldb/trunk/test/order/TestOrderFile.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/order/TestOrderFile.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/order/TestOrderFile.py (original) +++ lldb/trunk/test/order/TestOrderFile.py Thu Aug 19 13:17:48 2010 @@ -21,7 +21,7 @@ # Test that the debug symbols have Function f3 before Function f1. self.ci.HandleCommand("image dump symtab a.out", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('image dump')) output = res.GetOutput() mo_f3 = re.search("Function +.+f3", output) mo_f1 = re.search("Function +.+f1", output) Modified: lldb/trunk/test/persistent_variables/TestPersistentVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/persistent_variables/TestPersistentVariables.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/persistent_variables/TestPersistentVariables.py (original) +++ lldb/trunk/test/persistent_variables/TestPersistentVariables.py Thu Aug 19 13:17:48 2010 @@ -19,7 +19,7 @@ self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) self.ci.HandleCommand("breakpoint set --name main", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.ci.HandleCommand("run", res) self.runStarted = True @@ -47,10 +47,6 @@ #print res.GetOutput() # $3 = (int)14 - self.ci.HandleCommand("continue", res) - self.ci.HandleCommand("quit", res) - self.runStarted = False - if __name__ == '__main__': import atexit Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Thu Aug 19 13:17:48 2010 @@ -18,27 +18,27 @@ # Set breakpoints on several places to set program variables. self.ci.HandleCommand("breakpoint set -f main.c -l 15", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: file ='main.c', line = 15, locations = 1"), BREAKPOINT_CREATED) self.ci.HandleCommand("breakpoint set -f main.c -l 36", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 2: file ='main.c', line = 36, locations = 1"), BREAKPOINT_CREATED) self.ci.HandleCommand("breakpoint set -f main.c -l 57", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 3: file ='main.c', line = 57, locations = 1"), BREAKPOINT_CREATED) self.ci.HandleCommand("breakpoint set -f main.c -l 78", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 4: file ='main.c', line = 78, locations = 1"), BREAKPOINT_CREATED) self.ci.HandleCommand("breakpoint set -f main.c -l 85", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 5: file ='main.c', line = 85, locations = 1"), BREAKPOINT_CREATED) @@ -57,26 +57,26 @@ # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) # main.c:15 # Check that 'variable list' displays the correct data type and value. self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) self.assertTrue(res.GetOutput().startswith("i = (char) 'a'"), VARIABLES_DISPLAYED_CORRECTLY) # TODO: # Now set variable 'i' and check that it is correctly displayed. self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('continue')) # main.c:36 # Check that 'variable list' displays the correct data type and value. self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) self.assertTrue(res.GetOutput().startswith( "i = (short unsigned int) 0x0021"), VARIABLES_DISPLAYED_CORRECTLY) @@ -84,36 +84,36 @@ # Now set variable 'i' and check that it is correctly displayed. self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('continue')) # main.c:57 # Check that 'variable list' displays the correct data type and value. self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) self.assertTrue(res.GetOutput().startswith("i = (long int) 33"), VARIABLES_DISPLAYED_CORRECTLY) # TODO: # Now set variable 'i' and check that it is correctly displayed. self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('continue')) # main.c:78 # Check that 'variable list' displays the correct data type and value. self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) self.assertTrue(res.GetOutput().startswith("i = (double) 3.14159"), VARIABLES_DISPLAYED_CORRECTLY) # TODO: # Now set variable 'i' and check that it is correctly displayed. self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('continue')) # main.c:85 # Check that 'variable list' displays the correct data type and value. self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) self.assertTrue(res.GetOutput().startswith("i = (long double) "), VARIABLES_DISPLAYED_CORRECTLY) # TODO: Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Thu Aug 19 13:17:48 2010 @@ -24,7 +24,7 @@ # Break on line 13 of main.cpp. self.ci.HandleCommand("breakpoint set -f main.cpp -l 13", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: file ='main.cpp', line = 13, locations = 1" ), @@ -37,7 +37,7 @@ # Stop at 'std::string hello_world ("Hello World!");'. self.ci.HandleCommand("thread list", res) #print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) output = res.GetOutput() self.assertTrue(output.find('main.cpp:13') > 0 and output.find('stop reason = breakpoint') > 0, @@ -45,7 +45,7 @@ # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) @@ -61,7 +61,7 @@ self.ci.HandleCommand("thread backtrace", res) print "thread backtrace:", res.GetOutput() - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('thread backtarce')) output = res.GetOutput() self.assertTrue(output.find('[inlined]') > 0 and output.find('basic_string.h'), Modified: lldb/trunk/test/struct_types/TestStructTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/struct_types/TestStructTypes.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/struct_types/TestStructTypes.py (original) +++ lldb/trunk/test/struct_types/TestStructTypes.py Thu Aug 19 13:17:48 2010 @@ -22,7 +22,7 @@ # Break on the ctor function of class C. self.ci.HandleCommand("breakpoint set -f main.c -l 14", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: file ='main.c', line = 14, locations = 1"), BREAKPOINT_CREATED) @@ -35,7 +35,7 @@ # function where the original breakpoint was attempted. self.ci.HandleCommand("thread backtrace", res) #print "thread backtrace ->", res.GetOutput() - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('thread backtarce')) output = res.GetOutput() self.assertTrue(output.find('main.c:20') > 0 and output.find('stop reason = breakpoint') > 0, Modified: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/TestUnsignedTypes.py?rev=111536&r1=111535&r2=111536&view=diff ============================================================================== --- lldb/trunk/test/unsigned_types/TestUnsignedTypes.py (original) +++ lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Thu Aug 19 13:17:48 2010 @@ -21,7 +21,7 @@ # Break on line 19 in main() aftre the variables are assigned values. self.ci.HandleCommand("breakpoint set -f main.cpp -l 19", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: file ='main.cpp', line = 19, locations = 1" ), @@ -40,14 +40,14 @@ # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, BREAKPOINT_HIT_ONCE) # Test that unsigned types display correctly. self.ci.HandleCommand("variable list -a", res) #print "variable list -a ->", res.GetOutput() - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('variable list -a')) output = res.GetOutput() self.assertTrue( output.startswith("the_unsigned_char = (unsigned char) 'c'") From gclayton at apple.com Thu Aug 19 16:50:06 2010 From: gclayton at apple.com (Greg Clayton) Date: Thu, 19 Aug 2010 21:50:06 -0000 Subject: [Lldb-commits] [lldb] r111567 - /lldb/trunk/source/Target/Process.cpp Message-ID: <20100819215006.A940C2A6C12C@llvm.org> Author: gclayton Date: Thu Aug 19 16:50:06 2010 New Revision: 111567 URL: http://llvm.org/viewvc/llvm-project?rev=111567&view=rev Log: Fixed a long delay in shutdown times by invalidating m_private_state_thread right before the private state thread (which calls "void *Process::RunPrivateStateThread ()") exits. Modified: lldb/trunk/source/Target/Process.cpp Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=111567&r1=111566&r2=111567&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Thu Aug 19 16:50:06 2010 @@ -1567,6 +1567,7 @@ if (log) log->Printf ("Process::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, this, GetID()); + m_private_state_thread = LLDB_INVALID_HOST_THREAD; return NULL; } From johnny.chen at apple.com Thu Aug 19 18:26:59 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 19 Aug 2010 23:26:59 -0000 Subject: [Lldb-commits] [lldb] r111572 - in /lldb/trunk/test: lldbtest.py unsigned_types/TestUnsignedTypes.py Message-ID: <20100819232659.82B772A6C12C@llvm.org> Author: johnny Date: Thu Aug 19 18:26:59 2010 New Revision: 111572 URL: http://llvm.org/viewvc/llvm-project?rev=111572&view=rev Log: Abstracted the running of command through the command interpreter and checking its return status into lldbtest.TestBase.runCmd(); and runCmd() in combination with checking the output against matching substrings (including startswith) into lldbtest.TestBase.expect(). TestUnsignedTypes.py is refactored to use the abstracted APIs. Other test cases to be modified later. Modified: lldb/trunk/test/lldbtest.py lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=111572&r1=111571&r2=111572&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu Aug 19 18:26:59 2010 @@ -104,7 +104,6 @@ # And the result object. self.res = lldb.SBCommandReturnObject() - def tearDown(self): # Finish the inferior process, if it was "run" previously. if self.runStarted: @@ -114,3 +113,43 @@ # Restore old working directory. os.chdir(self.oldcwd) + + def runCmd(self, cmd, msg=None, check=True): + """ + Ask the command interpreter to handle the command and then check its + return status. + """ + # Fail fast if 'cmd' is not meaningful. + if not cmd or len(cmd) == 0: + raise Exception("Bad 'cmd' parameter encountered") + self.ci.HandleCommand(cmd, self.res) + if cmd == "run": + self.runStarted = True + if check: + self.assertTrue(self.res.Succeeded(), + msg if msg else CMD_MSG(cmd)) + + def expect(self, cmd, msg, startstr=None, substrs=None): + """ + Similar to runCmd; with additional expect style output matching ability. + + Ask the command interpreter to handle the command and then check its + return status. The 'msg' parameter specifies an informational assert + message. We expect the output from running the command to start with + 'startstr' and matches the substrings contained in 'substrs'. + """ + # Fail fast if 'msg' is not meaningful. + if not msg or len(msg) == 0: + raise Exception("Bad 'msg' parameter encountered") + self.runCmd(cmd) + + output = self.res.GetOutput() + matched = output.startswith(startstr) if startstr else True + if substrs: + for str in substrs: + matched = output.find(str) > 0 + if not matched: + break + + self.assertTrue(matched, msg) + Modified: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/TestUnsignedTypes.py?rev=111572&r1=111571&r2=111572&view=diff ============================================================================== --- lldb/trunk/test/unsigned_types/TestUnsignedTypes.py (original) +++ lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Thu Aug 19 18:26:59 2010 @@ -14,58 +14,31 @@ def test_unsigned_types(self): """Test that variables with unsigned types display correctly.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break on line 19 in main() aftre the variables are assigned values. - self.ci.HandleCommand("breakpoint set -f main.cpp -l 19", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.cpp', line = 19, locations = 1" - ), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + 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) # The stop reason of the thread should be breakpoint. - self.ci.HandleCommand("thread list", res) - self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) - self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_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.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) # Test that unsigned types display correctly. - self.ci.HandleCommand("variable list -a", res) - #print "variable list -a ->", res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('variable list -a')) - output = res.GetOutput() - self.assertTrue( - output.startswith("the_unsigned_char = (unsigned char) 'c'") - and - output.find("the_unsigned_short = (short unsigned int) 0x0063") > 0 - and - output.find("the_unsigned_int = (unsigned int) 0x00000063") > 0 - and - output.find("the_unsigned_long = (long unsigned int) " - "0x0000000000000063") > 0 - and - output.find("the_unsigned_long_long = (long long unsigned int)" - " 0x0000000000000063") > 0 - and - output.find("the_uint32 = (uint32_t) 0x00000063"), - - VARIABLES_DISPLAYED_CORRECTLY - ) + self.expect("variable list -a", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "the_unsigned_char = (unsigned char) 'c'", + substrs = ["the_unsigned_short = (short unsigned int) 0x0063", + "the_unsigned_int = (unsigned int) 0x00000063", + "the_unsigned_long = (long unsigned int) 0x0000000000000063", + "the_unsigned_long_long = (long long unsigned int) 0x0000000000000063", + "the_uint32 = (uint32_t) 0x00000063"]) if __name__ == '__main__': From johnny.chen at apple.com Thu Aug 19 18:53:56 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 19 Aug 2010 23:53:56 -0000 Subject: [Lldb-commits] [lldb] r111587 - /lldb/trunk/test/lldbtest.py Message-ID: <20100819235356.29E972A6C12C@llvm.org> Author: johnny Date: Thu Aug 19 18:53:55 2010 New Revision: 111587 URL: http://llvm.org/viewvc/llvm-project?rev=111587&view=rev Log: Use cmd.startswith("run") instead of string equivalence test. 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=111587&r1=111586&r2=111587&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Thu Aug 19 18:53:55 2010 @@ -123,7 +123,7 @@ if not cmd or len(cmd) == 0: raise Exception("Bad 'cmd' parameter encountered") self.ci.HandleCommand(cmd, self.res) - if cmd == "run": + if cmd.startswith("run"): self.runStarted = True if check: self.assertTrue(self.res.Succeeded(), From johnny.chen at apple.com Thu Aug 19 19:27:37 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 20 Aug 2010 00:27:37 -0000 Subject: [Lldb-commits] [lldb] r111593 - /lldb/trunk/test/array_types/TestArrayTypes.py Message-ID: <20100820002737.6BBAC2A6C12C@llvm.org> Author: johnny Date: Thu Aug 19 19:27:37 2010 New Revision: 111593 URL: http://llvm.org/viewvc/llvm-project?rev=111593&view=rev Log: Converted to use runCmd() and expect() for more abstraction. 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=111593&r1=111592&r2=111593&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Thu Aug 19 19:27:37 2010 @@ -11,67 +11,46 @@ def test_array_types(self): """Test 'variable list var_name' on some variables with array types.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break on line 42 inside main(). - self.ci.HandleCommand("breakpoint set -f main.c -l 42", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 42, locations = 1"), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + 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.ci.HandleCommand("thread list", res) - #print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_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.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find('resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = ['resolved, hit count = 1']) # Issue 'variable list' command on several array-type variables. - self.ci.HandleCommand("variable list strings", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) - output = res.GetOutput() - self.assertTrue(output.startswith('(char *[4])') and - output.find('(char *) strings[0]') > 0 and - output.find('(char *) strings[1]') > 0 and - output.find('(char *) strings[2]') > 0 and - output.find('(char *) strings[3]') > 0 and - output.find('Hello') > 0 and - output.find('Hola') > 0 and - output.find('Bonjour') > 0 and - output.find('Guten Tag') > 0, - VARIABLES_DISPLAYED_CORRECTLY) - - self.ci.HandleCommand("variable list char_16", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) - self.assertTrue(res.GetOutput().find('(char) char_16[0]') > 0 and - res.GetOutput().find('(char) char_16[15]') > 0, - VARIABLES_DISPLAYED_CORRECTLY) - - self.ci.HandleCommand("variable list ushort_matrix", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) - self.assertTrue(res.GetOutput().startswith('(unsigned short [2][3])'), - VARIABLES_DISPLAYED_CORRECTLY) - - self.ci.HandleCommand("variable list long_6", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) - self.assertTrue(res.GetOutput().startswith('(long [6])'), - VARIABLES_DISPLAYED_CORRECTLY) + self.expect("variable list strings", VARIABLES_DISPLAYED_CORRECTLY, + startstr = '(char *[4])', + substrs = ['(char *) strings[0]', + '(char *) strings[1]', + '(char *) strings[2]', + '(char *) strings[3]', + 'Hello', + 'Hola', + 'Bonjour', + 'Guten Tag']) + + self.expect("variable list char_16", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(char) char_16[0]', + '(char) char_16[15]']) + + self.expect("variable list ushort_matrix", VARIABLES_DISPLAYED_CORRECTLY, + startstr = '(unsigned short [2][3])') + + self.expect("variable list long_6", VARIABLES_DISPLAYED_CORRECTLY, + startstr = '(long [6])') if __name__ == '__main__': From scallanan at apple.com Thu Aug 19 20:02:30 2010 From: scallanan at apple.com (Sean Callanan) Date: Fri, 20 Aug 2010 01:02:30 -0000 Subject: [Lldb-commits] [lldb] r111600 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/ClangExpressionVariable.h include/lldb/Expression/ClangPersistentVariables.h source/Commands/CommandObjectExpression.cpp source/Expression/ClangExpressionDeclMap.cpp source/Expression/ClangExpressionVariable.cpp source/Expression/ClangPersistentVariables.cpp source/Expression/DWARFExpression.cpp source/Expression/IRForTarget.cpp source/Expression/IRToDWARF.cpp Message-ID: <20100820010230.AE16D2A6C131@llvm.org> Author: spyffe Date: Thu Aug 19 20:02:30 2010 New Revision: 111600 URL: http://llvm.org/viewvc/llvm-project?rev=111600&view=rev Log: First step of refactoring variable handling in the expression parser. There shouldn't be four separate classes encapsulating a variable. ClangExpressionVariable is now meant to be the container for all variable information. It has several optional components that hold data for different subsystems. ClangPersistentVariable has been removed; we now use ClangExpressionVariable instead. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/ClangExpressionVariable.cpp lldb/trunk/source/Expression/ClangPersistentVariables.cpp lldb/trunk/source/Expression/DWARFExpression.cpp lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Expression/IRToDWARF.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Thu Aug 19 20:02:30 2010 @@ -21,6 +21,7 @@ // Project includes #include "lldb/Core/ClangForward.h" #include "lldb/Core/Value.h" +#include "lldb/Expression/ClangExpressionVariable.h" #include "lldb/Symbol/TaggedASTType.h" namespace llvm { @@ -30,7 +31,7 @@ namespace lldb_private { -class ClangPersistentVariable; +class ClangExpressionVariables; class ClangPersistentVariables; class Error; class Function; @@ -301,7 +302,7 @@ /// The execution context from which to read the struct. /// /// @param[out] result - /// A ClangPersistentVariable containing the result of the + /// A ClangExpressionVariable containing the result of the /// expression, for potential re-use. /// /// @param[in] error @@ -312,7 +313,7 @@ /// True on success; false otherwise. //------------------------------------------------------------------ bool Dematerialize(ExecutionContext *exe_ctx, - ClangPersistentVariable *&result, + ClangExpressionVariable *&result, Error &error); //------------------------------------------------------------------ @@ -487,7 +488,7 @@ /// @param[in] pvar /// The persistent variable that needs a Decl. //------------------------------------------------------------------ - void AddOneVariable(NameSearchContext &context, ClangPersistentVariable *pvar); + void AddOneVariable(NameSearchContext &context, ClangExpressionVariable *pvar); //------------------------------------------------------------------ /// Use the NameSearchContext to generate a Decl for the given @@ -545,7 +546,7 @@ //------------------------------------------------------------------ bool DoMaterialize (bool dematerialize, ExecutionContext *exe_ctx, - ClangPersistentVariable **result, + ClangExpressionVariable **result, Error &err); //------------------------------------------------------------------ Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Thu Aug 19 20:02:30 2010 @@ -15,92 +15,312 @@ #include // C++ Includes +#include #include // Other libraries and framework includes // Project includes #include "lldb/Core/ClangForward.h" -#include "lldb/Core/Value.h" +#include "lldb/Symbol/TaggedASTType.h" + +namespace llvm { + class Value; +} namespace lldb_private { + +class DataBufferHeap; +class ExecutionContext; +class Stream; +class Value; //---------------------------------------------------------------------- -/// @class ClangExpressionVariableList ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" -/// @brief Manages local variables that the expression interpreter uses. +/// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" +/// @brief Encapsulates one variable for the expression parser. +/// +/// The expression parser uses variables in three different contexts: +/// +/// First, it stores persistent variables along with the process for use +/// in expressions. These persistent variables contain their own data +/// and are typed. /// -/// The DWARF interpreter, when interpreting expressions, occasionally -/// needs to interact with chunks of memory corresponding to local variable -/// values. These locals are distinct from the externally-defined values -/// handled by ClangExpressionDeclMap, and do not persist between expressions -/// so they are not handled by ClangPersistentVariables. They are kept in a -/// list, which is encapsulated in ClangEpxressionVariableList. +/// Second, in an interpreted expression, it stores the local variables +/// for the expression along with the expression. These variables +/// contain their own data and are typed. +/// +/// Third, in a JIT-compiled expression, it stores the variables that +/// the expression needs to have materialized and dematerialized at each +/// execution. These do not contain their own data but are named and +/// typed. +/// +/// This class supports all of these use cases using simple type +/// polymorphism, and provides necessary support methods. Its interface +/// is RTTI-neutral. //---------------------------------------------------------------------- -class ClangExpressionVariableList +struct ClangExpressionVariable { -public: + ClangExpressionVariable(); + + ClangExpressionVariable(const ClangExpressionVariable &cev); + //---------------------------------------------------------------------- - /// Constructor + /// If the variable contains its own data, make a Value point at it + /// + /// @param[in] value + /// The value to point at the data. + /// + /// @return + /// True on success; false otherwise (in particular, if this variable + /// does not contain its own data). //---------------------------------------------------------------------- - ClangExpressionVariableList(); + bool + PointValueAtData(Value &value); //---------------------------------------------------------------------- - /// Destructor + /// The following values should stay valid for the life of the variable //---------------------------------------------------------------------- - ~ClangExpressionVariableList(); - + std::string m_name; ///< The name of the variable + TypeFromUser m_user_type; ///< The type of the variable according to some LLDB context; NULL if the type hasn't yet been migrated to one + + //---------------------------------------------------------------------- + /// The following values should not live beyond parsing + //---------------------------------------------------------------------- + struct ParserVars { + 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 + }; + std::auto_ptr m_parser_vars; + + //---------------------------------------------------------------------- + /// Make this variable usable by the parser by allocating space for + /// parser-specific variables + //---------------------------------------------------------------------- + void EnableParserVars() + { + if (!m_parser_vars.get()) + m_parser_vars.reset(new struct ParserVars); + } + + //---------------------------------------------------------------------- + /// Deallocate parser-specific variables + //---------------------------------------------------------------------- + void DisableParserVars() + { + m_parser_vars.reset(); + } + //---------------------------------------------------------------------- - /// Get or create the chunk of data corresponding to a given VarDecl. + /// The following values are valid if the variable is used by JIT code + //---------------------------------------------------------------------- + struct JITVars { + off_t m_alignment; ///< The required alignment of the variable, in bytes + size_t m_size; ///< The space required for the variable, in bytes + off_t m_offset; ///< The offset of the variable in the struct, in bytes + }; + std::auto_ptr m_jit_vars; + + //---------------------------------------------------------------------- + /// Make this variable usable for materializing for the JIT by allocating + /// space for JIT-specific variables + //---------------------------------------------------------------------- + void EnableJITVars() + { + if (!m_jit_vars.get()) + m_jit_vars.reset(new struct JITVars); + } + + //---------------------------------------------------------------------- + /// Deallocate JIT-specific variables + //---------------------------------------------------------------------- + void DisableJITVars() + { + m_jit_vars.reset(); + } + + //---------------------------------------------------------------------- + /// The following values are valid if the value contains its own data + //---------------------------------------------------------------------- + struct DataVars { + lldb_private::DataBufferHeap *m_data; ///< The heap area allocated to contain this variable's data. Responsibility for deleting this falls to whoever uses the variable last + }; + std::auto_ptr m_data_vars; + + //---------------------------------------------------------------------- + /// Make this variable usable for storing its data internally by + /// allocating data-specific variables + //---------------------------------------------------------------------- + void EnableDataVars() + { + if (!m_jit_vars.get()) + m_data_vars.reset(new struct DataVars); + } + + //---------------------------------------------------------------------- + /// Deallocate data-specific variables + //---------------------------------------------------------------------- + void DisableDataVars(); + + //---------------------------------------------------------------------- + /// Return the variable's size in bytes + //---------------------------------------------------------------------- + size_t Size () + { + return (m_user_type.GetClangTypeBitWidth () + 7) / 8; + } + + //---------------------------------------------------------------------- + /// Pretty-print the variable, assuming it contains its own data + /// + /// @param[in] output_stream + /// The stream to pretty-print on. + /// + /// @param[in] exe_ctx + /// The execution context to use when resolving the contents of the + /// variable. + /// + /// @param[in] format + /// The format to print the variable in /// - /// @param[in] var_decl - /// The Decl for which a chunk of memory is to be allocated. + /// @param[in] show_types + /// If true, print the type of the variable /// - /// @param[out] idx - /// The index of the Decl in the list of variables. + /// @param[in] show_summary + /// If true, print a summary of the variable's type /// - /// @param[in] can_create - /// True if the memory should be created if necessary. + /// @param[in] verbose + /// If true, be verbose in printing the value of the variable /// /// @return - /// A Value for the allocated memory. NULL if the Decl couldn't be - /// found and can_create was false, or if some error occurred during - /// allocation. + /// An Error describing the result of the operation. If Error::Success() + /// returns true, the pretty printing completed successfully. //---------------------------------------------------------------------- - Value * - GetVariableForVarDecl (const clang::VarDecl *var_decl, - uint32_t& idx, - bool can_create); + Error Print(Stream &output_stream, + ExecutionContext &exe_ctx, + lldb::Format format, + bool show_types, + bool show_summary, + bool verbose); +}; +//---------------------------------------------------------------------- +/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" +/// @brief Manages variables that the expression parser uses. +/// +/// The expression parser uses variable lists in various contexts, as +/// discuessed at ClangExpressionVariable. This abstract class contains +/// the basic functions for managing a list of variables. Its subclasses +/// store pointers to variables or variables, depending on whether they +/// are backing stores or merely transient repositories. +//---------------------------------------------------------------------- +class ClangExpressionVariableListBase +{ +public: + //---------------------------------------------------------------------- + /// Return the number of variables in the list + //---------------------------------------------------------------------- + virtual uint64_t Size() = 0; + //---------------------------------------------------------------------- - /// Get the chunk of data corresponding to a given index into the list. + /// Return the variable at the given index in the list + //---------------------------------------------------------------------- + virtual ClangExpressionVariable &VariableAtIndex(uint64_t index) = 0; + + //---------------------------------------------------------------------- + /// Add a new variable and return its index + //---------------------------------------------------------------------- + virtual uint64_t AddVariable(ClangExpressionVariable& var) = 0; + + //---------------------------------------------------------------------- + /// Finds a variable by name in the list. /// - /// @param[in] idx - /// The index of the Decl in the list of variables. + /// @param[in] name + /// The name of the requested variable. /// /// @return - /// The value at the given index, or NULL if there is none. + /// The variable requested, or NULL if that variable is not in the list. //---------------------------------------------------------------------- - Value * - GetVariableAtIndex (uint32_t idx); + ClangExpressionVariable *GetVariable (const char *name) + { + for (uint64_t index = 0, size = Size(); index < size; ++index) + { + ClangExpressionVariable &candidate (VariableAtIndex(index)); + if (!candidate.m_name.compare(name)) + return &candidate; + } + return NULL; + } +}; + +//---------------------------------------------------------------------- +/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" +/// @brief A list of variable references. +/// +/// This class stores references to variables stored elsewhere. +//---------------------------------------------------------------------- +class ClangExpressionVariableList : public ClangExpressionVariableListBase +{ +public: + //---------------------------------------------------------------------- + /// Implementation of methods in ClangExpressionVariableListBase + //---------------------------------------------------------------------- + uint64_t Size() + { + return m_variables.size(); + } + + ClangExpressionVariable &VariableAtIndex(uint64_t index) + { + return *m_variables[index]; + } + + uint64_t AddVariable(ClangExpressionVariable &var) + { + m_variables.push_back(&var); + return m_variables.size() - 1; + } private: + std::vector m_variables; +}; + +//---------------------------------------------------------------------- +/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" +/// @brief A list of variable references. +/// +/// This class stores variables internally, acting as the permanent store. +//---------------------------------------------------------------------- +class ClangExpressionVariableStore : public ClangExpressionVariableListBase +{ +public: //---------------------------------------------------------------------- - /// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" - /// @brief Manages one local variable for the expression interpreter. - /// - /// The expression interpreter uses specially-created Values to hold its - /// temporary locals. These Values contain data buffers holding enough - /// space to contain a variable of the appropriate type. The VarDecls - /// are only used while creating the list and generating the DWARF code for - /// an expression; when interpreting the DWARF, the variables are identified - /// only by their index into the list of variables. + /// Implementation of methods in ClangExpressionVariableListBase //---------------------------------------------------------------------- - struct ClangExpressionVariable + uint64_t Size() { - const clang::VarDecl *m_var_decl; ///< The VarDecl corresponding to the parsed local. - Value *m_value; ///< The LLDB Value containing the data for the local. - }; + return m_variables.size(); + } + + ClangExpressionVariable &VariableAtIndex(uint64_t index) + { + return m_variables[index]; + } - typedef std::vector Variables; - Variables m_variables; ///< The list of variables used by the expression. + uint64_t AddVariable(ClangExpressionVariable &var) + { + m_variables.push_back(var); + return m_variables.size() - 1; + } + + //---------------------------------------------------------------------- + /// Create a new variable in the list and return its index + //---------------------------------------------------------------------- + uint64_t CreateVariable() + { + m_variables.push_back(ClangExpressionVariable()); + return m_variables.size() - 1; + } +private: + std::vector m_variables; }; } // namespace lldb_private Modified: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h (original) +++ lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Thu Aug 19 20:02:30 2010 @@ -10,147 +10,12 @@ #ifndef liblldb_ClangPersistentVariables_h_ #define liblldb_ClangPersistentVariables_h_ -#include "lldb/lldb-forward-rtti.h" -#include "lldb/Core/ConstString.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Symbol/TaggedASTType.h" - -#include -#include +#include "lldb/Expression/ClangExpressionVariable.h" namespace lldb_private { //---------------------------------------------------------------------- -/// @class ClangPersistentVariable ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h" -/// @brief Encapsulates a persistent value that need to be preserved between expression invocations. -/// -/// Although expressions can define truly local variables, frequently the user -/// wants to create variables whose values persist between invocations of the -/// expression. These variables are also created each time an expression returns -/// a result. The ClangPersistentVariable class encapsulates such a variable, -/// which contains data and a type. -//---------------------------------------------------------------------- -class ClangPersistentVariable -{ - friend class ClangPersistentVariables; -public: - //---------------------------------------------------------------------- - /// Constructor - //---------------------------------------------------------------------- - ClangPersistentVariable () : - m_name(), - m_user_type(), - m_data() - { - } - - //---------------------------------------------------------------------- - /// Copy constructor - /// - /// @param[in] pv - /// The persistent variable to make a copy of. - //---------------------------------------------------------------------- - ClangPersistentVariable (const ClangPersistentVariable &pv) : - m_name(pv.m_name), - m_user_type(pv.m_user_type), - m_data(pv.m_data) - { - } - - //---------------------------------------------------------------------- - /// Assignment operator - //---------------------------------------------------------------------- - ClangPersistentVariable &operator=(const ClangPersistentVariable &pv) - { - m_name = pv.m_name; - m_user_type = pv.m_user_type; - m_data = pv.m_data; - return *this; - } - - //---------------------------------------------------------------------- - /// Return the number of bytes required to store the variable - //---------------------------------------------------------------------- - size_t Size () - { - return (m_user_type.GetClangTypeBitWidth () + 7) / 8; - } - - //---------------------------------------------------------------------- - /// Return the variable's contents, in local memory but stored according - /// to the target's byte order - //---------------------------------------------------------------------- - uint8_t *Data () - { - return m_data->GetBytes(); - } - - //---------------------------------------------------------------------- - /// Return the variable's contents, in local memory but stored in a form - /// (byte order, etc.) appropriate for copying into the target's memory - //---------------------------------------------------------------------- - TypeFromUser Type () - { - return m_user_type; - } - - //---------------------------------------------------------------------- - /// Pretty-print the variable - /// - /// @param[in] output_stream - /// The stream to pretty-print on. - /// - /// @param[in] exe_ctx - /// The execution context to use when resolving the contents of the - /// variable. - /// - /// @param[in] format - /// The format to print the variable in - /// - /// @param[in] show_types - /// If true, print the type of the variable - /// - /// @param[in] show_summary - /// If true, print a summary of the variable's type - /// - /// @param[in] verbose - /// If true, be verbose in printing the value of the variable - /// - /// @return - /// An Error describing the result of the operation. If Error::Success() - /// returns true, the pretty printing completed successfully. - //---------------------------------------------------------------------- - Error Print(Stream &output_stream, - ExecutionContext &exe_ctx, - lldb::Format format, - bool show_types, - bool show_summary, - bool verbose); -private: - //---------------------------------------------------------------------- - /// Constructor - /// - /// @param[in] name - /// The name of the variable, usually of the form $foo. - /// - /// @param[in] user_type - /// The type of the variable, in an AST context that will survive - /// as long as the variable. - //---------------------------------------------------------------------- - ClangPersistentVariable (ConstString name, TypeFromUser user_type) - { - m_name = name; - m_user_type = user_type; - m_data = lldb::DataBufferSP(new DataBufferHeap(Size(), 0)); - } - - ConstString m_name; ///< The name of the variable, usually $foo. - TypeFromUser m_user_type; ///< The type of the variable. Must be valid as long as the variable exists. - lldb::DataBufferSP m_data; ///< A shared pointer to the variable's data. This is a shared pointer so the variable object can move around without excess copying. -}; - -//---------------------------------------------------------------------- /// @class ClangPersistentVariables ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h" /// @brief Manages persistent values that need to be preserved between expression invocations. /// @@ -158,55 +23,27 @@ /// ClangPersistentVariable for more discussion. Also provides an increasing, /// 0-based counter for naming result variables. //---------------------------------------------------------------------- -class ClangPersistentVariables +class ClangPersistentVariables : public ClangExpressionVariableStore { public: //---------------------------------------------------------------------- - /// Create a single named persistent variable - /// - /// @param[in] name - /// The desired name for the newly-created variable. - /// - /// @param[in] user_type - /// The desired type for the variable, in a context that will survive - /// as long as ClangPersistentVariables. - /// - /// @return - /// The newly-created persistent variable or NULL if a variable with the - /// same name already exists. - //---------------------------------------------------------------------- - ClangPersistentVariable *CreateVariable (ConstString name, TypeFromUser user_type); - - //---------------------------------------------------------------------- - /// Finds a persistent variable 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. - //---------------------------------------------------------------------- - ClangPersistentVariable *GetVariable (ConstString name); - - //---------------------------------------------------------------------- /// Return the next entry in the sequence of strings "$0", "$1", ... for use /// naming result variables. /// /// @param[in] name /// A string to place the variable name in. //---------------------------------------------------------------------- - void GetNextResultName(std::string &name); + void GetNextResultName (std::string &name); //---------------------------------------------------------------------- /// Constructor //---------------------------------------------------------------------- ClangPersistentVariables (); + + bool CreatePersistentVariable(const char *name, + TypeFromUser user_type); private: - typedef std::map PVarMap; - typedef PVarMap::iterator PVarIterator; - - PVarMap m_variables; ///< The backing store for the list of variables. - uint64_t m_result_counter; ///< The counter used by GetNextResultName(). + uint64_t m_result_counter; ///< The counter used by GetNextResultName(). }; } Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Aug 19 20:02:30 2010 @@ -252,7 +252,7 @@ bool success; bool canInterpret = false; - ClangPersistentVariable *expr_result = 0; + ClangExpressionVariable *expr_result = 0; Error expr_error; canInterpret = clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes); Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Thu Aug 19 20:02:30 2010 @@ -101,14 +101,7 @@ parser_type.GetOpaqueQualType()), context); - ConstString const_name(name); - - ClangPersistentVariable *pvar = m_persistent_vars->CreateVariable(const_name, user_type); - - if (!pvar) - return false; - - return true; + return m_persistent_vars->CreatePersistentVariable (name, user_type); } bool @@ -294,7 +287,7 @@ bool ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx, - ClangPersistentVariable *&result, + ClangExpressionVariable *&result, Error &err) { return DoMaterialize(true, exe_ctx, &result, err); @@ -368,7 +361,7 @@ bool ClangExpressionDeclMap::DoMaterialize (bool dematerialize, ExecutionContext *exe_ctx, - ClangPersistentVariable **result, + ClangExpressionVariable **result, Error &err) { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); @@ -451,7 +444,7 @@ if (log) log->PutCString("Returning result PVar"); - *result = m_persistent_vars->GetVariable(ConstString(m_result_name.c_str())); + *result = m_persistent_vars->GetVariable(m_result_name.c_str()); if (!*result) { @@ -506,7 +499,7 @@ if (log) log->Printf("Found persistent variable %s", name); - ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name))); + ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name)); if (!pvar) { @@ -515,7 +508,11 @@ } size_t pvar_size = pvar->Size(); - uint8_t *pvar_data = pvar->Data(); + + if (!pvar->m_data_vars.get()) + return false; + + uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes(); Error error; if (dematerialize) @@ -779,7 +776,7 @@ if (var) AddOneVariable(context, var); - ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name))); + ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name)); if (pvar) AddOneVariable(context, pvar); @@ -927,9 +924,9 @@ void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, - ClangPersistentVariable *pvar) + ClangExpressionVariable *pvar) { - TypeFromUser user_type = pvar->Type(); + TypeFromUser user_type = pvar->m_user_type; TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(), user_type.GetASTContext(), Modified: lldb/trunk/source/Expression/ClangExpressionVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionVariable.cpp?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionVariable.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionVariable.cpp Thu Aug 19 20:02:30 2010 @@ -14,74 +14,155 @@ // Other libraries and framework includes // Project includes #include "clang/AST/ASTContext.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/Value.h" using namespace lldb_private; using namespace clang; -ClangExpressionVariableList::ClangExpressionVariableList() : - m_variables() +ClangExpressionVariable::ClangExpressionVariable() { + m_name = ""; + m_user_type = TypeFromUser(NULL, NULL); + m_parser_vars.reset(NULL); + m_jit_vars.reset(NULL); + m_data_vars.reset(NULL); } -ClangExpressionVariableList::~ClangExpressionVariableList() +void ClangExpressionVariable::DisableDataVars() { - uint32_t num_variables = m_variables.size(); - uint32_t var_index; - - for (var_index = 0; var_index < num_variables; ++var_index) - delete m_variables[var_index].m_value; + if (m_data_vars.get() && m_data_vars->m_data) + delete m_data_vars->m_data; + m_data_vars.reset(); } -Value * -ValueForDecl(const VarDecl *var_decl) +Error +ClangExpressionVariable::Print (Stream &output_stream, + ExecutionContext &exe_ctx, + lldb::Format format, + bool show_types, + bool show_summary, + bool verbose) { - Value *ret = new Value; - - ret->SetContext(Value::eContextTypeOpaqueClangQualType, - var_decl->getType().getAsOpaquePtr()); + Error err; + + if (!m_data_vars.get() || !m_data_vars->m_data) + { + err.SetErrorToGenericError(); + err.SetErrorStringWithFormat("Variable doesn't contain a value"); + return err; + } + + Value val; + + clang::ASTContext *ast_context = m_user_type.GetASTContext(); + + val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ()); + val.SetValueType (Value::eValueTypeHostAddress); + val.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes (); + + val.ResolveValue (&exe_ctx, ast_context); + + if (val.GetContextType () == Value::eContextTypeInvalid && + val.GetValueType () == Value::eValueTypeScalar && + format == lldb::eFormatDefault) + { + // The expression result is just a scalar with no special formatting + val.GetScalar ().GetValue (&output_stream, show_types); + output_stream.EOL (); + return err; + } + + // The expression result is more complex and requires special handling + DataExtractor data; + Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0); + + if (!expr_error.Success ()) + { + err.SetErrorToGenericError (); + err.SetErrorStringWithFormat ("Couldn't resolve variable value: %s", expr_error.AsCString ()); + return err; + } - uint64_t bit_width = var_decl->getASTContext().getTypeSize(var_decl->getType()); + if (format == lldb::eFormatDefault) + format = val.GetValueDefaultFormat (); - uint32_t byte_size = (bit_width + 7 ) / 8; + void *clang_type = val.GetValueOpaqueClangQualType (); - ret->ResizeData(byte_size); + output_stream.Printf("%s = ", m_name.c_str()); - return ret; + if (clang_type) + { + if (show_types) + output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString()); + + ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to + clang_type, // The opaque clang type we want to dump that value of + &exe_ctx, // The execution context for memory and variable access + &output_stream, // Stream to dump to + format, // Format to use when dumping + data, // A buffer containing the bytes for the clang type + 0, // Byte offset within "data" where value is + data.GetByteSize (), // Size in bytes of the value we are dumping + 0, // Bitfield bit size + 0, // Bitfield bit offset + show_types, // Show types? + show_summary, // Show summary? + verbose, // Debug logging output? + UINT32_MAX); // Depth to dump in case this is an aggregate type + } + else + { + data.Dump (&output_stream, // Stream to dump to + 0, // Byte offset within "data" + format, // Format to use when dumping + data.GetByteSize (), // Size in bytes of each item we are dumping + 1, // Number of items to dump + UINT32_MAX, // Number of items per line + LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context + 0, // Bitfield bit size + 0); // Bitfield bit offset + } + + output_stream.EOL(); + + return err; } -Value * -ClangExpressionVariableList::GetVariableForVarDecl (const VarDecl *var_decl, uint32_t& idx, bool can_create) +ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &cev) : + m_name(cev.m_name), + m_user_type(cev.m_user_type) { - uint32_t num_variables = m_variables.size(); - uint32_t var_index; - - for (var_index = 0; var_index < num_variables; ++var_index) + if (cev.m_parser_vars.get()) { - if (m_variables[var_index].m_var_decl == var_decl) - { - idx = var_index; - return m_variables[var_index].m_value; - } + m_parser_vars.reset(new struct ParserVars); + *m_parser_vars.get() = *cev.m_parser_vars.get(); } - - if (!can_create) - return NULL; - - idx = m_variables.size(); - ClangExpressionVariable val; - val.m_var_decl = var_decl; - val.m_value = ValueForDecl(var_decl); - m_variables.push_back(val); + if (cev.m_jit_vars.get()) + { + m_jit_vars.reset(new struct JITVars); + *m_jit_vars.get() = *cev.m_jit_vars.get(); + } - return m_variables.back().m_value; + if (cev.m_data_vars.get()) + { + m_data_vars.reset(new struct DataVars); + *m_data_vars.get() = *cev.m_data_vars.get(); + } } -Value * -ClangExpressionVariableList::GetVariableAtIndex (uint32_t idx) +bool +ClangExpressionVariable::PointValueAtData(Value &value) { - if (idx < m_variables.size()) - return m_variables[idx].m_value; + if (!m_data_vars.get()) + return false; + + value.SetContext(Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType()); + value.SetValueType(Value::eValueTypeHostAddress); + value.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes(); - return NULL; + return true; } Modified: lldb/trunk/source/Expression/ClangPersistentVariables.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangPersistentVariables.cpp?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangPersistentVariables.cpp (original) +++ lldb/trunk/source/Expression/ClangPersistentVariables.cpp Thu Aug 19 20:02:30 2010 @@ -15,119 +15,10 @@ using namespace lldb_private; -Error -ClangPersistentVariable::Print (Stream &output_stream, - ExecutionContext &exe_ctx, - lldb::Format format, - bool show_types, - bool show_summary, - bool verbose) -{ - Error err; - - Value val; - - clang::ASTContext *ast_context = m_user_type.GetASTContext(); - - val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ()); - val.SetValueType (Value::eValueTypeHostAddress); - val.GetScalar() = (uint64_t)Data (); - - val.ResolveValue (&exe_ctx, ast_context); - - if (val.GetContextType () == Value::eContextTypeInvalid && - val.GetValueType () == Value::eValueTypeScalar && - format == lldb::eFormatDefault) - { - // The expression result is just a scalar with no special formatting - val.GetScalar ().GetValue (&output_stream, show_types); - output_stream.EOL (); - return err; - } - - // The expression result is more complext and requires special handling - DataExtractor data; - Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0); - - if (!expr_error.Success ()) - { - err.SetErrorToGenericError (); - err.SetErrorStringWithFormat ("Couldn't resolve result value: %s", expr_error.AsCString ()); - return err; - } - - if (format == lldb::eFormatDefault) - format = val.GetValueDefaultFormat (); - - void *clang_type = val.GetValueOpaqueClangQualType (); - - output_stream.Printf("%s = ", m_name.AsCString("")); - - if (clang_type) - { - if (show_types) - output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString()); - - ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to - clang_type, // The opaque clang type we want to dump that value of - &exe_ctx, // The execution context for memory and variable access - &output_stream, // Stream to dump to - format, // Format to use when dumping - data, // A buffer containing the bytes for the clang type - 0, // Byte offset within "data" where value is - data.GetByteSize (), // Size in bytes of the value we are dumping - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, // Show types? - show_summary, // Show summary? - verbose, // Debug logging output? - UINT32_MAX); // Depth to dump in case this is an aggregate type - } - else - { - data.Dump (&output_stream, // Stream to dump to - 0, // Byte offset within "data" - format, // Format to use when dumping - data.GetByteSize (), // Size in bytes of each item we are dumping - 1, // Number of items to dump - UINT32_MAX, // Number of items per line - LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context - 0, // Bitfield bit size - 0); // Bitfield bit offset - } - - output_stream.EOL(); - - return err; -} - ClangPersistentVariables::ClangPersistentVariables () : - m_variables(), - m_result_counter(0) + ClangExpressionVariableStore() { -} - -ClangPersistentVariable * -ClangPersistentVariables::CreateVariable (ConstString name, - TypeFromUser user_type) -{ - ClangPersistentVariable new_var(name, user_type); - - if (m_variables.find(name) != m_variables.end()) - return NULL; - - m_variables[name] = new_var; - - return &m_variables[name]; -} - -ClangPersistentVariable * -ClangPersistentVariables::GetVariable (ConstString name) -{ - if (m_variables.find(name) == m_variables.end()) - return NULL; - - return &m_variables[name]; + m_result_counter = 0; } void @@ -140,3 +31,22 @@ name = s.GetString(); } + +bool +ClangPersistentVariables::CreatePersistentVariable(const char *name, + TypeFromUser user_type) +{ + if (GetVariable(name)) + return false; + + ClangExpressionVariable &pvar (VariableAtIndex(CreateVariable())); + + pvar.m_name = name; + pvar.m_user_type = user_type; + + pvar.EnableDataVars(); + + pvar.m_data_vars->m_data = new DataBufferHeap(pvar.Size(), 0); + + return true; +} \ No newline at end of file Modified: lldb/trunk/source/Expression/DWARFExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/source/Expression/DWARFExpression.cpp (original) +++ lldb/trunk/source/Expression/DWARFExpression.cpp Thu Aug 19 20:02:30 2010 @@ -2435,6 +2435,7 @@ //---------------------------------------------------------------------- case DW_OP_APPLE_expr_local: { + /* uint32_t idx = opcodes.GetULEB128(&offset); if (expr_locals == NULL) { @@ -2453,6 +2454,7 @@ stack.push_back(*proxy); delete proxy; //stack.back().SetContext (Value::eContextTypeOpaqueClangQualType, expr_local_variable->GetOpaqueClangQualType()); + */ } break; Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Thu Aug 19 20:02:30 2010 @@ -32,7 +32,7 @@ IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, const TargetData *target_data) : - ModulePass(ID), + ModulePass(&ID), m_decl_map(decl_map), m_target_data(target_data), m_sel_registerName(NULL) Modified: lldb/trunk/source/Expression/IRToDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRToDWARF.cpp?rev=111600&r1=111599&r2=111600&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRToDWARF.cpp (original) +++ lldb/trunk/source/Expression/IRToDWARF.cpp Thu Aug 19 20:02:30 2010 @@ -29,7 +29,7 @@ IRToDWARF::IRToDWARF(lldb_private::ClangExpressionVariableList &variable_list, lldb_private::ClangExpressionDeclMap *decl_map, lldb_private::StreamString &strm) : - ModulePass(ID), + ModulePass(&ID), m_variable_list(variable_list), m_decl_map(decl_map), m_strm(strm) From jingham at apple.com Thu Aug 19 20:13:58 2010 From: jingham at apple.com (Jim Ingham) Date: Fri, 20 Aug 2010 01:13:58 -0000 Subject: [Lldb-commits] [lldb] r111605 - /lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Message-ID: <20100820011358.333ED2A6C131@llvm.org> Author: jingham Date: Thu Aug 19 20:13:58 2010 New Revision: 111605 URL: http://llvm.org/viewvc/llvm-project?rev=111605&view=rev Log: Remove redundant call to ParseCompileUnitLineTable. The call to sc.comp_unit->GetLineTable() will parse the line table if it hasn't been read in. Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=111605&r1=111604&r2=111605&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Thu Aug 19 20:13:58 2010 @@ -1976,11 +1976,7 @@ // We found the function, so we should find the line table // and line table entry as well LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table == NULL) - { - if (ParseCompileUnitLineTable(sc)) - line_table = sc.comp_unit->GetLineTable(); - } + if (line_table != NULL) line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry); From jingham at apple.com Thu Aug 19 20:15:02 2010 From: jingham at apple.com (Jim Ingham) Date: Fri, 20 Aug 2010 01:15:02 -0000 Subject: [Lldb-commits] [lldb] r111606 - in /lldb/trunk: include/lldb/Symbol/Function.h source/Symbol/Function.cpp Message-ID: <20100820011502.1411A2A6C131@llvm.org> Author: jingham Date: Thu Aug 19 20:15:01 2010 New Revision: 111606 URL: http://llvm.org/viewvc/llvm-project?rev=111606&view=rev Log: Add methods to Function to get the first and last source lines of the function, and to get whether this Function is an inlined instance or not. Modified: lldb/trunk/include/lldb/Symbol/Function.h lldb/trunk/source/Symbol/Function.cpp Modified: lldb/trunk/include/lldb/Symbol/Function.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Function.h?rev=111606&r1=111605&r2=111606&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Function.h (original) +++ lldb/trunk/include/lldb/Symbol/Function.h Thu Aug 19 20:15:01 2010 @@ -420,6 +420,44 @@ const AddressRange & GetAddressRange(); + + //------------------------------------------------------------------ + /// Find the file and line number of the source location of the start + /// of the function. This will use the declaration if present and fall + /// back on the line table if that fails. So there may NOT be a line + /// table entry for this source file/line combo. + /// + /// @param[out] source_file + /// The source file. + /// + /// @param[out] line_no + /// The line number. + //------------------------------------------------------------------ + void + GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no); + + //------------------------------------------------------------------ + /// Find the file and line number of the source location of the end + /// of the function. + /// + /// + /// @param[out] source_file + /// The source file. + /// + /// @param[out] line_no + /// The line number. + //------------------------------------------------------------------ + void + GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no); + + //------------------------------------------------------------------ + /// Return whether this Function represents an inlined version of the + /// original function. + /// + /// @return + /// \b true if inlined, \b false otherwise. + //------------------------------------------------------------------ + bool IsInlined(); //------------------------------------------------------------------ /// Get accessor for the block list. Modified: lldb/trunk/source/Symbol/Function.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Function.cpp?rev=111606&r1=111605&r2=111606&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Function.cpp (original) +++ lldb/trunk/source/Symbol/Function.cpp Thu Aug 19 20:15:01 2010 @@ -237,6 +237,70 @@ return GetBlocks(true).GetAddressRange(); } +bool +Function::IsInlined() +{ + Block *root_block = GetBlocks(true).GetBlockByID(Block::RootID); + if (root_block) + { + if (root_block->InlinedFunctionInfo() != NULL) + return true; + } + return false; + +} +void +Function::GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no) +{ + line_no = 0; + source_file.Clear(); + + if (m_comp_unit == NULL) + return; + + if (m_type != NULL && m_type->GetDeclaration().GetLine() != 0) + { + source_file = m_type->GetDeclaration().GetFile(); + line_no = m_type->GetDeclaration().GetLine(); + } + else + { + LineTable *line_table = m_comp_unit->GetLineTable(); + if (line_table == NULL) + return; + + LineEntry line_entry; + if (line_table->FindLineEntryByAddress (GetAddressRange().GetBaseAddress(), line_entry, NULL)) + { + line_no = line_entry.line; + source_file = line_entry.file; + } + } +} + +void +Function::GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no) +{ + line_no = 0; + source_file.Clear(); + + // The -1 is kind of cheesy, but I want to get the last line entry for the given function, not the + // first entry of the next. + Address scratch_addr(GetAddressRange().GetBaseAddress()); + scratch_addr.SetOffset (scratch_addr.GetOffset() + GetAddressRange().GetByteSize() - 1); + + LineTable *line_table = m_comp_unit->GetLineTable(); + if (line_table == NULL) + return; + + LineEntry line_entry; + if (line_table->FindLineEntryByAddress (scratch_addr, line_entry, NULL)) + { + line_no = line_entry.line; + source_file = line_entry.file; + } +} + BlockList & Function::GetBlocks(bool can_create) { From jingham at apple.com Thu Aug 19 20:15:38 2010 From: jingham at apple.com (Jim Ingham) Date: Fri, 20 Aug 2010 01:15:38 -0000 Subject: [Lldb-commits] [lldb] r111607 - in /lldb/trunk: include/lldb/Symbol/Type.h source/Symbol/Type.cpp Message-ID: <20100820011538.644A72A6C131@llvm.org> Author: jingham Date: Thu Aug 19 20:15:38 2010 New Revision: 111607 URL: http://llvm.org/viewvc/llvm-project?rev=111607&view=rev Log: Add an accessor to get the Declaration for a type. Modified: lldb/trunk/include/lldb/Symbol/Type.h lldb/trunk/source/Symbol/Type.cpp Modified: lldb/trunk/include/lldb/Symbol/Type.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=111607&r1=111606&r2=111607&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Type.h (original) +++ lldb/trunk/include/lldb/Symbol/Type.h Thu Aug 19 20:15:38 2010 @@ -168,6 +168,9 @@ m_context = context; } + const lldb_private::Declaration & + GetDeclaration () const; + void * GetOpaqueClangQualType (); Modified: lldb/trunk/source/Symbol/Type.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Type.cpp?rev=111607&r1=111606&r2=111607&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Type.cpp (original) +++ lldb/trunk/source/Symbol/Type.cpp Thu Aug 19 20:15:38 2010 @@ -389,6 +389,11 @@ return GetSymbolFile()->GetObjectFile()->GetModule()->GetTypeList(); } +const lldb_private::Declaration & +lldb_private::Type::GetDeclaration () const +{ + return m_decl; +} bool lldb_private::Type::ResolveClangType() From jingham at apple.com Thu Aug 19 20:17:08 2010 From: jingham at apple.com (Jim Ingham) Date: Fri, 20 Aug 2010 01:17:08 -0000 Subject: [Lldb-commits] [lldb] r111608 - /lldb/trunk/source/Commands/CommandObjectSource.cpp Message-ID: <20100820011708.0D0A42A6C131@llvm.org> Author: jingham Date: Thu Aug 19 20:17:07 2010 New Revision: 111608 URL: http://llvm.org/viewvc/llvm-project?rev=111608&view=rev Log: Added "source list -n" so you can list by symbol name. Moved "--count" from "-n" to "-c". Added a -s option so you can restrict the source listing to a particular shared library. Modified: lldb/trunk/source/Commands/CommandObjectSource.cpp Modified: lldb/trunk/source/Commands/CommandObjectSource.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSource.cpp?rev=111608&r1=111607&r2=111608&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSource.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectSource.cpp Thu Aug 19 20:17:07 2010 @@ -172,7 +172,7 @@ error.SetErrorStringWithFormat("Invalid line number: '%s'.\n", option_arg); break; - case 'n': + case 'c': num_lines = Args::StringToUInt32 (option_arg, 0); if (num_lines == 0) error.SetErrorStringWithFormat("Invalid line count: '%s'.\n", option_arg); @@ -181,7 +181,14 @@ case 'f': file_name = option_arg; break; + + case 'n': + symbol_name = option_arg; + break; + case 's': + m_modules.push_back (std::string (option_arg)); + break; default: error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option); break; @@ -197,8 +204,10 @@ file_spec.Clear(); file_name.clear(); + symbol_name.clear(); start_line = 0; num_lines = 10; + m_modules.clear(); } const lldb::OptionDefinition* @@ -211,9 +220,10 @@ // Instance variables to hold the values for command options. FileSpec file_spec; std::string file_name; + std::string symbol_name; uint32_t start_line; uint32_t num_lines; - + STLStringArray m_modules; }; public: @@ -253,7 +263,155 @@ } ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext()); - if (m_options.file_name.empty()) + + if (!m_options.symbol_name.empty()) + { + // Displaying the source for a symbol: + Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + if (target == NULL) + { + result.AppendError ("invalid target, set executable file using 'file' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + SymbolContextList sc_list; + ConstString name(m_options.symbol_name.c_str()); + bool append = true; + size_t num_matches = 0; + + if (m_options.m_modules.size() > 0) + { + ModuleList matching_modules; + for (int i = 0; i < m_options.m_modules.size(); i++) + { + FileSpec module_spec(m_options.m_modules[i].c_str()); + if (module_spec) + { + matching_modules.Clear(); + target->GetImages().FindModules (&module_spec, NULL, NULL, NULL, matching_modules); + num_matches += matching_modules.FindFunctions (name, eFunctionNameTypeBase, append, sc_list); + } + } + } + else + { + num_matches = target->GetImages().FindFunctions (name, eFunctionNameTypeBase, append, sc_list); + } + + SymbolContext sc; + + if (num_matches == 0) + { + result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", m_options.symbol_name.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + + sc_list.GetContextAtIndex (0, sc); + FileSpec start_file; + uint32_t start_line; + uint32_t end_line; + FileSpec end_file; + if (sc.function != NULL) + { + sc.function->GetStartLineSourceInfo (start_file, start_line); + if (start_line == 0) + { + result.AppendErrorWithFormat("Could not find line information for start of function: \"%s\".\n", m_options.symbol_name.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + sc.function->GetEndLineSourceInfo (end_file, end_line); + } + else + { + result.AppendErrorWithFormat("Could not find function info for: \"%s\".\n", m_options.symbol_name.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + + if (num_matches > 1) + { + // This could either be because there are multiple functions of this name, in which case + // we'll have to specify this further... Or it could be because there are multiple inlined instances + // of one function. So run through the matches and if they all have the same file & line then we can just + // list one. + + bool found_multiple = false; + + for (size_t i = 1; i < num_matches; i++) + { + SymbolContext scratch_sc; + sc_list.GetContextAtIndex (i, scratch_sc); + if (scratch_sc.function != NULL) + { + FileSpec scratch_file; + uint32_t scratch_line; + scratch_sc.function->GetStartLineSourceInfo (scratch_file, scratch_line); + if (scratch_file != start_file + || scratch_line != start_line) + { + found_multiple = true; + break; + } + } + } + if (found_multiple) + { + StreamString s; + for (size_t i = 0; i < num_matches; i++) + { + SymbolContext scratch_sc; + sc_list.GetContextAtIndex (i, scratch_sc); + if (scratch_sc.function != NULL) + { + s.Printf("\n%d: ", i); + scratch_sc.function->Dump (&s, true); + } + } + result.AppendErrorWithFormat("Multiple functions found matching: %s: \n%s\n", + m_options.symbol_name.c_str(), + s.GetData()); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + + + // This is a little hacky, but the first line table entry for a function points to the "{" that + // starts the function block. It would be nice to actually get the function + // declaration in there too. So back up a bit, but not further than what you're going to display. + size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2; + uint32_t line_no; + if (start_line <= lines_to_back_up) + line_no = 1; + else + line_no = start_line - lines_to_back_up; + + // For fun, if the function is shorter than the number of lines we're supposed to display, + // only display the function... + if (end_line != 0) + { + if (m_options.num_lines > end_line - line_no) + m_options.num_lines = end_line - line_no; + } + + char path_buf[PATH_MAX+1]; + start_file.GetPath(path_buf, PATH_MAX); + result.AppendMessageWithFormat("File: %s.\n", path_buf); + interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file, + line_no, + 0, + m_options.num_lines, + "", + &result.GetOutputStream()); + + result.SetStatus (eReturnStatusSuccessFinishResult); + return true; + + } + else if (m_options.file_name.empty()) { // Last valid source manager context, or the current frame if no // valid last context in source manager. @@ -294,32 +452,96 @@ bool check_inlines = false; SymbolContextList sc_list; - size_t num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename, - 0, - check_inlines, - eSymbolContextModule | eSymbolContextCompUnit, - sc_list); - if (num_matches > 0) + size_t num_matches = 0; + + if (m_options.m_modules.size() > 0) + { + ModuleList matching_modules; + for (int i = 0; i < m_options.m_modules.size(); i++) + { + FileSpec module_spec(m_options.m_modules[i].c_str()); + if (module_spec) + { + matching_modules.Clear(); + target->GetImages().FindModules (&module_spec, NULL, NULL, NULL, matching_modules); + num_matches += matching_modules.ResolveSymbolContextForFilePath (filename, + 0, + check_inlines, + eSymbolContextModule | eSymbolContextCompUnit, + sc_list); + } + } + } + else + { + num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename, + 0, + check_inlines, + eSymbolContextModule | eSymbolContextCompUnit, + sc_list); + } + + if (num_matches == 0) + { + result.AppendErrorWithFormat("Could not find source file \"%s\".\n", + m_options.file_name.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + + if (num_matches > 1) { SymbolContext sc; - if (sc_list.GetContextAtIndex(0, sc)) + bool got_multiple = false; + FileSpec *test_cu_spec = NULL; + + for (int i = 0; i < num_matches; i++) { + sc_list.GetContextAtIndex(i, sc); if (sc.comp_unit) { - interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit, - m_options.start_line, // Line to display - 0, // Lines before line to display - m_options.num_lines, // Lines after line to display - "", // Don't mark "line" - &result.GetOutputStream()); - - result.SetStatus (eReturnStatusSuccessFinishResult); - + if (test_cu_spec) + { + if (test_cu_spec != static_cast (sc.comp_unit)) + got_multiple = true; + break; + } + else + test_cu_spec = sc.comp_unit; } } + if (got_multiple) + { + result.AppendErrorWithFormat("Multiple source files found matching: \"%s.\"\n", + m_options.file_name.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + + SymbolContext sc; + if (sc_list.GetContextAtIndex(0, sc)) + { + if (sc.comp_unit) + { + interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit, + m_options.start_line, + 0, + m_options.num_lines, + "", + &result.GetOutputStream()); + + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n", + m_options.file_name.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } } } - return result.Succeeded(); } @@ -336,9 +558,12 @@ lldb::OptionDefinition CommandObjectSourceList::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, "", "The line number at which to start the display source."}, +{ LLDB_OPT_SET_ALL, false, "count", 'c', required_argument, NULL, 0, "", "The number of source lines to display."}, +{ LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "", + "Look up the source file in the given shared library."}, { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "", "The file from which to display source."}, -{ LLDB_OPT_SET_1, false, "count", 'n', required_argument, NULL, 0, "", "The number of source lines to display."}, +{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, "", "The line number at which to start the display source."}, +{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "", "The name of a function whose source to display."}, { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL } }; From johnny.chen at apple.com Fri Aug 20 12:04:20 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 20 Aug 2010 17:04:20 -0000 Subject: [Lldb-commits] [lldb] r111652 - in /lldb/trunk/test: class_types/TestClassTypes.py command_source/TestCommandSource.py dead-strip/TestDeadStrip.py lldbtest.py Message-ID: <20100820170420.B0F862A6C12C@llvm.org> Author: johnny Date: Fri Aug 20 12:04:20 2010 New Revision: 111652 URL: http://llvm.org/viewvc/llvm-project?rev=111652&view=rev Log: Converted some more test cases to use runCmd()/expect(). Modified: lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/command_source/TestCommandSource.py lldb/trunk/test/dead-strip/TestDeadStrip.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=111652&r1=111651&r2=111652&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Fri Aug 20 12:04:20 2010 @@ -11,41 +11,27 @@ def test_class_types(self): """Test 'variable list this' when stopped on a class constructor.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break on the ctor function of class C. - self.ci.HandleCommand("breakpoint set -f main.cpp -l 73", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.cpp', line = 73, locations = 1"), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + 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) # The stop reason of the thread should be breakpoint. - self.ci.HandleCommand("thread list", res) - #print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) - self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_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.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) # We should be stopped on the ctor function of class C. - self.ci.HandleCommand("variable list this", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) - self.assertTrue(res.GetOutput().startswith('(class C *const) this = '), - VARIABLES_DISPLAYED_CORRECTLY) + self.expect("variable list this", VARIABLES_DISPLAYED_CORRECTLY, + startstr = '(class C *const) this = ') if __name__ == '__main__': Modified: lldb/trunk/test/command_source/TestCommandSource.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/command_source/TestCommandSource.py?rev=111652&r1=111651&r2=111652&view=diff ============================================================================== --- lldb/trunk/test/command_source/TestCommandSource.py (original) +++ lldb/trunk/test/command_source/TestCommandSource.py Fri Aug 20 12:04:20 2010 @@ -15,18 +15,13 @@ def test_command_source(self): """Test that lldb command "command source" works correctly.""" - res = self.res # Sourcing .lldb in the current working directory, which in turn imports # the "my" package that defines the date() function. - self.ci.HandleCommand("command source .lldb", res) - self.assertTrue(res.Succeeded(), CMD_MSG('command source .lldb')) + self.runCmd("command source .lldb") # Python should evaluate "my.date()" successfully. - self.ci.HandleCommand("script my.date()", res) - if (not res.Succeeded()): - print res.GetError() - self.assertTrue(res.Succeeded(), CMD_MSG('script my.date()')) + self.runCmd("script my.date()") if __name__ == '__main__': Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/TestDeadStrip.py?rev=111652&r1=111651&r2=111652&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Fri Aug 20 12:04:20 2010 @@ -13,73 +13,46 @@ def test_dead_strip(self): """Test breakpoint works correctly with dead-code stripping.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break by function name f1 (live code). - self.ci.HandleCommand("breakpoint set -s a.out -n f1", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: name = 'f1', module = a.out, locations = 1" - ), - BREAKPOINT_CREATED) + self.expect("breakpoint set -s a.out -n f1", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: name = 'f1', module = a.out, locations = 1") # Break by function name f2 (dead code). - self.ci.HandleCommand("breakpoint set -s a.out -n f2", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 2: name = 'f2', module = a.out, locations = 0 " - "(pending)"), - BREAKPOINT_PENDING_CREATED) + self.expect("breakpoint set -s a.out -n f2", BREAKPOINT_PENDING_CREATED, + startstr = "Breakpoint created: 2: name = 'f2', module = a.out, locations = 0 (pending)") # Break by function name f3 (live code). - self.ci.HandleCommand("breakpoint set -s a.out -n f3", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 3: name = 'f3', module = a.out, locations = 1" - ), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + 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) # The stop reason of the thread should be breakpoint (breakpoint #1). - self.ci.HandleCommand("thread list", res) - output = res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) - self.assertTrue(output.find('state is Stopped') > 0 and - output.find('main.c:20') > 0 and - output.find('where = a.out`f1') > 0 and - output.find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_BREAKPOINT) + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['state is Stopped', + 'main.c:20', + 'where = a.out`f1', + 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. - self.ci.HandleCommand("breakpoint list 1", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list 1", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded(), CMD_MSG('continue')) + self.runCmd("continue") # The stop reason of the thread should be breakpoint (breakpoint #3). - self.ci.HandleCommand("thread list", res) - output = res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) - self.assertTrue(output.find('state is Stopped') > 0 and - output.find('main.c:40') > 0 and - output.find('where = a.out`f3') > 0 and - output.find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_BREAKPOINT) + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['state is Stopped', + 'main.c:40', + 'where = a.out`f3', + 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. - self.ci.HandleCommand("breakpoint list 3", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list 3", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) if __name__ == '__main__': Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=111652&r1=111651&r2=111652&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Aug 20 12:04:20 2010 @@ -126,6 +126,8 @@ if cmd.startswith("run"): self.runStarted = True if check: + if (not self.res.Succeeded()): + print self.res.GetError() self.assertTrue(self.res.Succeeded(), msg if msg else CMD_MSG(cmd)) From johnny.chen at apple.com Fri Aug 20 12:57:32 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 20 Aug 2010 17:57:32 -0000 Subject: [Lldb-commits] [lldb] r111658 - in /lldb/trunk/test: function_types/TestFunctionTypes.py lldbtest.py Message-ID: <20100820175732.A90FE2A6C12C@llvm.org> Author: johnny Date: Fri Aug 20 12:57:32 2010 New Revision: 111658 URL: http://llvm.org/viewvc/llvm-project?rev=111658&view=rev Log: Added verbose option to runCmd()/expect() in lldbtest.py. Converted TestFunctionTypes.py. Modified: lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=111658&r1=111657&r2=111658&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Fri Aug 20 12:57:32 2010 @@ -11,58 +11,37 @@ def test_function_types(self): """Test 'callback' has function ptr type, then break on the function.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside the main. - self.ci.HandleCommand("breakpoint set -f main.c -l 21", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 21, locations = 1"), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + 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) # The stop reason of the thread should be breakpoint. - self.ci.HandleCommand("thread list", res) - #print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) - self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_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.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) # Check that the 'callback' variable display properly. - self.ci.HandleCommand("variable list callback", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) - output = res.GetOutput() - self.assertTrue(output.startswith('(int (*)(char const *)) callback ='), - VARIABLES_DISPLAYED_CORRECTLY) + self.expect("variable list callback", VARIABLES_DISPLAYED_CORRECTLY, + startstr = '(int (*)(char const *)) callback =') # And that we can break on the callback function. - self.ci.HandleCommand("breakpoint set -n string_not_empty", res); - self.assertTrue(res.Succeeded(), BREAKPOINT_CREATED) - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded(), CMD_MSG('continue')) + self.runCmd("breakpoint set -n string_not_empty", BREAKPOINT_CREATED) + self.runCmd("continue") # Check that we do indeed stop on the string_not_empty function. - self.ci.HandleCommand("process status", res) - self.assertTrue(res.Succeeded(), CMD_MSG('process status')) - output = res.GetOutput() - #print "process status =", output - self.assertTrue(output.find('where = a.out`string_not_empty') > 0 and - output.find('main.c:12') > 0 and - output.find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_BREAKPOINT) + self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['where = a.out`string_not_empty', + 'main.c:12', + 'stop reason = breakpoint']) if __name__ == '__main__': Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=111658&r1=111657&r2=111658&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Aug 20 12:57:32 2010 @@ -114,7 +114,7 @@ # Restore old working directory. os.chdir(self.oldcwd) - def runCmd(self, cmd, msg=None, check=True): + def runCmd(self, cmd, msg=None, check=True, verbose=False): """ Ask the command interpreter to handle the command and then check its return status. @@ -122,16 +122,26 @@ # Fail fast if 'cmd' is not meaningful. if not cmd or len(cmd) == 0: raise Exception("Bad 'cmd' parameter encountered") + + if verbose: + print "runCmd:", cmd + self.ci.HandleCommand(cmd, self.res) + if cmd.startswith("run"): self.runStarted = True + + if not self.res.Succeeded(): + print self.res.GetError() + + if verbose: + print "output:", self.res.GetOutput() + if check: - if (not self.res.Succeeded()): - print self.res.GetError() self.assertTrue(self.res.Succeeded(), msg if msg else CMD_MSG(cmd)) - def expect(self, cmd, msg, startstr=None, substrs=None): + def expect(self, cmd, msg, startstr=None, substrs=None, verbose=False): """ Similar to runCmd; with additional expect style output matching ability. @@ -143,7 +153,7 @@ # Fail fast if 'msg' is not meaningful. if not msg or len(msg) == 0: raise Exception("Bad 'msg' parameter encountered") - self.runCmd(cmd) + self.runCmd(cmd, verbose = (True if verbose else False)) output = self.res.GetOutput() matched = output.startswith(startstr) if startstr else True From johnny.chen at apple.com Fri Aug 20 13:25:15 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 20 Aug 2010 18:25:15 -0000 Subject: [Lldb-commits] [lldb] r111666 - in /lldb/trunk/test: global_variables/TestGlobalVariables.py lldbtest.py Message-ID: <20100820182515.D71672A6C12E@llvm.org> Author: johnny Date: Fri Aug 20 13:25:15 2010 New Revision: 111666 URL: http://llvm.org/viewvc/llvm-project?rev=111666&view=rev Log: Added more verbose output when string match fails. Converted TestGlobalVariables.py. Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/TestGlobalVariables.py?rev=111666&r1=111665&r2=111666&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Fri Aug 20 13:25:15 2010 @@ -11,47 +11,32 @@ def test_global_variables(self): """Test 'variable list -s -a' which omits args and shows scopes.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside the main. - self.ci.HandleCommand("breakpoint set -f main.c -l 20", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 20, locations = 1"), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + 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) # The stop reason of the thread should be breakpoint. - self.ci.HandleCommand("thread list", res) - #print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) - self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_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.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) # Check that GLOBAL scopes are indicated for the variables. - self.ci.HandleCommand("variable list -s -a", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list ...')) - output = res.GetOutput() - self.assertTrue(output.find('GLOBAL: g_file_static_cstr') > 0 and - output.find('g_file_static_cstr') > 0 and - output.find('GLOBAL: g_file_global_int') > 0 and - output.find('(int) 42') > 0 and - output.find('GLOBAL: g_file_global_cstr') > 0 and - output.find('g_file_global_cstr') > 0, - VARIABLES_DISPLAYED_CORRECTLY) + self.expect("variable list -s -a", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['GLOBAL: g_file_static_cstr', + '"g_file_static_cstr"', + 'GLOBAL: g_file_global_int', + '(int) 42', + 'GLOBAL: g_file_global_cstr', + '"g_file_global_cstr"']) if __name__ == '__main__': Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=111666&r1=111665&r2=111666&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Aug 20 13:25:15 2010 @@ -157,10 +157,16 @@ output = self.res.GetOutput() matched = output.startswith(startstr) if startstr else True + + if not matched and startstr and verbose: + print "Startstr not matched:", startstr + if substrs: for str in substrs: matched = output.find(str) > 0 if not matched: + if verbose: + print "Substring not matched:", str break self.assertTrue(matched, msg) From johnny.chen at apple.com Fri Aug 20 14:17:39 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 20 Aug 2010 19:17:39 -0000 Subject: [Lldb-commits] [lldb] r111671 - in /lldb/trunk/test: help/TestHelp.py lldbtest.py Message-ID: <20100820191739.F2AB42A6C12C@llvm.org> Author: johnny Date: Fri Aug 20 14:17:39 2010 New Revision: 111671 URL: http://llvm.org/viewvc/llvm-project?rev=111671&view=rev Log: Changed TestBase.expect() to allow default 'msg' arg. Converted TestHelp.py. Modified: lldb/trunk/test/help/TestHelp.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/help/TestHelp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/help/TestHelp.py?rev=111671&r1=111670&r2=111671&view=diff ============================================================================== --- lldb/trunk/test/help/TestHelp.py (original) +++ lldb/trunk/test/help/TestHelp.py Fri Aug 20 14:17:39 2010 @@ -15,23 +15,14 @@ def test_simplehelp(self): """A simple test of 'help' command and its output.""" - res = lldb.SBCommandReturnObject() - self.ci.HandleCommand("help", res) - self.assertTrue(res.Succeeded() and - res.GetOutput().startswith( - 'The following is a list of built-in, permanent debugger commands'), - CMD_MSG('help')) + self.expect("help", + startstr = 'The following is a list of built-in, permanent debugger commands') def test_help_should_not_hang_emacsshell(self): """Command 'set term-width 0' should not hang the help command.""" - res = lldb.SBCommandReturnObject() - self.ci.HandleCommand("set term-width 0", res) - self.assertTrue(res.Succeeded(), CMD_MSG('set term-width 0')) - self.ci.HandleCommand("help", res) - self.assertTrue(res.Succeeded() and - res.GetOutput().startswith( - 'The following is a list of built-in, permanent debugger commands'), - CMD_MSG('help')) + self.runCmd("set term-width 0") + self.expect("help", + startstr = 'The following is a list of built-in, permanent debugger commands') if __name__ == '__main__': Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=111671&r1=111670&r2=111671&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Aug 20 14:17:39 2010 @@ -141,7 +141,7 @@ self.assertTrue(self.res.Succeeded(), msg if msg else CMD_MSG(cmd)) - def expect(self, cmd, msg, startstr=None, substrs=None, verbose=False): + def expect(self, cmd, msg=None, startstr=None, substrs=None, verbose=False): """ Similar to runCmd; with additional expect style output matching ability. @@ -150,11 +150,11 @@ message. We expect the output from running the command to start with 'startstr' and matches the substrings contained in 'substrs'. """ - # Fail fast if 'msg' is not meaningful. - if not msg or len(msg) == 0: - raise Exception("Bad 'msg' parameter encountered") + + # First run the command. self.runCmd(cmd, verbose = (True if verbose else False)) + # Then compare the output against expected strings. output = self.res.GetOutput() matched = output.startswith(startstr) if startstr else True @@ -169,5 +169,5 @@ print "Substring not matched:", str break - self.assertTrue(matched, msg) + self.assertTrue(matched, msg if msg else CMD_MSG(cmd)) From johnny.chen at apple.com Fri Aug 20 16:03:10 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 20 Aug 2010 21:03:10 -0000 Subject: [Lldb-commits] [lldb] r111677 - in /lldb/trunk/test: lldbtest.py load_unload/TestLoadUnload.py order/TestOrderFile.py persistent_variables/TestPersistentVariables.py set_values/TestSetValues.py stl/TestSTL.py struct_types/TestStructTypes.py Message-ID: <20100820210310.28B972A6C12E@llvm.org> Author: johnny Date: Fri Aug 20 16:03:09 2010 New Revision: 111677 URL: http://llvm.org/viewvc/llvm-project?rev=111677&view=rev Log: Print the verbose output of runCmd()/expect() to stderr instead of stdout. And converted the rest of the test cases to runCmd()/expect(). Modified: lldb/trunk/test/lldbtest.py lldb/trunk/test/load_unload/TestLoadUnload.py lldb/trunk/test/order/TestOrderFile.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 Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=111677&r1=111676&r2=111677&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Fri Aug 20 16:03:09 2010 @@ -28,6 +28,7 @@ """ import os +import sys import unittest2 import lldb @@ -37,7 +38,7 @@ CURRENT_EXECUTABLE_SET = "Current executable set successfully" -RUN_STOPPED = "Process is stopped successfully" +RUN_STOPPED = "Process is launched and then stopped successfully" RUN_COMPLETED = "Process exited successfully" @@ -124,18 +125,18 @@ raise Exception("Bad 'cmd' parameter encountered") if verbose: - print "runCmd:", cmd + print >> sys.stderr, "runCmd:", cmd self.ci.HandleCommand(cmd, self.res) if cmd.startswith("run"): self.runStarted = True - if not self.res.Succeeded(): - print self.res.GetError() - if verbose: - print "output:", self.res.GetOutput() + if self.res.Succeeded(): + print >> sys.stderr, "output:", self.res.GetOutput() + else: + print >> sys.stderr, self.res.GetError() if check: self.assertTrue(self.res.Succeeded(), @@ -159,14 +160,14 @@ matched = output.startswith(startstr) if startstr else True if not matched and startstr and verbose: - print "Startstr not matched:", startstr + print >> sys.stderr, "Startstr not matched:", startstr if substrs: for str in substrs: matched = output.find(str) > 0 if not matched: if verbose: - print "Substring not matched:", str + print >> sys.stderr, "Substring not matched:", str break self.assertTrue(matched, msg if msg else CMD_MSG(cmd)) Modified: lldb/trunk/test/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/TestLoadUnload.py?rev=111677&r1=111676&r2=111677&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Fri Aug 20 16:03:09 2010 @@ -13,57 +13,38 @@ def test_load_unload(self): """Test breakpoint by name works correctly with dlopen'ing.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break by function name a_function (not yet loaded). - self.ci.HandleCommand("breakpoint set -n a_function", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: name = 'a_function', locations = 0 " - "(pending)" - ), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + self.expect("breakpoint set -n a_function", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: name = 'a_function', locations = 0 (pending)") + + self.runCmd("run", RUN_STOPPED) # The stop reason of the thread should be breakpoint and at a_function. - self.ci.HandleCommand("thread list", res) - output = res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) - self.assertTrue(output.find('state is Stopped') > 0 and - output.find('a_function') > 0 and - output.find('a.c:14') > 0 and - output.find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_BREAKPOINT) + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['state is Stopped', + 'a_function', + 'a.c:14', + 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. - self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) -# # We should stop agaian at a_function. +# # Issue the 'contnue' command. We should stop agaian at a_function. # # The stop reason of the thread should be breakpoint and at a_function. -# self.ci.HandleCommand("thread list", res) -# output = res.GetOutput() -# self.assertTrue(res.Succeeded()) -# self.assertTrue(output.find('state is Stopped') > 0 and -# output.find('a_function') > 0 and -# output.find('a.c:14') > 0 and -# output.find('stop reason = breakpoint') > 0) - +# self.runCmd("continue") +# self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, +# substrs = ['state is Stopped', +# 'a_function', +# 'a.c:14', +# 'stop reason = breakpoint']) +# # # The breakpoint should have a hit count of 2. -# self.ci.HandleCommand("breakpoint list", res) -# self.assertTrue(res.Succeeded()) -# self.assertTrue(res.GetOutput().find(' resolved, hit count = 2') > 0) - -# self.ci.HandleCommand("continue", res) -# self.assertTrue(res.Succeeded()) +# self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, +# substrs = [' resolved, hit count = 2']) if __name__ == '__main__': Modified: lldb/trunk/test/order/TestOrderFile.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/order/TestOrderFile.py?rev=111677&r1=111676&r2=111677&view=diff ============================================================================== --- lldb/trunk/test/order/TestOrderFile.py (original) +++ lldb/trunk/test/order/TestOrderFile.py Fri Aug 20 16:03:09 2010 @@ -14,15 +14,12 @@ def test_order_file(self): """Test debug symbols follow the correct order by the order file.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Test that the debug symbols have Function f3 before Function f1. - self.ci.HandleCommand("image dump symtab a.out", res) - self.assertTrue(res.Succeeded(), CMD_MSG('image dump')) - output = res.GetOutput() + self.runCmd("image dump symtab a.out") + output = self.res.GetOutput() mo_f3 = re.search("Function +.+f3", output) mo_f1 = re.search("Function +.+f1", output) @@ -30,9 +27,7 @@ self.assertTrue(mo_f3 and mo_f1 and mo_f3.start() < mo_f1.start(), "Symbols have correct order by the order file") - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_COMPLETED) + self.runCmd("run", RUN_COMPLETED) if __name__ == '__main__': Modified: lldb/trunk/test/persistent_variables/TestPersistentVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/persistent_variables/TestPersistentVariables.py?rev=111677&r1=111676&r2=111677&view=diff ============================================================================== --- lldb/trunk/test/persistent_variables/TestPersistentVariables.py (original) +++ lldb/trunk/test/persistent_variables/TestPersistentVariables.py Fri Aug 20 16:03:09 2010 @@ -13,38 +13,23 @@ def test_persistent_variables(self): """Test that lldb persistent variables works correctly.""" - res = self.res + self.runCmd("file ../array_types/a.out", CURRENT_EXECUTABLE_SET) - self.ci.HandleCommand("file ../array_types/a.out", res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("breakpoint set --name main") - self.ci.HandleCommand("breakpoint set --name main", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) + self.runCmd("run", RUN_STOPPED) - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) - - self.ci.HandleCommand("expr int $i = 5; $i + 1", res) - self.assertTrue(res.Succeeded(), CMD_MSG('expr int $i = 5; $i + 1')) - #print res.GetOutput() + self.runCmd("expr int $i = 5; $i + 1") # $0 = (int)6 - self.ci.HandleCommand("expr $i + 3", res) - self.assertTrue(res.Succeeded(), CMD_MSG('expr $i + 3')) - #print res.GetOutput() + self.runCmd("expr $i + 3") # $1 = (int)8 - self.ci.HandleCommand("expr $1 + $0", res) - self.assertTrue(res.Succeeded(), CMD_MSG('expr $1 + $0')) - #print res.GetOutput() + self.runCmd("expr $1 + $0") # $2 = (int)14 - self.ci.HandleCommand("expr $2", res) - self.assertTrue(res.Succeeded() and - res.GetOutput().startswith("$3 = (int) 14"), - CMD_MSG('expr $2')) - #print res.GetOutput() + self.expect("expr $2", + startstr = "$3 = (int) 14") # $3 = (int)14 Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=111677&r1=111676&r2=111677&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Fri Aug 20 16:03:09 2010 @@ -11,111 +11,81 @@ def test_set_values(self): """Test settings and readings of program variables.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Set breakpoints on several places to set program variables. - self.ci.HandleCommand("breakpoint set -f main.c -l 15", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 15, locations = 1"), - BREAKPOINT_CREATED) - self.ci.HandleCommand("breakpoint set -f main.c -l 36", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 2: file ='main.c', line = 36, locations = 1"), - BREAKPOINT_CREATED) - self.ci.HandleCommand("breakpoint set -f main.c -l 57", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 3: file ='main.c', line = 57, locations = 1"), - BREAKPOINT_CREATED) - self.ci.HandleCommand("breakpoint set -f main.c -l 78", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 4: file ='main.c', line = 78, locations = 1"), - BREAKPOINT_CREATED) - self.ci.HandleCommand("breakpoint set -f main.c -l 85", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 5: file ='main.c', line = 85, locations = 1"), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + self.expect("breakpoint set -f main.c -l 15", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.c', line = 15, locations = 1") + + self.expect("breakpoint set -f main.c -l 36", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 2: file ='main.c', line = 36, locations = 1") + + self.expect("breakpoint set -f main.c -l 57", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 3: file ='main.c', line = 57, locations = 1") + + self.expect("breakpoint set -f main.c -l 78", BREAKPOINT_CREATED, + startstr = "Breakpoint created: 4: file ='main.c', line = 78, locations = 1") + + 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) # The stop reason of the thread should be breakpoint. - self.ci.HandleCommand("thread list", res) - #print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) - self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_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.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) # main.c:15 # Check that 'variable list' displays the correct data type and value. - self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) - self.assertTrue(res.GetOutput().startswith("i = (char) 'a'"), - VARIABLES_DISPLAYED_CORRECTLY) + self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "i = (char) 'a'") + # TODO: # Now set variable 'i' and check that it is correctly displayed. - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded(), CMD_MSG('continue')) + self.runCmd("continue") # main.c:36 # Check that 'variable list' displays the correct data type and value. - self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) - self.assertTrue(res.GetOutput().startswith( - "i = (short unsigned int) 0x0021"), - VARIABLES_DISPLAYED_CORRECTLY) + self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "i = (short unsigned int) 0x0021") + # TODO: # Now set variable 'i' and check that it is correctly displayed. - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded(), CMD_MSG('continue')) + self.runCmd("continue") # main.c:57 # Check that 'variable list' displays the correct data type and value. - self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) - self.assertTrue(res.GetOutput().startswith("i = (long int) 33"), - VARIABLES_DISPLAYED_CORRECTLY) + self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "i = (long int) 33") + # TODO: # Now set variable 'i' and check that it is correctly displayed. - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded(), CMD_MSG('continue')) + self.runCmd("continue") # main.c:78 # Check that 'variable list' displays the correct data type and value. - self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) - self.assertTrue(res.GetOutput().startswith("i = (double) 3.14159"), - VARIABLES_DISPLAYED_CORRECTLY) + self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "i = (double) 3.14159") + # TODO: # Now set variable 'i' and check that it is correctly displayed. - self.ci.HandleCommand("continue", res) - self.assertTrue(res.Succeeded(), CMD_MSG('continue')) + self.runCmd("continue") # main.c:85 # Check that 'variable list' displays the correct data type and value. - self.ci.HandleCommand("variable list", res); - self.assertTrue(res.Succeeded(), CMD_MSG('variable list')) - self.assertTrue(res.GetOutput().startswith("i = (long double) "), - VARIABLES_DISPLAYED_CORRECTLY) + self.expect("variable list", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "i = (long double) ") + # TODO: # Now set variable 'i' and check that it is correctly displayed. Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=111677&r1=111676&r2=111677&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Fri Aug 20 16:03:09 2010 @@ -14,58 +14,40 @@ @unittest2.expectedFailure def test_step_into_stl(self): """Test that we can successfully step into an STL function.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") + # The following two lines, if uncommented, will enable loggings. #self.ci.HandleCommand("log enable -f /tmp/lldb.log lldb default", res) #self.assertTrue(res.Succeeded()) - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break on line 13 of main.cpp. - self.ci.HandleCommand("breakpoint set -f main.cpp -l 13", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.cpp', line = 13, locations = 1" - ), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + 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) # Stop at 'std::string hello_world ("Hello World!");'. - self.ci.HandleCommand("thread list", res) - #print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) - output = res.GetOutput() - self.assertTrue(output.find('main.cpp:13') > 0 and - output.find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_BREAKPOINT) + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['main.cpp:13', + 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. - self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint list')) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) # Now do 'thread step-in', we should stop on the basic_string template. - self.ci.HandleCommand("thread step-in", res) - #print "thread step-in:", res.GetOutput() - # # This assertion currently always fails. # This might be related: rdar://problem/8247112. # - self.assertTrue(res.Succeeded(), CMD_MSG("thread step-in")) + #self.runCmd("thread step-in", verbose=True) + self.runCmd("thread step-in") - self.ci.HandleCommand("thread backtrace", res) - print "thread backtrace:", res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread backtarce')) - output = res.GetOutput() - self.assertTrue(output.find('[inlined]') > 0 and - output.find('basic_string.h'), - "Command 'thread backtrace' shows we stepped in STL") + self.expect("thread backtrace", "We have stepped in STL", + substrs = ['[inlined]', + 'basic_string.h']) if __name__ == '__main__': Modified: lldb/trunk/test/struct_types/TestStructTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/struct_types/TestStructTypes.py?rev=111677&r1=111676&r2=111677&view=diff ============================================================================== --- lldb/trunk/test/struct_types/TestStructTypes.py (original) +++ lldb/trunk/test/struct_types/TestStructTypes.py Fri Aug 20 16:03:09 2010 @@ -15,37 +15,24 @@ def test_struct_types(self): """Test that break on a struct declaration has no effect.""" - res = self.res exe = os.path.join(os.getcwd(), "a.out") - self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break on the ctor function of class C. - self.ci.HandleCommand("breakpoint set -f main.c -l 14", res) - self.assertTrue(res.Succeeded(), CMD_MSG('breakpoint set')) - self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 14, locations = 1"), - BREAKPOINT_CREATED) - - self.ci.HandleCommand("run", res) - self.runStarted = True - self.assertTrue(res.Succeeded(), RUN_STOPPED) + 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) # We should be stopped on the first executable statement within the # function where the original breakpoint was attempted. - self.ci.HandleCommand("thread backtrace", res) - #print "thread backtrace ->", res.GetOutput() - self.assertTrue(res.Succeeded(), CMD_MSG('thread backtarce')) - output = res.GetOutput() - self.assertTrue(output.find('main.c:20') > 0 and - output.find('stop reason = breakpoint') > 0, - STOPPED_DUE_TO_BREAKPOINT) + self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['main.c:20', + 'stop reason = breakpoint']) # The breakpoint should have a hit count of 1. - self.ci.HandleCommand("breakpoint list", res) - self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, - BREAKPOINT_HIT_ONCE) + self.expect("breakpoint list", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) if __name__ == '__main__': From gclayton at apple.com Fri Aug 20 21:22:51 2010 From: gclayton at apple.com (Greg Clayton) Date: Sat, 21 Aug 2010 02:22:51 -0000 Subject: [Lldb-commits] [lldb] r111706 - in /lldb/trunk: include/lldb/ include/lldb/Host/ include/lldb/Symbol/ lldb.xcodeproj/ source/Expression/ source/Host/macosx/ source/Plugins/Process/MacOSX-User/source/ source/Plugins/Process/gdb-remote/ source/Plugins/SymbolFile/DWARF/ source/Symbol/ source/Target/ Message-ID: <20100821022252.1C7532A6C12C@llvm.org> Author: gclayton Date: Fri Aug 20 21:22:51 2010 New Revision: 111706 URL: http://llvm.org/viewvc/llvm-project?rev=111706&view=rev Log: Modified the host process monitor callback function Host::StartMonitoringChildProcess to spawn a thread for each process that is being monitored. Previously LLDB would spawn a single thread that would wait for any child process which isn't ok to do as a shared library (LLDB.framework on Mac OSX, or lldb.so on linux). The old single thread used to call wait4() with a pid of -1 which could cause it to reap child processes that it shouldn't have. Re-wrote the way Function blocks are handles. Previously I attempted to keep all blocks in a single memory allocation (in a std::vector). This made the code somewhat efficient, but hard to work with. I got rid of the old BlockList class, and went to a straight parent with children relationship. This new approach will allow for partial parsing of the blocks within a function. Modified: lldb/trunk/include/lldb/Host/Host.h lldb/trunk/include/lldb/Symbol/Block.h lldb/trunk/include/lldb/Symbol/Function.h lldb/trunk/include/lldb/lldb-forward.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Host/macosx/Host.mm lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h lldb/trunk/source/Symbol/Block.cpp lldb/trunk/source/Symbol/Function.cpp lldb/trunk/source/Symbol/SymbolContext.cpp lldb/trunk/source/Symbol/Variable.cpp lldb/trunk/source/Target/StackFrame.cpp Modified: lldb/trunk/include/lldb/Host/Host.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/include/lldb/Host/Host.h (original) +++ lldb/trunk/include/lldb/Host/Host.h Fri Aug 20 21:22:51 2010 @@ -66,34 +66,18 @@ /// get called if the child process exits. /// /// @return - /// A unique handle to the process monitoring information that - /// can be used to stop monitoring a child process. + /// A thread handle that can be used to cancel the thread that + /// was spawned to monitor \a pid. /// /// @see static void Host::StopMonitoringChildProcess (uint32_t) //------------------------------------------------------------------ - static uint32_t + static lldb::thread_t StartMonitoringChildProcess (MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals); //------------------------------------------------------------------ - /// Stop monitoring a child process. - /// - /// @param[in] handle - /// A unique handle returned from a previous call to - /// Host::StartMonitoringChildProcess(...). - /// - /// @return - /// \b true if the the handle was found and disabled, \b false - /// if the monitor map with handle of \a handle was not found. - /// - /// @see static int Host::StartMonitoringChildProcess (MonitorChildProcessCallback *, void *, lldb::pid_t, bool) - //------------------------------------------------------------------ - static bool - StopMonitoringChildProcess (uint32_t handle); - - //------------------------------------------------------------------ /// Get the host page size. /// /// @return Modified: lldb/trunk/include/lldb/Symbol/Block.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Block.h?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Block.h (original) +++ lldb/trunk/include/lldb/Symbol/Block.h Fri Aug 20 21:22:51 2010 @@ -43,17 +43,6 @@ public SymbolContextScope { public: - friend class Function; - friend class BlockList; - //------------------------------------------------------------------ - /// Enumeration values for special and invalid Block User ID - /// values. - //------------------------------------------------------------------ - enum - { - RootID = LLDB_INVALID_UID - 1, ///< The Block UID for the root block - InvalidID = LLDB_INVALID_UID ///< Invalid Block UID. - }; //------------------------------------------------------------------ /// Construct with a User ID \a uid, \a depth. @@ -79,17 +68,7 @@ /// /// @see BlockList //------------------------------------------------------------------ - Block (lldb::user_id_t uid, uint32_t depth, BlockList* block_list); - - //------------------------------------------------------------------ - /// Copy constructor. - /// - /// Makes a copy of the another Block object \a rhs. - /// - /// @param[in] rhs - /// A const Block object reference to copy. - //------------------------------------------------------------------ - Block (const Block& rhs); + Block (lldb::user_id_t uid); //------------------------------------------------------------------ /// Destructor. @@ -97,37 +76,14 @@ ~Block (); //------------------------------------------------------------------ - /// Assignment operator. - /// - /// Copies the block value from another Block object \a rhs - /// into \a this object. - /// - /// @param[in] rhs - /// A const Block object reference to copy. - /// - /// @return - /// A const Block object reference to \a this. - //------------------------------------------------------------------ - const Block& - operator= (const Block& rhs); - - //------------------------------------------------------------------ /// Add a child to this object. /// - /// @param[in] uid - /// The UID for a given block. This value is given by the - /// SymbolFile plug-in and can be any value that helps the - /// SymbolFile plug-in to match this block back to the debug - /// information data that it parses for further or more in - /// depth parsing. Common values would be the index into a - /// table, or an offset into the debug information. - /// - /// @return - /// Returns \a uid if the child was successfully added to this - /// block, or Block::InvalidID on failure. + /// @param[in] child_block_sp + /// A shared pointer to a child block that will get added to + /// this block. //------------------------------------------------------------------ - lldb::user_id_t - AddChild (lldb::user_id_t uid); + void + AddChild (const lldb::BlockSP &child_block_sp); //------------------------------------------------------------------ /// Add a new offset range to this block. @@ -177,9 +133,6 @@ bool Contains (const VMRange& range) const; - bool - ContainsBlockWithID (lldb::user_id_t block_id) const; - //------------------------------------------------------------------ /// Dump the block contents. /// @@ -215,41 +168,11 @@ void GetDescription (Stream *s, + Function *function, lldb::DescriptionLevel level, Process *process) const; //------------------------------------------------------------------ - /// Get the parent block's UID. - /// - /// @return - /// The UID of the parent block, or Block::InvalidID - /// if this block has no parent. - //------------------------------------------------------------------ - lldb::user_id_t - GetParentUID () const; - - //------------------------------------------------------------------ - /// Get the sibling block's UID. - /// - /// @return - /// The UID of the sibling block, or Block::InvalidID - /// if this block has no sibling. - //------------------------------------------------------------------ - lldb::user_id_t - GetSiblingUID () const; - - //------------------------------------------------------------------ - /// Get the first child block's UID. - /// - /// @return - /// The UID of the first child block, or Block::InvalidID - /// if this block has no first child. - //------------------------------------------------------------------ - lldb::user_id_t - GetFirstChildUID () const; - - - //------------------------------------------------------------------ /// Get the parent block. /// /// @return @@ -260,14 +183,17 @@ GetParent () const; //------------------------------------------------------------------ - /// Get the sibling block. + /// Get the sibling block for this block. /// /// @return /// The sibling block pointer, or NULL if this block has no /// sibling. //------------------------------------------------------------------ Block * - GetSibling () const; + GetSibling () const + { + return m_sibling; + } //------------------------------------------------------------------ /// Get the first child block. @@ -387,6 +313,19 @@ const Declaration *decl_ptr, const Declaration *call_decl_ptr); + + void + SetParentScope (SymbolContextScope *parent_scope) + { + m_parent_scope = parent_scope; + } + + void + SetSibling (Block *block) + { + m_sibling = block; + } + //------------------------------------------------------------------ /// Set accessor for the variable list. /// @@ -400,358 +339,39 @@ void SetVariableList (lldb::VariableListSP& variable_list_sp); -protected: - //------------------------------------------------------------------ - /// Get accessor for the integer block depth value. - /// - /// @return - /// The integer depth of this block in the block hiearchy. - //------------------------------------------------------------------ - uint32_t Depth () const; - - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - BlockList *m_block_list; ///< The block list, one of which is this one - uint32_t m_depth; ///< The depth of this block where zero is the root block - 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. - // TOOD: add a Type* list -}; - -//---------------------------------------------------------------------- -/// @class BlockList Block.h "lldb/Symbol/Block.h" -/// @brief A class that contains a heirachical collection of lexical -/// block objects where one block is the root. -/// -/// A collection of Block objects is managed by this class. All access -/// to the block data is made through the block_uid of each block. This -/// facilitates partial parsing and can enable block specific data to -/// only be parsed when the data is asked for (variables, params, types, -/// etc). -//---------------------------------------------------------------------- - -class BlockList -{ -public: - friend class Block; - typedef std::vector collection;///< Our block collection type. - - //------------------------------------------------------------------ - /// Construct with \a function and section offset based address - /// range. - /// - /// @param[in] function - /// A const Function object that owns this block list. - /// - /// @param[in] range - /// A section offset based address range object. - //------------------------------------------------------------------ - BlockList (Function *function, const AddressRange& range); - - //------------------------------------------------------------------ - /// Destructor. - //------------------------------------------------------------------ - ~BlockList (); - - //------------------------------------------------------------------ - /// Add a child block to a parent block. - /// - /// Adds a new child to a parent block. The UID values for - /// blocks are created by the SymbolFile plug-ins and should have - /// values that facilitate correlating an existing Block object - /// with information in the debug information file. Typically - /// a table index, or a debug information offset is used. - /// - /// @param[in] parent_uid - /// The UID for a the existing parent block that will have - /// a new child, whose UID is \a child_uid, added to its - /// child list. - /// - /// @param[in] child_uid - /// The UID for the new child block. - /// - /// @return - /// Returns \a child_uid if the child was successfully added - /// to the parent \a parent_uid, or Block::InvalidID on - /// failure (if the parent doesn't exist). - //------------------------------------------------------------------ - lldb::user_id_t - AddChild (lldb::user_id_t parent_uid, lldb::user_id_t child_uid); - //------------------------------------------------------------------ - /// Add a child block to a parent block. - /// - /// Adds a new child to a parent block. The UID values for - /// blocks are created by the SymbolFile plug-ins and should have - /// values that facilitate correlating an existing Block object - /// with information in the debug information file. Typically - /// a table index, or a debug information offset is used. - /// - /// @param[in] block_uid - /// The UID for a the existing block that will get the - /// new range. - /// - /// @param[in] start_offset - /// An offset into this object's address range that - /// describes the start address of a range for \a block_uid. - /// - /// @param[in] end_offset - /// An offset into this object's address range that - /// describes the end address of a range for for \a block_uid. - /// - /// @return - /// Returns \b true if the range was successfully added to - /// the block whose UID is \a block_uid, \b false otherwise. - //------------------------------------------------------------------ bool - AddRange (lldb::user_id_t block_uid, lldb::addr_t start_offset, lldb::addr_t end_offset); - -// const Block * -// FindDeepestBlockForAddress (const Address &addr); - - //------------------------------------------------------------------ - /// Get accessor for the section offset based address range. - /// - /// All Block objects contained in a BlockList are relative to - /// the base address in this object. - /// - /// @return - /// Returns a reference to the section offset based address - /// range object. - //------------------------------------------------------------------ - AddressRange & - GetAddressRange (); - - //------------------------------------------------------------------ - /// Get const accessor for the section offset based address range. - /// - /// All Block objects contained in a BlockList are relative to - /// the base address in this object. - /// - /// @return - /// Returns a const reference to the section offset based - /// address range object. - //------------------------------------------------------------------ - const AddressRange & - GetAddressRange () const; - - //------------------------------------------------------------------ - /// Dump the block list contents. - /// - /// @param[in] s - /// The stream to which to dump the object descripton. - /// - /// @param[in] block_uid - /// The UID of the block in the block list to dump. If this - /// value is Block::RootID, then the entire block list will - /// dumped as long as \a depth is set to a large enough value. - /// - /// @param[in] depth - /// Limit the number of levels deep that this function should - /// print as the block whose UID is \a block_uid can contain - /// child blocks. Specify INT_MAX to dump all child blocks. - /// - /// @param[in] show_context - /// If \b true, variables will dump their context information. - //------------------------------------------------------------------ + BlockInfoHasBeenParsed() const + { + return m_parsed_block_info; + } + void - Dump (Stream *s, lldb::user_id_t block_uid, uint32_t depth, bool show_context) const; + SetBlockInfoHasBeenParsed (bool b, bool set_children); - //------------------------------------------------------------------ - /// Get a block object pointer by block UID. - /// - /// @param[in] block_uid - /// The UID of the block to retrieve. - /// - /// @return - /// A pointer to the block object, or NULL if \a block_uid - /// doesn't exist in the block list. - //------------------------------------------------------------------ Block * - GetBlockByID (lldb::user_id_t block_uid); - - //------------------------------------------------------------------ - /// Get a const block object pointer by block UID. - /// - /// @param[in] block_uid - /// The UID of the block to retrieve. - /// - /// @return - /// A const pointer to the block object, or NULL if \a block_uid - /// doesn't exist in the block list. - //------------------------------------------------------------------ - const Block * - GetBlockByID (lldb::user_id_t block_uid) const; - - //------------------------------------------------------------------ - /// Get a function object pointer for the block list. - /// - /// @return - /// A pointer to the function object. - //------------------------------------------------------------------ - Function * - GetFunction (); - - //------------------------------------------------------------------ - /// Get a const function object pointer for the block list. - /// - /// @return - /// A const pointer to the function object. - //------------------------------------------------------------------ - const Function * - GetFunction () const; - - //------------------------------------------------------------------ - /// Get the first child block UID for the block whose UID is \a - /// block_uid. - /// - /// @param[in] block_uid - /// The UID of the block we wish to access information for. - /// - /// @return - /// The UID of the first child block, or Block::InvalidID - /// if this block has no children, or if \a block_uid is not - /// a valid block ID for this block list. - //------------------------------------------------------------------ - lldb::user_id_t - GetFirstChild (lldb::user_id_t block_uid) const; - - //------------------------------------------------------------------ - /// Get the parent block UID for the block whose UID is \a - /// block_uid. - /// - /// @param[in] block_uid - /// The UID of the block we wish to access information for. - /// - /// @return - /// The UID of the parent block, or Block::InvalidID - /// if this block has no parent, or if \a block_uid is not - /// a valid block ID for this block list. - //------------------------------------------------------------------ - lldb::user_id_t - GetParent (lldb::user_id_t block_uid) const; - - //------------------------------------------------------------------ - /// Get the sibling block UID for the block whose UID is \a - /// block_uid. - /// - /// @param[in] block_uid - /// The UID of the block we wish to access information for. - /// - /// @return - /// The UID of the sibling block, or Block::InvalidID - /// if this block has no sibling, or if \a block_uid is not - /// a valid block ID for this block list. - //------------------------------------------------------------------ - lldb::user_id_t - GetSibling (lldb::user_id_t block_uid) const; - - //------------------------------------------------------------------ - /// Get the variable list for the block whose UID is \a block_uid. - /// - /// @param[in] block_uid - /// The UID of the block we wish to access information for. - /// - /// @param[in] can_create - /// If \b true, the variable list can be parsed on demand. If - /// \b false, the variable list contained in this object will - /// be returned. - /// - /// @return - /// The variable list shared pointer which may contain a NULL - /// variable list object. - //------------------------------------------------------------------ - lldb::VariableListSP - GetVariableList (lldb::user_id_t block_uid, bool get_child_variables, bool can_create); - - //------------------------------------------------------------------ - /// Check if the block list is empty. - /// - /// @return - /// Returns \b true if the block list is empty, \b false - /// otherwise. - //------------------------------------------------------------------ - bool - IsEmpty () const; - - //------------------------------------------------------------------ - /// Get the memory cost of this object. - /// - /// Returns the cost of this object plus any owned objects (address - /// range, and contains Block objects). - /// - /// @return - /// The number of bytes that this object occupies in memory. - //------------------------------------------------------------------ - size_t - MemorySize () const; - - //------------------------------------------------------------------ - /// Set the variable list for the block whose UID is \a block_uid. - /// - /// @param[in] block_uid - /// The UID of the block we wish to set information for. - /// - /// @param[in] variable_list_sp - /// A shared pointer to list of variables. - /// - /// @return - /// Returns \b true if the variable list was successfully added - /// to the block, \b false otherwise. - //------------------------------------------------------------------ - bool - SetVariableList (lldb::user_id_t block_uid, lldb::VariableListSP& variable_list_sp); - - //------------------------------------------------------------------ - /// Set the inlined function info for the block whose UID is \a - /// block_uid. - /// - /// @param[in] block_uid - /// The UID of the block we wish to set information for. - /// - /// @param[in] name - /// The method name for the inlined function. This value should - /// not be NULL. - /// - /// @param[in] mangled - /// The mangled method name for the inlined function. This can - /// be NULL if there is no mangled name for an inlined function - /// or if the name is the same as \a name. - /// - /// @param[in] decl_ptr - /// A optional pointer to declaration information for the - /// inlined function information. This value can be NULL to - /// indicate that no declaration information is available. - /// - /// @param[in] call_decl_ptr - /// Optional calling location declaration information that - /// describes from where this inlined function was called. - /// - /// @return - /// Returns \b true if the inline function info was successfully - /// associated with the block, \b false otherwise. - //------------------------------------------------------------------ - bool - SetInlinedFunctionInfo (lldb::user_id_t block_uid, const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr); + FindBlockByID (lldb::user_id_t block_id); protected: + typedef std::vector collection; //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ - Function *m_function; ///< A pointer to the function that owns this block list. - AddressRange m_range; ///< The section offset based address range. - collection m_blocks; ///< A contiguous array of block objects. - - bool - BlockContainsBlockWithID (const lldb::user_id_t block_id, const lldb::user_id_t find_block_id) const; + SymbolContextScope *m_parent_scope; + Block *m_sibling; + 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. + 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; private: - - DISALLOW_COPY_AND_ASSIGN (BlockList); + DISALLOW_COPY_AND_ASSIGN (Block); }; + } // namespace lldb_private #endif // liblldb_Block_h_ Modified: lldb/trunk/include/lldb/Symbol/Function.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Function.h?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Function.h (original) +++ lldb/trunk/include/lldb/Symbol/Function.h Fri Aug 20 21:22:51 2010 @@ -419,8 +419,11 @@ CalculateSymbolContext(SymbolContext* sc); const AddressRange & - GetAddressRange(); - + GetAddressRange() + { + return m_range; + } + //------------------------------------------------------------------ /// Find the file and line number of the source location of the start /// of the function. This will use the declaration if present and fall @@ -450,15 +453,6 @@ void GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no); - //------------------------------------------------------------------ - /// Return whether this Function represents an inlined version of the - /// original function. - /// - /// @return - /// \b true if inlined, \b false otherwise. - //------------------------------------------------------------------ - bool IsInlined(); - //------------------------------------------------------------------ /// Get accessor for the block list. /// @@ -468,8 +462,8 @@ /// /// @see BlockList //------------------------------------------------------------------ - BlockList& - GetBlocks (bool can_create); + Block& + GetBlock (bool can_create); //------------------------------------------------------------------ /// Get accessor for the compile unit that owns this function. @@ -611,14 +605,15 @@ //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ - CompileUnit *m_comp_unit; ///< The compile unit that owns this function. + CompileUnit *m_comp_unit; ///< The compile unit that owns this function. lldb::user_id_t m_type_uid; ///< The user ID of for the prototype Type for this function. - Type * m_type; ///< The function prototype type for this function that include the function info (FunctionInfo), return type and parameters. - Mangled m_mangled; ///< The mangled function name if any, if empty, there is no mangled information. - BlockList m_blocks; ///< All lexical blocks contained in this function. + Type * m_type; ///< The function prototype type for this function that include the function info (FunctionInfo), return type and parameters. + Mangled m_mangled; ///< The mangled function name if any, if empty, there is no mangled information. + Block m_block; ///< All lexical blocks contained in this function. + AddressRange m_range; ///< The function address range that covers the widest range needed to contain all blocks DWARFExpression m_frame_base; ///< The frame base expression for variables that are relative to the frame pointer. Flags m_flags; - uint32_t m_prologue_byte_size; ///< Compute the prologue size once and cache it + uint32_t m_prologue_byte_size; ///< Compute the prologue size once and cache it private: DISALLOW_COPY_AND_ASSIGN(Function); }; Modified: lldb/trunk/include/lldb/lldb-forward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward.h (original) +++ lldb/trunk/include/lldb/lldb-forward.h Fri Aug 20 21:22:51 2010 @@ -25,7 +25,6 @@ class Args; class Baton; class Block; -class BlockList; class Breakpoint; class BreakpointID; class BreakpointIDList; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Aug 20 21:22:51 2010 @@ -2791,6 +2791,7 @@ ); LLVM_BUILD_DIR = "$(SRCROOT)/llvm"; LLVM_CONFIGURATION = Release; + ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "-DFOR_DYLD=0", "-DSUPPORT_REMOTE_UNWINDING", Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri Aug 20 21:22:51 2010 @@ -626,28 +626,21 @@ { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - Function *function(m_sym_ctx->function); - Block *block(m_sym_ctx->block); - - if (!function || !block) + if (m_sym_ctx->function == NULL || m_sym_ctx->block == NULL) { if (log) - log->Printf("function = %p, block = %p", function, block); + log->Printf("function = %p, block = %p", m_sym_ctx->function, m_sym_ctx->block); return NULL; } - BlockList& blocks(function->GetBlocks(true)); - ConstString name_cs(name); - lldb::user_id_t current_block_id; + Block *current_block; - for (current_block_id = block->GetID(); - current_block_id != Block::InvalidID; - current_block_id = blocks.GetParent(current_block_id)) - { - Block *current_block(blocks.GetBlockByID(current_block_id)); - + for (current_block = m_sym_ctx->block; + current_block != NULL; + current_block = current_block->GetParent()) + { lldb::VariableListSP var_list = current_block->GetVariableList(false, true); if (!var_list) Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Fri Aug 20 21:22:51 2010 @@ -508,102 +508,48 @@ struct MonitorInfo { - uint32_t handle; - pthread_t thread; - Host::MonitorChildProcessCallback callback; - void *callback_baton; - bool monitor_signals; + lldb::pid_t pid; // The process ID to monitor + Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals + void *callback_baton; // The callback baton for the callback function + bool monitor_signals; // If true, call the callback when "pid" gets signaled. }; -typedef std::multimap MonitorInfoMap; -static pthread_mutex_t g_monitor_map_mutex = PTHREAD_MUTEX_INITIALIZER; -typedef lldb::SharedPtr::Type MonitorInfoMapSP; - -static MonitorInfoMapSP& -GetMonitorMap (bool can_create) -{ - static MonitorInfoMapSP g_monitor_map_sp; - if (can_create && g_monitor_map_sp.get() == NULL) - { - g_monitor_map_sp.reset (new MonitorInfoMap); - } - return g_monitor_map_sp; -} - -static Predicate& -GetChildProcessPredicate () -{ - static Predicate g_has_child_processes; - return g_has_child_processes; -} - static void * MonitorChildProcessThreadFunction (void *arg); -static pthread_t g_monitor_thread; - -uint32_t +lldb::thread_t Host::StartMonitoringChildProcess ( - MonitorChildProcessCallback callback, + Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals ) { - static uint32_t g_handle = 0; + + lldb::thread_t thread = LLDB_INVALID_HOST_THREAD; if (callback) { - Mutex::Locker locker(&g_monitor_map_mutex); - if (!g_monitor_thread) - { - lldb::pid_t wait_pid = -1; - g_monitor_thread = ThreadCreate ("", - MonitorChildProcessThreadFunction, - &wait_pid, - NULL); - if (g_monitor_thread) - { - //Host::ThreadDetach (g_monitor_thread, NULL); - } - } - - if (g_monitor_thread) - { - MonitorInfo info = { ++g_handle, 0, callback, callback_baton, monitor_signals }; - MonitorInfoMapSP monitor_map_sp (GetMonitorMap (true)); - if (monitor_map_sp) - { - monitor_map_sp->insert(std::make_pair(pid, info)); - GetChildProcessPredicate ().SetValue (true, eBroadcastOnChange); - return info.handle; - } - } - } - return 0; -} - -bool -Host::StopMonitoringChildProcess (uint32_t handle) -{ - Mutex::Locker locker(&g_monitor_map_mutex); - MonitorInfoMapSP monitor_map_sp (GetMonitorMap (false)); - if (monitor_map_sp) - { - MonitorInfoMap::iterator pos, end = monitor_map_sp->end(); - for (pos = monitor_map_sp->end(); pos != end; ++pos) - { - if (pos->second.handle == handle) - { - monitor_map_sp->erase(pos); - return true; - } - } + std::auto_ptr info_ap(new MonitorInfo); + + info_ap->pid = pid; + info_ap->callback = callback; + info_ap->callback_baton = callback_baton; + info_ap->monitor_signals = monitor_signals; + + char thread_name[256]; + ::snprintf (thread_name, sizeof(thread_name), "", pid); + thread = ThreadCreate (thread_name, + MonitorChildProcessThreadFunction, + info_ap.get(), + NULL); + + if (thread != LLDB_INVALID_HOST_THREAD) + info_ap.release(); } - return false; + return thread; } - //------------------------------------------------------------------ // Scoped class that will disable thread canceling when it is // constructed, and exception safely restore the previous value it @@ -643,64 +589,37 @@ if (log) log->Printf ("%s (arg = %p) thread starting...", function, arg); - const lldb::pid_t wait_pid = -1;//*((pid_t*)arg); + MonitorInfo *info = (MonitorInfo *)arg; + + const Host::MonitorChildProcessCallback callback = info->callback; + void * const callback_baton = info->callback_baton; + const lldb::pid_t pid = info->pid; + const bool monitor_signals = info->monitor_signals; + + delete info; + int status = -1; const int options = 0; struct rusage *rusage = NULL; while (1) { if (log) - log->Printf("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p)...", function, wait_pid, options, rusage); + log->Printf("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p)...", function, pid, options, rusage); // Wait for all child processes ::pthread_testcancel (); - lldb::pid_t pid = ::wait4 (wait_pid, &status, options, rusage); + const lldb::pid_t wait_pid = ::wait4 (pid, &status, options, rusage); ::pthread_testcancel (); - if (pid < 0) + if (wait_pid == -1) { - // No child processes to watch wait for the mutex to be cleared - - // Scope for "locker" - { - ScopedPThreadCancelDisabler pthread_cancel_disabler; - - // First clear out all monitor entries since we have no processes - // to watch. - Mutex::Locker locker(&g_monitor_map_mutex); - // Since we don't have any child processes, we can safely clear - // anyone with a valid pid. - MonitorInfoMapSP monitor_map_sp(GetMonitorMap (false)); - if (monitor_map_sp) - { - MonitorInfoMap::iterator pos = monitor_map_sp->begin(); - while (pos != monitor_map_sp->end()) - { - // pid value of 0 and -1 are special (see man page on wait4...) - if (pos->first > 0) - { - MonitorInfoMap::iterator next_pos = pos; ++next_pos; - monitor_map_sp->erase (pos, next_pos); - pos = next_pos; - } - else - ++pos; - } - } - } - - if (log) - log->Printf("%s no child processes, wait for some...", function); - GetChildProcessPredicate ().SetValue (false, eBroadcastNever); - ::pthread_testcancel(); - GetChildProcessPredicate ().WaitForValueEqualTo (true); - if (log) - log->Printf("%s resuming monitoring of child processes.", function); - + if (errno == EINTR) + continue; + else + break; } - else + else if (wait_pid == pid) { - ScopedPThreadCancelDisabler pthread_cancel_disabler; bool exited = false; int signal = 0; int exit_status = 0; @@ -728,80 +647,47 @@ status_cstr = "(???)"; } - if (log) - log->Printf ("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i", - function, - wait_pid, - options, - rusage, - pid, - status, - status_cstr, - signal, - exit_status); - - // Scope for mutex locker + // Scope for pthread_cancel_disabler { - // Notify anyone listening to this process - Mutex::Locker locker(&g_monitor_map_mutex); - MonitorInfoMapSP monitor_map_sp(GetMonitorMap (false)); - if (monitor_map_sp) + ScopedPThreadCancelDisabler pthread_cancel_disabler; + + if (log) + log->Printf ("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i", + function, + wait_pid, + options, + rusage, + pid, + status, + status_cstr, + signal, + exit_status); + + if (exited || (signal != 0 && monitor_signals)) { - std::pair range; - range = monitor_map_sp->equal_range(pid); - MonitorInfoMap::iterator pos; - for (pos = range.first; pos != range.second; ++pos) - { - if (exited || (signal != 0 && pos->second.monitor_signals)) - { - bool callback_return = pos->second.callback (pos->second.callback_baton, pid, signal, exit_status); - - if (exited || callback_return) - { - // Make this entry as needing to be removed by - // setting its handle to zero - pos->second.handle = 0; - } - } - } - - // Remove any entries that requested to be removed or any - // entries for child processes that did exit. We know this - // because we changed the handles to an invalid value. - pos = monitor_map_sp->begin(); - while (pos != monitor_map_sp->end()) - { - if (pos->second.handle == 0) - { - MonitorInfoMap::iterator next_pos = pos; ++next_pos; - monitor_map_sp->erase (pos, next_pos); - pos = next_pos; - } - else - ++pos; - } + bool callback_return = callback (callback_baton, pid, signal, exit_status); + + // If our process exited, then this thread should exit + if (exited) + break; + // If the callback returns true, it means this process should + // exit + if (callback_return) + break; } } } } if (log) - log->Printf ("ProcessMacOSX::%s (arg = %p) thread exiting...", __FUNCTION__, arg); + log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg); - g_monitor_thread = NULL; return NULL; } void Host::WillTerminate () { - if (g_monitor_thread != NULL) - { - ThreadCancel (g_monitor_thread, NULL); - GetChildProcessPredicate ().SetValue (true, eBroadcastAlways); - ThreadJoin(g_monitor_thread, NULL, NULL); - g_monitor_thread = NULL; - } } uint32_t Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp Fri Aug 20 21:22:51 2010 @@ -226,6 +226,7 @@ m_task (this), m_flags (eFlagsNone), m_stdio_thread (LLDB_INVALID_HOST_THREAD), + m_monitor_thread (LLDB_INVALID_HOST_THREAD), m_stdio_mutex (Mutex::eMutexTypeRecursive), m_stdout_data (), m_exception_messages (), @@ -244,6 +245,7 @@ { // m_mach_process.UnregisterNotificationCallbacks (this); Clear(); + } //---------------------------------------------------------------------- @@ -450,7 +452,7 @@ // Install a signal handler so we can catch when our child process // dies and set the exit status correctly. - Host::StartMonitoringChildProcess (Process::SetProcessExitStatus, NULL, GetID(), false); + m_monitor_thread = Host::StartMonitoringChildProcess (Process::SetProcessExitStatus, NULL, GetID(), false); if (m_arch_spec == ArchSpec("arm")) { @@ -1156,6 +1158,14 @@ m_exception_messages.clear(); } + if (m_monitor_thread != LLDB_INVALID_HOST_THREAD) + { + Host::ThreadCancel (m_monitor_thread, NULL); + thread_result_t thread_result; + Host::ThreadJoin (m_monitor_thread, &thread_result, NULL); + m_monitor_thread = LLDB_INVALID_HOST_THREAD; + } + } bool Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h Fri Aug 20 21:22:51 2010 @@ -239,6 +239,7 @@ MachTask m_task; // The mach task for this process lldb_private::Flags m_flags; // Process specific flags (see eFlags enums) lldb::thread_t m_stdio_thread; // Thread ID for the thread that watches for child process stdio + lldb::thread_t m_monitor_thread; // Thread ID for the thread that watches for child process stdio lldb_private::Mutex m_stdio_mutex; // Multithreaded protection for stdio std::string m_stdout_data; MachException::Message::collection m_exception_messages; // A collection of exception messages caught when listening to the exception port Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Aug 20 21:22:51 2010 @@ -110,7 +110,7 @@ m_byte_order (eByteOrderHost), m_gdb_comm(), m_debugserver_pid (LLDB_INVALID_PROCESS_ID), - m_debugserver_monitor (0), + m_debugserver_thread (LLDB_INVALID_HOST_THREAD), m_last_stop_packet (), m_register_info (), m_async_broadcaster ("lldb.process.gdb-remote.async-broadcaster"), @@ -134,6 +134,13 @@ //---------------------------------------------------------------------- ProcessGDBRemote::~ProcessGDBRemote() { + if (m_debugserver_thread != LLDB_INVALID_HOST_THREAD) + { + Host::ThreadCancel (m_debugserver_thread, NULL); + thread_result_t thread_result; + Host::ThreadJoin (m_debugserver_thread, &thread_result, NULL); + m_debugserver_thread = LLDB_INVALID_HOST_THREAD; + } // m_mach_process.UnregisterNotificationCallbacks (this); Clear(); } @@ -535,11 +542,11 @@ m_gdb_comm.SendAck('+'); if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) - m_debugserver_monitor = Host::StartMonitoringChildProcess (MonitorDebugserverProcess, - (void*)(intptr_t)GetID(), // Pass the inferior pid in the thread argument (which is a void *) - m_debugserver_pid, - false); - + m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess, + this, + m_debugserver_pid, + false); + StringExtractorGDBRemote response; if (m_gdb_comm.SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false)) { @@ -1907,47 +1914,42 @@ // "debugserver_pid" argument passed in is the process ID for // debugserver that we are tracking... - lldb::pid_t gdb_remote_pid = (lldb::pid_t)(intptr_t)callback_baton; - TargetSP target_sp(Debugger::FindTargetWithProcessID (gdb_remote_pid)); - if (target_sp) - { - ProcessSP process_sp (target_sp->GetProcessSP()); - if (process_sp) - { - // Sleep for a half a second to make sure our inferior process has - // time to set its exit status before we set it incorrectly when - // both the debugserver and the inferior process shut down. - usleep (500000); - // If our process hasn't yet exited, debugserver might have died. - // If the process did exit, the we are reaping it. - if (process_sp->GetState() != eStateExited) - { - char error_str[1024]; - if (signo) - { - const char *signal_cstr = process_sp->GetUnixSignals().GetSignalAsCString (signo); - if (signal_cstr) - ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr); - else - ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo); - } + ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton; + + if (process) + { + // Sleep for a half a second to make sure our inferior process has + // time to set its exit status before we set it incorrectly when + // both the debugserver and the inferior process shut down. + usleep (500000); + // If our process hasn't yet exited, debugserver might have died. + // If the process did exit, the we are reaping it. + if (process->GetState() != eStateExited) + { + char error_str[1024]; + if (signo) + { + const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo); + if (signal_cstr) + ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr); else - { - ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status); - } - - process_sp->SetExitStatus (-1, error_str); + ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo); } else { - ProcessGDBRemote *gdb_process = (ProcessGDBRemote *)process_sp.get(); - // Debugserver has exited we need to let our ProcessGDBRemote - // know that it no longer has a debugserver instance - gdb_process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID; - // We are returning true to this function below, so we can - // forget about the monitor handle. - gdb_process->m_debugserver_monitor = 0; + ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status); } + + process->SetExitStatus (-1, error_str); + } + else + { + // Debugserver has exited we need to let our ProcessGDBRemote + // know that it no longer has a debugserver instance + process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID; + // We are returning true to this function below, so we can + // forget about the monitor handle. + process->m_debugserver_thread = LLDB_INVALID_HOST_THREAD; } } return true; Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Fri Aug 20 21:22:51 2010 @@ -324,7 +324,7 @@ lldb::ByteOrder m_byte_order; GDBRemoteCommunication m_gdb_comm; lldb::pid_t m_debugserver_pid; - uint32_t m_debugserver_monitor; + lldb::thread_t m_debugserver_thread; StringExtractor m_last_stop_packet; GDBRemoteDynamicRegisterInfo m_register_info; lldb_private::Broadcaster m_async_broadcaster; Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Aug 20 21:22:51 2010 @@ -785,8 +785,7 @@ static void AddRangesToBlock ( - BlockList& blocks, - lldb::user_id_t blockID, + Block& block, DWARFDebugRanges::RangeList& ranges, addr_t block_base_addr ) @@ -796,7 +795,7 @@ const DWARFDebugRanges::Range *debug_range; for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++) { - blocks.AddRange(blockID, debug_range->begin_offset, debug_range->end_offset); + block.AddRange(debug_range->begin_offset, debug_range->end_offset); } } @@ -1129,7 +1128,7 @@ SymbolFileDWARF::ParseFunctionBlocks ( const SymbolContext& sc, - lldb::user_id_t parentBlockID, + Block *parent_block, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, addr_t subprogram_low_pc, @@ -1151,18 +1150,31 @@ DWARFDebugRanges::RangeList ranges; const char *name = NULL; const char *mangled_name = NULL; - BlockList& blocks = sc.function->GetBlocks(false); + Block *block = NULL; + if (tag != DW_TAG_subprogram) + { + BlockSP block_sp(new Block (die->GetOffset())); + parent_block->AddChild(block_sp); + block = block_sp.get(); + } + else + { + block = parent_block; + } - lldb::user_id_t blockID = blocks.AddChild(parentBlockID, die->GetOffset()); int decl_file = 0; int decl_line = 0; int decl_column = 0; int call_file = 0; int call_line = 0; int call_column = 0; - if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, - decl_file, decl_line, decl_column, - call_file, call_line, call_column)) + if (die->GetDIENamesAndRanges (this, + dwarf_cu, + name, + mangled_name, + ranges, + decl_file, decl_line, decl_column, + call_file, call_line, call_column)) { if (tag == DW_TAG_subprogram) { @@ -1185,7 +1197,7 @@ } } - AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc); + AddRangesToBlock (*block, ranges, subprogram_low_pc); if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) { @@ -1199,15 +1211,20 @@ call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column)); - blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get()); + block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get()); } ++blocks_added; if (parse_children && die->HasChildren()) { - blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), - subprogram_low_pc, true, true); + blocks_added += ParseFunctionBlocks (sc, + block, + dwarf_cu, + die->GetFirstChild(), + subprogram_low_pc, + true, + true); } } } @@ -1582,12 +1599,12 @@ if (resolve_scope & eSymbolContextBlock) { - BlockList& blocks = sc.function->GetBlocks(true); + Block& block = sc.function->GetBlock (true); if (block_die != NULL) - sc.block = blocks.GetBlockByID(block_die->GetOffset()); + sc.block = block.FindBlockByID (block_die->GetOffset()); else - sc.block = blocks.GetBlockByID(function_die->GetOffset()); + sc.block = block.FindBlockByID (function_die->GetOffset()); if (sc.block) resolved |= eSymbolContextBlock; } @@ -1674,12 +1691,12 @@ if (sc.function != NULL) { - BlockList& blocks = sc.function->GetBlocks(true); + Block& block = sc.function->GetBlock (true); if (block_die != NULL) - sc.block = blocks.GetBlockByID(block_die->GetOffset()); + sc.block = block.FindBlockByID (block_die->GetOffset()); else - sc.block = blocks.GetBlockByID(function_die->GetOffset()); + sc.block = block.FindBlockByID (function_die->GetOffset()); } } } @@ -3126,7 +3143,7 @@ } else if (sc.function != NULL) { - symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset()); + symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); if (symbol_context_scope == NULL) symbol_context_scope = sc.function; } @@ -3235,7 +3252,7 @@ const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset); if (function_die) { - ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true); + ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true); } } @@ -3430,7 +3447,7 @@ } else if (sc.function != NULL) { - symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset()); + symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); if (symbol_context_scope == NULL) symbol_context_scope = sc.function; } @@ -3495,11 +3512,14 @@ if (sc.function != NULL) { // Check to see if we already have parsed the variables for the given scope - variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false); + + Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); + assert (block != NULL); + variables = block->GetVariableList(false, true); if (variables.get() == NULL) { variables.reset(new VariableList()); - sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables); + block->SetVariableList(variables); } } else Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Fri Aug 20 21:22:51 2010 @@ -222,7 +222,7 @@ bool GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, lldb_private::SymbolContext& sc); lldb_private::Function * ParseCompileUnitFunction (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die); size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc, - lldb::user_id_t parentBlockID, + lldb_private::Block *parent_block, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, lldb::addr_t subprogram_low_pc, Modified: lldb/trunk/source/Symbol/Block.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Block.cpp?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Block.cpp (original) +++ lldb/trunk/source/Symbol/Block.cpp Fri Aug 20 21:22:51 2010 @@ -17,47 +17,26 @@ using namespace lldb; using namespace lldb_private; -Block::Block(user_id_t uid, uint32_t depth, BlockList* blocks) : +Block::Block(lldb::user_id_t uid) : UserID(uid), - m_block_list(blocks), - m_depth(depth), - m_ranges(), - m_inlineInfoSP(), - m_variables() + m_parent_scope (NULL), + m_sibling (NULL), + m_children (), + m_ranges (), + m_inlineInfoSP (), + m_variables (), + m_parsed_block_info (false), + m_parsed_block_variables (false), + m_parsed_child_blocks (false) { } -Block::Block(const Block& rhs) : - UserID(rhs), - m_block_list(rhs.m_block_list), - m_depth(rhs.m_depth), - m_ranges(rhs.m_ranges), - m_inlineInfoSP(rhs.m_inlineInfoSP), - m_variables(rhs.m_variables) -{ -} - -const Block& -Block::operator= (const Block& rhs) -{ - if (this != &rhs) - { - UserID::operator= (rhs); - m_block_list = rhs.m_block_list; - m_depth = rhs.m_depth; - m_ranges = rhs.m_ranges; - m_inlineInfoSP = rhs.m_inlineInfoSP; - m_variables = rhs.m_variables; - } - return *this; -} - Block::~Block () { } void -Block::GetDescription(Stream *s, lldb::DescriptionLevel level, Process *process) const +Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Process *process) const { size_t num_ranges = m_ranges.size(); if (num_ranges) @@ -65,9 +44,9 @@ addr_t base_addr = LLDB_INVALID_ADDRESS; if (process) - base_addr = m_block_list->GetAddressRange().GetBaseAddress().GetLoadAddress(process); + base_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(process); if (base_addr == LLDB_INVALID_ADDRESS) - base_addr = m_block_list->GetAddressRange().GetBaseAddress().GetFileAddress(); + base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress(); s->Printf("range%s = ", num_ranges > 1 ? "s" : ""); std::vector::const_iterator pos, end = m_ranges.end(); @@ -85,9 +64,13 @@ { if (depth < 0) { - // We have a depth that is less than zero, print our parent blocks - // first - m_block_list->Dump(s, GetParentUID(), depth + 1, show_context); + Block *parent = GetParent(); + if (parent) + { + // We have a depth that is less than zero, print our parent blocks + // first + parent->Dump(s, base_addr, depth + 1, show_context); + } } s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); @@ -126,12 +109,9 @@ m_variables->Dump(s, show_context); } - uint32_t blockID = m_block_list->GetFirstChild(GetID()); - while (blockID != Block::InvalidID) + for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling()) { - m_block_list->Dump(s, blockID, depth - 1, show_context); - - blockID = m_block_list->GetSibling(blockID); + child_block->Dump(s, base_addr, depth - 1, show_context); } s->IndentLess(); @@ -140,11 +120,28 @@ } +Block * +Block::FindBlockByID (user_id_t block_id) +{ + if (block_id == GetID()) + return this; + + Block *matching_block = NULL; + for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling()) + { + matching_block = child_block->FindBlockByID (block_id); + if (matching_block) + break; + } + return matching_block; +} + void Block::CalculateSymbolContext(SymbolContext* sc) { + if (m_parent_scope) + m_parent_scope->CalculateSymbolContext(sc); sc->block = this; - m_block_list->GetFunction()->CalculateSymbolContext(sc); } void @@ -196,7 +193,10 @@ void Block::DumpSymbolContext(Stream *s) { - m_block_list->GetFunction()->DumpSymbolContext(s); + SymbolContext sc; + CalculateSymbolContext(&sc); + if (sc.function) + sc.function->DumpSymbolContext(s); s->Printf(", Block{0x%8.8x}", GetID()); } @@ -212,37 +212,19 @@ return VMRange::ContainsRange(m_ranges, range); } - - -bool -BlockList::BlockContainsBlockWithID (const user_id_t block_id, const user_id_t find_block_id) const +Block * +Block::GetParent () const { - if (block_id == Block::InvalidID) - return false; - - if (block_id == find_block_id) - return true; - else + if (m_parent_scope) { - user_id_t child_block_id = GetFirstChild(block_id); - while (child_block_id != Block::InvalidID) - { - if (BlockContainsBlockWithID (child_block_id, find_block_id)) - return true; - child_block_id = GetSibling(child_block_id); - } + SymbolContext sc; + m_parent_scope->CalculateSymbolContext(&sc); + if (sc.block) + return sc.block; } - - return false; -} - -bool -Block::ContainsBlockWithID (user_id_t block_id) const -{ - return m_block_list->BlockContainsBlockWithID (GetID(), block_id); + return NULL; } - void Block::AddRange(addr_t start_offset, addr_t end_offset) { @@ -276,45 +258,29 @@ } Block * -Block::GetParent () const -{ - return m_block_list->GetBlockByID (m_block_list->GetParent(GetID())); -} - -Block * -Block::GetSibling () const -{ - return m_block_list->GetBlockByID (m_block_list->GetSibling(GetID())); -} - -Block * Block::GetFirstChild () const { - return m_block_list->GetBlockByID (m_block_list->GetFirstChild(GetID())); + if (m_children.empty()) + return NULL; + return m_children.front().get(); } -user_id_t -Block::GetParentUID() const +void +Block::AddChild(const BlockSP &child_block_sp) { - return m_block_list->GetParent(GetID()); -} + if (child_block_sp) + { + Block *block_needs_sibling = NULL; -user_id_t -Block::GetSiblingUID() const -{ - return m_block_list->GetSibling(GetID()); -} + if (!m_children.empty()) + block_needs_sibling = m_children.back().get(); -user_id_t -Block::GetFirstChildUID() const -{ - return m_block_list->GetFirstChild(GetID()); -} + child_block_sp->SetParentScope (this); + m_children.push_back (child_block_sp); -user_id_t -Block::AddChild(user_id_t userID) -{ - return m_block_list->AddChild(GetID(), userID); + if (block_needs_sibling) + block_needs_sibling->SetSibling (child_block_sp.get()); + } } void @@ -329,12 +295,16 @@ Block::GetVariableList (bool get_child_variables, bool can_create) { VariableListSP variable_list_sp; - if (m_variables.get() == NULL && can_create) + if (m_parsed_block_variables == false) { - SymbolContext sc; - CalculateSymbolContext(&sc); - assert(sc.module_sp); - sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc); + if (m_variables.get() == NULL && can_create) + { + m_parsed_block_variables = true; + SymbolContext sc; + CalculateSymbolContext(&sc); + assert(sc.module_sp); + sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc); + } } if (m_variables.get()) @@ -387,285 +357,14 @@ m_variables = variables; } -uint32_t -Block::Depth () const -{ - return m_depth; -} - -BlockList::BlockList(Function *function, const AddressRange& range) : - m_function(function), - m_range(range), - m_blocks() -{ -} - -BlockList::~BlockList() -{ -} - -AddressRange & -BlockList::GetAddressRange() -{ - return m_range; -} - -const AddressRange & -BlockList::GetAddressRange() const -{ - return m_range; -} - void -BlockList::Dump(Stream *s, user_id_t blockID, uint32_t depth, bool show_context) const -{ - const Block* block = GetBlockByID(blockID); - if (block) - block->Dump(s, m_range.GetBaseAddress().GetFileAddress(), depth, show_context); -} - -Function * -BlockList::GetFunction() -{ - return m_function; -} - - -const Function * -BlockList::GetFunction() const -{ - return m_function; -} - -user_id_t -BlockList::GetParent(user_id_t blockID) const +Block::SetBlockInfoHasBeenParsed (bool b, bool set_children) { - collection::const_iterator end = m_blocks.end(); - collection::const_iterator begin = m_blocks.begin(); - collection::const_iterator pos = std::find_if(begin, end, UserID::IDMatches(blockID)); - - if (pos != end && pos != begin && pos->Depth() > 0) + m_parsed_block_info = b; + if (set_children) { - const uint32_t parent_depth = pos->Depth() - 1; - - while (--pos >= begin) - { - if (pos->Depth() == parent_depth) - return pos->GetID(); - } + m_parsed_child_blocks = true; + for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling()) + child_block->SetBlockInfoHasBeenParsed (b, true); } - return Block::InvalidID; -} - -user_id_t -BlockList::GetSibling(user_id_t blockID) const -{ - collection::const_iterator end = m_blocks.end(); - collection::const_iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID)); - - if (pos != end) - { - const uint32_t sibling_depth = pos->Depth(); - while (++pos != end) - { - uint32_t depth = pos->Depth(); - if (depth == sibling_depth) - return pos->GetID(); - if (depth < sibling_depth) - break; - } - } - return Block::InvalidID; -} - -user_id_t -BlockList::GetFirstChild(user_id_t blockID) const -{ - if (!m_blocks.empty()) - { - if (blockID == Block::RootID) - { - return m_blocks.front().GetID(); - } - else - { - collection::const_iterator end = m_blocks.end(); - collection::const_iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID)); - - if (pos != end) - { - collection::const_iterator child_pos = pos + 1; - if (child_pos != end) - { - if (child_pos->Depth() == pos->Depth() + 1) - return child_pos->GetID(); - } - } - } - } - return Block::InvalidID; -} - - -// Return the current number of bytes that this object occupies in memory -size_t -BlockList::MemorySize() const -{ - size_t mem_size = sizeof(BlockList); - - collection::const_iterator pos, end = m_blocks.end(); - for (pos = m_blocks.begin(); pos != end; ++pos) - mem_size += pos->MemorySize(); // Each block can vary in size - - return mem_size; - -} - -user_id_t -BlockList::AddChild (user_id_t parentID, user_id_t childID) -{ - bool added = false; - if (parentID == Block::RootID) - { - assert(m_blocks.empty()); - Block block(childID, 0, this); - m_blocks.push_back(block); - added = true; - } - else - { - collection::iterator end = m_blocks.end(); - collection::iterator parent_pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(parentID)); - assert(parent_pos != end); - if (parent_pos != end) - { - const uint32_t parent_sibling_depth = parent_pos->Depth(); - - collection::iterator insert_pos = parent_pos; - collection::iterator prev_sibling = end; - while (++insert_pos != end) - { - if (insert_pos->Depth() <= parent_sibling_depth) - break; - } - - Block child_block(childID, parent_pos->Depth() + 1, this); - collection::iterator child_pos = m_blocks.insert(insert_pos, child_block); - added = true; - } - } - if (added) - return childID; - return Block::InvalidID; -} - -const Block * -BlockList::GetBlockByID(user_id_t blockID) const -{ - if (m_blocks.empty() || blockID == Block::InvalidID) - return NULL; - - if (blockID == Block::RootID) - blockID = m_blocks.front().GetID(); - - collection::const_iterator end = m_blocks.end(); - collection::const_iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID)); - if (pos != end) - return &(*pos); - return NULL; -} - -Block * -BlockList::GetBlockByID(user_id_t blockID) -{ - if (m_blocks.empty() || blockID == Block::InvalidID) - return NULL; - - if (blockID == Block::RootID) - blockID = m_blocks.front().GetID(); - - collection::iterator end = m_blocks.end(); - collection::iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID)); - if (pos != end) - return &(*pos); - return NULL; -} - -bool -BlockList::AddRange(user_id_t blockID, addr_t start_offset, addr_t end_offset) -{ - Block *block = GetBlockByID(blockID); - - if (block) - { - block->AddRange(start_offset, end_offset); - return true; - } - return false; -} -// -//const Block * -//BlockList::FindDeepestBlockForAddress (const Address &addr) -//{ -// if (m_range.Contains(addr)) -// { -// addr_t block_offset = addr.GetFileAddress() - m_range.GetBaseAddress().GetFileAddress(); -// collection::const_iterator pos, end = m_blocks.end(); -// collection::const_iterator deepest_match_pos = end; -// for (pos = m_blocks.begin(); pos != end; ++pos) -// { -// if (pos->Contains (block_offset)) -// { -// if (deepest_match_pos == end || deepest_match_pos->Depth() < pos->Depth()) -// deepest_match_pos = pos; -// } -// } -// if (deepest_match_pos != end) -// return &(*deepest_match_pos); -// } -// return NULL; -//} -// -bool -BlockList::SetInlinedFunctionInfo(user_id_t blockID, const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr) -{ - Block *block = GetBlockByID(blockID); - - if (block) - { - block->SetInlinedFunctionInfo(name, mangled, decl_ptr, call_decl_ptr); - return true; - } - return false; -} - -VariableListSP -BlockList::GetVariableList(user_id_t blockID, bool get_child_variables, bool can_create) -{ - VariableListSP variable_list_sp; - Block *block = GetBlockByID(blockID); - if (block) - variable_list_sp = block->GetVariableList(get_child_variables, can_create); - return variable_list_sp; -} - -bool -BlockList::IsEmpty() const -{ - return m_blocks.empty(); -} - - - -bool -BlockList::SetVariableList(user_id_t blockID, VariableListSP& variables) -{ - Block *block = GetBlockByID(blockID); - if (block) - { - block->SetVariableList(variables); - return true; - } - return false; - } Modified: lldb/trunk/source/Symbol/Function.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Function.cpp?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Function.cpp (original) +++ lldb/trunk/source/Symbol/Function.cpp Fri Aug 20 21:22:51 2010 @@ -191,16 +191,18 @@ Type * type, const AddressRange& range ) : - UserID(func_uid), - m_comp_unit(comp_unit), - m_type_uid(type_uid), - m_type(type), - m_mangled(mangled), - m_blocks(this, range), - m_frame_base(), - m_flags(), - m_prologue_byte_size(0) + UserID (func_uid), + m_comp_unit (comp_unit), + m_type_uid (type_uid), + m_type (type), + m_mangled (mangled), + m_block (func_uid), + m_range (range), + m_frame_base (), + m_flags (), + m_prologue_byte_size (0) { + m_block.SetParentScope(this); assert(comp_unit != NULL); } @@ -213,16 +215,18 @@ Type *type, const AddressRange &range ) : - UserID(func_uid), - m_comp_unit(comp_unit), - m_type_uid(type_uid), - m_type(type), - m_mangled(mangled, true), - m_blocks(this, range), - m_frame_base(), - m_flags(), - m_prologue_byte_size(0) + UserID (func_uid), + m_comp_unit (comp_unit), + m_type_uid (type_uid), + m_type (type), + m_mangled (mangled, true), + m_block (func_uid), + m_range (range), + m_frame_base (), + m_flags (), + m_prologue_byte_size (0) { + m_block.SetParentScope(this); assert(comp_unit != NULL); } @@ -231,24 +235,6 @@ { } -const AddressRange & -Function::GetAddressRange() -{ - return GetBlocks(true).GetAddressRange(); -} - -bool -Function::IsInlined() -{ - Block *root_block = GetBlocks(true).GetBlockByID(Block::RootID); - if (root_block) - { - if (root_block->InlinedFunctionInfo() != NULL) - return true; - } - return false; - -} void Function::GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no) { @@ -301,17 +287,18 @@ } } -BlockList & -Function::GetBlocks(bool can_create) +Block & +Function::GetBlock (bool can_create) { - if (m_blocks.IsEmpty() && can_create) + if (!m_block.BlockInfoHasBeenParsed() && can_create) { SymbolContext sc; CalculateSymbolContext(&sc); assert(sc.module_sp); sc.module_sp->GetSymbolVendor()->ParseFunctionBlocks(sc); + m_block.SetBlockInfoHasBeenParsed (true, true); } - return m_blocks; + return m_block; } CompileUnit* @@ -358,8 +345,8 @@ s->EOL(); // Dump the root object - if (!m_blocks.IsEmpty()) - m_blocks.Dump(s, Block::RootID, INT_MAX, show_context); + if (m_block.BlockInfoHasBeenParsed ()) + m_block.Dump(s, m_range.GetBaseAddress().GetFileAddress(), INT_MAX, show_context); } @@ -380,7 +367,7 @@ size_t Function::MemorySize () const { - size_t mem_size = sizeof(Function) + m_blocks.MemorySize(); + size_t mem_size = sizeof(Function) + m_block.MemorySize(); return mem_size; } Modified: lldb/trunk/source/Symbol/SymbolContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Symbol/SymbolContext.cpp (original) +++ lldb/trunk/source/Symbol/SymbolContext.cpp Fri Aug 20 21:22:51 2010 @@ -217,7 +217,7 @@ s->Indent(" Blocks: "); else s->Indent(" "); - (*pos)->GetDescription(s, level, process); + (*pos)->GetDescription(s, function, level, process); s->EOL(); } } Modified: lldb/trunk/source/Symbol/Variable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Variable.cpp?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Variable.cpp (original) +++ lldb/trunk/source/Symbol/Variable.cpp Fri Aug 20 21:22:51 2010 @@ -154,7 +154,7 @@ SymbolContext variable_sc; CalculateSymbolContext (&variable_sc); if (variable_sc.function && variable_sc.block) - return variable_sc.block->ContainsBlockWithID (frame_block->GetID()); + return variable_sc.block->FindBlockByID(frame_block->GetID()) != NULL; } } break; Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=111706&r1=111705&r2=111706&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Fri Aug 20 21:22:51 2010 @@ -280,7 +280,7 @@ { bool get_child_variables = true; bool can_create = true; - m_variable_list_sp = m_sc.function->GetBlocks(can_create).GetVariableList (Block::RootID, get_child_variables, can_create); + m_variable_list_sp = m_sc.function->GetBlock (can_create).GetVariableList (get_child_variables, can_create); } } return m_variable_list_sp.get(); From gclayton at apple.com Sat Aug 21 15:12:22 2010 From: gclayton at apple.com (Greg Clayton) Date: Sat, 21 Aug 2010 20:12:22 -0000 Subject: [Lldb-commits] [lldb] r111743 - /lldb/trunk/lldb.xcodeproj/project.pbxproj Message-ID: <20100821201222.6F63F2A6C12C@llvm.org> Author: gclayton Date: Sat Aug 21 15:12:22 2010 New Revision: 111743 URL: http://llvm.org/viewvc/llvm-project?rev=111743&view=rev Log: Fixed the Xcode project file to not build all architectures for Debug builds. I accidentally checked this in with my last round of changes. Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=111743&r1=111742&r2=111743&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Sat Aug 21 15:12:22 2010 @@ -2791,7 +2791,6 @@ ); LLVM_BUILD_DIR = "$(SRCROOT)/llvm"; LLVM_CONFIGURATION = Release; - ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "-DFOR_DYLD=0", "-DSUPPORT_REMOTE_UNWINDING",