diff options
author | Jason Molenda <jmolenda@apple.com> | 2013-10-18 05:55:24 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2013-10-18 05:55:24 +0000 |
commit | 3dc4f44e71bc9d5650b2cd134ca4733438acfbfb (patch) | |
tree | cebabb5909032f4f2100b2f12c575cfdfc445048 | |
parent | 19bff32e093de869aaf7fe2161ed23718d62e437 (diff) | |
download | bcm5719-llvm-3dc4f44e71bc9d5650b2cd134ca4733438acfbfb.tar.gz bcm5719-llvm-3dc4f44e71bc9d5650b2cd134ca4733438acfbfb.zip |
Move the code which translates a dispatch_qaddr into a
queue name out of ProcessGDBRemote and in to the Platform
plugin, specifically PlatformDarwin.
Also add a Platform method to translate a dispatch_quaddr
to a QueueID, and a Thread::GetQueueID().
I'll add an SBThread::GetQueueID() next.
llvm-svn: 192949
-rw-r--r-- | lldb/include/lldb/Target/Platform.h | 55 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Thread.h | 6 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-defines.h | 1 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-types.h | 1 | ||||
-rw-r--r-- | lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp | 110 | ||||
-rw-r--r-- | lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h | 7 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 94 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h | 1 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp | 34 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h | 3 | ||||
-rw-r--r-- | lldb/tools/darwin-threads/examine-threads.c | 20 |
11 files changed, 223 insertions, 109 deletions
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index c844e069244..f4fde2a98c3 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -732,7 +732,60 @@ namespace lldb_private { { return 1; } - + + //------------------------------------------------------------------ + /// Locate a queue name given a thread's qaddr + /// + /// On a system using libdispatch ("Grand Central Dispatch") style + /// queues, a thread may be associated with a GCD queue or not, + /// and a queue may be associated with multiple threads. + /// The process/thread must provide a way to find the "dispatch_qaddr" + /// for each thread, and from that dispatch_qaddr this Platform method + /// will locate the queue name and provide that. + /// + /// @param[in] process + /// A process is required for reading memory. + /// + /// @param[in] dispatch_qaddr + /// The dispatch_qaddr for this thread. + /// + /// @return + /// The name of the queue, if there is one. An empty string + /// means that this thread is not associated with a dispatch + /// queue. + //------------------------------------------------------------------ + virtual std::string + GetQueueNameForThreadQAddress (Process *process, lldb::addr_t dispatch_qaddr) + { + return ""; + } + + //------------------------------------------------------------------ + /// Locate a queue ID given a thread's qaddr + /// + /// On a system using libdispatch ("Grand Central Dispatch") style + /// queues, a thread may be associated with a GCD queue or not, + /// and a queue may be associated with multiple threads. + /// The process/thread must provide a way to find the "dispatch_qaddr" + /// for each thread, and from that dispatch_qaddr this Platform method + /// will locate the queue ID and provide that. + /// + /// @param[in] process + /// A process is required for reading memory. + /// + /// @param[in] dispatch_qaddr + /// The dispatch_qaddr for this thread. + /// + /// @return + /// The queue_id for this thread, if this thread is associated + /// with a dispatch queue. Else LLDB_INVALID_QUEUE_ID is returned. + //------------------------------------------------------------------ + virtual lldb::queue_id_t + GetQueueIDForThreadQAddress (Process *process, lldb::addr_t dispatch_qaddr) + { + return LLDB_INVALID_QUEUE_ID; + } + protected: bool m_is_host; // Set to true when we are able to actually set the OS version while diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index 42aa2c81219..7dac37caa20 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -339,6 +339,12 @@ public: return NULL; } + virtual lldb::queue_id_t + GetQueueID () + { + return LLDB_INVALID_QUEUE_ID; + } + virtual const char * GetQueueName () { diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h index bca905e6761..82307d2f531 100644 --- a/lldb/include/lldb/lldb-defines.h +++ b/lldb/include/lldb/lldb-defines.h @@ -83,6 +83,7 @@ #define LLDB_INVALID_SIGNAL_NUMBER INT32_MAX #define LLDB_INVALID_OFFSET UINT64_MAX // Must match max of lldb::offset_t #define LLDB_INVALID_LINE_NUMBER UINT32_MAX +#define LLDB_INVALID_QUEUE_ID 0 //---------------------------------------------------------------------- /// CPU Type defintions diff --git a/lldb/include/lldb/lldb-types.h b/lldb/include/lldb/lldb-types.h index c7b3e7e6c3c..5851b5d3f92 100644 --- a/lldb/include/lldb/lldb-types.h +++ b/lldb/include/lldb/lldb-types.h @@ -95,6 +95,7 @@ namespace lldb typedef int32_t break_id_t; typedef int32_t watch_id_t; typedef void * clang_type_t; + typedef uint64_t queue_id_t; } diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index 084aa3886b6..841d5405e1a 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -38,7 +38,8 @@ using namespace lldb_private; //------------------------------------------------------------------ PlatformDarwin::PlatformDarwin (bool is_host) : PlatformPOSIX(is_host), // This is the local host platform - m_developer_directory () + m_developer_directory (), + m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS) { } @@ -847,6 +848,113 @@ PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Targ return false; } +std::string +PlatformDarwin::GetQueueNameForThreadQAddress (Process *process, addr_t thread_dispatch_qaddr) +{ + std::string dispatch_queue_name; + if (thread_dispatch_qaddr == LLDB_INVALID_ADDRESS || thread_dispatch_qaddr == 0 || process == NULL) + return ""; + + Target &target = process->GetTarget(); + + // Cache the dispatch_queue_offsets_addr value so we don't always have + // to look it up + if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS) + { + static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets"); + const Symbol *dispatch_queue_offsets_symbol = NULL; + + // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6 ("Snow Leopard") + ModuleSpec libSystem_module_spec (FileSpec("libSystem.B.dylib", false)); + ModuleSP module_sp(target.GetImages().FindFirstModule (libSystem_module_spec)); + if (module_sp) + dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData); + + // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion") and later + if (dispatch_queue_offsets_symbol == NULL) + { + ModuleSpec libdispatch_module_spec (FileSpec("libdispatch.dylib", false)); + module_sp = target.GetImages().FindFirstModule (libdispatch_module_spec); + if (module_sp) + dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData); + } + if (dispatch_queue_offsets_symbol) + m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetAddress().GetLoadAddress(&target); + + if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS) + return ""; + } + + uint8_t memory_buffer[8]; + DataExtractor data (memory_buffer, + sizeof(memory_buffer), + target.GetArchitecture().GetByteOrder(), + target.GetArchitecture().GetAddressByteSize()); + + // Excerpt from src/queue_private.h + // version 4 of this struct first appears in Mac OS X 10.9 ("Mavericks") and iOS 7. + // TODO When version 1-3 no longer needs to be supported, the dqo_label offset should be + // read from the inferior one time and saved in an ivar like m_dispatch_queue_offsets_addr. + struct dispatch_queue_offsets_s + { + uint16_t dqo_version; + uint16_t dqo_label; // in version 1-3, offset to string; in version 4+, offset to a pointer to a string + uint16_t dqo_label_size; // in version 1-3, length of string; in version 4+, size of a (void*) in this process + } dispatch_queue_offsets; + + Error error; + if (process->ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets)) + { + lldb::offset_t data_offset = 0; + if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t))) + { + if (process->ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize()) + { + data_offset = 0; + lldb::addr_t queue_addr = data.GetAddress(&data_offset); + if (dispatch_queue_offsets.dqo_version >= 4) + { + // libdispatch versions 4+, pointer to dispatch name is in the + // queue structure. + lldb::addr_t pointer_to_label_address = queue_addr + dispatch_queue_offsets.dqo_label; + if (process->ReadMemory (pointer_to_label_address, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize()) + { + data_offset = 0; + lldb::addr_t label_addr = data.GetAddress(&data_offset); + process->ReadCStringFromMemory (label_addr, dispatch_queue_name, error); + } + } + else + { + // libdispatch versions 1-3, dispatch name is a fixed width char array + // in the queue structure. + lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label; + dispatch_queue_name.resize(dispatch_queue_offsets.dqo_label_size, '\0'); + size_t bytes_read = process->ReadMemory (label_addr, &dispatch_queue_name[0], dispatch_queue_offsets.dqo_label_size, error); + if (bytes_read < dispatch_queue_offsets.dqo_label_size) + dispatch_queue_name.erase (bytes_read); + } + } + } + } + return dispatch_queue_name; +} + +lldb::queue_id_t +PlatformDarwin::GetQueueIDForThreadQAddress (Process *process, lldb::addr_t dispatch_qaddr) +{ + if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0 || process == NULL) + return LLDB_INVALID_QUEUE_ID; + + Error error; + uint32_t ptr_size = process->GetTarget().GetArchitecture().GetAddressByteSize(); + uint64_t this_thread_queue_id = process->ReadUnsignedIntegerFromMemory (dispatch_qaddr, ptr_size, LLDB_INVALID_QUEUE_ID, error); + if (!error.Success()) + return LLDB_INVALID_QUEUE_ID; + + return this_thread_queue_id; +} + bool PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index 4e9b7029b51..64598c93f6b 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -111,6 +111,12 @@ public: virtual size_t GetEnvironment (lldb_private::StringList &environment); + std::string + GetQueueNameForThreadQAddress (lldb_private::Process *process, lldb::addr_t dispatch_qaddr); + + lldb::queue_id_t + GetQueueIDForThreadQAddress (lldb_private::Process *process, lldb::addr_t dispatch_qaddr); + bool ARMGetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch); @@ -129,6 +135,7 @@ protected: bool *did_create_ptr); std::string m_developer_directory; + lldb::addr_t m_dispatch_queue_offsets_addr; const char * GetDeveloperDirectory(); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 1b8791c6e74..0f5f8903799 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -266,7 +266,6 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : m_continue_C_tids (), m_continue_s_tids (), m_continue_S_tids (), - m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS), m_max_memory_size (512), m_addr_to_mmap_size (), m_thread_create_bp_sp (), @@ -934,8 +933,6 @@ ProcessGDBRemote::DidLaunchOrAttach () log->Printf ("ProcessGDBRemote::DidLaunch()"); if (GetID() != LLDB_INVALID_PROCESS_ID) { - m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS; - BuildDynamicRegisterInfo (false); // See if the GDB server supports the qHostInfo information @@ -2994,97 +2991,6 @@ ProcessGDBRemote::AsyncThread (void *arg) return NULL; } -const char * -ProcessGDBRemote::GetDispatchQueueNameForThread -( - addr_t thread_dispatch_qaddr, - std::string &dispatch_queue_name -) -{ - dispatch_queue_name.clear(); - if (thread_dispatch_qaddr != 0 && thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) - { - // Cache the dispatch_queue_offsets_addr value so we don't always have - // to look it up - if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS) - { - static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets"); - const Symbol *dispatch_queue_offsets_symbol = NULL; - ModuleSpec libSystem_module_spec (FileSpec("libSystem.B.dylib", false)); - ModuleSP module_sp(GetTarget().GetImages().FindFirstModule (libSystem_module_spec)); - if (module_sp) - dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData); - - if (dispatch_queue_offsets_symbol == NULL) - { - ModuleSpec libdispatch_module_spec (FileSpec("libdispatch.dylib", false)); - module_sp = GetTarget().GetImages().FindFirstModule (libdispatch_module_spec); - if (module_sp) - dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData); - } - if (dispatch_queue_offsets_symbol) - m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetAddress().GetLoadAddress(&m_target); - - if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS) - return NULL; - } - - uint8_t memory_buffer[8]; - DataExtractor data (memory_buffer, - sizeof(memory_buffer), - m_target.GetArchitecture().GetByteOrder(), - m_target.GetArchitecture().GetAddressByteSize()); - - // Excerpt from src/queue_private.h - struct dispatch_queue_offsets_s - { - uint16_t dqo_version; - uint16_t dqo_label; // in version 1-3, offset to string; in version 4+, offset to a pointer to a string - uint16_t dqo_label_size; // in version 1-3, length of string; in version 4+, size of a (void*) in this process - } dispatch_queue_offsets; - - - Error error; - if (ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets)) - { - lldb::offset_t data_offset = 0; - if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t))) - { - if (ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize()) - { - data_offset = 0; - lldb::addr_t queue_addr = data.GetAddress(&data_offset); - if (dispatch_queue_offsets.dqo_version >= 4) - { - // libdispatch versions 4+, pointer to dispatch name is in the - // queue structure. - lldb::addr_t pointer_to_label_address = queue_addr + dispatch_queue_offsets.dqo_label; - if (ReadMemory (pointer_to_label_address, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize()) - { - data_offset = 0; - lldb::addr_t label_addr = data.GetAddress(&data_offset); - ReadCStringFromMemory (label_addr, dispatch_queue_name, error); - } - } - else - { - // libdispatch versions 1-3, dispatch name is a fixed width char array - // in the queue structure. - lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label; - dispatch_queue_name.resize(dispatch_queue_offsets.dqo_label_size, '\0'); - size_t bytes_read = ReadMemory (label_addr, &dispatch_queue_name[0], dispatch_queue_offsets.dqo_label_size, error); - if (bytes_read < dispatch_queue_offsets.dqo_label_size) - dispatch_queue_name.erase (bytes_read); - } - } - } - } - } - if (dispatch_queue_name.empty()) - return NULL; - return dispatch_queue_name.c_str(); -} - //uint32_t //ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids) //{ diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index ef79d776b50..86f051040a8 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -332,7 +332,6 @@ protected: tid_sig_collection m_continue_C_tids; // 'C' for continue with signal tid_collection m_continue_s_tids; // 's' for step tid_sig_collection m_continue_S_tids; // 'S' for step with signal - lldb::addr_t m_dispatch_queue_offsets_addr; size_t m_max_memory_size; // The maximum number of bytes to read/write when reading and writing memory MMapMap m_addr_to_mmap_size; lldb::BreakpointSP m_thread_create_bp_sp; diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index cce5a599566..4e475c80bda 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -10,16 +10,17 @@ #include "ThreadGDBRemote.h" +#include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/DataExtractor.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/State.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Unwind.h" -#include "lldb/Breakpoint/Watchpoint.h" #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" @@ -73,13 +74,38 @@ ThreadGDBRemote::GetQueueName () ProcessSP process_sp (GetProcess()); if (process_sp) { - ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get()); - return gdb_process->GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name); + PlatformSP platform_sp (process_sp->GetTarget().GetPlatform()); + if (platform_sp) + { + m_dispatch_queue_name = platform_sp->GetQueueNameForThreadQAddress (process_sp.get(), m_thread_dispatch_qaddr); + } + if (m_dispatch_queue_name.length() > 0) + { + return m_dispatch_queue_name.c_str(); + } } } return NULL; } +queue_id_t +ThreadGDBRemote::GetQueueID () +{ + if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) + { + ProcessSP process_sp (GetProcess()); + if (process_sp) + { + PlatformSP platform_sp (process_sp->GetTarget().GetPlatform()); + if (platform_sp) + { + return platform_sp->GetQueueIDForThreadQAddress (process_sp.get(), m_thread_dispatch_qaddr); + } + } + } + return LLDB_INVALID_QUEUE_ID; +} + void ThreadGDBRemote::WillResume (StateType resume_state) { diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index 50a3f19c650..dd4cc036ef8 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -38,6 +38,9 @@ public: virtual const char * GetQueueName (); + virtual lldb::queue_id_t + GetQueueID (); + virtual lldb::RegisterContextSP GetRegisterContext (); diff --git a/lldb/tools/darwin-threads/examine-threads.c b/lldb/tools/darwin-threads/examine-threads.c index 291f1780996..9f02396e515 100644 --- a/lldb/tools/darwin-threads/examine-threads.c +++ b/lldb/tools/darwin-threads/examine-threads.c @@ -8,6 +8,7 @@ #include <ctype.h> #include <libproc.h> #include <errno.h> +#include <dispatch/dispatch.h> /* Step through the process table, find a matching process name, return the pid of that matched process. @@ -419,20 +420,23 @@ main (int argc, char **argv) case TH_STATE_HALTED: puts ("halted"); break; default: puts (""); } + + printf (" pthread handle id 0x%llx (not the same value as pthread_self() returns)\n", (uint64_t) identifier_info.thread_handle); + + struct proc_threadinfo pth; + int proc_threadinfo_succeeded = get_proc_threadinfo (pid, identifier_info.thread_handle, &pth); + + if (proc_threadinfo_succeeded && pth.pth_name[0] != '\0') + printf (" thread name '%s'\n", pth.pth_name); + + printf (" libdispatch qaddr 0x%llx (not the same as the dispatch_queue_t token)\n", (uint64_t) identifier_info.dispatch_qaddr); + if (verbose) { printf (" (examine-threads port namespace) mach port # 0x%4.4x\n", (int) thread_list[i]); thread_t mach_port_inferior_namespace; if (inferior_namespace_mach_port_num (task, thread_list[i], &mach_port_inferior_namespace)) printf (" (inferior port namepsace) mach port # 0x%4.4x\n", (int) mach_port_inferior_namespace); - printf (" pthread handle id 0x%llx\n", (uint64_t) identifier_info.thread_handle); - - struct proc_threadinfo pth; - int proc_threadinfo_succeeded = get_proc_threadinfo (pid, identifier_info.thread_handle, &pth); - - if (proc_threadinfo_succeeded && pth.pth_name[0] != '\0') - printf (" thread name '%s' ", pth.pth_name); - printf (" user %d.%06ds, system %d.%06ds", basic_info->user_time.seconds, basic_info->user_time.microseconds, basic_info->system_time.seconds, basic_info->system_time.microseconds); |