Exemplo n.º 1
0
Error PlatformiOSSimulator::GetSymbolFile(const FileSpec &platform_file,
        const UUID *uuid_ptr,
        FileSpec &local_file) {
    Error error;
    char platform_file_path[PATH_MAX];
    if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
        char resolved_path[PATH_MAX];

        const char *sdk_dir = GetSDKDirectoryAsCString();
        if (sdk_dir) {
            ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", sdk_dir,
                       platform_file_path);

            // First try in the SDK and see if the file is in there
            local_file.SetFile(resolved_path, true);
            if (local_file.Exists())
                return error;

            // Else fall back to the actual path itself
            local_file.SetFile(platform_file_path, true);
            if (local_file.Exists())
                return error;
        }
        error.SetErrorStringWithFormat(
            "unable to locate a platform file for '%s' in platform '%s'",
            platform_file_path, GetPluginName().GetCString());
    } else {
        error.SetErrorString("invalid platform file argument");
    }
    return error;
}
Exemplo n.º 2
0
static bool
LocateDSYMInVincinityOfExecutable (const ModuleSpec &module_spec, FileSpec &dsym_fspec)
{
    const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
    if (exec_fspec)
    {
        char path[PATH_MAX];
        if (exec_fspec->GetPath(path, sizeof(path)))
        {
            // Make sure the module isn't already just a dSYM file...
            if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL)
            {
                size_t obj_file_path_length = strlen(path);
                strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path));
                strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path));

                dsym_fspec.SetFile(path, false);

                if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
                {
                    return true;
                }
                else
                {
                    path[obj_file_path_length] = '\0';

                    char *last_dot = strrchr(path, '.');
                    while (last_dot != NULL && last_dot[0])
                    {
                        char *next_slash = strchr(last_dot, '/');
                        if (next_slash != NULL)
                        {
                            *next_slash = '\0';
                            strlcat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path));
                            strlcat(path, exec_fspec->GetFilename().AsCString(), sizeof(path));
                            dsym_fspec.SetFile(path, false);
                            if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID (dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr()))
                                return true;
                            else
                            {
                                *last_dot = '\0';
                                char *prev_slash = strrchr(path, '/');
                                if (prev_slash != NULL)
                                    *prev_slash = '\0';
                                else
                                    break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
        }
    }
    dsym_fspec.Clear();
    return false;
}
Exemplo n.º 3
0
Error PlatformRemoteAppleWatch::GetSymbolFile(const FileSpec &platform_file,
                                              const UUID *uuid_ptr,
                                              FileSpec &local_file) {
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  Error error;
  char platform_file_path[PATH_MAX];
  if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
    char resolved_path[PATH_MAX];

    const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
    if (os_version_dir) {
      ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
                 platform_file_path);

      local_file.SetFile(resolved_path, true);
      if (local_file.Exists()) {
        if (log) {
          log->Printf("Found a copy of %s in the DeviceSupport dir %s",
                      platform_file_path, os_version_dir);
        }
        return error;
      }

      ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
                 os_version_dir, platform_file_path);

      local_file.SetFile(resolved_path, true);
      if (local_file.Exists()) {
        if (log) {
          log->Printf(
              "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
              platform_file_path, os_version_dir);
        }
        return error;
      }
      ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
                 os_version_dir, platform_file_path);

      local_file.SetFile(resolved_path, true);
      if (local_file.Exists()) {
        if (log) {
          log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
                      platform_file_path, os_version_dir);
        }
        return error;
      }
    }
    local_file = platform_file;
    if (local_file.Exists())
      return error;

    error.SetErrorStringWithFormat(
        "unable to locate a platform file for '%s' in platform '%s'",
        platform_file_path, GetPluginName().GetCString());
  } else {
    error.SetErrorString("invalid platform file argument");
  }
  return error;
}
Exemplo n.º 4
0
Error
PlatformRemoteiOS::GetSymbolFile (const FileSpec &platform_file, 
                                  const UUID *uuid_ptr,
                                  FileSpec &local_file)
{
    Error error;
    char platform_file_path[PATH_MAX];
    if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
    {
        char resolved_path[PATH_MAX];
    
        const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion();
        if (os_version_dir)
        {
            ::snprintf (resolved_path, 
                        sizeof(resolved_path), 
                        "%s/%s", 
                        os_version_dir, 
                        platform_file_path);
            
            local_file.SetFile(resolved_path, true);
            if (local_file.Exists())
                return error;

            ::snprintf (resolved_path, 
                        sizeof(resolved_path), 
                        "%s/Symbols.Internal/%s", 
                        os_version_dir, 
                        platform_file_path);

            local_file.SetFile(resolved_path, true);
            if (local_file.Exists())
                return error;
            ::snprintf (resolved_path, 
                        sizeof(resolved_path), 
                        "%s/Symbols/%s", 
                        os_version_dir, 
                        platform_file_path);

            local_file.SetFile(resolved_path, true);
            if (local_file.Exists())
                return error;

        }
        local_file = platform_file;
        if (local_file.Exists())
            return error;

        error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", 
                                        platform_file_path,
                                        GetPluginName().GetCString());
    }
    else
    {
        error.SetErrorString ("invalid platform file argument");
    }
    return error;
}
Exemplo n.º 5
0
Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
  Status error;
  std::wstring wsrc;
  if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc)) {
    error.SetErrorString(PATH_CONVERSION_ERROR);
    return error;
  }

  HANDLE h = ::CreateFileW(wsrc.c_str(), GENERIC_READ,
                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                           OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL);
  if (h == INVALID_HANDLE_VALUE) {
    error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
    return error;
  }

  std::vector<wchar_t> buf(PATH_MAX + 1);
  // Subtract 1 from the path length since this function does not add a null
  // terminator.
  DWORD result = ::GetFinalPathNameByHandleW(
      h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
  std::string path;
  if (result == 0)
    error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
  else if (!llvm::convertWideToUTF8(buf.data(), path))
    error.SetErrorString(PATH_CONVERSION_ERROR);
  else
    dst.SetFile(path, false);

  ::CloseHandle(h);
  return error;
}
Exemplo n.º 6
0
Error HostProcessPosix::GetMainModule(FileSpec &file_spec) const
{
    Error error;

    // Use special code here because proc/[pid]/exe is a symbolic link.
    char link_path[PATH_MAX];
    char exe_path[PATH_MAX] = "";
    if (snprintf (link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", m_pid) <= 0)
    {
        error.SetErrorString("Unable to build /proc/<pid>/exe string");
        return error;
    }

    error = FileSystem::Readlink(link_path, exe_path, llvm::array_lengthof(exe_path));
    if (!error.Success())
        return error;

    const ssize_t len = strlen(exe_path);
    // If the binary has been deleted, the link name has " (deleted)" appended.
    // Remove if there.
    static const ssize_t deleted_len = strlen(" (deleted)");
    if (len > deleted_len &&
        !strcmp(exe_path + len - deleted_len, " (deleted)"))
    {
        exe_path[len - deleted_len] = 0;
    }

    file_spec.SetFile(exe_path, false);
    return error;
}
Exemplo n.º 7
0
bool
PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const
{
    if (!m_pairs.empty())
    {
        char orig_path[PATH_MAX];
        char new_path[PATH_MAX];
        const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path));
        if (orig_path_len > 0)
        {
            const_iterator pos, end = m_pairs.end();
            for (pos = m_pairs.begin(); pos != end; ++pos)
            {
                const size_t prefix_len = pos->first.GetLength();
                
                if (orig_path_len >= prefix_len)
                {
                    if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0)
                    {
                        const size_t new_path_len = snprintf(new_path, sizeof(new_path), "%s/%s", pos->second.GetCString(), orig_path + prefix_len);
                        if (new_path_len < sizeof(new_path))
                        {
                            new_spec.SetFile (new_path, true);
                            if (new_spec.Exists())
                                return true;
                        }
                    }
                }
            }
        }
    }
    new_spec.Clear();
    return false;
}
Exemplo n.º 8
0
FileSpec
Host::GetProgramFileSpec ()
{
    static FileSpec g_program_filespec;
    if (!g_program_filespec)
    {
#if defined (__APPLE__)
        char program_fullpath[PATH_MAX];
        // If DST is NULL, then return the number of bytes needed.
        uint32_t len = sizeof(program_fullpath);
        int err = _NSGetExecutablePath (program_fullpath, &len);
        if (err == 0)
            g_program_filespec.SetFile (program_fullpath, false);
        else if (err == -1)
        {
            char *large_program_fullpath = (char *)::malloc (len + 1);

            err = _NSGetExecutablePath (large_program_fullpath, &len);
            if (err == 0)
                g_program_filespec.SetFile (large_program_fullpath, false);

            ::free (large_program_fullpath);
        }
#elif defined (__linux__)
        char exe_path[PATH_MAX];
        ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
        if (len > 0) {
            exe_path[len] = 0;
            g_program_filespec.SetFile(exe_path, false);
        }
#elif defined (__FreeBSD__)
        int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() };
        size_t exe_path_size;
        if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0)
        {
            char *exe_path = new char[exe_path_size];
            if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
                g_program_filespec.SetFile(exe_path, false);
            delete[] exe_path;
        }
#endif
    }
    return g_program_filespec;
}
Exemplo n.º 9
0
Arquivo: File.cpp Projeto: filcab/lldb
Error
File::GetFileSpec (FileSpec &file_spec) const
{
    Error error;
#ifdef LLDB_CONFIG_FCNTL_GETPATH_SUPPORTED
    if (IsValid ())
    {
        char path[PATH_MAX];
        if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1)
            error.SetErrorToErrno();
        else
            file_spec.SetFile (path, false);
    }
    else 
    {
        error.SetErrorString("invalid file handle");
    }
#elif defined(__linux__)
    char proc[64];
    char path[PATH_MAX];
    if (::snprintf(proc, sizeof(proc), "/proc/self/fd/%d", GetDescriptor()) < 0)
        error.SetErrorString ("cannot resolve file descriptor");
    else
    {
        ssize_t len;
        if ((len = ::readlink(proc, path, sizeof(path) - 1)) == -1)
            error.SetErrorToErrno();
        else
        {
            path[len] = '\0';
            file_spec.SetFile (path, false);
        }
    }
#else
    error.SetErrorString ("File::GetFileSpec is not supported on this platform");
#endif

    if (error.Fail())
        file_spec.Clear();
    return error;
}
Exemplo n.º 10
0
FileSpec HostInfoFreeBSD::GetProgramFileSpec() {
  static FileSpec g_program_filespec;
  if (!g_program_filespec) {
    int exe_path_mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid()};
    size_t exe_path_size;
    if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) {
      char *exe_path = new char[exe_path_size];
      if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
        g_program_filespec.SetFile(exe_path, false);
      delete[] exe_path;
    }
  }
  return g_program_filespec;
}
Exemplo n.º 11
0
Error HostProcessWindows::GetMainModule(FileSpec &file_spec) const {
  Error error;
  if (m_process == nullptr)
    error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);

  std::vector<wchar_t> wpath(PATH_MAX);
  if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size())) {
    std::string path;
    if (llvm::convertWideToUTF8(wpath.data(), path))
      file_spec.SetFile(path, false);
    else
      error.SetErrorString("Error converting path to UTF-8");
  } else
    error.SetError(::GetLastError(), lldb::eErrorTypeWin32);

  return error;
}
Exemplo n.º 12
0
FileSpec
HostInfoLinux::GetProgramFileSpec()
{
    static FileSpec g_program_filespec;

    if (!g_program_filespec)
    {
        char exe_path[PATH_MAX];
        ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
        if (len > 0)
        {
            exe_path[len] = 0;
            g_program_filespec.SetFile(exe_path, false);
        }
    }

    return g_program_filespec;
}
Exemplo n.º 13
0
bool
ObjectFile::SplitArchivePathWithObject (const char *path_with_object, FileSpec &archive_file, ConstString &archive_object)
{
    RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
    if (g_object_regex.Execute (path_with_object, 2))
    {
        std::string path;
        std::string obj;
        if (g_object_regex.GetMatchAtIndex (path_with_object, 1, path) &&
            g_object_regex.GetMatchAtIndex (path_with_object, 2, obj))
        {
            archive_file.SetFile (path.c_str(), false);
            archive_object.SetCString(obj.c_str());
            return true;
        }
    }
    return false;
}
Exemplo n.º 14
0
bool ObjectFile::SplitArchivePathWithObject(const char *path_with_object,
                                            FileSpec &archive_file,
                                            ConstString &archive_object,
                                            bool must_exist) {
  RegularExpression g_object_regex(llvm::StringRef("(.*)\\(([^\\)]+)\\)$"));
  RegularExpression::Match regex_match(2);
  if (g_object_regex.Execute(llvm::StringRef::withNullAsEmpty(path_with_object),
                             &regex_match)) {
    std::string path;
    std::string obj;
    if (regex_match.GetMatchAtIndex(path_with_object, 1, path) &&
        regex_match.GetMatchAtIndex(path_with_object, 2, obj)) {
      archive_file.SetFile(path.c_str(), false);
      archive_object.SetCString(obj.c_str());
      if (must_exist && !archive_file.Exists())
        return false;
      return true;
    }
  }
  return false;
}
Exemplo n.º 15
0
static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
                                              FileSpec &dsym_fspec) {
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
  if (exec_fspec) {
    char path[PATH_MAX];
    if (exec_fspec->GetPath(path, sizeof(path))) {
      // Make sure the module isn't already just a dSYM file...
      if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) {
        if (log) {
          if (module_spec.GetUUIDPtr() && module_spec.GetUUIDPtr()->IsValid()) {
            log->Printf(
                "Searching for dSYM bundle next to executable %s, UUID %s",
                path, module_spec.GetUUIDPtr()->GetAsString().c_str());
          } else {
            log->Printf("Searching for dSYM bundle next to executable %s",
                        path);
          }
        }
        size_t obj_file_path_length = strlen(path);
        ::strncat(path, ".dSYM/Contents/Resources/DWARF/",
                  sizeof(path) - strlen(path) - 1);
        ::strncat(path, exec_fspec->GetFilename().AsCString(),
                  sizeof(path) - strlen(path) - 1);

        dsym_fspec.SetFile(path, false);

        ModuleSpecList module_specs;
        ModuleSpec matched_module_spec;
        if (dsym_fspec.Exists() &&
            FileAtPathContainsArchAndUUID(dsym_fspec,
                                          module_spec.GetArchitecturePtr(),
                                          module_spec.GetUUIDPtr())) {
          if (log) {
            log->Printf("dSYM with matching UUID & arch found at %s", path);
          }
          return true;
        } else {
          path[obj_file_path_length] = '\0';

          char *last_dot = strrchr(path, '.');
          while (last_dot != NULL && last_dot[0]) {
            char *next_slash = strchr(last_dot, '/');
            if (next_slash != NULL) {
              *next_slash = '\0';
              ::strncat(path, ".dSYM/Contents/Resources/DWARF/",
                        sizeof(path) - strlen(path) - 1);
              ::strncat(path, exec_fspec->GetFilename().AsCString(),
                        sizeof(path) - strlen(path) - 1);
              dsym_fspec.SetFile(path, false);
              if (dsym_fspec.Exists() &&
                  FileAtPathContainsArchAndUUID(
                      dsym_fspec, module_spec.GetArchitecturePtr(),
                      module_spec.GetUUIDPtr())) {
                if (log) {
                  log->Printf("dSYM with matching UUID & arch found at %s",
                              path);
                }
                return true;
              } else {
                *last_dot = '\0';
                char *prev_slash = strrchr(path, '/');
                if (prev_slash != NULL)
                  *prev_slash = '\0';
                else
                  break;
              }
            } else {
              break;
            }
          }
        }
      }
    }
  }
  dsym_fspec.Clear();
  return false;
}
Exemplo n.º 16
0
static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
                                              FileSpec &dsym_fspec) {
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
  if (exec_fspec) {
    char path[PATH_MAX];
    if (exec_fspec->GetPath(path, sizeof(path))) {
      // Make sure the module isn't already just a dSYM file...
      if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) {
        if (log) {
          if (module_spec.GetUUIDPtr() && module_spec.GetUUIDPtr()->IsValid()) {
            log->Printf(
                "Searching for dSYM bundle next to executable %s, UUID %s",
                path, module_spec.GetUUIDPtr()->GetAsString().c_str());
          } else {
            log->Printf("Searching for dSYM bundle next to executable %s",
                        path);
          }
        }
        ::strncat(path, ".dSYM/Contents/Resources/DWARF/",
                  sizeof(path) - strlen(path) - 1);
        ::strncat(path, exec_fspec->GetFilename().AsCString(),
                  sizeof(path) - strlen(path) - 1);

        dsym_fspec.SetFile(path, false);

        ModuleSpecList module_specs;
        ModuleSpec matched_module_spec;
        if (dsym_fspec.Exists() &&
            FileAtPathContainsArchAndUUID(dsym_fspec,
                                          module_spec.GetArchitecturePtr(),
                                          module_spec.GetUUIDPtr())) {
          if (log) {
            log->Printf("dSYM with matching UUID & arch found at %s", path);
          }
          return true;
        } else {
          FileSpec parent_dirs = exec_fspec;

          // Remove the binary name from the FileSpec
          parent_dirs.RemoveLastPathComponent();

          // Add a ".dSYM" name to each directory component of the path,
          // stripping off components.  e.g. we may have a binary like
          // /S/L/F/Foundation.framework/Versions/A/Foundation
          // and
          // /S/L/F/Foundation.framework.dSYM
          //
          // so we'll need to start with /S/L/F/Foundation.framework/Versions/A,
          // add the .dSYM part to the "A", and if that doesn't exist, strip off
          // the "A" and try it again with "Versions", etc., until we find a
          // dSYM bundle or we've stripped off enough path components that
          // there's no need to continue.

          for (int i = 0; i < 4; i++) {
            // Does this part of the path have a "." character - could it be a
            // bundle's top level directory?
            const char *fn = parent_dirs.GetFilename().AsCString();
            if (fn == nullptr)
              break;
            if (::strchr(fn, '.') != nullptr) {
              dsym_fspec = parent_dirs;
              dsym_fspec.RemoveLastPathComponent();

              // If the current directory name is "Foundation.framework", see if
              // "Foundation.framework.dSYM/Contents/Resources/DWARF/Foundation"
              // exists & has the right uuid.
              std::string dsym_fn = fn;
              dsym_fn += ".dSYM";
              dsym_fspec.AppendPathComponent(dsym_fn.c_str());
              dsym_fspec.AppendPathComponent("Contents");
              dsym_fspec.AppendPathComponent("Resources");
              dsym_fspec.AppendPathComponent("DWARF");
              dsym_fspec.AppendPathComponent(
                  exec_fspec->GetFilename().AsCString());
              if (dsym_fspec.Exists() &&
                  FileAtPathContainsArchAndUUID(
                      dsym_fspec, module_spec.GetArchitecturePtr(),
                      module_spec.GetUUIDPtr())) {
                if (log) {
                  log->Printf("dSYM with matching UUID & arch found at %s",
                              dsym_fspec.GetPath().c_str());
                }
                return true;
              }
            }
            parent_dirs.RemoveLastPathComponent();
          }
        }
      }
    }
  }
  dsym_fspec.Clear();
  return false;
}
Exemplo n.º 17
0
ConstString
PlatformMacOSX::GetSDKDirectory (lldb_private::Target &target)
{
    ModuleSP exe_module_sp (target.GetExecutableModule());
    if (exe_module_sp)
    {
        ObjectFile *objfile = exe_module_sp->GetObjectFile();
        if (objfile)
        {
            std::string xcode_contents_path;
            std::string default_xcode_sdk;
            FileSpec fspec;
            uint32_t versions[2];
            if (objfile->GetSDKVersion(versions, sizeof(versions)))
            {
                if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, fspec))
                {
                    std::string path;
                    xcode_contents_path = fspec.GetPath();
                    size_t pos = xcode_contents_path.find("/Xcode.app/Contents/");
                    if (pos != std::string::npos)
                    {
                        // LLDB.framework is inside an Xcode app bundle, we can locate the SDK from here
                        xcode_contents_path.erase(pos + strlen("/Xcode.app/Contents/"));
                    }
                    else
                    {
                        xcode_contents_path.clear();
                        // Use the selected Xcode
                        int status = 0;
                        int signo = 0;
                        std::string output;
                        const char *command = "xcrun -sdk macosx --show-sdk-path";
                        lldb_private::Error error = RunShellCommand (command,   // shell command to run
                                                                     NULL,      // current working directory
                                                                     &status,   // Put the exit status of the process in here
                                                                     &signo,    // Put the signal that caused the process to exit in here
                                                                     &output,   // Get the output from the command and place it in this string
                                                                     3);        // Timeout in seconds to wait for shell program to finish
                        if (status == 0 && !output.empty())
                        {
                            size_t first_non_newline = output.find_last_not_of("\r\n");
                            if (first_non_newline != std::string::npos)
                                output.erase(first_non_newline+1);
                            default_xcode_sdk = output;
                           
                            pos = default_xcode_sdk.find("/Xcode.app/Contents/");
                            if (pos != std::string::npos)
                                xcode_contents_path = default_xcode_sdk.substr(0, pos + strlen("/Xcode.app/Contents/"));
                        }
                    }
                }

                if (!xcode_contents_path.empty())
                {
                    StreamString sdk_path;
                    sdk_path.Printf("%sDeveloper/Platforms/MacOSX.platform/Developer/SDKs/MacOSX%u.%u.sdk", xcode_contents_path.c_str(), versions[0], versions[1]);
                    fspec.SetFile(sdk_path.GetString().c_str(), false);
                    if (fspec.Exists())
                        return ConstString(sdk_path.GetString().c_str());
                }
                
                if (!default_xcode_sdk.empty())
                {
                    fspec.SetFile(default_xcode_sdk.c_str(), false);
                    if (fspec.Exists())
                        return ConstString(default_xcode_sdk.c_str());
                }
            }
        }
    }
    return ConstString();
}