[Lldb-commits] [lldb] r155594 - in /lldb/branches/lldb-platform-work/source: Host/common/Host.cpp Host/freebsd/Host.cpp Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp Plugins/Platform/FreeBSD/PlatformFreeBSD.h

Enrico Granata egranata at apple.com
Wed Apr 25 15:47:11 PDT 2012


Author: enrico
Date: Wed Apr 25 17:47:11 2012
New Revision: 155594

URL: http://llvm.org/viewvc/llvm-project?rev=155594&view=rev
Log:
Patch by Viktor Kutuzov <vkutuzov at accesssoftek.com> to:

- enable the 'platform shell' command for FreeBSD.
- update PlatformFreeBSD::ResolveExecutable/PlatformFreeBSD::PlatformFreeBSD/ methods.
- add an implementation of Host::FindProcesses method.
- add an implementation of Host::LaunchProcess method.
- updatd the platform depended method for the Host class - GetOSKernelDescription and GetOSBuildString.
- retrieve of the current system shell from the SHELL environment variable.
- fix arguments in the AppendDuplicateFileAction method call.
- avoid overriding of the error value from LaunchProcess.


Modified:
    lldb/branches/lldb-platform-work/source/Host/common/Host.cpp
    lldb/branches/lldb-platform-work/source/Host/freebsd/Host.cpp
    lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
    lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h

Modified: lldb/branches/lldb-platform-work/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/Host.cpp?rev=155594&r1=155593&r2=155594&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/Host.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/Host.cpp Wed Apr 25 17:47:11 2012
@@ -1203,7 +1203,7 @@
     return getegid();
 }
 
-#if !defined (__APPLE__)
+#if !defined (__APPLE__) && !defined (__FreeBSD__)
 uint32_t
 Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
 {
@@ -1291,15 +1291,26 @@
 {
     Error error;
     ProcessLaunchInfo launch_info;
-    launch_info.SetShell("/bin/bash");
-    launch_info.GetArguments().AppendArgument(command);
+
     const bool localhost = true;
     const bool will_debug = false;
     const bool first_arg_is_full_shell_command = true;
-    launch_info.ConvertArgumentsForLaunchingInShell (error,
+
+#ifndef LLDB_DEFAULT_SHELL_COMMAND
+#define LLDB_DEFAULT_SHELL_COMMAND   "/bin/bash"
+#endif
+    const char* shell_cmd = ::getenv("SHELL");
+    if (shell_cmd == NULL)
+        shell_cmd = LLDB_DEFAULT_SHELL_COMMAND;
+
+    launch_info.SetShell(shell_cmd);
+    launch_info.GetArguments().AppendArgument(command);
+
+    if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
                                                      localhost,
                                                      will_debug,
-                                                     first_arg_is_full_shell_command);
+                                                          first_arg_is_full_shell_command))
+        return error;
     
     if (working_dir)
         launch_info.SetWorkingDirectory(working_dir);
@@ -1313,7 +1324,7 @@
         output_file_path = ::tmpnam(output_file_path_buffer);
         launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
         launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true);
-        launch_info.AppendDuplicateFileAction(STDERR_FILENO, STDOUT_FILENO);
+        launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
     }
     else
     {
@@ -1330,7 +1341,11 @@
     
     error = LaunchProcess (launch_info);
     const lldb::pid_t pid = launch_info.GetProcessID();
-    if (pid != LLDB_INVALID_PROCESS_ID)
+
+    if (error.Success() && pid == LLDB_INVALID_PROCESS_ID)
+        error.SetErrorString("failed to get process ID");
+
+    if (error.Success())
     {
         // The process successfully launched, so we can defer ownership of
         // "shell_info" to the MonitorShellCommand callback function that will
@@ -1382,10 +1397,6 @@
         }
         shell_info->can_delete.SetValue(true, eBroadcastAlways);
     }
-    else
-    {
-        error.SetErrorString("failed to get process ID");
-    }
 
     if (output_file_path)
         ::unlink (output_file_path);

Modified: lldb/branches/lldb-platform-work/source/Host/freebsd/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/freebsd/Host.cpp?rev=155594&r1=155593&r2=155594&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/freebsd/Host.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/freebsd/Host.cpp Wed Apr 25 17:47:11 2012
@@ -15,11 +15,13 @@
 #include <sys/user.h>
 #include <sys/utsname.h>
 #include <sys/sysctl.h>
+#include <sys/proc.h>
 
 #include <sys/ptrace.h>
 #include <sys/exec.h>
 #include <machine/elf.h>
 
+#include <spawn.h>
 
 // C++ Includes
 // Other libraries and framework includes
@@ -27,13 +29,17 @@
 #include "lldb/Core/Error.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Target/Platform.h"
 
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataExtractor.h"
+#include "lldb/Utility/CleanUp.h"
+
 #include "llvm/Support/Host.h"
 
 
@@ -44,7 +50,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-
 class FreeBSDThread
 {
 public:
@@ -111,7 +116,8 @@
 {
     char *v;
     char **var = environ;
-    for (; var != NULL && *var != NULL; ++var) {
+    for (; var != NULL && *var != NULL; ++var)
+    {
         v = strchr(*var, (int)'-');
         if (v == NULL)
             continue;
@@ -126,20 +132,207 @@
                    uint32_t &update)
 {
     struct utsname un;
-    int status;
 
+    ::memset(&un, 0, sizeof(utsname));
     if (uname(&un) < 0)
         return false;
 
-    status = sscanf(un.release, "%u.%u-%u", &major, &minor, &update);
-    return status == 3;
+    // We expect the FreeBSD OS version string in the following formats:
+    //  <n>-<string>, <n>.<n>-<string> or <n>.<n>.<n>-<string>.
+    // We should get one digit value as minimum.
+    return (sscanf(un.release, "%u.%u.%u", &major, &minor, &update) > 0);
 }
 
+// The posix_spawn() and posix_spawnp() functions first appeared in FreeBSD 8.0.
+static Error
+LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid)
+{
+    Error error;
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+
+    assert(exe_path);
+    assert(!launch_info.GetFlags().Test (eLaunchFlagDebug));
+
+    posix_spawnattr_t attr;
+
+    error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
+    error.LogIfError(log.get(), "::posix_spawnattr_init ( &attr )");
+    if (error.Fail())
+        return error;
+
+    // Make a quick class that will cleanup the posix spawn attributes in case
+    // we return in the middle of this function.
+    lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy);
+
+    sigset_t no_signals;
+    sigset_t all_signals;
+    sigemptyset (&no_signals);
+    sigfillset (&all_signals);
+    ::posix_spawnattr_setsigmask(&attr, &all_signals);
+    ::posix_spawnattr_setsigdefault(&attr, &no_signals);
+
+    short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
+
+    error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
+    error.LogIfError(log.get(), "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
+    if (error.Fail())
+        return error;
+
+    const size_t num_file_actions = launch_info.GetNumFileActions ();
+    posix_spawn_file_actions_t file_actions, *file_action_ptr = NULL;
+    // Make a quick class that will cleanup the posix spawn attributes in case
+    // we return in the middle of this function.
+    lldb_utility::CleanUp <posix_spawn_file_actions_t *, int>
+        posix_spawn_file_actions_cleanup (file_action_ptr, NULL, posix_spawn_file_actions_destroy);
+
+    if (num_file_actions > 0)
+    {
+        error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
+        error.LogIfError(log.get(), "::posix_spawn_file_actions_init ( &file_actions )");
+        if (error.Fail())
+            return error;
+
+        file_action_ptr = &file_actions;
+        posix_spawn_file_actions_cleanup.set(file_action_ptr);
+
+        for (size_t i = 0; i < num_file_actions; ++i)
+        {
+            const ProcessLaunchInfo::FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i);
+            if (launch_file_action &&
+                !ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions,
+                                                                         launch_file_action,
+                                                                         log.get(),
+                                                                         error))
+                return error;
+        }
+    }
+
+    // Change working directory if neccessary.
+    char current_dir[PATH_MAX];
+    current_dir[0] = '\0';
+
+    const char *working_dir = launch_info.GetWorkingDirectory();
+    if (working_dir != NULL)
+    {
+        if (::getcwd(current_dir, sizeof(current_dir)) == NULL)
+        {
+            error.SetError(errno, eErrorTypePOSIX);
+            error.LogIfError(log.get(), "unable to save the current directory");
+            return error;
+        }
+
+        if (::chdir(working_dir) == -1)
+        {
+            error.SetError(errno, eErrorTypePOSIX);
+            error.LogIfError(log.get(), "unable to change working directory to %s", working_dir);
+            return error;
+        }
+    }
+
+    const char *tmp_argv[2];
+    char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector();
+    char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector();
+
+    // Prepare minimal argument list if we didn't get it from the launch_info structure.
+    // We must pass argv into posix_spawnp and it must contain at least two items -
+    // pointer to an executable and NULL.
+    if (argv == NULL)
+    {
+        tmp_argv[0] = exe_path;
+        tmp_argv[1] = NULL;
+        argv = (char * const*)tmp_argv;
+    }
+
+    error.SetError (::posix_spawnp (&pid,
+                                    exe_path,
+                                    (num_file_actions > 0) ? &file_actions : NULL,
+                                    &attr,
+                                    argv,
+                                    envp),
+                    eErrorTypePOSIX);
+
+    error.LogIfError(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )",
+                     pid, exe_path, file_action_ptr, &attr, argv, envp);
+
+    // Change back the current directory.
+    // NOTE: do not override previously established error from posix_spawnp.
+    if (working_dir != NULL && ::chdir(current_dir) == -1 && error.Success())
+    {
+        error.SetError(errno, eErrorTypePOSIX);
+        error.LogIfError(log.get(), "unable to change current directory back to %s",
+                         current_dir);
+    }
+
+    return error;
+}
+
+
 Error
 Host::LaunchProcess (ProcessLaunchInfo &launch_info)
 {
     Error error;
-    assert(!"Not implemented yet!!!");
+    char exe_path[PATH_MAX];
+
+    PlatformSP host_platform_sp (Platform::GetDefaultPlatform ());
+
+    const ArchSpec &arch_spec = launch_info.GetArchitecture();
+
+    FileSpec exe_spec(launch_info.GetExecutableFile());
+
+    FileSpec::FileType file_type = exe_spec.GetFileType();
+    if (file_type != FileSpec::eFileTypeRegular)
+    {
+        lldb::ModuleSP exe_module_sp;
+        error = host_platform_sp->ResolveExecutable (exe_spec,
+                                                     arch_spec,
+                                                     exe_module_sp,
+                                                     NULL);
+
+        if (error.Fail())
+    return error;
+
+        if (exe_module_sp)
+            exe_spec = exe_module_sp->GetFileSpec();
+}
+
+    if (exe_spec.Exists())
+    {
+        exe_spec.GetPath (exe_path, sizeof(exe_path));
+    }
+    else
+    {
+        launch_info.GetExecutableFile().GetPath (exe_path, sizeof(exe_path));
+        error.SetErrorStringWithFormat ("executable doesn't exist: '%s'", exe_path);
+        return error;
+    }
+
+    assert(!launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY));
+
+    ::pid_t pid = LLDB_INVALID_PROCESS_ID;
+
+    error = LaunchProcessPosixSpawn(exe_path, launch_info, pid);
+
+    if (pid != LLDB_INVALID_PROCESS_ID)
+    {
+        // If all went well, then set the process ID into the launch info
+        launch_info.SetProcessID(pid);
+
+        // Make sure we reap any processes we spawn or we will have zombies.
+        if (!launch_info.MonitorProcess())
+        {
+            const bool monitor_signals = false;
+            StartMonitoringChildProcess (Process::SetProcessExitStatus,
+                                         NULL,
+                                         pid,
+                                         monitor_signals);
+        }
+    }
+    else
+    {
+        // Invalid process ID, something didn't go well
+        if (error.Success())
+            error.SetErrorString ("process launch failed for unknown reasons");
+    }
     return error;
 }
 
@@ -147,13 +340,17 @@
 Host::GetOSBuildString (std::string &s)
 {
     int mib[2] = { CTL_KERN, KERN_OSREV };
-    char cstr[PATH_MAX];
-    size_t cstr_len = sizeof(cstr);
-    if (::sysctl (mib, 2, cstr, &cstr_len, NULL, 0) == 0)
+    char osrev_str[12];
+    uint32_t osrev = 0;
+    size_t osrev_len = sizeof(osrev);
+
+    if (::sysctl (mib, 2, &osrev, &osrev_len, NULL, 0) == 0)
     {
-        s.assign (cstr, cstr_len);
+        ::snprintf(osrev_str, sizeof(osrev_str), "%-8.8u", osrev);
+        s.assign (osrev_str);
         return true;
     }
+
     s.clear();
     return false;
 }
@@ -161,23 +358,25 @@
 bool
 Host::GetOSKernelDescription (std::string &s)
 {
-    int mib[2] = { CTL_KERN, KERN_VERSION };
-    char cstr[PATH_MAX];
-    size_t cstr_len = sizeof(cstr);
-    if (::sysctl (mib, 2, cstr, &cstr_len, NULL, 0) == 0)
-    {
-        s.assign (cstr, cstr_len);
-        return true;
-    }
+    struct utsname un;
+
+    ::memset(&un, 0, sizeof(utsname));
     s.clear();
+
+    if (uname(&un) < 0)
     return false;
+
+    s.assign (un.version);
+
+    return true;
 }
 
 static bool
 GetFreeBSDProcessArgs (const ProcessInstanceInfoMatch *match_info_ptr,
                       ProcessInstanceInfo &process_info)
 {
-    if (process_info.ProcessIDIsValid()) {
+    if (process_info.ProcessIDIsValid())
+    {
         int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, process_info.GetProcessID() };
 
         char arg_data[8192];
@@ -226,7 +425,8 @@
 static bool
 GetFreeBSDProcessCPUType (ProcessInstanceInfo &process_info)
 {
-    if (process_info.ProcessIDIsValid()) {
+    if (process_info.ProcessIDIsValid())
+    {
         process_info.GetArchitecture() = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
         return true;
     }
@@ -270,16 +470,95 @@
     return false;
 }
 
+uint32_t
+Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
+{
+    std::vector<struct kinfo_proc> kinfos;
+
+    int mib[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
+
+    size_t pid_data_size = 0;
+    if (::sysctl (mib, 3, NULL, &pid_data_size, NULL, 0) != 0)
+        return 0;
+
+    // Add a few extra in case a few more show up
+    const size_t estimated_pid_count = (pid_data_size / sizeof(struct kinfo_proc)) + 10;
+
+    kinfos.resize (estimated_pid_count);
+    pid_data_size = kinfos.size() * sizeof(struct kinfo_proc);
+
+    if (::sysctl (mib, 3, &kinfos[0], &pid_data_size, NULL, 0) != 0)
+        return 0;
+
+    const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc));
+
+    bool all_users = match_info.GetMatchAllUsers();
+    const lldb::pid_t our_pid = getpid();
+    const uid_t our_uid = getuid();
+    for (int i = 0; i < actual_pid_count; i++)
+    {
+        const struct kinfo_proc &kinfo = kinfos[i];
+        const bool kinfo_user_matches = (all_users ||
+                                         (kinfo.ki_ruid == our_uid) ||
+                                         // Special case, if lldb is being run as root we can attach to anything.
+                                         (our_uid == 0)
+                                         );
+
+        if (kinfo_user_matches == false      || // Make sure the user is acceptable
+            kinfo.ki_pid == our_pid          || // Skip this process
+            kinfo.ki_pid == 0                || // Skip kernel (kernel pid is zero)
+            kinfo.ki_stat == SZOMB    || // Zombies are bad, they like brains...
+            kinfo.ki_flag & P_TRACED  || // Being debugged?
+            kinfo.ki_flag & P_WEXIT)     // Working on exiting
+            continue;
+
+        // Every thread is a process in FreeBSD, but all the threads of a single process
+        // have the same pid. Do not store the process info in the result list if a process
+        // with given identifier is already registered there.
+        bool already_registered = false;
+        for (uint32_t pi = 0;
+             !already_registered &&
+             (const int)kinfo.ki_numthreads > 1 &&
+             pi < (const uint32_t)process_infos.GetSize(); pi++)
+            already_registered = (process_infos.GetProcessIDAtIndex(pi) == (uint32_t)kinfo.ki_pid);
+
+        if (already_registered)
+            continue;
+
+        ProcessInstanceInfo process_info;
+        process_info.SetProcessID (kinfo.ki_pid);
+        process_info.SetParentProcessID (kinfo.ki_ppid);
+        process_info.SetUserID (kinfo.ki_ruid);
+        process_info.SetGroupID (kinfo.ki_rgid);
+        process_info.SetEffectiveUserID (kinfo.ki_svuid);
+        process_info.SetEffectiveGroupID (kinfo.ki_svgid);
+
+        // Make sure our info matches before we go fetch the name and cpu type
+        if (match_info.Matches (process_info) &&
+            GetFreeBSDProcessArgs (&match_info, process_info))
+        {
+            GetFreeBSDProcessCPUType (process_info);
+            if (match_info.Matches (process_info))
+                process_infos.Append (process_info);
+        }
+    }
+
+    return process_infos.GetSize();
+}
+
 bool
 Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
 {
     process_info.SetProcessID(pid);
-    if (GetFreeBSDProcessArgs(NULL, process_info)) {
+
+    if (GetFreeBSDProcessArgs(NULL, process_info))
+    {
         // should use libprocstat instead of going right into sysctl?
         GetFreeBSDProcessCPUType(process_info);
         GetFreeBSDProcessUserAndGroup(process_info);
         return true;
     }
+
     process_info.Clear();
     return false;
 }

Modified: lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp?rev=155594&r1=155593&r2=155594&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp Wed Apr 25 17:47:11 2012
@@ -113,6 +113,26 @@
 {
 }
 
+//TODO:VK: inherit PlatformPOSIX
+lldb_private::Error
+PlatformFreeBSD::RunShellCommand (const char *command,
+                                  const char *working_dir,
+                                  int *status_ptr,
+                                  int *signo_ptr,
+                                  std::string *command_output,
+                                  uint32_t timeout_sec)
+{
+    if (IsHost())
+        return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
+    else
+    {
+        if (m_remote_platform_sp)
+            return m_remote_platform_sp->RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
+        else
+            return Error("unable to run a remote command without a platform");
+    }
+}
+
 
 Error
 PlatformFreeBSD::ResolveExecutable (const FileSpec &exe_file,
@@ -120,134 +140,23 @@
                                     lldb::ModuleSP &exe_module_sp,
                                     const FileSpecList *module_search_paths_ptr)
 {
-    Error error;
     // Nothing special to do here, just use the actual file and architecture
 
-    char exe_path[PATH_MAX];
-    FileSpec resolved_exe_file (exe_file);
-
-    if (IsHost())
+    if (lldb_private::IsLogVerbose())
     {
-        // If we have "ls" as the exe_file, resolve the executable loation based on
-        // the current path variables
-        if (!resolved_exe_file.Exists())
-        {
-            exe_file.GetPath(exe_path, sizeof(exe_path));
-            resolved_exe_file.SetFile(exe_path, true);
+        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_VERBOSE));
+        log->Printf("Resolve executable '%s/%s'", exe_file.GetDirectory().AsCString(), exe_file.GetFilename().AsCString());
+        log->Printf("Resolve executable arch '%s'", exe_arch.GetArchitectureName());
         }
 
-        if (!resolved_exe_file.Exists())
-            resolved_exe_file.ResolveExecutableLocation ();
-
-        // Resolve any executable within a bundle on MacOSX
-        //Host::ResolveExecutableInBundle (resolved_exe_file);
-
-        if (resolved_exe_file.Exists())
-            error.Clear();
-        else
-        {
-            exe_file.GetPath(exe_path, sizeof(exe_path));
-            error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path);
-        }
-    }
-    else
-    {
-        if (m_remote_platform_sp)
-        {
-            error = m_remote_platform_sp->ResolveExecutable (exe_file,
+    if (IsRemote() && m_remote_platform_sp)
+        return m_remote_platform_sp->ResolveExecutable (exe_file,
                                                              exe_arch,
                                                              exe_module_sp,
                                                              module_search_paths_ptr);
-        }
-        else
-        {
-            // We may connect to a process and use the provided executable (Don't use local $PATH).
             
-            // Resolve any executable within a bundle on MacOSX
-            Host::ResolveExecutableInBundle (resolved_exe_file);
-            
-            if (resolved_exe_file.Exists()) {
-                error.Clear();
-            }
-            else
-            {
-                exe_file.GetPath(exe_path, sizeof(exe_path));
-                error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path);
+    return Platform::ResolveExecutable(exe_file, exe_arch, exe_module_sp, module_search_paths_ptr);
             }
-        }
-    }
-
-
-    if (error.Success())
-    {
-        ModuleSpec module_spec (resolved_exe_file, exe_arch);
-        if (module_spec.GetArchitecture().IsValid())
-        {
-            error = ModuleList::GetSharedModule (module_spec,
-                                                 exe_module_sp,
-                                                 module_search_paths_ptr,
-                                                 NULL,
-                                                 NULL);
-
-            if (exe_module_sp->GetObjectFile() == NULL)
-            {
-                exe_module_sp.reset();
-                error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain the architecture %s",
-                                                exe_file.GetDirectory().AsCString(""),
-                                                exe_file.GetDirectory() ? "/" : "",
-                                                exe_file.GetFilename().AsCString(""),
-                                                exe_arch.GetArchitectureName());
-            }
-        }
-        else
-        {
-            // No valid architecture was specified, ask the platform for
-            // the architectures that we should be using (in the correct order)
-            // and see if we can find a match that way
-            StreamString arch_names;
-            ArchSpec platform_arch;
-            for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx)
-            {
-                error = ModuleList::GetSharedModule (module_spec,
-                                                     exe_module_sp,
-                                                     module_search_paths_ptr,
-                                                     NULL,
-                                                     NULL);
-                // Did we find an executable using one of the
-                if (error.Success())
-                {
-                    if (exe_module_sp && exe_module_sp->GetObjectFile())
-                        break;
-                    else
-                        error.SetErrorToGenericError();
-                }
-
-                if (idx > 0)
-                    arch_names.PutCString (", ");
-                arch_names.PutCString (platform_arch.GetArchitectureName());
-            }
-
-            if (error.Fail() || !exe_module_sp)
-            {
-                error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s",
-                                                exe_file.GetDirectory().AsCString(""),
-                                                exe_file.GetDirectory() ? "/" : "",
-                                                exe_file.GetFilename().AsCString(""),
-                                                GetShortPluginName(),
-                                                arch_names.GetString().c_str());
-            }
-        }
-    }
-    else
-    {
-        error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
-                                        exe_file.GetDirectory().AsCString(""),
-                                        exe_file.GetDirectory() ? "/" : "",
-                                        exe_file.GetFilename().AsCString(""));
-    }
-
-    return error;
-}
 
 size_t
 PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
@@ -608,11 +517,17 @@
 {
     struct utsname un;
 
-    if (uname(&un)) {
-        strm << "FreeBSD";
-        return;
-    }
+    strm << "      Host: ";
+
+    ::memset(&un, 0, sizeof(utsname));
+    if (uname(&un) == -1)
+        strm << "FreeBSD" << '\n';
+
+    strm << un.sysname << ' ' << un.release;
+    if (un.nodename[0] != '\0')
+        strm << " (" << un.nodename << ')';
+    strm << '\n';
 
-    strm << "Host: " << un.sysname << ' ' << un.release << ' ' << un.version << '\n';
+    // Dump a common information about the platform status.
     Platform::GetStatus(strm);
 }

Modified: lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h?rev=155594&r1=155593&r2=155594&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h Wed Apr 25 17:47:11 2012
@@ -81,6 +81,14 @@
     // lldb_private::Platform functions
     //------------------------------------------------------------
     virtual lldb_private::Error
+    RunShellCommand (const char *command,
+                     const char *working_dir,
+                     int *status_ptr,
+                     int *signo_ptr,
+                     std::string *command_output,
+                     uint32_t timeout_sec);
+
+    virtual lldb_private::Error
     ResolveExecutable (const lldb_private::FileSpec &exe_file,
                        const lldb_private::ArchSpec &arch,
                        lldb::ModuleSP &module_sp,





More information about the lldb-commits mailing list