diff options
author | Jason Molenda <jmolenda@apple.com> | 2014-06-13 02:37:02 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2014-06-13 02:37:02 +0000 |
commit | 705b1809641ba3e102d437cffff29bfe2b611cab (patch) | |
tree | d7d544a448ba355e7a363e91e2a782ccf3c01f11 /lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp | |
parent | b4ad29be9277829737ce984494f80d2bf17cfd11 (diff) | |
download | bcm5719-llvm-705b1809641ba3e102d437cffff29bfe2b611cab.tar.gz bcm5719-llvm-705b1809641ba3e102d437cffff29bfe2b611cab.zip |
Initial merge of some of the iOS 8 / Mac OS X Yosemite specific
lldb support. I'll be doing more testing & cleanup but I wanted to
get the initial checkin done.
This adds a new SBExpressionOptions::SetLanguage API for selecting a
language of an expression.
I added adds a new SBThread::GetInfoItemByPathString for retriving
information about a thread from that thread's StructuredData.
I added a new StructuredData class for representing
key-value/array/dictionary information (e.g. JSON formatted data).
Helper functions to read JSON and create a StructuredData object,
and to print a StructuredData object in JSON format are included.
A few Cocoa / Cocoa Touch data formatters were updated by Enrico
to track changes in iOS 8 / Yosemite.
Before we query a thread's extended information, the system runtime may
provide hints to the remote debug stub that it will use to retrieve values
out of runtime structures. I added a new SystemRuntime method
AddThreadExtendedInfoPacketHints which allows the SystemRuntime to add
key-value type data to the initial request that we send to the remote stub.
The thread-format formatter string can now retrieve values out of a thread's
extended info structured data. The default thread-format string picks up
two of these - thread.info.activity.name and thread.info.trace_messages.
I added a new "jThreadExtendedInfo" packet in debugserver; I will
add documentation to the lldb-gdb-remote.txt doc soon. It accepts
JSON formatted arguments (most importantly, "thread":threadnum) and
it returns a variety of information regarding the thread to lldb
in JSON format. This JSON return is scanned into a StructuredData
object that is associated with the thread; UI layers can query the
thread's StructuredData to see if key-values are present, and if
so, show them to the user. These key-values are likely to be
specific to different targets with some commonality among many
targets. For instance, many targets will be able to advertise the
pthread_t value for a thread.
I added an initial rough cut of "thread info" command which will print
the information about a thread from the jThreadExtendedInfo result.
I need to do more work to make this format reasonably.
Han Ming added calls into the pmenergy and pmsample libraries if
debugserver is run on Mac OS X Yosemite to get information about the
inferior's power use.
I added support to debugserver for gathering the Genealogy information
about threads, if it exists, and returning it in the jThreadExtendedInfo
JSON result.
llvm-svn: 210874
Diffstat (limited to 'lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp')
-rw-r--r-- | lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp | 180 |
1 files changed, 178 insertions, 2 deletions
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp index f3f1fa31cd7..c04c42b1279 100644 --- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp +++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/DataExtractor.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Section.h" +#include "lldb/Core/StreamString.h" #include "lldb/Expression/ClangFunction.h" #include "lldb/Expression/ClangUtilityFunction.h" #include "lldb/Host/FileSpec.h" @@ -28,7 +29,6 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/Process.h" - #include "SystemRuntimeMacOSX.h" using namespace lldb; @@ -93,7 +93,13 @@ SystemRuntimeMacOSX::SystemRuntimeMacOSX (Process* process) : m_page_to_free_size(0), m_lib_backtrace_recording_info(), m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS), - m_libdispatch_offsets() + m_libdispatch_offsets(), + m_libpthread_layout_offsets_addr (LLDB_INVALID_ADDRESS), + m_libpthread_offsets(), + m_dispatch_tsd_indexes_addr (LLDB_INVALID_ADDRESS), + m_libdispatch_tsd_indexes(), + m_dispatch_voucher_offsets_addr (LLDB_INVALID_ADDRESS), + m_libdispatch_voucher_offsets() { } @@ -214,6 +220,30 @@ SystemRuntimeMacOSX::GetQueueKind (addr_t dispatch_queue_addr) return kind; } +void +SystemRuntimeMacOSX::AddThreadExtendedInfoPacketHints (lldb_private::StructuredData::ObjectSP dict_sp) +{ + StructuredData::Dictionary *dict = dict_sp->GetAsDictionary(); + if (dict) + { + ReadLibpthreadOffsets(); + if (m_libpthread_offsets.IsValid()) + { + dict->AddIntegerItem ("plo_pthread_tsd_base_offset", m_libpthread_offsets.plo_pthread_tsd_base_offset); + dict->AddIntegerItem ("plo_pthread_tsd_base_address_offset", m_libpthread_offsets.plo_pthread_tsd_base_address_offset); + dict->AddIntegerItem ("plo_pthread_tsd_entry_size", m_libpthread_offsets.plo_pthread_tsd_entry_size); + } + + ReadLibdispatchTSDIndexes (); + if (m_libdispatch_tsd_indexes.IsValid()) + { + dict->AddIntegerItem ("dti_queue_index", m_libdispatch_tsd_indexes.dti_queue_index); + dict->AddIntegerItem ("dti_voucher_index", m_libdispatch_tsd_indexes.dti_voucher_index); + dict->AddIntegerItem ("dti_qos_class_index", m_libdispatch_tsd_indexes.dti_qos_class_index); + } + } +} + bool SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread (ThreadSP thread_sp) { @@ -312,6 +342,152 @@ SystemRuntimeMacOSX::ReadLibdispatchOffsets () } } +void +SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress () +{ + if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS) + return; + + static ConstString g_libpthread_layout_offsets_symbol_name ("pthread_layout_offsets"); + const Symbol *libpthread_layout_offsets_symbol = NULL; + + ModuleSpec libpthread_module_spec (FileSpec("libsystem_pthread.dylib", false)); + ModuleSP module_sp (m_process->GetTarget().GetImages().FindFirstModule (libpthread_module_spec)); + if (module_sp) + { + libpthread_layout_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType + (g_libpthread_layout_offsets_symbol_name, eSymbolTypeData); + if (libpthread_layout_offsets_symbol) + { + m_libpthread_layout_offsets_addr = libpthread_layout_offsets_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget()); + } + } +} + +void +SystemRuntimeMacOSX::ReadLibpthreadOffsets () +{ + if (m_libpthread_offsets.IsValid()) + return; + + ReadLibpthreadOffsetsAddress (); + + if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS) + { + uint8_t memory_buffer[sizeof (struct LibpthreadOffsets)]; + DataExtractor data (memory_buffer, + sizeof(memory_buffer), + m_process->GetByteOrder(), + m_process->GetAddressByteSize()); + Error error; + if (m_process->ReadMemory (m_libpthread_layout_offsets_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer)) + { + lldb::offset_t data_offset = 0; + + // The struct LibpthreadOffsets is a series of uint16_t's - extract them all + // in one big go. + data.GetU16 (&data_offset, &m_libpthread_offsets.plo_version, sizeof (struct LibpthreadOffsets) / sizeof (uint16_t)); + } + } +} + +void +SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress () +{ + if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) + return; + + static ConstString g_libdispatch_tsd_indexes_symbol_name ("dispatch_tsd_indexes"); + const Symbol *libdispatch_tsd_indexes_symbol = NULL; + + ModuleSpec libpthread_module_spec (FileSpec("libdispatch.dylib", false)); + ModuleSP module_sp (m_process->GetTarget().GetImages().FindFirstModule (libpthread_module_spec)); + if (module_sp) + { + libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType + (g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData); + if (libdispatch_tsd_indexes_symbol) + { + m_dispatch_tsd_indexes_addr = libdispatch_tsd_indexes_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget()); + } + } +} + +void +SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes () +{ + if (m_libdispatch_tsd_indexes.IsValid()) + return; + + ReadLibdispatchTSDIndexesAddress (); + + if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) + { + size_t maximum_tsd_indexes_struct_size; + Address dti_struct_addr; + uint16_t dti_version = 2; + if (m_process->GetTarget().ResolveLoadAddress(m_dispatch_tsd_indexes_addr, dti_struct_addr)) + { + Error error; + uint16_t version = m_process->GetTarget().ReadUnsignedIntegerFromMemory (dti_struct_addr, false, 2, UINT16_MAX, error); + if (error.Success() && dti_version != UINT16_MAX) + { + dti_version = version; + } + } + if (dti_version == 1) + { + if (m_process->GetAddressByteSize() == 4) + { + maximum_tsd_indexes_struct_size = 4 + 4 + 4 + 4; + } + else + { + maximum_tsd_indexes_struct_size = 8 + 8 + 8 + 8; + } + } + else + { + maximum_tsd_indexes_struct_size = 2 + 2 + 2 + 2; + } + + uint8_t memory_buffer[maximum_tsd_indexes_struct_size]; + DataExtractor data (memory_buffer, + sizeof(memory_buffer), + m_process->GetByteOrder(), + m_process->GetAddressByteSize()); + Error error; + if (m_process->ReadMemory (m_dispatch_tsd_indexes_addr, memory_buffer, sizeof(memory_buffer), error) == sizeof(memory_buffer)) + { + lldb::offset_t offset = 0; + + if (dti_version == 1) + { + m_libdispatch_tsd_indexes.dti_version = data.GetU16 (&offset); + // word alignment to next item + if (m_process->GetAddressByteSize() == 4) + { + offset += 2; + } + else + { + offset += 6; + } + m_libdispatch_tsd_indexes.dti_queue_index = data.GetPointer (&offset); + m_libdispatch_tsd_indexes.dti_voucher_index = data.GetPointer (&offset); + m_libdispatch_tsd_indexes.dti_qos_class_index = data.GetPointer (&offset); + } + else + { + m_libdispatch_tsd_indexes.dti_version = data.GetU16 (&offset); + m_libdispatch_tsd_indexes.dti_queue_index = data.GetU16 (&offset); + m_libdispatch_tsd_indexes.dti_voucher_index = data.GetU16 (&offset); + m_libdispatch_tsd_indexes.dti_qos_class_index = data.GetU16 (&offset); + } + } + } +} + ThreadSP SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP real_thread, ConstString type) |