176fd5dd398aefd482323212524289298b75d9a63Stephen Wilson//===-- source/Host/linux/Host.cpp ------------------------------*- C++ -*-===//
276fd5dd398aefd482323212524289298b75d9a63Stephen Wilson//
376fd5dd398aefd482323212524289298b75d9a63Stephen Wilson//                     The LLVM Compiler Infrastructure
476fd5dd398aefd482323212524289298b75d9a63Stephen Wilson//
576fd5dd398aefd482323212524289298b75d9a63Stephen Wilson// This file is distributed under the University of Illinois Open Source
676fd5dd398aefd482323212524289298b75d9a63Stephen Wilson// License. See LICENSE.TXT for details.
776fd5dd398aefd482323212524289298b75d9a63Stephen Wilson//
876fd5dd398aefd482323212524289298b75d9a63Stephen Wilson//===----------------------------------------------------------------------===//
976fd5dd398aefd482323212524289298b75d9a63Stephen Wilson
1076fd5dd398aefd482323212524289298b75d9a63Stephen Wilson// C Includes
1176fd5dd398aefd482323212524289298b75d9a63Stephen Wilson#include <stdio.h>
1276fd5dd398aefd482323212524289298b75d9a63Stephen Wilson#include <sys/utsname.h>
137e9964783acae183c23a7ea470cedd64472eb233Johnny Chen#include <sys/types.h>
147e9964783acae183c23a7ea470cedd64472eb233Johnny Chen#include <sys/stat.h>
159b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea#include <dirent.h>
167e9964783acae183c23a7ea470cedd64472eb233Johnny Chen#include <fcntl.h>
170bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain#include <execinfo.h>
187e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
1976fd5dd398aefd482323212524289298b75d9a63Stephen Wilson// C++ Includes
2076fd5dd398aefd482323212524289298b75d9a63Stephen Wilson// Other libraries and framework includes
2176fd5dd398aefd482323212524289298b75d9a63Stephen Wilson// Project includes
22527b2b9befeeacfb153403d519d65cc399c6883fJohnny Chen#include "lldb/Core/Error.h"
237e9964783acae183c23a7ea470cedd64472eb233Johnny Chen#include "lldb/Target/Process.h"
247e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
2576fd5dd398aefd482323212524289298b75d9a63Stephen Wilson#include "lldb/Host/Host.h"
267e9964783acae183c23a7ea470cedd64472eb233Johnny Chen#include "lldb/Core/DataBufferHeap.h"
277e9964783acae183c23a7ea470cedd64472eb233Johnny Chen#include "lldb/Core/DataExtractor.h"
2876fd5dd398aefd482323212524289298b75d9a63Stephen Wilson
290be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain#include "lldb/Core/ModuleSpec.h"
300be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain#include "lldb/Symbol/ObjectFile.h"
310be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain
3276fd5dd398aefd482323212524289298b75d9a63Stephen Wilsonusing namespace lldb;
3376fd5dd398aefd482323212524289298b75d9a63Stephen Wilsonusing namespace lldb_private;
3476fd5dd398aefd482323212524289298b75d9a63Stephen Wilson
359b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Maleatypedef enum ProcessStateFlags
369b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea{
379b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    eProcessStateRunning           = (1u << 0), // Running
389b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    eProcessStateSleeping          = (1u << 1), // Sleeping in an interruptible wait
399b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    eProcessStateWaiting           = (1u << 2), // Waiting in an uninterruptible disk sleep
409b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    eProcessStateZombie            = (1u << 3), // Zombie
419b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    eProcessStateTracedOrStopped   = (1u << 4), // Traced or stopped (on a signal)
429b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    eProcessStatePaging            = (1u << 5)  // Paging
439b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea} ProcessStateFlags;
449b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
459b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Maleatypedef struct ProcessStatInfo
469b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea{
479b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    lldb::pid_t ppid;           // Parent Process ID
489b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    uint32_t fProcessState;     // ProcessStateFlags
499b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea} ProcessStatInfo;
509b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
519b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea// Get the process info with additional information from /proc/$PID/stat (like process state, and tracer pid).
529b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Maleastatic bool GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid);
539b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
54519bc3c9372c6c50796a79e0923d851fed1b241cMichael Sartain
556c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylornamespace
5676fd5dd398aefd482323212524289298b75d9a63Stephen Wilson{
57527b2b9befeeacfb153403d519d65cc399c6883fJohnny Chen
587e9964783acae183c23a7ea470cedd64472eb233Johnny Chenlldb::DataBufferSP
599b4c5483a697a45744975c395de08b06a6c7d1d0Daniel MaleaReadProcPseudoFile (lldb::pid_t pid, const char *name)
607e9964783acae183c23a7ea470cedd64472eb233Johnny Chen{
617e9964783acae183c23a7ea470cedd64472eb233Johnny Chen    int fd;
629b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    char path[PATH_MAX];
639b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
649b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // Make sure we've got a nil terminated buffer for all the folks calling
659b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // GetBytes() directly off our returned DataBufferSP if we hit an error.
669b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    lldb::DataBufferSP buf_sp (new DataBufferHeap(1, 0));
677e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
687e9964783acae183c23a7ea470cedd64472eb233Johnny Chen    // Ideally, we would simply create a FileSpec and call ReadFileContents.
697e9964783acae183c23a7ea470cedd64472eb233Johnny Chen    // However, files in procfs have zero size (since they are, in general,
707e9964783acae183c23a7ea470cedd64472eb233Johnny Chen    // dynamically generated by the kernel) which is incompatible with the
719b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // current ReadFileContents implementation. Therefore we simply stream the
727e9964783acae183c23a7ea470cedd64472eb233Johnny Chen    // data into a DataBuffer ourselves.
739b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (snprintf (path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0)
749b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    {
759b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        if ((fd = open (path, O_RDONLY, 0)) >= 0)
769b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        {
779b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            size_t bytes_read = 0;
789b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
799b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
809b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            for (;;)
819b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            {
829b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                size_t avail = buf_ap->GetByteSize() - bytes_read;
839b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                ssize_t status = read (fd, buf_ap->GetBytes() + bytes_read, avail);
849b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
859b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                if (status < 0)
869b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                    break;
879b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
889b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                if (status == 0)
899b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                {
909b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                    buf_ap->SetByteSize (bytes_read);
919b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                    buf_sp.reset (buf_ap.release());
929b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                    break;
939b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                }
949b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
959b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                bytes_read += status;
969b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
979b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                if (avail - status == 0)
989b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                    buf_ap->SetByteSize (2 * buf_ap->GetByteSize());
999b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            }
1009b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
1019b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            close (fd);
1029b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        }
1039b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    }
1049b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
1059b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    return buf_sp;
1069b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea}
1077e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
1089b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea} // anonymous namespace
1099b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
1109b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Maleastatic bool
1119b4c5483a697a45744975c395de08b06a6c7d1d0Daniel MaleaReadProcPseudoFileStat (lldb::pid_t pid, ProcessStatInfo& stat_info)
1129b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea{
1139b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // Read the /proc/$PID/stat file.
1149b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, "stat");
1157e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
1169b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // The filename of the executable is stored in parenthesis right after the pid. We look for the closing
1179b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // parenthesis for the filename and work from there in case the name has something funky like ')' in it.
1189b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    const char *filename_end = strrchr ((const char *)buf_sp->GetBytes(), ')');
1199b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (filename_end)
1207e9964783acae183c23a7ea470cedd64472eb233Johnny Chen    {
1219b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        char state = '\0';
1229b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        int ppid = LLDB_INVALID_PROCESS_ID;
1237e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
1249b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        // Read state and ppid.
1259b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        sscanf (filename_end + 1, " %c %d", &state, &ppid);
1267e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
1279b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        stat_info.ppid = ppid;
1287e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
1299b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        switch (state)
1307e9964783acae183c23a7ea470cedd64472eb233Johnny Chen        {
1319b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            case 'R':
1329b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                stat_info.fProcessState |= eProcessStateRunning;
1339b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                break;
1349b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            case 'S':
1359b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                stat_info.fProcessState |= eProcessStateSleeping;
1369b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                break;
1379b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            case 'D':
1389b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                stat_info.fProcessState |= eProcessStateWaiting;
1399b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                break;
1409b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            case 'Z':
1419b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                stat_info.fProcessState |= eProcessStateZombie;
1429b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                break;
1439b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            case 'T':
1449b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                stat_info.fProcessState |= eProcessStateTracedOrStopped;
1459b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                break;
1469b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            case 'W':
1479b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                stat_info.fProcessState |= eProcessStatePaging;
1489b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                break;
1497e9964783acae183c23a7ea470cedd64472eb233Johnny Chen        }
1507e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
1519b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        return true;
1527e9964783acae183c23a7ea470cedd64472eb233Johnny Chen    }
1537e9964783acae183c23a7ea470cedd64472eb233Johnny Chen
1549b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    return false;
1557e9964783acae183c23a7ea470cedd64472eb233Johnny Chen}
1566c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
1579b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Maleastatic void
1589b4c5483a697a45744975c395de08b06a6c7d1d0Daniel MaleaGetLinuxProcessUserAndGroup (lldb::pid_t pid, ProcessInstanceInfo &process_info, lldb::pid_t &tracerpid)
1599b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea{
1609b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    tracerpid = 0;
1619b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    uint32_t rUid = UINT32_MAX;     // Real User ID
1629b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    uint32_t eUid = UINT32_MAX;     // Effective User ID
1639b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    uint32_t rGid = UINT32_MAX;     // Real Group ID
1649b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    uint32_t eGid = UINT32_MAX;     // Effective Group ID
1659b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
1669b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // Read the /proc/$PID/status file and parse the Uid:, Gid:, and TracerPid: fields.
1679b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, "status");
1689b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
1699b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    static const char uid_token[] = "Uid:";
1709b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    char *buf_uid = strstr ((char *)buf_sp->GetBytes(), uid_token);
1719b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (buf_uid)
1729b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    {
1739b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        // Real, effective, saved set, and file system UIDs. Read the first two.
1749b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        buf_uid += sizeof(uid_token);
1759b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        rUid = strtol (buf_uid, &buf_uid, 10);
1769b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        eUid = strtol (buf_uid, &buf_uid, 10);
1779b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    }
1789b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
1799b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    static const char gid_token[] = "Gid:";
1809b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    char *buf_gid = strstr ((char *)buf_sp->GetBytes(), gid_token);
1819b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (buf_gid)
1829b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    {
1839b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        // Real, effective, saved set, and file system GIDs. Read the first two.
1849b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        buf_gid += sizeof(gid_token);
1859b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        rGid = strtol (buf_gid, &buf_gid, 10);
1869b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        eGid = strtol (buf_gid, &buf_gid, 10);
1879b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    }
1889b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
1899b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    static const char tracerpid_token[] = "TracerPid:";
1909b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    char *buf_tracerpid = strstr((char *)buf_sp->GetBytes(), tracerpid_token);
1919b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (buf_tracerpid)
1929b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    {
1939b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        // Tracer PID. 0 if we're not being debugged.
1949b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        buf_tracerpid += sizeof(tracerpid_token);
1959b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        tracerpid = strtol (buf_tracerpid, &buf_tracerpid, 10);
1969b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    }
1979b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
1989b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    process_info.SetUserID (rUid);
1999b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    process_info.SetEffectiveUserID (eUid);
2009b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    process_info.SetGroupID (rGid);
2019b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    process_info.SetEffectiveGroupID (eGid);
2029b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea}
2036c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
2046c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylorbool
2056c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew KaylorHost::GetOSVersion(uint32_t &major,
2066c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor                   uint32_t &minor,
2076c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor                   uint32_t &update)
2086c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor{
2096c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    struct utsname un;
2106c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    int status;
2116c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
2126c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    if (uname(&un))
2136c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor        return false;
2146c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
2156c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    status = sscanf(un.release, "%u.%u.%u", &major, &minor, &update);
2166c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    return status == 3;
2176c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor}
2186c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
2196c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew KaylorError
2206c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew KaylorHost::LaunchProcess (ProcessLaunchInfo &launch_info)
2216c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor{
2226c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    Error error;
2236c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    assert(!"Not implemented yet!!!");
2246c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    return error;
2256c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor}
2266c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
2276c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylorlldb::DataBufferSP
2286c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew KaylorHost::GetAuxvData(lldb_private::Process *process)
2296c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor{
2306c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    return ReadProcPseudoFile(process->GetID(), "auxv");
2316c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor}
2326c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
2339b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Maleastatic bool
2349b4c5483a697a45744975c395de08b06a6c7d1d0Daniel MaleaIsDirNumeric(const char *dname)
2359b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea{
2369b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    for (; *dname; dname++)
2379b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    {
2389b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        if (!isdigit (*dname))
2399b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            return false;
2409b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    }
2419b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    return true;
2429b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea}
2436c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
2449b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Maleauint32_t
2459b4c5483a697a45744975c395de08b06a6c7d1d0Daniel MaleaHost::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
2469b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea{
2479b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    static const char procdir[] = "/proc/";
2489b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2499b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    DIR *dirproc = opendir (procdir);
2509b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (dirproc)
2519b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    {
2529b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        struct dirent *direntry = NULL;
2539b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        const uid_t our_uid = getuid();
2549b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        const lldb::pid_t our_pid = getpid();
2559b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        bool all_users = match_info.GetMatchAllUsers();
2569b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2579b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        while ((direntry = readdir (dirproc)) != NULL)
2589b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        {
2599b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            if (direntry->d_type != DT_DIR || !IsDirNumeric (direntry->d_name))
2609b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                continue;
2619b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2629b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            lldb::pid_t pid = atoi (direntry->d_name);
2639b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2649b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            // Skip this process.
2659b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            if (pid == our_pid)
2669b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                continue;
2679b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2689b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            lldb::pid_t tracerpid;
2699b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            ProcessStatInfo stat_info;
2709b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            ProcessInstanceInfo process_info;
2719b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2729b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            if (!GetProcessAndStatInfo (pid, process_info, stat_info, tracerpid))
2739b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                continue;
2749b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2759b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            // Skip if process is being debugged.
2769b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            if (tracerpid != 0)
2779b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                continue;
2789b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2799b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            // Skip zombies.
2809b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            if (stat_info.fProcessState & eProcessStateZombie)
2819b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                continue;
2829b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2839b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            // Check for user match if we're not matching all users and not running as root.
2849b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
2859b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                continue;
2869b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2879b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            if (match_info.Matches (process_info))
2889b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            {
2899b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea                process_infos.Append (process_info);
2909b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea            }
2919b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        }
2929b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2939b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        closedir (dirproc);
2949b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    }
2959b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
2969b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    return process_infos.GetSize();
2979b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea}
2989b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
299c350e13fd3351613345141bee7d8b2543df54636Matt Kopecbool
300c350e13fd3351613345141bee7d8b2543df54636Matt KopecHost::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
301c350e13fd3351613345141bee7d8b2543df54636Matt Kopec{
302c350e13fd3351613345141bee7d8b2543df54636Matt Kopec    bool tids_changed = false;
303c350e13fd3351613345141bee7d8b2543df54636Matt Kopec    static const char procdir[] = "/proc/";
304c350e13fd3351613345141bee7d8b2543df54636Matt Kopec    static const char taskdir[] = "/task/";
305c350e13fd3351613345141bee7d8b2543df54636Matt Kopec    std::string process_task_dir = procdir + std::to_string(pid) + taskdir;
306c350e13fd3351613345141bee7d8b2543df54636Matt Kopec    DIR *dirproc = opendir (process_task_dir.c_str());
307c350e13fd3351613345141bee7d8b2543df54636Matt Kopec
308c350e13fd3351613345141bee7d8b2543df54636Matt Kopec    if (dirproc)
309c350e13fd3351613345141bee7d8b2543df54636Matt Kopec    {
310c350e13fd3351613345141bee7d8b2543df54636Matt Kopec        struct dirent *direntry = NULL;
311c350e13fd3351613345141bee7d8b2543df54636Matt Kopec        while ((direntry = readdir (dirproc)) != NULL)
312c350e13fd3351613345141bee7d8b2543df54636Matt Kopec        {
313c350e13fd3351613345141bee7d8b2543df54636Matt Kopec            if (direntry->d_type != DT_DIR || !IsDirNumeric (direntry->d_name))
314c350e13fd3351613345141bee7d8b2543df54636Matt Kopec                continue;
315c350e13fd3351613345141bee7d8b2543df54636Matt Kopec
316c350e13fd3351613345141bee7d8b2543df54636Matt Kopec            lldb::tid_t tid = atoi(direntry->d_name);
317c350e13fd3351613345141bee7d8b2543df54636Matt Kopec            TidMap::iterator it = tids_to_attach.find(tid);
318c350e13fd3351613345141bee7d8b2543df54636Matt Kopec            if (it == tids_to_attach.end())
319c350e13fd3351613345141bee7d8b2543df54636Matt Kopec            {
320c350e13fd3351613345141bee7d8b2543df54636Matt Kopec                tids_to_attach.insert(TidPair(tid, false));
321c350e13fd3351613345141bee7d8b2543df54636Matt Kopec                tids_changed = true;
322c350e13fd3351613345141bee7d8b2543df54636Matt Kopec            }
323c350e13fd3351613345141bee7d8b2543df54636Matt Kopec        }
324c350e13fd3351613345141bee7d8b2543df54636Matt Kopec        closedir (dirproc);
325c350e13fd3351613345141bee7d8b2543df54636Matt Kopec    }
326c350e13fd3351613345141bee7d8b2543df54636Matt Kopec
327c350e13fd3351613345141bee7d8b2543df54636Matt Kopec    return tids_changed;
328c350e13fd3351613345141bee7d8b2543df54636Matt Kopec}
329c350e13fd3351613345141bee7d8b2543df54636Matt Kopec
3309b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Maleastatic bool
3310be9b3b58e6ba0929b325c4520d388aafed5891fMichael SartainGetELFProcessCPUType (const char *exe_path, ProcessInstanceInfo &process_info)
3320be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain{
3330be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    // Clear the architecture.
3340be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    process_info.GetArchitecture().Clear();
3350be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain
3360be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    ModuleSpecList specs;
3370be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    FileSpec filespec (exe_path, false);
3389671f05a834b16d345d403410f6a6336e3f9c454Jason Molenda    const size_t num_specs = ObjectFile::GetModuleSpecifications (filespec, 0, 0, specs);
3390be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    // GetModuleSpecifications() could fail if the executable has been deleted or is locked.
3400be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    // But it shouldn't return more than 1 architecture.
3410be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
3420be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    if (num_specs == 1)
3430be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    {
3440be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain        ModuleSpec module_spec;
3450be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain        if (specs.GetModuleSpecAtIndex (0, module_spec) && module_spec.GetArchitecture().IsValid())
3460be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain        {
3470be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain            process_info.GetArchitecture () = module_spec.GetArchitecture();
3480be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain            return true;
3490be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain        }
3500be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    }
3510be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    return false;
3520be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain}
3530be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain
3540be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartainstatic bool
3559b4c5483a697a45744975c395de08b06a6c7d1d0Daniel MaleaGetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid)
3566c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor{
3579b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    tracerpid = 0;
3586c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    process_info.Clear();
3599b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    ::memset (&stat_info, 0, sizeof(stat_info));
3609b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    stat_info.ppid = LLDB_INVALID_PROCESS_ID;
3616c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
3626c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    // Use special code here because proc/[pid]/exe is a symbolic link.
3636c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    char link_path[PATH_MAX];
3646c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    char exe_path[PATH_MAX] = "";
3659b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (snprintf (link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", pid) <= 0)
3669b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        return false;
3676c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
3689b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    ssize_t len = readlink (link_path, exe_path, sizeof(exe_path) - 1);
3699b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (len <= 0)
3709b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        return false;
3719b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
3729b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // readlink does not append a null byte.
3739b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    exe_path[len] = 0;
3749b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
3759b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // If the binary has been deleted, the link name has " (deleted)" appended.
3769b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    //  Remove if there.
3779b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    static const ssize_t deleted_len = strlen(" (deleted)");
3789b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (len > deleted_len &&
3799b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        !strcmp(exe_path + len - deleted_len, " (deleted)"))
3809b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    {
3819b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        exe_path[len - deleted_len] = 0;
3826c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    }
3830be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    else
3840be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    {
3850be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain        GetELFProcessCPUType (exe_path, process_info);
3860be9b3b58e6ba0929b325c4520d388aafed5891fMichael Sartain    }
3879b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
3889b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    process_info.SetProcessID(pid);
3896c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    process_info.GetExecutableFile().SetFile(exe_path, false);
3906c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
3916c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    lldb::DataBufferSP buf_sp;
3926c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
3936c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    // Get the process environment.
3946c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    buf_sp = ReadProcPseudoFile(pid, "environ");
3956c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    Args &info_env = process_info.GetEnvironmentEntries();
3966c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    char *next_var = (char *)buf_sp->GetBytes();
3976c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    char *end_buf = next_var + buf_sp->GetByteSize();
3986c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    while (next_var < end_buf && 0 != *next_var)
3996c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    {
4006c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor        info_env.AppendArgument(next_var);
4016c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor        next_var += strlen(next_var) + 1;
4026c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    }
4036c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
4046c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    // Get the commond line used to start the process.
4056c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    buf_sp = ReadProcPseudoFile(pid, "cmdline");
4066c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
4076c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    // Grab Arg0 first.
4086c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    char *cmd = (char *)buf_sp->GetBytes();
4096c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    process_info.SetArg0(cmd);
4106c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
4116c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    // Now process any remaining arguments.
4126c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    Args &info_args = process_info.GetArguments();
4136c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    char *next_arg = cmd + strlen(cmd) + 1;
4146c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    end_buf = cmd + buf_sp->GetByteSize();
4156c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    while (next_arg < end_buf && 0 != *next_arg)
4166c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    {
4176c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor        info_args.AppendArgument(next_arg);
4186c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor        next_arg += strlen(next_arg) + 1;
4196c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    }
4206c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
4219b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // Read /proc/$PID/stat to get our parent pid.
4229b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    if (ReadProcPseudoFileStat (pid, stat_info))
4239b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    {
4249b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea        process_info.SetParentProcessID (stat_info.ppid);
4259b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    }
4269b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
4279b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    // Get User and Group IDs and get tracer pid.
4289b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    GetLinuxProcessUserAndGroup (pid, process_info, tracerpid);
4296c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor
4306c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    return true;
431024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec}
432024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec
4339b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Maleabool
4349b4c5483a697a45744975c395de08b06a6c7d1d0Daniel MaleaHost::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
4359b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea{
4369b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    lldb::pid_t tracerpid;
4379b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    ProcessStatInfo stat_info;
4389b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
4399b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea    return GetProcessAndStatInfo (pid, process_info, stat_info, tracerpid);
4409b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea}
4419b4c5483a697a45744975c395de08b06a6c7d1d0Daniel Malea
442024497728739eedffc9b79c28337fba22f07f8b4Matt Kopecvoid
443024497728739eedffc9b79c28337fba22f07f8b4Matt KopecHost::ThreadCreated (const char *thread_name)
444024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec{
445024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec    if (!Host::SetThreadName (LLDB_INVALID_PROCESS_ID, LLDB_INVALID_THREAD_ID, thread_name))
446024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec    {
447f476592805f813aa7a94f7d6770481503140aae2Ed Maste        Host::SetShortThreadName (LLDB_INVALID_PROCESS_ID, LLDB_INVALID_THREAD_ID, thread_name, 16);
448024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec    }
449024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec}
450024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec
4510ba7548c72ed9a242415cb78f2351146d7afe3b7Matt Kopecstd::string
4520ba7548c72ed9a242415cb78f2351146d7afe3b7Matt KopecHost::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
4530ba7548c72ed9a242415cb78f2351146d7afe3b7Matt Kopec{
4547526625a76ca97a2637749b0cc4068bf0bd907fbMichael Sartain    assert(pid != LLDB_INVALID_PROCESS_ID);
4557526625a76ca97a2637749b0cc4068bf0bd907fbMichael Sartain    assert(tid != LLDB_INVALID_THREAD_ID);
4567526625a76ca97a2637749b0cc4068bf0bd907fbMichael Sartain
45717c4bc477e3007db9d34f6f4947543f8ad946717Michael Sartain    // Read /proc/$TID/comm file.
45817c4bc477e3007db9d34f6f4947543f8ad946717Michael Sartain    lldb::DataBufferSP buf_sp = ReadProcPseudoFile (tid, "comm");
4597526625a76ca97a2637749b0cc4068bf0bd907fbMichael Sartain    const char *comm_str = (const char *)buf_sp->GetBytes();
4607526625a76ca97a2637749b0cc4068bf0bd907fbMichael Sartain    const char *cr_str = ::strchr(comm_str, '\n');
4617526625a76ca97a2637749b0cc4068bf0bd907fbMichael Sartain    size_t length = cr_str ? (cr_str - comm_str) : strlen(comm_str);
4620ba7548c72ed9a242415cb78f2351146d7afe3b7Matt Kopec
4637526625a76ca97a2637749b0cc4068bf0bd907fbMichael Sartain    std::string thread_name(comm_str, length);
4647526625a76ca97a2637749b0cc4068bf0bd907fbMichael Sartain    return thread_name;
4650ba7548c72ed9a242415cb78f2351146d7afe3b7Matt Kopec}
4660ba7548c72ed9a242415cb78f2351146d7afe3b7Matt Kopec
467024497728739eedffc9b79c28337fba22f07f8b4Matt Kopecvoid
468024497728739eedffc9b79c28337fba22f07f8b4Matt KopecHost::Backtrace (Stream &strm, uint32_t max_frames)
469024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec{
4700bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain    if (max_frames > 0)
4710bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain    {
4720bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain        std::vector<void *> frame_buffer (max_frames, NULL);
4730bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain        int num_frames = ::backtrace (&frame_buffer[0], frame_buffer.size());
4740bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain        char** strs = ::backtrace_symbols (&frame_buffer[0], num_frames);
4750bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain        if (strs)
4760bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain        {
4770bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain            // Start at 1 to skip the "Host::Backtrace" frame
4780bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain            for (int i = 1; i < num_frames; ++i)
4790bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain                strm.Printf("%s\n", strs[i]);
4800bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain            ::free (strs);
4810bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain        }
4820bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain    }
483024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec}
484024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec
485024497728739eedffc9b79c28337fba22f07f8b4Matt Kopecsize_t
486024497728739eedffc9b79c28337fba22f07f8b4Matt KopecHost::GetEnvironment (StringList &env)
487024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec{
4880bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain    char **host_env = environ;
4890bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain    char *env_entry;
4900bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain    size_t i;
4910bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain    for (i=0; (env_entry = host_env[i]) != NULL; ++i)
4920bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain        env.AppendString(env_entry);
4930bbfea68d47cc401b6f8309acc788d8224401ed6Michael Sartain    return i;
494024497728739eedffc9b79c28337fba22f07f8b4Matt Kopec}
495