From fca9c6bb9f33e53782ec7592a1faa82aef8b23d0 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Tue, 18 Dec 2012 04:39:43 +0000 Subject: [PATCH] Add a new qProcessInfo packet to debugserver. This can be used by lldb to ask for information about the process debugserver is attached to/launched. Particularly useful on a 64-bit x86 Mac system which can run 32-bit or 64-bit user-land processes. llvm-svn: 170409 --- lldb/docs/lldb-gdb-remote.txt | 31 ++++++++ lldb/tools/debugserver/source/RNBRemote.cpp | 79 +++++++++++++++++++++ lldb/tools/debugserver/source/RNBRemote.h | 2 + 3 files changed, 112 insertions(+) diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt index bfede67df707..594e3fc3a86d 100644 --- a/lldb/docs/lldb-gdb-remote.txt +++ b/lldb/docs/lldb-gdb-remote.txt @@ -397,6 +397,37 @@ vendor: is a string that represents the vendor (apple) endian: is one of "little", "big", or "pdp" ptrsize: is a number that represents how big pointers are in bytes on the debug target +//---------------------------------------------------------------------- +// "qProcessInfo" +// +// BRIEF +// Get information about the process we are currently debugging. +// +// PRIORITY TO IMPLEMENT +// Medium. On systems which can launch multiple different architecture processes, +// the qHostInfo may not disambiguate sufficiently to know what kind of +// process is being debugged. +// e.g. on a 64-bit x86 Mc system both 32-bit and 64-bit user processes are possible, +// and with Mach-O univeral files, the executable file may contain both 32- and +// 64-bit slices so it may be impossible to know until you're attached to a real +// process to know what you're working with. +//---------------------------------------------------------------------- + +send packet: $qProcessInfo#00 +$pid:0x9517;parent-pid:0x9519;real-uid:0xecf;real-gid:0xb;effective-uid:0xecf;effective-gid:0xb;cputype:0x7;ptrsize:0x4;#00 + +Key value pairs include: + +pid: the process id +parent-pid: the process of the parent process (often debugserver will become the parent when attaching) +real-uid: the real user id of the process +real-gid: the real group id of the process +effective-uid: the effective user id of the process +effective-gid: the effective group id of the process +cputype: the Mach-O CPU type of the process +ptrsize: is a number that represents how big pointers are in bytes + + //---------------------------------------------------------------------- // "qShlibInfoAddr" // diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 4ba0ce08dbd9..1c13a325e757 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -173,6 +173,7 @@ RNBRemote::CreatePacketTable () t.push_back (Packet (query_vattachorwait_supported, &RNBRemote::HandlePacket_qVAttachOrWaitSupported,NULL, "qVAttachOrWaitSupported", "Replys with OK if the 'vAttachOrWait' packet is supported.")); t.push_back (Packet (query_sync_thread_state_supported, &RNBRemote::HandlePacket_qSyncThreadStateSupported,NULL, "qSyncThreadStateSupported", "Replys with OK if the 'QSyncThreadState:' packet is supported.")); t.push_back (Packet (query_host_info, &RNBRemote::HandlePacket_qHostInfo, NULL, "qHostInfo", "Replies with multiple 'key:value;' tuples appended to each other.")); + t.push_back (Packet (query_process_info, &RNBRemote::HandlePacket_qProcessInfo, NULL, "qProcessInfo", "Replies with multiple 'key:value;' tuples appended to each other.")); // t.push_back (Packet (query_symbol_lookup, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qSymbol", "Notify that host debugger is ready to do symbol lookups")); t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets")); t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specifc packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command")); @@ -3777,3 +3778,81 @@ RNBRemote::HandlePacket_qHostInfo (const char *p) strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; return SendPacket (strm.str()); } + + +// Note that all numeric values returned by qProcessInfo are hex encoded, +// including the pid and the cpu type, and are fixed with "0x" to indicate +// this encoding. + +rnb_err_t +RNBRemote::HandlePacket_qProcessInfo (const char *p) +{ + nub_process_t pid; + std::ostringstream rep; + + // If we haven't run the process yet, return an error. + if (!m_ctx.HasValidProcessID()) + return SendPacket ("E68"); + + pid = m_ctx.ProcessID(); + + rep << "pid:0x" << std::hex << pid << ";"; + + int procpid_mib[4]; + procpid_mib[0] = CTL_KERN; + procpid_mib[1] = KERN_PROC; + procpid_mib[2] = KERN_PROC_PID; + procpid_mib[3] = pid; + struct kinfo_proc proc_kinfo; + size_t proc_kinfo_size = sizeof(struct kinfo_proc); + + if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) + { + if (proc_kinfo_size > 0) + { + rep << "parent-pid:0x" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";"; + rep << "real-uid:0x" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";"; + rep << "real-gid:0x" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";"; + rep << "effective-uid:0x" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";"; + if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) + rep << "effective-gid:0x" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";"; + } + } + + int cputype_mib[CTL_MAXNAME]={0,}; + size_t cputype_mib_len = CTL_MAXNAME; + if (::sysctlnametomib("sysctl.proc_cputype", cputype_mib, &cputype_mib_len) == 0) + { + cputype_mib[cputype_mib_len] = pid; + cputype_mib_len++; + cpu_type_t cpu; + size_t len = sizeof(cpu); + if (::sysctl (cputype_mib, cputype_mib_len, &cpu, &len, 0, 0) == 0) + { + rep << "cputype:0x" << std::hex << cpu << ";"; + } + } + + nub_thread_t thread = DNBProcessGetCurrentThread (pid); + + kern_return_t kr; + +#if defined (__x86_64__) || defined (__i386__) + x86_thread_state_t gp_regs; + mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; + kr = thread_get_state (thread, x86_THREAD_STATE, + (thread_state_t) &gp_regs, &gp_count); + if (kr == KERN_SUCCESS) + { + if (gp_regs.tsh.flavor == x86_THREAD_STATE64) + rep << "ptrsize:0x8;"; + else + rep << "ptrsize:0x4;"; + } +#elif defined (__arm__) + rep << "ptrsize:0x4;"; +#endif + + return SendPacket (rep.str()); +} + diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h index 0255e7f6e6c8..8ea470ef3163 100644 --- a/lldb/tools/debugserver/source/RNBRemote.h +++ b/lldb/tools/debugserver/source/RNBRemote.h @@ -95,6 +95,7 @@ public: query_vattachorwait_supported, // 'qVAttachOrWaitSupported' query_sync_thread_state_supported,// 'QSyncThreadState' query_host_info, // 'qHostInfo' + query_process_info, // 'qProcessInfo' pass_signals_to_inferior, // 'QPassSignals' start_noack_mode, // 'QStartNoAckMode' prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID @@ -176,6 +177,7 @@ public: rnb_err_t HandlePacket_qThreadExtraInfo (const char *p); rnb_err_t HandlePacket_qThreadStopInfo (const char *p); rnb_err_t HandlePacket_qHostInfo (const char *p); + rnb_err_t HandlePacket_qProcessInfo (const char *p); rnb_err_t HandlePacket_QStartNoAckMode (const char *p); rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p); rnb_err_t HandlePacket_QSetLogging (const char *p);