[Lldb-commits] [lldb] r110624 - in /lldb/trunk: include/lldb/Core/ include/lldb/Host/ include/lldb/Symbol/ include/lldb/Target/ source/Commands/ source/Core/ source/Host/macosx/ source/Plugins/DynamicLoader/MacOSX-DYLD/ source/Plugins/ObjectContainer/Universal-Mach-O/ source/Plugins/ObjectFile/ELF/ source/Plugins/ObjectFile/Mach-O/ source/Plugins/Process/MacOSX-User/source/ source/Plugins/Process/gdb-remote/ source/Symbol/ source/Target/

Jim Ingham jingham at apple.com
Mon Aug 9 16:31:02 PDT 2010


Author: jingham
Date: Mon Aug  9 18:31:02 2010
New Revision: 110624

URL: http://llvm.org/viewvc/llvm-project?rev=110624&view=rev
Log:
Change Target & Process so they can really be initialized with an invalid architecture. 
Arrange that this then gets properly set on attach, or when a "file" is set.
Add a completer for "process attach -n".

Caveats: there isn't currently a way to handle multiple processes with the same name.  That
will have to wait on a way to pass annotations along with the completion strings.


Modified:
    lldb/trunk/include/lldb/Core/Module.h
    lldb/trunk/include/lldb/Host/Host.h
    lldb/trunk/include/lldb/Symbol/ObjectFile.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/source/Commands/CommandObjectFile.cpp
    lldb/trunk/source/Commands/CommandObjectProcess.cpp
    lldb/trunk/source/Core/Module.cpp
    lldb/trunk/source/Host/macosx/Host.mm
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
    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/Symbol/ObjectFile.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/StopInfo.cpp
    lldb/trunk/source/Target/Target.cpp
    lldb/trunk/source/Target/TargetList.cpp

Modified: lldb/trunk/include/lldb/Core/Module.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Module.h?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Module.h (original)
+++ lldb/trunk/include/lldb/Core/Module.h Mon Aug  9 18:31:02 2010
@@ -13,6 +13,7 @@
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/UUID.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Host/Mutex.h"
 #include "lldb/Host/TimeValue.h"
 #include "lldb/Symbol/CompileUnit.h"
@@ -46,6 +47,7 @@
 {
 public:
     friend class ModuleList;
+    friend bool ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch);
 
     enum
     {
@@ -343,6 +345,16 @@
 
     const TimeValue &
     GetModificationTime () const;
+   
+    //------------------------------------------------------------------
+    /// Tells whether this module is capable of being the main executable
+    /// for a process.
+    ///
+    /// @return
+    ///     \b true if it is, \b false otherwise.
+    //------------------------------------------------------------------
+    bool
+    IsExecutable ();
 
     //------------------------------------------------------------------
     /// Get the number of compile units for this module.
@@ -547,7 +559,7 @@
     //------------------------------------------------------------------
     mutable Mutex               m_mutex;        ///< A mutex to keep this object happy in multi-threaded environments.
     TimeValue                   m_mod_time;     ///< The modification time for this module when it was created.
-    const ArchSpec              m_arch;         ///< The architecture for this module.
+    ArchSpec                    m_arch;         ///< The architecture for this module.
     UUID                        m_uuid;         ///< Each module is assumed to have a unique identifier to help match it up to debug symbols.
     FileSpec                    m_file;         ///< The file representation on disk for this module (if there is one).
     Flags                       m_flags;        ///< Flags for this module to track what has been parsed already.
@@ -592,7 +604,9 @@
     ResolveSymbolContextForAddress (lldb::addr_t vm_addr, bool vm_addr_is_file_addr, uint32_t resolve_scope, Address& so_addr, SymbolContext& sc);
 
     void SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list);
-
+    
+    bool SetArchitecture (const ArchSpec &new_arch);
+    
 private:
 
     DISALLOW_COPY_AND_ASSIGN (Module);

Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Mon Aug  9 18:31:02 2010
@@ -13,6 +13,7 @@
 
 
 #include "lldb/lldb-private.h"
+#include "lldb/Core/StringList.h"
 
 namespace lldb_private {
 
@@ -273,6 +274,16 @@
 
     static bool
     ResolveExecutableInBundle (FileSpec *file);
+    
+    static uint32_t
+    ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids);
+    
+    static ArchSpec
+    GetArchSpecForExistingProcess (lldb::pid_t pid);
+    
+    static ArchSpec
+    GetArchSpecForExistingProcess (const char *process_name);
+
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Mon Aug  9 18:31:02 2010
@@ -51,6 +51,8 @@
     public PluginInterface,
     public ModuleChild
 {
+friend class lldb_private::Module;
+
 public:
     //------------------------------------------------------------------
     /// Construct with a parent module, offset, and header data.
@@ -159,7 +161,17 @@
     //------------------------------------------------------------------
     virtual uint32_t
     GetDependentModules (FileSpecList& file_list) = 0;
-
+    
+    //------------------------------------------------------------------
+    /// Tells whether this object file is capable of being the main executable
+    /// for a process.
+    ///
+    /// @return
+    ///     \b true if it is, \b false otherwise.
+    //------------------------------------------------------------------
+    virtual bool
+    IsExecutable () const = 0;
+    
     //------------------------------------------------------------------
     /// Returns the offset into a file at which this object resides.
     ///
@@ -290,6 +302,20 @@
     lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory
     lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined).
     DataExtractor m_data; ///< The data for this object file so things can be parsed lazily.
+    
+    //------------------------------------------------------------------
+    /// Sets the architecture for a module.  At present the architecture
+    /// can only be set if it is invalid.  It is not allowed to switch from
+    /// one concrete architecture to another.
+    /// 
+    /// @param[in] new_arch
+    ///     The architecture this module will be set to.
+    ///
+    /// @return
+    ///     Returns \b true if the architecture was changed, \b
+    ///     false otherwise.
+    //------------------------------------------------------------------
+    bool SetModulesArchitecture (const ArchSpec &new_arch);
 
 private:
     DISALLOW_COPY_AND_ASSIGN (ObjectFile);

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Mon Aug  9 18:31:02 2010
@@ -20,6 +20,7 @@
 #include "lldb/Core/Broadcaster.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Event.h"
+#include "lldb/Core/StringList.h"
 #include "lldb/Core/ThreadSafeValue.h"
 #include "lldb/Core/ThreadSafeSTLMap.h"
 #include "lldb/Core/PluginInterface.h"
@@ -313,6 +314,58 @@
     //------------------------------------------------------------------
     virtual Error
     Attach (const char *process_name, bool wait_for_launch);
+    
+    //------------------------------------------------------------------
+    /// List the processes matching the given partial name.
+    ///
+    /// FIXME: Is it too heavyweight to create an entire process object to do this?
+    /// The problem is for remote processes we're going to have to set up the same transport
+    /// to get this data as to actually attach.  So we need to factor out transport
+    /// and process before we can do this separately from the process.
+    ///
+    /// @param[in] name
+    ///     A partial name to match against the current process list.
+    ///
+    /// @param[out] matches
+    ///     The list of process names matching \a name.
+    ///
+    /// @param[in] pids
+    ///     A vector filled with the pids that correspond to the names in \a matches.
+    ///
+    /// @return
+    ///     Returns the number of matching processes.
+    //------------------------------------------------------------------
+
+    virtual uint32_t
+    ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids);
+    
+    //------------------------------------------------------------------
+    /// Find the architecture of a process by pid.
+    ///
+    /// FIXME: See comment for ListProcessesMatchingName.
+    ///
+    /// @param[in] pid
+    ///     A pid to inspect.
+    ///
+    /// @return
+    ///     Returns the architecture of the process or an invalid architecture if the process can't be found.
+    //------------------------------------------------------------------
+    virtual ArchSpec
+    GetArchSpecForExistingProcess (lldb::pid_t pid);
+    
+    //------------------------------------------------------------------
+    /// Find the architecture of a process by name.
+    ///
+    /// FIXME: See comment for ListProcessesMatchingName.
+    ///
+    /// @param[in] process_name
+    ///     The process name to inspect.
+    ///
+    /// @return
+    ///     Returns the architecture of the process or an invalid architecture if the process can't be found.
+    //------------------------------------------------------------------
+    virtual ArchSpec
+    GetArchSpecForExistingProcess (const char *process_name);
 
     uint32_t
     GetAddressByteSize();

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Mon Aug  9 18:31:02 2010
@@ -253,6 +253,27 @@
 
     ArchSpec
     GetArchitecture () const;
+    
+    //------------------------------------------------------------------
+    /// Set the architecture for this target.
+    ///
+    /// If the current target has no Images read in, then this just sets the architecture, which will
+    /// be used to select the architecture of the ExecutableModule when that is set.
+    /// If the current target has an ExecutableModule, then calling SetArchitecture with a different
+    /// architecture from the currently selected one will reset the ExecutableModule to that slice
+    /// of the file backing the ExecutableModule.  If the file backing the ExecutableModule does not
+    /// contain a fork of this architecture, then this code will return false, and the architecture
+    /// won't be changed.
+    /// If the input arch_spec is the same as the already set architecture, this is a no-op.
+    ///
+    /// @param[in] arch_spec
+    ///     The new architecture.
+    ///
+    /// @return
+    ///     \b true if the architecture was successfully set, \bfalse otherwise.
+    //------------------------------------------------------------------
+    bool
+    SetArchitecture (const ArchSpec &arch_spec);
 
     Debugger &
     GetDebugger ()
@@ -300,6 +321,7 @@
     // Member variables.
     //------------------------------------------------------------------
     Debugger &      m_debugger;
+    ArchSpec        m_arch_spec;
     ModuleList      m_images;           ///< The list of images for this process (shared libraries and anything dynamically loaded).
     BreakpointList  m_breakpoint_list;
     BreakpointList  m_internal_breakpoint_list;

Modified: lldb/trunk/source/Commands/CommandObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFile.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFile.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFile.cpp Mon Aug  9 18:31:02 2010
@@ -126,31 +126,14 @@
 
         TargetSP target_sp;
 
-        ArchSpec arch;
-        if (m_options.m_arch.IsValid())
-            arch = m_options.m_arch;
-        else
-        {
-            arch = lldb_private::GetDefaultArchitecture ();
-            if (!arch.IsValid())
-                arch = LLDB_ARCH_DEFAULT;
-        }
+        ArchSpec arch = m_options.m_arch;
         Debugger &debugger = interpreter.GetDebugger();
-        Error error = debugger.GetTargetList().CreateTarget (debugger, file_spec, arch, NULL, true, target_sp);
-
-        if (error.Fail() && !m_options.m_arch.IsValid())
-        {
-            if (arch == LLDB_ARCH_DEFAULT_32BIT)
-                arch = LLDB_ARCH_DEFAULT_64BIT;
-            else
-                arch = LLDB_ARCH_DEFAULT_32BIT;
-            error = debugger.GetTargetList().CreateTarget (debugger, file_spec, arch, NULL, true, target_sp);
-        }
+        Error error = debugger.GetTargetList().CreateTarget (debugger, file_spec, m_options.m_arch, NULL, true, target_sp);
 
         if (target_sp)
         {
             debugger.GetTargetList().SetCurrentTarget(target_sp.get());
-            result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, arch.AsCString());
+            result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().AsCString());
             result.SetStatus (eReturnStatusSuccessFinishNoResult);
         }
         else

Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Mon Aug  9 18:31:02 2010
@@ -279,110 +279,6 @@
 {
 public:
 
-    CommandObjectProcessAttach () :
-        CommandObject ("process attach",
-                       "Attaches to a process.",
-                       "process attach <cmd-options>")
-    {
-        SetHelpLong("Currently, you must set the executable file before you can attach "
-                    "to a process.\n");
-    }
-
-    ~CommandObjectProcessAttach ()
-    {
-    }
-
-    bool
-    Execute (CommandInterpreter &interpreter,
-             Args& command,
-             CommandReturnObject &result)
-    {
-        Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
-        if (target == NULL)
-        {
-            result.AppendError ("invalid target, set executable file using 'file' command");
-            result.SetStatus (eReturnStatusFailed);
-            return false;
-        }
-
-        // If our listener is NULL, users aren't allows to launch
-
-        Process *process = interpreter.GetDebugger().GetExecutionContext().process;
-        if (process)
-        {
-            if (process->IsAlive())
-            {
-                result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", process->GetID());
-                result.SetStatus (eReturnStatusFailed);
-                return false;
-            }
-        }
-
-        if (command.GetArgumentCount())
-        {
-            result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
-            result.SetStatus (eReturnStatusFailed);
-        }
-        else
-        {
-            const char *plugin_name = NULL;
-            
-            if (!m_options.plugin_name.empty())
-                plugin_name = m_options.plugin_name.c_str();
-
-            process = target->CreateProcess (interpreter.GetDebugger().GetListener(), plugin_name).get();
-
-            if (process)
-            {
-                Error error;
-                int attach_pid = m_options.pid;
-
-                if (attach_pid != LLDB_INVALID_PROCESS_ID)
-                {
-                    error = process->Attach (attach_pid);
-                    if (error.Success())
-                    {
-                        result.SetStatus (eReturnStatusSuccessContinuingNoResult);
-                    }
-                    else
-                    {
-                        result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 
-                                                     attach_pid, 
-                                                     error.AsCString());
-                        result.SetStatus (eReturnStatusFailed);
-                    }
-                }
-                else if (!m_options.name.empty())
-                {
-                    error = process->Attach (m_options.name.c_str(), m_options.waitfor);
-                    if (error.Success())
-                    {
-                        result.SetStatus (eReturnStatusSuccessContinuingNoResult);
-                    }
-                    else
-                    {
-                        if (m_options.waitfor)
-                            result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 
-                                                         m_options.name.c_str(),
-                                                         error.AsCString());
-                        else
-                            result.AppendErrorWithFormat ("Failed to a process named '%s': %s\n", 
-                                                         m_options.name.c_str(),
-                                                         error.AsCString());
-                        result.SetStatus (eReturnStatusFailed);
-                    }
-                }
-            }
-        }
-        return result.Succeeded();
-    }
-    
-    Options *
-    GetOptions ()
-    {
-        return &m_options;
-    }
-
     class CommandOptions : public Options
     {
     public:
@@ -448,6 +344,68 @@
             return g_option_table;
         }
 
+        virtual bool
+        HandleOptionArgumentCompletion (CommandInterpreter &interpreter,
+                                        Args &input,
+                                        int cursor_index,
+                                        int char_pos,
+                                        OptionElementVector &opt_element_vector,
+                                        int opt_element_index,
+                                        int match_start_point,
+                                        int max_return_elements,
+                                        bool &word_complete,
+                                        StringList &matches)
+        {
+            int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
+            int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
+    
+            // We are only completing the name option for now...
+            
+            const lldb::OptionDefinition *opt_defs = GetDefinitions();
+            if (opt_defs[opt_defs_index].short_option == 'n')
+            {
+                // Are we in the name?
+                
+                // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
+                // use the default plugin.
+                Process *process = interpreter.GetDebugger().GetExecutionContext().process;
+                bool need_to_delete_process = false;
+                
+                const char *partial_name = NULL;
+                partial_name = input.GetArgumentAtIndex(opt_arg_pos);
+                
+                if (process && process->IsAlive())
+                    return true;
+                    
+                Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
+                if (target == NULL)
+                {
+                    // No target has been set yet, for now do host completion.  Otherwise I don't know how we would
+                    // figure out what the right target to use is...
+                    std::vector<lldb::pid_t> pids;
+                    Host::ListProcessesMatchingName (partial_name, matches, pids);
+                    return true;
+                }
+                if (!process)
+                {
+                    process = target->CreateProcess (interpreter.GetDebugger().GetListener(), partial_name).get();
+                    need_to_delete_process = true;
+                }
+                
+                if (process)
+                {
+                    matches.Clear();
+                    std::vector<lldb::pid_t> pids;
+                    process->ListProcessesMatchingName (NULL, matches, pids);
+                    if (need_to_delete_process)
+                        target->DeleteCurrentProcess();
+                    return true;
+                }
+            }
+            
+            return false;
+        }
+
         // Options table: Required for subclasses of Options.
 
         static lldb::OptionDefinition g_option_table[];
@@ -460,6 +418,211 @@
         bool waitfor;
     };
 
+    CommandObjectProcessAttach () :
+        CommandObject ("process attach",
+                       "Attaches to a process.",
+                       "process attach <cmd-options>")
+    {
+        SetHelpLong("Currently, you must set the executable file before you can attach "
+                    "to a process.\n");
+    }
+
+    ~CommandObjectProcessAttach ()
+    {
+    }
+
+    bool
+    Execute (CommandInterpreter &interpreter,
+             Args& command,
+             CommandReturnObject &result)
+    {
+        Target *target = interpreter.GetDebugger().GetCurrentTarget().get();
+
+        Process *process = interpreter.GetDebugger().GetExecutionContext().process;
+        if (process)
+        {
+            if (process->IsAlive())
+            {
+                result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", 
+                                              process->GetID());
+                result.SetStatus (eReturnStatusFailed);
+                return false;
+            }
+        }
+
+        if (target == NULL)
+        {
+            // If there isn't a current target create one.
+            TargetSP new_target_sp;
+            FileSpec emptyFileSpec;
+            ArchSpec emptyArchSpec;
+            Error error;
+            
+            error = interpreter.GetDebugger().GetTargetList().CreateTarget(interpreter.GetDebugger(), 
+                                                                           emptyFileSpec,
+                                                                           emptyArchSpec, 
+                                                                           NULL, 
+                                                                           false,
+                                                                           new_target_sp);
+            target = new_target_sp.get();
+            if (target == NULL || error.Fail())
+            {
+                result.AppendError(error.AsCString("Error creating empty target"));
+                return false;
+            }
+            interpreter.GetDebugger().GetTargetList().SetCurrentTarget(target);
+        }
+        
+        // Record the old executable module, we want to issue a warning if the process of attaching changed the
+        // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
+         
+        ModuleSP old_exec_module_sp = target->GetExecutableModule();
+        ArchSpec old_arch_spec = target->GetArchitecture();
+
+        if (command.GetArgumentCount())
+        {
+            result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
+            result.SetStatus (eReturnStatusFailed);
+        }
+        else
+        {
+            const char *plugin_name = NULL;
+            
+            if (!m_options.plugin_name.empty())
+                plugin_name = m_options.plugin_name.c_str();
+
+            process = target->CreateProcess (interpreter.GetDebugger().GetListener(), plugin_name).get();
+
+            if (process)
+            {
+                Error error;
+                int attach_pid = m_options.pid;
+                
+                // If we are waiting for a process with this name to show up, do that first.
+                if (m_options.waitfor)
+                {
+                    if (m_options.name.empty())
+                    {
+                        result.AppendError("Invalid arguments: must supply a process name with the waitfor option.\n");
+                        result.SetStatus (eReturnStatusFailed);
+                        return false;
+                    }
+                    else
+                    {
+                        error = process->Attach (m_options.name.c_str(), m_options.waitfor);
+                        if (error.Success())
+                        {
+                            result.SetStatus (eReturnStatusSuccessContinuingNoResult);
+                        }
+                        else
+                        {
+                            result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", 
+                                                             m_options.name.c_str(),
+                                                             error.AsCString());
+                            result.SetStatus (eReturnStatusFailed);
+                            return false;                
+                        }
+                    }
+                }
+                else
+                {
+                    // If the process was specified by name look it up, so we can warn if there are multiple
+                    // processes with this pid.
+                    
+                    if (attach_pid == LLDB_INVALID_PROCESS_ID && !m_options.name.empty())
+                    {
+                        std::vector<lldb::pid_t> pids;
+                        StringList matches;
+                        
+                        process->ListProcessesMatchingName(m_options.name.c_str(), matches, pids);
+                        if (matches.GetSize() > 1)
+                        {
+                            result.AppendErrorWithFormat("More than one process named %s\n", m_options.name.c_str());
+                            result.SetStatus (eReturnStatusFailed);
+                            return false;
+                        }
+                        else if (matches.GetSize() == 0)
+                        {
+                            result.AppendErrorWithFormat("Could not find a process named %s\n", m_options.name.c_str());
+                            result.SetStatus (eReturnStatusFailed);
+                            return false;
+                        }
+                        else 
+                        {
+                            attach_pid = pids[0];
+                        }
+
+                    }
+
+                    if (attach_pid != LLDB_INVALID_PROCESS_ID)
+                    {
+                        error = process->Attach (attach_pid);
+                        if (error.Success())
+                        {
+                            result.SetStatus (eReturnStatusSuccessContinuingNoResult);
+                        }
+                        else
+                        {
+                            result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", 
+                                                         attach_pid, 
+                                                         error.AsCString());
+                            result.SetStatus (eReturnStatusFailed);
+                        }
+                    }
+                    else
+                    {
+                        result.AppendErrorWithFormat ("No PID specified for attach\n", 
+                                                         attach_pid, 
+                                                         error.AsCString());
+                        result.SetStatus (eReturnStatusFailed);
+                    
+                    }
+                }
+            }
+        }
+        
+        if (result.Succeeded())
+        {
+            // Okay, we're done.  Last step is to warn if the executable module has changed:
+            if (!old_exec_module_sp)
+            {
+                char new_path[PATH_MAX + 1];
+                target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX);
+                
+                result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
+                    new_path);
+            }
+            else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec())
+            {
+                char old_path[PATH_MAX + 1];
+                char new_path[PATH_MAX + 1];
+                
+                old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
+                target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX);
+                
+                result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
+                                                    old_path, new_path);
+            }
+            
+            if (!old_arch_spec.IsValid())
+            {
+                result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString());
+            }
+            else if (old_arch_spec != target->GetArchitecture())
+            {
+                result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", 
+                                                old_arch_spec.AsCString(), target->GetArchitecture().AsCString());
+            }
+        }
+        return result.Succeeded();
+    }
+    
+    Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+
 protected:
 
     CommandOptions m_options;

Modified: lldb/trunk/source/Core/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Core/Module.cpp (original)
+++ lldb/trunk/source/Core/Module.cpp Mon Aug  9 18:31:02 2010
@@ -43,7 +43,6 @@
                      m_object_name.IsEmpty() ? "" : "(",
                      m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
                      m_object_name.IsEmpty() ? "" : ")");
-
 }
 
 Module::~Module()
@@ -516,3 +515,30 @@
 {
     return m_mod_time;
 }
+
+bool
+Module::IsExecutable ()
+{
+    if (GetObjectFile() == NULL)
+        return false;
+    else
+        return GetObjectFile()->IsExecutable();
+}
+
+bool 
+Module::SetArchitecture (const ArchSpec &new_arch)
+{
+    if (m_arch == new_arch)
+        return true;
+    else if (!m_arch.IsValid())
+    {
+        m_arch = new_arch;
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+
+}
+

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Mon Aug  9 18:31:02 2010
@@ -15,6 +15,8 @@
 #include <stddef.h>
 #include <sys/sysctl.h>
 #include <unistd.h>
+#include <libproc.h>
+#include <sys/proc_info.h>
 
 #include <map>
 #include <string>
@@ -802,3 +804,86 @@
     }
 }
 
+uint32_t
+Host::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
+{
+
+    int num_pids;
+    int size_of_pids;
+    int *pid_list;
+    uint32_t num_matches = 0;
+    
+    size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
+    if (size_of_pids == -1)
+        return 0;
+        
+    num_pids = size_of_pids/sizeof(int);
+    pid_list = (int *) malloc(size_of_pids);
+    size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, pid_list, size_of_pids);
+    if (size_of_pids == -1)
+        return 0;
+        
+    pid_t our_pid = getpid();
+    
+    for (int i = 0; i < num_pids; i++)
+    {
+        struct proc_bsdinfo bsd_info;
+        int error = proc_pidinfo (pid_list[i], PROC_PIDTBSDINFO, (uint64_t) 0, &bsd_info, PROC_PIDTBSDINFO_SIZE);
+        if (error == 0)
+            continue;
+        
+        // Don't offer to attach to zombie processes, already traced or exiting
+        // processes, and of course, ourselves...  It looks like passing the second arg of
+        // 0 to proc_listpids will exclude zombies anyway, but that's not documented so...
+        if ((bsd_info.pbi_flags & (PROC_FLAG_TRACED | PROC_FLAG_INEXIT) != 0)
+             || (bsd_info.pbi_status == SZOMB)
+             || (bsd_info.pbi_pid == our_pid))
+             continue;
+        char pid_name[MAXCOMLEN * 2 + 1];
+        int name_len;
+        name_len = proc_name(bsd_info.pbi_pid, pid_name, MAXCOMLEN * 2);
+        if (name_len == 0)
+            continue;
+        
+        if (strstr(pid_name, name) != pid_name)
+            continue;
+        matches.AppendString (pid_name);
+        pids.push_back (bsd_info.pbi_pid);
+        num_matches++;        
+    }
+    
+    return num_matches;
+}
+
+ArchSpec
+Host::GetArchSpecForExistingProcess (lldb::pid_t pid)
+{
+    ArchSpec return_spec;
+    
+    struct proc_bsdinfo bsd_info;
+    int error = proc_pidinfo (pid, PROC_PIDTBSDINFO, (uint64_t) 0, &bsd_info, PROC_PIDTBSDINFO_SIZE);
+    if (error == 0)
+        return return_spec;
+    if (bsd_info.pbi_flags & PROC_FLAG_LP64)
+        return_spec.SetArch(LLDB_ARCH_DEFAULT_64BIT);
+    else 
+        return_spec.SetArch(LLDB_ARCH_DEFAULT_32BIT);
+        
+    return return_spec;
+}
+
+ArchSpec
+Host::GetArchSpecForExistingProcess (const char *process_name)
+{
+    ArchSpec returnSpec;
+    StringList matches;
+    std::vector<lldb::pid_t> pids;
+    if (ListProcessesMatchingName(process_name, matches, pids))
+    {
+        if (matches.GetSize() == 1)
+        {
+            return GetArchSpecForExistingProcess(pids[0]);
+        }
+    }
+    return returnSpec;
+}

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Mon Aug  9 18:31:02 2010
@@ -1016,8 +1016,7 @@
     return m_break_id != LLDB_INVALID_BREAK_ID;
 }
 
-//----------------------------------------------------------------------Target.h
-
+//----------------------------------------------------------------------
 // Member function that gets called when the process state changes.
 //----------------------------------------------------------------------
 void

Modified: lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp Mon Aug  9 18:31:02 2010
@@ -199,7 +199,18 @@
 ObjectContainerUniversalMachO::GetObjectFile (const FileSpec *file)
 {
     uint32_t arch_idx = 0;
-    const ArchSpec arch = m_module->GetArchitecture();
+    ArchSpec arch;
+    // If the module hasn't specified an architecture yet, set it to the default 
+    // architecture:
+    if (!m_module->GetArchitecture().IsValid())
+    {
+        arch = lldb_private::GetDefaultArchitecture ();
+        if (!arch.IsValid())
+            arch = LLDB_ARCH_DEFAULT;
+    }
+    else
+        arch = m_module->GetArchitecture();
+        
     ArchSpec curr_arch;
     for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
     {

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Mon Aug  9 18:31:02 2010
@@ -145,6 +145,13 @@
 {
 }
 
+bool
+ObjectFileELF::IsExecutable() const
+{
+    // FIXME: How is this marked in ELF?
+    return false;
+}
+
 ByteOrder
 ObjectFileELF::GetByteOrder() const
 {

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Mon Aug  9 18:31:02 2010
@@ -86,6 +86,9 @@
     virtual lldb::ByteOrder
     GetByteOrder() const;
 
+    virtual bool
+    IsExecutable () const;
+
     virtual size_t
     GetAddressByteSize() const;
 

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Mon Aug  9 18:31:02 2010
@@ -161,7 +161,8 @@
         m_data.GetU32(&offset, &m_header.cputype, 6);
 
         ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
-        if (mach_arch == m_module->GetArchitecture())
+        
+        if (SetModulesArchitecture (mach_arch))
         {
             // Read in all only the load command data
             DataBufferSP data_sp(m_file.ReadFileContents(m_offset, m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic)));
@@ -184,6 +185,11 @@
     return m_data.GetByteOrder ();
 }
 
+bool
+ObjectFileMachO::IsExecutable() const
+{
+    return m_header.filetype == HeaderFileTypeExecutable;
+}
 
 size_t
 ObjectFileMachO::GetAddressByteSize () const

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Mon Aug  9 18:31:02 2010
@@ -66,6 +66,9 @@
 
     virtual lldb::ByteOrder
     GetByteOrder () const;
+    
+    virtual bool
+    IsExecutable () const;
 
     virtual size_t
     GetAddressByteSize ()  const;

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=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp Mon Aug  9 18:31:02 2010
@@ -2208,5 +2208,10 @@
     }
 }
 
+uint32_t
+ProcessMacOSX::ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids)
+{
+    return Host::ListProcessesMatchingName (name, matches, pids);
+}
 
 

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=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h Mon Aug  9 18:31:02 2010
@@ -18,6 +18,7 @@
 // Other libraries and framework includes
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/ThreadSafeValue.h"
+#include "lldb/Core/StringList.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Thread.h"
 
@@ -110,6 +111,9 @@
 
     virtual void
     DidAttach ();
+    
+    virtual uint32_t
+    ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids);
 
     //------------------------------------------------------------------
     // PluginInterface protocol

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=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Mon Aug  9 18:31:02 2010
@@ -93,7 +93,8 @@
     ModuleSP exe_module_sp(target.GetExecutableModule());
     if (exe_module_sp.get())
         return exe_module_sp->GetFileSpec().Exists();
-    return false;
+    // However, if there is no executable module, we return true since we might be preparing to attach.
+    return true;
 }
 
 //----------------------------------------------------------------------
@@ -106,7 +107,6 @@
     m_stdio_communication ("gdb-remote.stdio"),
     m_stdio_mutex (Mutex::eMutexTypeRecursive),
     m_stdout_data (),
-    m_arch_spec (),
     m_byte_order (eByteOrderHost),
     m_gdb_comm(),
     m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
@@ -124,7 +124,8 @@
     m_max_memory_size (512),
     m_libunwind_target_type (UNW_TARGET_UNSPECIFIED),
     m_libunwind_addr_space (NULL),
-    m_waiting_for_attach (false)
+    m_waiting_for_attach (false),
+    m_local_debugserver (true)
 {
 }
 
@@ -563,11 +564,9 @@
     {
         m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS;
 
-        Module * exe_module = GetTarget().GetExecutableModule ().get();
+        Module * exe_module = GetTarget().GetExecutableModule ().get();        
         assert(exe_module);
 
-        m_arch_spec = exe_module->GetArchitecture();
-
         ObjectFile *exe_objfile = exe_module->GetObjectFile();
         assert(exe_objfile);
 
@@ -580,8 +579,9 @@
         // See if the GDB server supports the qHostInfo information
         const char *vendor = m_gdb_comm.GetVendorString().AsCString();
         const char *os_type = m_gdb_comm.GetOSString().AsCString();
+        ArchSpec arch_spec = GetTarget().GetArchitecture();
         
-        if (m_arch_spec.IsValid() && m_arch_spec == ArchSpec ("arm"))
+        if (arch_spec.IsValid() && arch_spec == ArchSpec ("arm"))
         {
             // For ARM we can't trust the arch of the process as it could
             // have an armv6 object file, but be running on armv7 kernel.
@@ -589,7 +589,7 @@
         }
         
         if (!inferior_arch.IsValid())
-            inferior_arch = m_arch_spec;
+            inferior_arch = arch_spec;
 
         if (vendor == NULL)
             vendor = Host::GetVendorString().AsCString("apple");
@@ -622,11 +622,11 @@
     Error error;
     // Clear out and clean up from any current state
     Clear();
-    // HACK: require arch be set correctly at the target level until we can
-    // figure out a good way to determine the arch of what we are attaching to
-    m_arch_spec = m_target.GetArchitecture();
-
+    ArchSpec arch_spec = GetTarget().GetArchitecture();
+    
     //Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
+    
+    
     if (attach_pid != LLDB_INVALID_PROCESS_ID)
     {
         SetPrivateState (eStateAttaching);
@@ -638,7 +638,7 @@
                                          NULL,
                                          LLDB_INVALID_PROCESS_ID,
                                          NULL, false,
-                                         m_arch_spec);
+                                         arch_spec);
         
         if (error.Fail())
         {
@@ -724,7 +724,6 @@
     Clear();
     // HACK: require arch be set correctly at the target level until we can
     // figure out a good way to determine the arch of what we are attaching to
-    m_arch_spec = m_target.GetArchitecture();
 
     //Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
     if (process_name && process_name[0])
@@ -732,6 +731,7 @@
 
         SetPrivateState (eStateAttaching);
         char host_port[128];
+        ArchSpec arch_spec = GetTarget().GetArchitecture();
         snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
         error = StartDebugserverProcess (host_port,
                                          NULL,
@@ -739,7 +739,7 @@
                                          NULL,
                                          LLDB_INVALID_PROCESS_ID,
                                          NULL, false,
-                                         m_arch_spec);
+                                         arch_spec);
         if (error.Fail())
         {
             const char *error_string = error.AsCString();
@@ -840,9 +840,26 @@
 void
 ProcessGDBRemote::DidAttach ()
 {
-    DidLaunchOrAttach ();
+    // If we haven't got an executable module yet, then we should make a dynamic loader, and
+    // see if it can find the executable module for us.  If we do have an executable module,
+    // make sure it matches the process we've just attached to.
+    
+    ModuleSP exe_module_sp = GetTarget().GetExecutableModule();        
+    if (!m_dynamic_loader_ap.get())
+    {
+       m_dynamic_loader_ap.reset(DynamicLoader::FindPlugin(this, "dynamic-loader.macosx-dyld"));
+    }
+
     if (m_dynamic_loader_ap.get())
         m_dynamic_loader_ap->DidAttach();
+
+    Module * new_exe_module = GetTarget().GetExecutableModule().get();        
+    if (new_exe_module == NULL)
+    {
+        
+    }
+    
+    DidLaunchOrAttach ();
 }
 
 Error
@@ -876,7 +893,7 @@
     static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 };
     static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
 
-    ArchSpec::CPU arch_cpu = m_arch_spec.GetGenericCPUType();
+    ArchSpec::CPU arch_cpu = GetTarget().GetArchitecture().GetGenericCPUType();
     switch (arch_cpu)
     {
     case ArchSpec::eCPU_i386:
@@ -1060,13 +1077,16 @@
 void
 ProcessGDBRemote::RefreshStateAfterStop ()
 {
+    // FIXME - add a variable to tell that we're in the middle of attaching if we
+    // need to know that.
     // We must be attaching if we don't already have a valid architecture
-    if (!m_arch_spec.IsValid())
-    {
-        Module *exe_module = GetTarget().GetExecutableModule().get();
-        if (exe_module)
-            m_arch_spec = exe_module->GetArchitecture();
-    }
+//    if (!GetTarget().GetArchitecture().IsValid())
+//    {
+//        Module *exe_module = GetTarget().GetExecutableModule().get();
+//        if (exe_module)
+//            m_arch_spec = exe_module->GetArchitecture();
+//    }
+    
     // Let all threads recover from stopping and do any clean up based
     // on the previous thread state (if any).
     m_thread_list.RefreshStateAfterStop();
@@ -2251,3 +2271,19 @@
     return dispatch_queue_name.c_str();
 }
 
+uint32_t
+ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
+{
+    // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver
+    // process and ask it for the list of processes. But if we are local, we can let the Host do it.
+    if (m_local_debugserver)
+    {
+        return Host::ListProcessesMatchingName (name, matches, pids);
+    }
+    else 
+    {
+        // FIXME: Implement talking to the remote debugserver.
+        return 0;
+    }
+
+}

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=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Mon Aug  9 18:31:02 2010
@@ -21,6 +21,7 @@
 #include "lldb/Core/Error.h"
 #include "lldb/Core/InputReader.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Core/StringList.h"
 #include "lldb/Core/ThreadSafeValue.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Thread.h"
@@ -67,6 +68,9 @@
     virtual bool
     CanDebug (lldb_private::Target &target);
 
+    virtual uint32_t
+    ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids);
+
     //------------------------------------------------------------------
     // Creating a new process, or attaching to an existing one
     //------------------------------------------------------------------
@@ -262,17 +266,6 @@
     void
     AppendSTDOUT (const char* s, size_t len);
 
-    lldb_private::ArchSpec&
-    GetArchSpec()
-    {
-        return m_arch_spec;
-    }
-    const lldb_private::ArchSpec&
-    GetArchSpec() const
-    {
-        return m_arch_spec;
-    }
-
     void
     Clear ( );
 
@@ -328,7 +321,6 @@
     lldb_private::Communication m_stdio_communication;
     lldb_private::Mutex m_stdio_mutex;      // Multithreaded protection for stdio
     std::string m_stdout_data;
-    lldb_private::ArchSpec m_arch_spec;
     lldb::ByteOrder m_byte_order;
     GDBRemoteCommunication m_gdb_comm;
     lldb::pid_t m_debugserver_pid;
@@ -349,6 +341,7 @@
     lldb_private::unw_targettype_t m_libunwind_target_type;
     lldb_private::unw_addr_space_t m_libunwind_addr_space; // libunwind address space object for this process.
     bool m_waiting_for_attach;
+    bool m_local_debugserver;  // Is the debugserver process we are talking to local or on another machine.
 
     void
     ResetGDBRemoteState ();

Modified: lldb/trunk/source/Symbol/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ObjectFile.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ObjectFile.cpp (original)
+++ lldb/trunk/source/Symbol/ObjectFile.cpp Mon Aug  9 18:31:02 2010
@@ -90,3 +90,10 @@
     }
     return NULL;
 }
+
+bool 
+ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch)
+{
+    return m_module->SetArchitecture (new_arch);
+}
+

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Mon Aug  9 18:31:02 2010
@@ -1048,6 +1048,24 @@
     if (state == eStateStopped || state == eStateCrashed)
     {
         DidAttach ();
+        // Figure out which one is the executable, and set that in our target:
+        ModuleList &modules = GetTarget().GetImages();
+    
+        size_t num_modules = modules.GetSize();
+        for (int i = 0; i < num_modules; i++)
+        {
+            ModuleSP module_sp = modules.GetModuleAtIndex(i);
+            if (module_sp->IsExecutable())
+            {
+                ModuleSP exec_module = GetTarget().GetExecutableModule();
+                if (!exec_module || exec_module != module_sp)
+                {
+                    
+                    GetTarget().SetExecutableModule (module_sp, false);
+                }
+                break;
+            }
+        }
 
         // This delays passing the stopped event to listeners till DidLaunch gets
         // a chance to complete...
@@ -1073,6 +1091,16 @@
     m_target_triple.Clear();
     m_abi_sp.reset();
 
+    // 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 (attach_pid);
+    if (attach_spec != GetTarget().GetArchitecture())
+    {
+        // Set the architecture on the target.
+        GetTarget().SetArchitecture(attach_spec);
+    }
+
     Error error (WillAttachToProcessWithID(attach_pid));
     if (error.Success())
     {
@@ -1102,6 +1130,16 @@
 {
     m_target_triple.Clear();
     m_abi_sp.reset();
+    
+    // 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())
+    {
+        // Set the architecture on the target.
+        GetTarget().SetArchitecture(attach_spec);
+    }
 
     Error error (WillAttachToProcessWithName(process_name, wait_for_launch));
     if (error.Success())
@@ -1863,3 +1901,22 @@
     return m_objc_object_printer;
 }
 
+uint32_t
+Process::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
+{
+    return 0;
+}
+    
+ArchSpec
+Process::GetArchSpecForExistingProcess (lldb::pid_t pid)
+{
+    return Host::GetArchSpecForExistingProcess (pid);
+}
+
+ArchSpec
+Process::GetArchSpecForExistingProcess (const char *process_name)
+{
+    return Host::GetArchSpecForExistingProcess (process_name);
+}
+
+

Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Mon Aug  9 18:31:02 2010
@@ -79,7 +79,7 @@
                                                   &m_thread.GetProcess(), 
                                                   &m_thread, 
                                                   m_thread.GetStackFrameAtIndex(0).get(),
-                                                  false);
+                                                  true);
                 
                 m_should_stop = bp_site_sp->ShouldStop (&context);
             }

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Mon Aug  9 18:31:02 2010
@@ -373,6 +373,10 @@
         m_images.Append(executable_sp); // The first image is our exectuable file
 
         ArchSpec exe_arch = executable_sp->GetArchitecture();
+        // If we haven't set an architecture yet, reset our architecture based on what we found in the executable module.
+        if (!m_arch_spec.IsValid())
+            m_arch_spec = exe_arch;
+        
         FileSpecList dependent_files;
         ObjectFile * executable_objfile = executable_sp->GetObjectFile();
         if (executable_objfile == NULL)
@@ -426,18 +430,63 @@
 ArchSpec
 Target::GetArchitecture () const
 {
-    ArchSpec arch;
-    if (m_images.GetSize() > 0)
+    return m_arch_spec;
+}
+
+bool
+Target::SetArchitecture (const ArchSpec &arch_spec)
+{
+    if (m_arch_spec == arch_spec)
     {
-        Module *exe_module = m_images.GetModulePointerAtIndex(0);
-        if (exe_module)
-            arch = exe_module->GetArchitecture();
+        // If we're setting the architecture to our current architecture, we
+        // don't need to do anything.
+        return true;
+    }
+    else if (!m_arch_spec.IsValid())
+    {
+        // If we haven't got a valid arch spec, then we just need to set it.
+        m_arch_spec = arch_spec;
+        return true;
+    }
+    else
+    {
+        // If we have an executable file, try to reset the executable to the desired architecture
+        m_arch_spec = arch_spec;
+        ModuleSP executable_sp = GetExecutableModule ();
+        m_images.Clear();
+        m_scratch_ast_context_ap.reset();
+        m_triple.Clear();
+        // Need to do something about unsetting breakpoints.
+        
+        if (executable_sp)
+        {
+            FileSpec exec_file_spec = executable_sp->GetFileSpec();
+            Error error = ModuleList::GetSharedModule(exec_file_spec, 
+                                                      arch_spec, 
+                                                      NULL, 
+                                                      NULL, 
+                                                      0, 
+                                                      executable_sp, 
+                                                      NULL, 
+                                                      NULL);
+                                          
+            if (!error.Fail() && executable_sp)
+            {
+                SetExecutableModule (executable_sp, true);
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        else
+        {
+            return false;
+        }
     }
-    return arch;
 }
 
-
-
 bool
 Target::GetTargetTriple(ConstString &triple)
 {

Modified: lldb/trunk/source/Target/TargetList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/TargetList.cpp?rev=110624&r1=110623&r2=110624&view=diff
==============================================================================
--- lldb/trunk/source/Target/TargetList.cpp (original)
+++ lldb/trunk/source/Target/TargetList.cpp Mon Aug  9 18:31:02 2010
@@ -60,30 +60,50 @@
                         file.GetFilename().AsCString(),
                         arch.AsCString(),
                         uuid_ptr);
-    ModuleSP exe_module_sp;
-    FileSpec resolved_file(file);
-    if (!Host::ResolveExecutableInBundle (&resolved_file))
-        resolved_file = file;
-
-    Error error = ModuleList::GetSharedModule(resolved_file, 
-                                              arch, 
-                                              uuid_ptr, 
-                                              NULL, 
-                                              0, 
-                                              exe_module_sp, 
-                                              NULL, 
-                                              NULL);
-    if (exe_module_sp)
+    Error error;
+    
+    if (!file)
     {
         target_sp.reset(new Target(debugger));
-        target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
-
-        if (target_sp.get())
+        target_sp->SetArchitecture(arch);
+    }
+    else
+    {
+        ModuleSP exe_module_sp;
+        FileSpec resolved_file(file);
+        if (!Host::ResolveExecutableInBundle (&resolved_file))
+            resolved_file = file;
+
+        error = ModuleList::GetSharedModule(resolved_file, 
+                                                  arch, 
+                                                  uuid_ptr, 
+                                                  NULL, 
+                                                  0, 
+                                                  exe_module_sp, 
+                                                  NULL, 
+                                                  NULL);
+        if (exe_module_sp)
         {
-            Mutex::Locker locker(m_target_list_mutex);
-            m_current_target_idx = m_target_list.size();
-            m_target_list.push_back(target_sp);
+            if (exe_module_sp->GetObjectFile() == NULL)
+            {
+                error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
+                                               file.GetDirectory().AsCString(),
+                                               file.GetDirectory() ? "/" : "",
+                                               file.GetFilename().AsCString(),
+                                               arch.AsCString());
+                return error;
+            }
+            target_sp.reset(new Target(debugger));
+            target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
         }
+    }
+    
+    if (target_sp.get())
+    {
+        Mutex::Locker locker(m_target_list_mutex);
+        m_current_target_idx = m_target_list.size();
+        m_target_list.push_back(target_sp);
+    }
 
 //        target_sp.reset(new Target);
 //        // Let the target resolve any funky bundle paths before we try and get
@@ -107,7 +127,6 @@
 //                m_target_list.push_back(target_sp);
 //            }
 //        }
-    }
     else
     {
         target_sp.reset();





More information about the lldb-commits mailing list