[Lldb-commits] [lldb] r164806 - in /lldb/trunk: include/lldb/Core/UUID.h include/lldb/Interpreter/OptionGroupBoolean.h include/lldb/Interpreter/OptionValueFileSpec.h include/lldb/Interpreter/OptionValueUUID.h source/API/SBTarget.cpp source/Commands/CommandObjectTarget.cpp source/Core/UUID.cpp source/Host/macosx/Symbols.cpp source/Interpreter/OptionGroupBoolean.cpp source/Interpreter/OptionValueFileSpec.cpp source/Interpreter/OptionValueUUID.cpp source/Interpreter/Property.cpp

Greg Clayton gclayton at apple.com
Thu Sep 27 15:26:11 PDT 2012


Author: gclayton
Date: Thu Sep 27 17:26:11 2012
New Revision: 164806

URL: http://llvm.org/viewvc/llvm-project?rev=164806&view=rev
Log:
Wrapped up the work I am going to do for now for the "add-dsym" or "target symfile add" command.

We can now do:

Specify a path to a debug symbols file:
(lldb) add-dsym <path-to-dsym>

Go and download the dSYM file for the "libunc.dylib" module in your target:
(lldb) add-dsym --shlib libunc.dylib

Go and download the dSYM given a UUID:
(lldb) add-dsym --uuid <UUID>

Go and download the dSYM file for the current frame:
(lldb) add-dsym --frame


Modified:
    lldb/trunk/include/lldb/Core/UUID.h
    lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h
    lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h
    lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/Commands/CommandObjectTarget.cpp
    lldb/trunk/source/Core/UUID.cpp
    lldb/trunk/source/Host/macosx/Symbols.cpp
    lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp
    lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp
    lldb/trunk/source/Interpreter/OptionValueUUID.cpp
    lldb/trunk/source/Interpreter/Property.cpp

Modified: lldb/trunk/include/lldb/Core/UUID.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/UUID.h?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/UUID.h (original)
+++ lldb/trunk/include/lldb/Core/UUID.h Thu Sep 27 17:26:11 2012
@@ -58,8 +58,36 @@
     GetAsCString (char *dst, size_t dst_len) const;
 
     size_t
-    SetfromCString (const char *c_str);
+    SetFromCString (const char *c_str);
 
+    // Decode as many UUID bytes (up to 16) as possible from the C string "cstr"
+    // This is used for auto completion where a partial UUID might have been
+    // typed in. It 
+    //------------------------------------------------------------------
+    /// Decode as many UUID bytes (up to 16) as possible from the C
+    /// string \a cstr.
+    ///
+    /// @param[in] cstr
+    ///     A NULL terminate C string that points at a UUID string value
+    ///     (no leading spaces). The string must contain only hex
+    ///     characters and optionally can contain the '-' sepearators.
+    ///
+    /// @param[in] uuid_bytes
+    ///     A buffer of bytes that will contain a full or patially
+    ///     decoded UUID.
+    ///
+    /// @param[out] end
+    ///     If \a end is not NULL, it will be filled in with the a
+    ///     pointer to the character after the last successfully decoded
+    ///     byte.
+    ///
+    /// @return
+    ///     Returns the number of bytes that were successfully decoded
+    ///     which should be 16 if a full UUID value was properly decoded.
+    //------------------------------------------------------------------
+    static size_t
+    DecodeUUIDBytesFromCString (const char *cstr, ValueType &uuid_bytes, const char **end);
+    
 protected:
     //------------------------------------------------------------------
     // Classes that inherit from UUID can see and modify these

Modified: lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h (original)
+++ lldb/trunk/include/lldb/Interpreter/OptionGroupBoolean.h Thu Sep 27 17:26:11 2012
@@ -25,15 +25,16 @@
     class OptionGroupBoolean : public OptionGroup
     {
     public:
-        
+         // When 'no_argument_toggle_default' is true, then setting the option
+         // value does NOT require an argument, it sets the boolean value to the
+         // inverse of the default value
         OptionGroupBoolean (uint32_t usage_mask,
                             bool required,
                             const char *long_option, 
                             char short_option,
-                            uint32_t completion_type,
-                            lldb::CommandArgumentType argument_type,
                             const char *usage_text,
-                            bool default_value);
+                            bool default_value,
+                            bool no_argument_toggle_default);
         
         virtual
         ~OptionGroupBoolean ();
@@ -76,7 +77,7 @@
         OptionDefinition m_option_definition;
         
     };
-    
+
 } // namespace lldb_private
 
 #endif  // liblldb_OptionGroupBoolean_h_

Modified: lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h (original)
+++ lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h Thu Sep 27 17:26:11 2012
@@ -22,30 +22,12 @@
 class OptionValueFileSpec : public OptionValue
 {
 public:
-    OptionValueFileSpec () :
-        OptionValue(),
-        m_current_value (),
-        m_default_value (),
-        m_data_sp()
-    {
-    }
+    OptionValueFileSpec ();
     
-    OptionValueFileSpec (const FileSpec &value) :
-        OptionValue(),
-        m_current_value (value),
-        m_default_value (value),
-        m_data_sp()
-    {
-    }
+    OptionValueFileSpec (const FileSpec &value);
     
     OptionValueFileSpec (const FileSpec &current_value, 
-                         const FileSpec &default_value) :
-        OptionValue(),
-        m_current_value (current_value),
-        m_default_value (default_value),
-        m_data_sp()
-    {
-    }
+                         const FileSpec &default_value);
     
     virtual 
     ~OptionValueFileSpec()
@@ -129,10 +111,17 @@
     const lldb::DataBufferSP &
     GetFileContents(bool null_terminate);
     
+    void
+    SetCompletionMask (uint32_t mask)
+    {
+        m_completion_mask = mask;
+    }
+
 protected:
     FileSpec m_current_value;
     FileSpec m_default_value;
     lldb::DataBufferSP m_data_sp;
+    uint32_t m_completion_mask;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h (original)
+++ lldb/trunk/include/lldb/Interpreter/OptionValueUUID.h Thu Sep 27 17:26:11 2012
@@ -89,6 +89,14 @@
         m_uuid = value;
     }
     
+    virtual size_t
+    AutoComplete (CommandInterpreter &interpreter,
+                  const char *s,
+                  int match_start_point,
+                  int max_return_elements,
+                  bool &word_complete,
+                  StringList &matches);
+
 protected:
     UUID m_uuid;
 };

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Thu Sep 27 17:26:11 2012
@@ -1801,7 +1801,7 @@
             module_spec.GetFileSpec().SetFile(path, false);
         
         if (uuid_cstr)
-            module_spec.GetUUID().SetfromCString(uuid_cstr);
+            module_spec.GetUUID().SetFromCString(uuid_cstr);
         
         if (triple)
             module_spec.GetArchitecture().SetTriple (triple, target_sp->GetPlatform ().get());

Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Thu Sep 27 17:26:11 2012
@@ -451,7 +451,7 @@
                              NULL,
                              0),
         m_option_group (interpreter),
-        m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', 0, eArgTypeNone, "Perform extra cleanup to minimize memory consumption after deleting the target.", false)
+        m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false)
     {
         m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
         m_option_group.Finalize();
@@ -3984,9 +3984,17 @@
     CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
         CommandObjectParsed (interpreter,
                              "target symbols add",
-                             "Add a debug symbol file to one of the target's current modules.",
-                             "target symbols add [<symfile>]")
+                             "Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.",
+                             "target symbols add [<symfile>]"),
+        m_option_group (interpreter),
+        m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
+        m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
+
     {
+        m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+        m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+        m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
+        m_option_group.Finalize();
     }
     
     virtual
@@ -4018,152 +4026,260 @@
         return matches.GetSize();
     }
     
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_option_group;
+    }
+    
+
 protected:
+    
+    bool
+    AddModuleSymbols (Target *target,
+                      const FileSpec &symfile_spec,
+                      bool &flush,
+                      CommandReturnObject &result)
+    {
+        ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture()));
+        const UUID &symfile_uuid = symfile_module_sp->GetUUID();
+        StreamString ss_symfile_uuid;
+        symfile_uuid.Dump(&ss_symfile_uuid);
+        
+        if (symfile_module_sp)
+        {
+            char symfile_path[PATH_MAX];
+            symfile_spec.GetPath (symfile_path, sizeof(symfile_path));
+            // We now have a module that represents a symbol file
+            // that can be used for a module that might exist in the
+            // current target, so we need to find that module in the
+            // target
+            
+            ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid));
+            if (old_module_sp)
+            {
+                // The module has not yet created its symbol vendor, we can just
+                // give the existing target module the symfile path to use for
+                // when it decides to create it!
+                old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec());
+                
+                // Provide feedback that the symfile has been successfully added.
+                const FileSpec &module_fs = old_module_sp->GetFileSpec();
+                result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n",
+                                               symfile_path, ss_symfile_uuid.GetData(),
+                                               module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString());
+                
+                // Let clients know something changed in the module
+                // if it is currently loaded
+                ModuleList module_list;
+                module_list.Append (old_module_sp);
+                target->ModulesDidLoad (module_list);
+                flush = true;
+            }
+            else
+            {
+                result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n",
+                                              symfile_path, ss_symfile_uuid.GetData(),
+                                              (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular)
+                                              ? "\n       please specify the full path to the symbol file"
+                                              : "");
+                return false;
+            }
+        }
+        else
+        {
+            result.AppendError ("one or more executable image paths must be specified");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+        result.SetStatus (eReturnStatusSuccessFinishResult);
+        return true;
+    }
+
     virtual bool
     DoExecute (Args& args,
              CommandReturnObject &result)
     {
         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
         Target *target = exe_ctx.GetTargetPtr();
+        result.SetStatus (eReturnStatusFailed);
         if (target == NULL)
         {
             result.AppendError ("invalid target, create a debug target using the 'target create' command");
-            result.SetStatus (eReturnStatusFailed);
         }
         else
         {
             bool flush = false;
+            ModuleSpec sym_spec;
+            const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
+            const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
+            const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
+
             const size_t argc = args.GetArgumentCount();
             if (argc == 0)
             {
-                result.AppendError ("one or more symbol file paths must be specified");
-                result.SetStatus (eReturnStatusFailed);
-            }
-            else
-            {
-                PlatformSP platform_sp (target->GetPlatform());
-
-                for (size_t i=0; i<argc; ++i)
+                if (uuid_option_set || file_option_set || frame_option_set)
                 {
-                    const char *symfile_path = args.GetArgumentAtIndex(i);
-                    if (symfile_path)
+                    bool success = false;
+                    bool error_set = false;
+                    if (frame_option_set)
                     {
-                        ModuleSpec sym_spec;
-                        FileSpec symfile_spec;
-                        sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
-                        if (platform_sp)
-                            platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec);
-                        else
-                            symfile_spec.SetFile(symfile_path, true);
-                        
-                        ArchSpec arch;
-                        bool symfile_exists = symfile_spec.Exists();
-                        // The code below was testing the new "Symbols::DownloadObjectAndSymbolFile"
-                        // functionality. Now that it works on MacOSX, it will be enabled soon with
-                        // option values (like "--uuid <UUID>" or "--file <module>", or "--frame"
-                        // for the current stack frame's module). So it is commented out for now.
-//                        if (!symfile_exists)
-//                        {
-//                            if (sym_spec.GetUUID().SetfromCString(symfile_path))
-//                            {
-//                                // A UUID was specified, look it up via UUID
-//                                if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
-//                                {
-////                                    printf ("UUID: %s\n", symfile_path);
-////                                    printf ("objfile_spec: %s/%s\n",
-////                                            sym_spec.GetFileSpec().GetDirectory().GetCString(),
-////                                            sym_spec.GetFileSpec().GetFilename().GetCString());
-////                                    printf ("symfile_spec: %s/%s\n",
-////                                            sym_spec.GetSymbolFileSpec().GetDirectory().GetCString(),
-////                                            sym_spec.GetSymbolFileSpec().GetFilename().GetCString());
-//                                    symfile_spec = sym_spec.GetSymbolFileSpec();
-//                                    symfile_exists = symfile_spec.Exists();
-//                                }
-//                            }
-//                        }
-
-                        if (symfile_exists)
+                        Process *process = exe_ctx.GetProcessPtr();
+                        if (process)
                         {
-                            ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture()));
-                            const UUID &symfile_uuid = symfile_module_sp->GetUUID();
-                            StreamString ss_symfile_uuid;
-                            symfile_uuid.Dump(&ss_symfile_uuid);
-
-                            if (symfile_module_sp)
+                            const StateType process_state = process->GetState();
+                            if (StateIsStoppedState (process_state, true))
                             {
-                                // We now have a module that represents a symbol file
-                                // that can be used for a module that might exist in the
-                                // current target, so we need to find that module in the
-                                // target
-                                
-                                ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid));
-                                if (old_module_sp)
+                                StackFrame *frame = exe_ctx.GetFramePtr();
+                                if (frame)
                                 {
-                                    // The module has not yet created its symbol vendor, we can just
-                                    // give the existing target module the symfile path to use for
-                                    // when it decides to create it!
-                                    old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec());
-
-                                    // Provide feedback that the symfile has been successfully added.
-                                    const FileSpec &module_fs = old_module_sp->GetFileSpec();
-                                    result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n",
-                                                                   symfile_path, ss_symfile_uuid.GetData(),
-                                                                   module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString());
-
-                                    // Let clients know something changed in the module
-                                    // if it is currently loaded
-                                    ModuleList module_list;
-                                    module_list.Append (old_module_sp);
-                                    target->ModulesDidLoad (module_list);
-                                    flush = true;
+                                    ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
+                                    if (frame_module_sp)
+                                    {
+                                        if (frame_module_sp->GetPlatformFileSpec().Exists())
+                                        {
+                                            sym_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
+                                            sym_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
+                                        }
+                                        sym_spec.GetUUID() = frame_module_sp->GetUUID();
+                                        success = sym_spec.GetUUID().IsValid() || sym_spec.GetFileSpec();
+                                    }
+                                    else
+                                    {
+                                        result.AppendError ("frame has no module");
+                                        error_set = true;
+                                    }
                                 }
                                 else
                                 {
-                                    result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n",
-                                                                  symfile_path, ss_symfile_uuid.GetData(),
-                                                                  (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular)
-                                                                      ? "\n       please specify the full path to the symbol file"
-                                                                      : "");
-                                    break;
+                                    result.AppendError ("invalid current frame");
+                                    error_set = true;
                                 }
                             }
                             else
                             {
-                                result.AppendError ("one or more executable image paths must be specified");
-                                result.SetStatus (eReturnStatusFailed);
-                                break;
+                                result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
+                                error_set = true;
                             }
-                            result.SetStatus (eReturnStatusSuccessFinishResult);
                         }
                         else
                         {
-//                            sym_spec.GetSymbolFileSpec().Clear();
-//                            if (sym_spec.GetUUID().SetfromCString(symfile_path))
-//                            {
-//                                if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
-//                                {
-//                                    printf ("UUID: %s\n", symfile_path);
-//                                    printf ("objfile_spec: %s/%s\n",
-//                                            sym_spec.GetFileSpec().GetDirectory().GetCString(),
-//                                            sym_spec.GetFileSpec().GetFilename().GetCString());
-//                                    printf ("symfile_spec: %s/%s\n",
-//                                            sym_spec.GetSymbolFileSpec().GetDirectory().GetCString(),
-//                                            sym_spec.GetSymbolFileSpec().GetFilename().GetCString());
-//                                }
-//                            }
+                            result.AppendError ("a process must exist in order to use the --frame option");
+                            error_set = true;
+                        }
+                    }
+                    else
+                    {
+                        if (uuid_option_set)
+                        {
+                            sym_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
+                            success |= sym_spec.GetUUID().IsValid();
+                        }
+                        else if (file_option_set)
+                        {
+                            sym_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
+                            ModuleSP module_sp (target->GetImages().FindFirstModule(sym_spec));
+                            if (module_sp)
+                            {
+                                sym_spec.GetFileSpec() = module_sp->GetFileSpec();
+                                sym_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
+                                sym_spec.GetUUID() = module_sp->GetUUID();
+                                sym_spec.GetArchitecture() = module_sp->GetArchitecture();
+                            }
+                            else
+                            {
+                                sym_spec.GetArchitecture() = target->GetArchitecture();
+                            }
+                            success |= sym_spec.GetFileSpec().Exists();
+                        }
+                    }
+
+                    if (success)
+                    {
+                        if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
+                        {
+                            if (sym_spec.GetSymbolFileSpec())
+                                success = AddModuleSymbols (target, sym_spec.GetSymbolFileSpec(), flush, result);
+                        }
+                    }
+
+                    if (!success && !error_set)
+                    {
+                        StreamString error_strm;
+                        if (uuid_option_set)
+                        {
+                            error_strm.PutCString("unable to find debug symbols for UUID ");
+                            sym_spec.GetUUID().Dump (&error_strm);
+                        }
+                        else if (file_option_set)
+                        {
+                            error_strm.PutCString("unable to find debug symbols for the executable file ");
+                            error_strm << sym_spec.GetFileSpec();
+                        }
+                        else if (frame_option_set)
+                        {
+                            error_strm.PutCString("unable to find debug symbols for the current frame");                            
+                        }
+                        result.AppendError (error_strm.GetData());
+                    }
+                }
+                else
+                {
+                    result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
+                }
+            }
+            else
+            {
+                if (uuid_option_set)
+                {
+                    result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
+                }
+                else if (file_option_set)
+                {
+                    result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
+                }
+                else if (frame_option_set)
+                {
+                    result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
+                }
+                else
+                {
+                    PlatformSP platform_sp (target->GetPlatform());
+
+                    for (size_t i=0; i<argc; ++i)
+                    {
+                        const char *symfile_path = args.GetArgumentAtIndex(i);
+                        if (symfile_path)
+                        {
+                            FileSpec symfile_spec;
+                            sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
+                            if (platform_sp)
+                                platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec);
+                            else
+                                symfile_spec.SetFile(symfile_path, true);
                             
-                            char resolved_symfile_path[PATH_MAX];
-                            result.SetStatus (eReturnStatusFailed);
-                            if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
+                            ArchSpec arch;
+                            bool symfile_exists = symfile_spec.Exists();
+
+                            if (symfile_exists)
                             {
-                                if (strcmp (resolved_symfile_path, symfile_path) != 0)
-                                {
-                                    result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
+                                if (!AddModuleSymbols (target, symfile_spec, flush, result))
                                     break;
+                            }
+                            else
+                            {
+                                char resolved_symfile_path[PATH_MAX];
+                                if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
+                                {
+                                    if (strcmp (resolved_symfile_path, symfile_path) != 0)
+                                    {
+                                        result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
+                                        break;
+                                    }
                                 }
+                                result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
+                                break;
                             }
-                            result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
-                            break;
                         }
                     }
                 }
@@ -4179,6 +4295,12 @@
         return result.Succeeded();
     }
     
+    OptionGroupOptions m_option_group;
+    OptionGroupUUID m_uuid_option_group;
+    OptionGroupFile m_file_option;
+    OptionGroupBoolean m_current_frame_option;
+
+    
 };
 
 

Modified: lldb/trunk/source/Core/UUID.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/UUID.cpp?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/source/Core/UUID.cpp (original)
+++ lldb/trunk/source/Core/UUID.cpp Thu Sep 27 17:26:11 2012
@@ -128,47 +128,58 @@
 }
 
 size_t
-UUID::SetfromCString (const char *cstr)
+UUID::DecodeUUIDBytesFromCString (const char *p, ValueType &uuid_bytes, const char **end)
+{
+    size_t uuid_byte_idx = 0;
+    if (p)
+    {
+        while (*p)
+        {
+            if (isxdigit(p[0]) && isxdigit(p[1]))
+            {
+                int hi_nibble = xdigit_to_int(p[0]);
+                int lo_nibble = xdigit_to_int(p[1]);
+                // Translate the two hex nibble characters into a byte
+                uuid_bytes[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble;
+                
+                // Skip both hex digits
+                p += 2;
+                
+                // Increment the byte that we are decoding within the UUID value
+                // and break out if we are done
+                if (++uuid_byte_idx == 16)
+                    break;
+            }
+            else if (*p == '-')
+            {
+                // Skip dashes
+                p++;
+            }
+            else
+            {
+                // UUID values can only consist of hex characters and '-' chars
+                break;
+            }
+        }
+    }
+    if (end)
+        *end = p;
+    return uuid_byte_idx;
+}
+size_t
+UUID::SetFromCString (const char *cstr)
 {
     if (cstr == NULL)
         return 0;
 
-    uint32_t uuid_byte_idx = 0;
     const char *p = cstr;
 
     // Skip leading whitespace characters
     while (isspace(*p))
         ++p;
+    
+    const uint32_t uuid_byte_idx = UUID::DecodeUUIDBytesFromCString (p, m_uuid, &p);
 
-    // Try and decode a UUID
-    while (*p != '\0')
-    {
-        if (isxdigit(*p) && isxdigit(p[1]))
-        {
-            int hi_nibble = xdigit_to_int(p[0]);
-            int lo_nibble = xdigit_to_int(p[1]);
-            // Translate the two hex nibble characters into a byte
-            m_uuid[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble;
-
-            // Skip both hex digits
-            p += 2;
-
-            // Increment the byte that we are decoding within the UUID value
-            // and break out if we are done
-            if (++uuid_byte_idx == 16)
-                break;
-        }
-        else if (*p == '-')
-        {
-            // Skip dashes
-            p++;
-        }
-        else
-        {
-            // UUID values can only consist of hex characters and '-' chars
-            return 0;
-        }
-    }
     // If we successfully decoded a UUID, return the amount of characters that
     // were consumed
     if (uuid_byte_idx == 16)

Modified: lldb/trunk/source/Host/macosx/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Symbols.cpp?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Symbols.cpp (original)
+++ lldb/trunk/source/Host/macosx/Symbols.cpp Thu Sep 27 17:26:11 2012
@@ -585,6 +585,61 @@
 }
 
 
+static bool
+GetModuleSpecInfoFromUUIDDictionary (CFDictionaryRef uuid_dict, ModuleSpec &module_spec)
+{
+    bool success = false;
+    if (uuid_dict != NULL && CFGetTypeID (uuid_dict) == CFDictionaryGetTypeID ())
+    {
+        std::string str;
+        CFStringRef cf_str;
+        
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSymbolRichExecutable"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            if (CFCString::FileSystemRepresentation(cf_str, str))
+                module_spec.GetFileSpec().SetFile (str.c_str(), true);
+        }
+        
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGDSYMPath"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            if (CFCString::FileSystemRepresentation(cf_str, str))
+            {
+                module_spec.GetSymbolFileSpec().SetFile (str.c_str(), true);
+                success = true;
+            }
+        }
+        
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGArchitecture"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            if (CFCString::FileSystemRepresentation(cf_str, str))
+                module_spec.GetArchitecture().SetTriple(str.c_str());
+        }
+
+        std::string DBGBuildSourcePath;
+        std::string DBGSourcePath;
+
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGBuildSourcePath"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
+        }
+
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSourcePath"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
+        }
+        
+        if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty())
+        {
+            module_spec.GetSourceMappingList().Append (ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true);
+        }
+    }
+    return success;
+}
 
 
 bool
@@ -592,7 +647,8 @@
 {
     bool success = false;
     const UUID *uuid_ptr = module_spec.GetUUIDPtr();
-    if (uuid_ptr)
+    const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
+    if (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists()))
     {
         static bool g_located_dsym_for_uuid_exe = false;
         static bool g_dsym_for_uuid_exe_exists = false;
@@ -623,55 +679,80 @@
         }
         if (g_dsym_for_uuid_exe_exists)
         {
-            StreamString command;
             char uuid_cstr_buffer[64];
-            const char *uuid_cstr = uuid_ptr->GetAsCString(uuid_cstr_buffer, sizeof(uuid_cstr_buffer));
-            command.Printf("%s --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_cstr);
-            int exit_status = -1;
-            int signo = -1;
-            std::string command_output;
-            Error error = Host::RunShellCommand (command.GetData(),
-                                                 NULL,              // current working directory
-                                                 &exit_status,      // Exit status
-                                                 &signo,            // Signal int *
-                                                 &command_output,   // Command output
-                                                 30,                // Large timeout to allow for long dsym download times
-                                                 NULL);             // Don't run in a shell (we don't need shell expansion)
-            if (error.Success() && exit_status == 0 && !command_output.empty())
+            char file_path[PATH_MAX];
+            uuid_cstr_buffer[0] = '\0';
+            file_path[0] = '\0';
+            const char *uuid_cstr = NULL;
+
+            if (uuid_ptr)
+                uuid_cstr = uuid_ptr->GetAsCString(uuid_cstr_buffer, sizeof(uuid_cstr_buffer));
+
+            if (file_spec_ptr)
+                file_spec_ptr->GetPath(file_path, sizeof(file_path));
+            
+            StreamString command;
+            if (uuid_cstr)
+                command.Printf("%s --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_cstr);
+            else if (file_path && file_path[0])
+                command.Printf("%s --copyExecutable %s", g_dsym_for_uuid_exe_path, file_path);
+            
+            if (!command.GetString().empty())
             {
-                CFCData data (CFDataCreateWithBytesNoCopy (NULL,
-                                                           (const UInt8 *)command_output.data(),
-                                                           command_output.size(),
-                                                           kCFAllocatorNull));
-                
-                CFCReleaser<CFPropertyListRef> plist(::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL));
-                
-                if (CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
+                int exit_status = -1;
+                int signo = -1;
+                std::string command_output;
+                Error error = Host::RunShellCommand (command.GetData(),
+                                                     NULL,              // current working directory
+                                                     &exit_status,      // Exit status
+                                                     &signo,            // Signal int *
+                                                     &command_output,   // Command output
+                                                     30,                // Large timeout to allow for long dsym download times
+                                                     NULL);             // Don't run in a shell (we don't need shell expansion)
+                if (error.Success() && exit_status == 0 && !command_output.empty())
                 {
-                    std::string str;
-                    CFCString uuid_cfstr(uuid_cstr);
-                    CFTypeRef uuid_dict = CFDictionaryGetValue ((CFDictionaryRef) plist.get(), uuid_cfstr.get());
-                    if (uuid_dict != NULL && CFGetTypeID (uuid_dict) == CFDictionaryGetTypeID ())
+                    CFCData data (CFDataCreateWithBytesNoCopy (NULL,
+                                                               (const UInt8 *)command_output.data(),
+                                                               command_output.size(),
+                                                               kCFAllocatorNull));
+                    
+                    CFCReleaser<CFDictionaryRef> plist((CFDictionaryRef)::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL));
+                    
+                    if (CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
                     {
-                        CFStringRef cf_str;
-                        
-                        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSymbolRichExecutable"));
-                        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+                        if (uuid_cstr)
                         {
-                            if (CFCString::FileSystemRepresentation(cf_str, str))
-                            {
-                                success = true;
-                                module_spec.GetFileSpec().SetFile (str.c_str(), true);
-                            }
+                            CFCString uuid_cfstr(uuid_cstr);
+                            CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue (plist.get(), uuid_cfstr.get());
+                            success = GetModuleSpecInfoFromUUIDDictionary (uuid_dict, module_spec);
                         }
-    
-                        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGDSYMPath"));
-                        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+                        else
                         {
-                            if (CFCString::FileSystemRepresentation(cf_str, str))
+                            const CFIndex num_values = ::CFDictionaryGetCount(plist.get());
+                            if (num_values > 0)
                             {
-                                success = true;
-                                module_spec.GetSymbolFileSpec().SetFile (str.c_str(), true);
+                                std::vector<CFStringRef> keys (num_values, NULL);
+                                std::vector<CFDictionaryRef> values (num_values, NULL);
+                                ::CFDictionaryGetKeysAndValues(plist.get(), NULL, (const void **)&values[0]);
+                                if (num_values == 1)
+                                {
+                                    return GetModuleSpecInfoFromUUIDDictionary (values[0], module_spec);
+                                }
+                                else
+                                {
+                                    for (CFIndex i=0; i<num_values; ++i)
+                                    {
+                                        ModuleSpec curr_module_spec;
+                                        if (GetModuleSpecInfoFromUUIDDictionary (values[i], curr_module_spec))
+                                        {
+                                            if (module_spec.GetArchitecture() == curr_module_spec.GetArchitecture())
+                                            {
+                                                module_spec = curr_module_spec;
+                                                return true;
+                                            }
+                                        }
+                                    }
+                                }
                             }
                         }
                     }

Modified: lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp (original)
+++ lldb/trunk/source/Interpreter/OptionGroupBoolean.cpp Thu Sep 27 17:26:11 2012
@@ -21,20 +21,19 @@
                                         bool required,
                                         const char *long_option, 
                                         char short_option,
-                                        uint32_t completion_type,
-                                        lldb::CommandArgumentType argument_type,
                                         const char *usage_text,
-                                        bool default_value) :
+                                        bool default_value,
+                                        bool no_argument_toggle_default) :
     m_value (default_value, default_value)
 {
     m_option_definition.usage_mask = usage_mask;
     m_option_definition.required = required;
     m_option_definition.long_option = long_option;
     m_option_definition.short_option = short_option;
-    m_option_definition.option_has_arg = required_argument;
+    m_option_definition.option_has_arg = no_argument_toggle_default ? no_argument : required_argument;
     m_option_definition.enum_values = NULL;
-    m_option_definition.completion_type = completion_type;
-    m_option_definition.argument_type = argument_type;
+    m_option_definition.completion_type = 0;
+    m_option_definition.argument_type = eArgTypeBoolean;
     m_option_definition.usage_text = usage_text;
 }
 
@@ -47,7 +46,17 @@
                                     uint32_t option_idx,
                                     const char *option_arg)
 {
-    Error error (m_value.SetValueFromCString (option_arg));
+    Error error;
+    if (m_option_definition.option_has_arg == no_argument)
+    {
+        // Not argument, toggle the default value and mark the option as having been set
+        m_value.SetCurrentValue (!m_value.GetDefaultValue());
+        m_value.SetOptionWasSet ();
+    }
+    else
+    {
+        error = m_value.SetValueFromCString (option_arg);
+    }
     return error;
 }
 

Modified: lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp (original)
+++ lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp Thu Sep 27 17:26:11 2012
@@ -21,6 +21,35 @@
 using namespace lldb;
 using namespace lldb_private;
 
+
+OptionValueFileSpec::OptionValueFileSpec () :
+    OptionValue(),
+    m_current_value (),
+    m_default_value (),
+    m_data_sp(),
+    m_completion_mask (CommandCompletions::eDiskFileCompletion)
+{
+}
+
+OptionValueFileSpec::OptionValueFileSpec (const FileSpec &value) :
+    OptionValue(),
+    m_current_value (value),
+    m_default_value (value),
+    m_data_sp(),
+    m_completion_mask (CommandCompletions::eDiskFileCompletion)
+{
+}
+
+OptionValueFileSpec::OptionValueFileSpec (const FileSpec &current_value,
+                                          const FileSpec &default_value) :
+    OptionValue(),
+    m_current_value (current_value),
+    m_default_value (default_value),
+    m_data_sp(),
+    m_completion_mask (CommandCompletions::eDiskFileCompletion)
+{
+}
+
 void
 OptionValueFileSpec::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
 {
@@ -101,7 +130,7 @@
     word_complete = false;
     matches.Clear();
     CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
-                                                         CommandCompletions::eDiskFileCompletion,
+                                                         m_completion_mask,
                                                          s,
                                                          match_start_point,
                                                          max_return_elements,

Modified: lldb/trunk/source/Interpreter/OptionValueUUID.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionValueUUID.cpp?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/OptionValueUUID.cpp (original)
+++ lldb/trunk/source/Interpreter/OptionValueUUID.cpp Thu Sep 27 17:26:11 2012
@@ -13,7 +13,10 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
+#include "lldb/Core/Module.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -45,7 +48,7 @@
         case eVarSetOperationReplace:
         case eVarSetOperationAssign:
             {
-                if (m_uuid.SetfromCString(value_cstr) == 0)
+                if (m_uuid.SetFromCString(value_cstr) == 0)
                     error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value_cstr);
                 else
                     m_value_was_set = true;
@@ -68,3 +71,50 @@
 {
     return OptionValueSP(new OptionValueUUID(*this));
 }
+
+size_t
+OptionValueUUID::AutoComplete (CommandInterpreter &interpreter,
+                               const char *s,
+                               int match_start_point,
+                               int max_return_elements,
+                               bool &word_complete,
+                               StringList &matches)
+{
+    word_complete = false;
+    matches.Clear();
+    ExecutionContext exe_ctx(interpreter.GetExecutionContext());
+    Target *target = exe_ctx.GetTargetPtr();
+    if (target)
+    {
+        const size_t num_modules = target->GetImages().GetSize();
+        if (num_modules > 0)
+        {
+            char uuid_cstr[64];
+            UUID::ValueType uuid_bytes;
+            const size_t num_bytes_decoded = UUID::DecodeUUIDBytesFromCString(s, uuid_bytes, NULL);
+            for (size_t i=0; i<num_modules; ++i)
+            {
+                ModuleSP module_sp (target->GetImages().GetModuleAtIndex(i));
+                if (module_sp)
+                {
+                    const UUID &module_uuid = module_sp->GetUUID();
+                    if (module_uuid.IsValid())
+                    {
+                        bool add_uuid = false;
+                        if (num_bytes_decoded == 0)
+                            add_uuid = true;
+                        else
+                            add_uuid = ::memcmp(module_uuid.GetBytes(), uuid_bytes, num_bytes_decoded) == 0;
+                        if (add_uuid)
+                        {
+                            if (module_uuid.GetAsCString(uuid_cstr, sizeof(uuid_cstr)))
+                                matches.AppendString(uuid_cstr);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return matches.GetSize();
+}
+

Modified: lldb/trunk/source/Interpreter/Property.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Property.cpp?rev=164806&r1=164805&r2=164806&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/Property.cpp (original)
+++ lldb/trunk/source/Interpreter/Property.cpp Thu Sep 27 17:26:11 2012
@@ -148,7 +148,7 @@
         {
             UUID uuid;
             if (definition.default_cstr_value)
-                uuid.SetfromCString (definition.default_cstr_value);
+                uuid.SetFromCString (definition.default_cstr_value);
             m_value_sp.reset (new OptionValueUUID(uuid));
         }
             break;





More information about the lldb-commits mailing list