180814287SRaphael Isemann //===-- SystemRuntimeMacOSX.cpp -------------------------------------------===//
2a7b5afa9SJason Molenda //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a7b5afa9SJason Molenda //
7a7b5afa9SJason Molenda //===----------------------------------------------------------------------===//
8a7b5afa9SJason Molenda
9b9c1b51eSKate Stone #include "Plugins/Process/Utility/HistoryThread.h"
108be30215SAlex Langford #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
11a7b5afa9SJason Molenda #include "lldb/Breakpoint/StoppointCallbackContext.h"
12a7b5afa9SJason Molenda #include "lldb/Core/Module.h"
13a7b5afa9SJason Molenda #include "lldb/Core/ModuleSpec.h"
14a7b5afa9SJason Molenda #include "lldb/Core/PluginManager.h"
15a7b5afa9SJason Molenda #include "lldb/Core/Section.h"
16a7b5afa9SJason Molenda #include "lldb/Symbol/ObjectFile.h"
17a7b5afa9SJason Molenda #include "lldb/Symbol/SymbolContext.h"
18b9c1b51eSKate Stone #include "lldb/Target/Process.h"
1901c3243fSZachary Turner #include "lldb/Target/ProcessStructReader.h"
205e8dce4dSJason Molenda #include "lldb/Target/Queue.h"
215e8dce4dSJason Molenda #include "lldb/Target/QueueList.h"
22a7b5afa9SJason Molenda #include "lldb/Target/Target.h"
23a7b5afa9SJason Molenda #include "lldb/Target/Thread.h"
24666cc0b2SZachary Turner #include "lldb/Utility/DataBufferHeap.h"
25666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
265713a05bSZachary Turner #include "lldb/Utility/FileSpec.h"
27c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
286f9e6901SZachary Turner #include "lldb/Utility/Log.h"
29bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
302fd83355SJason Molenda
31a7b5afa9SJason Molenda #include "SystemRuntimeMacOSX.h"
32a7b5afa9SJason Molenda
33796ac80bSJonas Devlieghere #include <memory>
34796ac80bSJonas Devlieghere
35a7b5afa9SJason Molenda using namespace lldb;
36a7b5afa9SJason Molenda using namespace lldb_private;
37a7b5afa9SJason Molenda
LLDB_PLUGIN_DEFINE(SystemRuntimeMacOSX)38bba9ba8dSJonas Devlieghere LLDB_PLUGIN_DEFINE(SystemRuntimeMacOSX)
39fbb4d1e4SJonas Devlieghere
4005097246SAdrian Prantl // Create an instance of this class. This function is filled into the plugin
4105097246SAdrian Prantl // info class that gets handed out by the plugin factory and allows the lldb to
4205097246SAdrian Prantl // instantiate an instance of this class.
43b9c1b51eSKate Stone SystemRuntime *SystemRuntimeMacOSX::CreateInstance(Process *process) {
44a7b5afa9SJason Molenda bool create = false;
45b9c1b51eSKate Stone if (!create) {
46a7b5afa9SJason Molenda create = true;
47a7b5afa9SJason Molenda Module *exe_module = process->GetTarget().GetExecutableModulePointer();
48b9c1b51eSKate Stone if (exe_module) {
49a7b5afa9SJason Molenda ObjectFile *object_file = exe_module->GetObjectFile();
50b9c1b51eSKate Stone if (object_file) {
51a7b5afa9SJason Molenda create = (object_file->GetStrata() == ObjectFile::eStrataUser);
52a7b5afa9SJason Molenda }
53a7b5afa9SJason Molenda }
54a7b5afa9SJason Molenda
55b9c1b51eSKate Stone if (create) {
56b9c1b51eSKate Stone const llvm::Triple &triple_ref =
57b9c1b51eSKate Stone process->GetTarget().GetArchitecture().GetTriple();
58b9c1b51eSKate Stone switch (triple_ref.getOS()) {
59a7b5afa9SJason Molenda case llvm::Triple::Darwin:
60a7b5afa9SJason Molenda case llvm::Triple::MacOSX:
61a7b5afa9SJason Molenda case llvm::Triple::IOS:
62a814f704SJason Molenda case llvm::Triple::TvOS:
63a814f704SJason Molenda case llvm::Triple::WatchOS:
6432762fd2SJason Molenda // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
65a7b5afa9SJason Molenda create = triple_ref.getVendor() == llvm::Triple::Apple;
66a7b5afa9SJason Molenda break;
67a7b5afa9SJason Molenda default:
68a7b5afa9SJason Molenda create = false;
69a7b5afa9SJason Molenda break;
70a7b5afa9SJason Molenda }
71a7b5afa9SJason Molenda }
72a7b5afa9SJason Molenda }
73a7b5afa9SJason Molenda
74a7b5afa9SJason Molenda if (create)
75a7b5afa9SJason Molenda return new SystemRuntimeMacOSX(process);
76248a1305SKonrad Kleine return nullptr;
77a7b5afa9SJason Molenda }
78a7b5afa9SJason Molenda
79a7b5afa9SJason Molenda // Constructor
SystemRuntimeMacOSX(Process * process)8016ff8604SSaleem Abdulrasool SystemRuntimeMacOSX::SystemRuntimeMacOSX(Process *process)
81b9c1b51eSKate Stone : SystemRuntime(process), m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
82b9c1b51eSKate Stone m_get_queues_handler(process), m_get_pending_items_handler(process),
83b9c1b51eSKate Stone m_get_item_info_handler(process), m_get_thread_item_info_handler(process),
84b9c1b51eSKate Stone m_page_to_free(LLDB_INVALID_ADDRESS), m_page_to_free_size(0),
852fd83355SJason Molenda m_lib_backtrace_recording_info(),
862fd83355SJason Molenda m_dispatch_queue_offsets_addr(LLDB_INVALID_ADDRESS),
87705b1809SJason Molenda m_libdispatch_offsets(),
88705b1809SJason Molenda m_libpthread_layout_offsets_addr(LLDB_INVALID_ADDRESS),
89b9c1b51eSKate Stone m_libpthread_offsets(), m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
90705b1809SJason Molenda m_libdispatch_tsd_indexes(),
91705b1809SJason Molenda m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
92b9c1b51eSKate Stone m_libdispatch_voucher_offsets() {}
93a7b5afa9SJason Molenda
94a7b5afa9SJason Molenda // Destructor
~SystemRuntimeMacOSX()95b9c1b51eSKate Stone SystemRuntimeMacOSX::~SystemRuntimeMacOSX() { Clear(true); }
96a7b5afa9SJason Molenda
Detach()97b9c1b51eSKate Stone void SystemRuntimeMacOSX::Detach() {
982fd83355SJason Molenda m_get_queues_handler.Detach();
992fd83355SJason Molenda m_get_pending_items_handler.Detach();
1002fd83355SJason Molenda m_get_item_info_handler.Detach();
1012fd83355SJason Molenda m_get_thread_item_info_handler.Detach();
1022fd83355SJason Molenda }
1032fd83355SJason Molenda
104a7b5afa9SJason Molenda // Clear out the state of this class.
Clear(bool clear_process)105b9c1b51eSKate Stone void SystemRuntimeMacOSX::Clear(bool clear_process) {
10616ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_mutex);
107a7b5afa9SJason Molenda
108a7b5afa9SJason Molenda if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
109a7b5afa9SJason Molenda m_process->ClearBreakpointSiteByID(m_break_id);
110a7b5afa9SJason Molenda
111a7b5afa9SJason Molenda if (clear_process)
112248a1305SKonrad Kleine m_process = nullptr;
113a7b5afa9SJason Molenda m_break_id = LLDB_INVALID_BREAK_ID;
1142fd83355SJason Molenda }
1152fd83355SJason Molenda
1162fd83355SJason Molenda std::string
GetQueueNameFromThreadQAddress(addr_t dispatch_qaddr)117b9c1b51eSKate Stone SystemRuntimeMacOSX::GetQueueNameFromThreadQAddress(addr_t dispatch_qaddr) {
1182fd83355SJason Molenda std::string dispatch_queue_name;
1192fd83355SJason Molenda if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
1202fd83355SJason Molenda return "";
1212fd83355SJason Molenda
1222fd83355SJason Molenda ReadLibdispatchOffsets();
123b9c1b51eSKate Stone if (m_libdispatch_offsets.IsValid()) {
124b9c1b51eSKate Stone // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
12505097246SAdrian Prantl // thread - deref it to get the address of the dispatch_queue_t structure
12605097246SAdrian Prantl // for this thread's queue.
12797206d57SZachary Turner Status error;
128b9c1b51eSKate Stone addr_t dispatch_queue_addr =
129b9c1b51eSKate Stone m_process->ReadPointerFromMemory(dispatch_qaddr, error);
130b9c1b51eSKate Stone if (error.Success()) {
131b9c1b51eSKate Stone if (m_libdispatch_offsets.dqo_version >= 4) {
13205097246SAdrian Prantl // libdispatch versions 4+, pointer to dispatch name is in the queue
13305097246SAdrian Prantl // structure.
134b9c1b51eSKate Stone addr_t pointer_to_label_address =
135b9c1b51eSKate Stone dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
136b9c1b51eSKate Stone addr_t label_addr =
137b9c1b51eSKate Stone m_process->ReadPointerFromMemory(pointer_to_label_address, error);
138b9c1b51eSKate Stone if (error.Success()) {
139b9c1b51eSKate Stone m_process->ReadCStringFromMemory(label_addr, dispatch_queue_name,
140b9c1b51eSKate Stone error);
1412fd83355SJason Molenda }
142b9c1b51eSKate Stone } else {
1432fd83355SJason Molenda // libdispatch versions 1-3, dispatch name is a fixed width char array
1442fd83355SJason Molenda // in the queue structure.
145b9c1b51eSKate Stone addr_t label_addr =
146b9c1b51eSKate Stone dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
1472fd83355SJason Molenda dispatch_queue_name.resize(m_libdispatch_offsets.dqo_label_size, '\0');
148b9c1b51eSKate Stone size_t bytes_read =
149b9c1b51eSKate Stone m_process->ReadMemory(label_addr, &dispatch_queue_name[0],
150b9c1b51eSKate Stone m_libdispatch_offsets.dqo_label_size, error);
1512fd83355SJason Molenda if (bytes_read < m_libdispatch_offsets.dqo_label_size)
1522fd83355SJason Molenda dispatch_queue_name.erase(bytes_read);
1532fd83355SJason Molenda }
1542fd83355SJason Molenda }
1552fd83355SJason Molenda }
1562fd83355SJason Molenda return dispatch_queue_name;
1572fd83355SJason Molenda }
1582fd83355SJason Molenda
GetLibdispatchQueueAddressFromThreadQAddress(addr_t dispatch_qaddr)159b9c1b51eSKate Stone lldb::addr_t SystemRuntimeMacOSX::GetLibdispatchQueueAddressFromThreadQAddress(
160b9c1b51eSKate Stone addr_t dispatch_qaddr) {
161aac16e0fSJason Molenda addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
16297206d57SZachary Turner Status error;
163b9c1b51eSKate Stone libdispatch_queue_t_address =
164b9c1b51eSKate Stone m_process->ReadPointerFromMemory(dispatch_qaddr, error);
165b9c1b51eSKate Stone if (!error.Success()) {
166aac16e0fSJason Molenda libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
167aac16e0fSJason Molenda }
168aac16e0fSJason Molenda return libdispatch_queue_t_address;
169aac16e0fSJason Molenda }
170aac16e0fSJason Molenda
GetQueueKind(addr_t dispatch_queue_addr)171b9c1b51eSKate Stone lldb::QueueKind SystemRuntimeMacOSX::GetQueueKind(addr_t dispatch_queue_addr) {
172aac16e0fSJason Molenda if (dispatch_queue_addr == LLDB_INVALID_ADDRESS || dispatch_queue_addr == 0)
173aac16e0fSJason Molenda return eQueueKindUnknown;
174aac16e0fSJason Molenda
175aac16e0fSJason Molenda QueueKind kind = eQueueKindUnknown;
176aac16e0fSJason Molenda ReadLibdispatchOffsets();
177b9c1b51eSKate Stone if (m_libdispatch_offsets.IsValid() &&
178b9c1b51eSKate Stone m_libdispatch_offsets.dqo_version >= 4) {
17997206d57SZachary Turner Status error;
180b9c1b51eSKate Stone uint64_t width = m_process->ReadUnsignedIntegerFromMemory(
181b9c1b51eSKate Stone dispatch_queue_addr + m_libdispatch_offsets.dqo_width,
182b9c1b51eSKate Stone m_libdispatch_offsets.dqo_width_size, 0, error);
183b9c1b51eSKate Stone if (error.Success()) {
184b9c1b51eSKate Stone if (width == 1) {
185aac16e0fSJason Molenda kind = eQueueKindSerial;
186aac16e0fSJason Molenda }
187b9c1b51eSKate Stone if (width > 1) {
188aac16e0fSJason Molenda kind = eQueueKindConcurrent;
189aac16e0fSJason Molenda }
190aac16e0fSJason Molenda }
191aac16e0fSJason Molenda }
192aac16e0fSJason Molenda return kind;
193aac16e0fSJason Molenda }
194aac16e0fSJason Molenda
AddThreadExtendedInfoPacketHints(lldb_private::StructuredData::ObjectSP dict_sp)195b9c1b51eSKate Stone void SystemRuntimeMacOSX::AddThreadExtendedInfoPacketHints(
196b9c1b51eSKate Stone lldb_private::StructuredData::ObjectSP dict_sp) {
197705b1809SJason Molenda StructuredData::Dictionary *dict = dict_sp->GetAsDictionary();
198b9c1b51eSKate Stone if (dict) {
199705b1809SJason Molenda ReadLibpthreadOffsets();
200b9c1b51eSKate Stone if (m_libpthread_offsets.IsValid()) {
201b9c1b51eSKate Stone dict->AddIntegerItem("plo_pthread_tsd_base_offset",
202b9c1b51eSKate Stone m_libpthread_offsets.plo_pthread_tsd_base_offset);
203b9c1b51eSKate Stone dict->AddIntegerItem(
204b9c1b51eSKate Stone "plo_pthread_tsd_base_address_offset",
205b9c1b51eSKate Stone m_libpthread_offsets.plo_pthread_tsd_base_address_offset);
206b9c1b51eSKate Stone dict->AddIntegerItem("plo_pthread_tsd_entry_size",
207b9c1b51eSKate Stone m_libpthread_offsets.plo_pthread_tsd_entry_size);
208705b1809SJason Molenda }
209705b1809SJason Molenda
210705b1809SJason Molenda ReadLibdispatchTSDIndexes();
211b9c1b51eSKate Stone if (m_libdispatch_tsd_indexes.IsValid()) {
212b9c1b51eSKate Stone dict->AddIntegerItem("dti_queue_index",
213b9c1b51eSKate Stone m_libdispatch_tsd_indexes.dti_queue_index);
214b9c1b51eSKate Stone dict->AddIntegerItem("dti_voucher_index",
215b9c1b51eSKate Stone m_libdispatch_tsd_indexes.dti_voucher_index);
216b9c1b51eSKate Stone dict->AddIntegerItem("dti_qos_class_index",
217b9c1b51eSKate Stone m_libdispatch_tsd_indexes.dti_qos_class_index);
218705b1809SJason Molenda }
219705b1809SJason Molenda }
220705b1809SJason Molenda }
221705b1809SJason Molenda
SafeToCallFunctionsOnThisThread(ThreadSP thread_sp)222b9c1b51eSKate Stone bool SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread(ThreadSP thread_sp) {
223b9c1b51eSKate Stone if (thread_sp && thread_sp->GetStackFrameCount() > 0 &&
224b9c1b51eSKate Stone thread_sp->GetFrameWithConcreteFrameIndex(0)) {
225b9c1b51eSKate Stone const SymbolContext sym_ctx(
226b9c1b51eSKate Stone thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext(
227b9c1b51eSKate Stone eSymbolContextSymbol));
228b4892cd2SJason Molenda static ConstString g_select_symbol("__select");
229b9c1b51eSKate Stone if (sym_ctx.GetFunctionName() == g_select_symbol) {
230b4892cd2SJason Molenda return false;
231b4892cd2SJason Molenda }
232b4892cd2SJason Molenda }
233b4892cd2SJason Molenda return true;
234b4892cd2SJason Molenda }
235b4892cd2SJason Molenda
2362fd83355SJason Molenda lldb::queue_id_t
GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr)237b9c1b51eSKate Stone SystemRuntimeMacOSX::GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
2382fd83355SJason Molenda queue_id_t queue_id = LLDB_INVALID_QUEUE_ID;
2392fd83355SJason Molenda
2402fd83355SJason Molenda if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
2412fd83355SJason Molenda return queue_id;
2422fd83355SJason Molenda
2432fd83355SJason Molenda ReadLibdispatchOffsets();
244b9c1b51eSKate Stone if (m_libdispatch_offsets.IsValid()) {
245b9c1b51eSKate Stone // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
24605097246SAdrian Prantl // thread - deref it to get the address of the dispatch_queue_t structure
24705097246SAdrian Prantl // for this thread's queue.
24897206d57SZachary Turner Status error;
249b9c1b51eSKate Stone uint64_t dispatch_queue_addr =
250b9c1b51eSKate Stone m_process->ReadPointerFromMemory(dispatch_qaddr, error);
251b9c1b51eSKate Stone if (error.Success()) {
252b9c1b51eSKate Stone addr_t serialnum_address =
253b9c1b51eSKate Stone dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
254b9c1b51eSKate Stone queue_id_t serialnum = m_process->ReadUnsignedIntegerFromMemory(
255b9c1b51eSKate Stone serialnum_address, m_libdispatch_offsets.dqo_serialnum_size,
256b9c1b51eSKate Stone LLDB_INVALID_QUEUE_ID, error);
257b9c1b51eSKate Stone if (error.Success()) {
2582fd83355SJason Molenda queue_id = serialnum;
2592fd83355SJason Molenda }
2602fd83355SJason Molenda }
2612fd83355SJason Molenda }
2622fd83355SJason Molenda
2632fd83355SJason Molenda return queue_id;
264a7b5afa9SJason Molenda }
265a7b5afa9SJason Molenda
ReadLibdispatchOffsetsAddress()266b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress() {
2672fd83355SJason Molenda if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
2682fd83355SJason Molenda return;
2692fd83355SJason Molenda
270b9c1b51eSKate Stone static ConstString g_dispatch_queue_offsets_symbol_name(
271b9c1b51eSKate Stone "dispatch_queue_offsets");
272248a1305SKonrad Kleine const Symbol *dispatch_queue_offsets_symbol = nullptr;
2732fd83355SJason Molenda
274b9c1b51eSKate Stone // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6
275b9c1b51eSKate Stone // ("Snow Leopard")
2768f3be7a3SJonas Devlieghere ModuleSpec libSystem_module_spec(FileSpec("libSystem.B.dylib"));
277b9c1b51eSKate Stone ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
278b9c1b51eSKate Stone libSystem_module_spec));
2792fd83355SJason Molenda if (module_sp)
280b9c1b51eSKate Stone dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
281b9c1b51eSKate Stone g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2822fd83355SJason Molenda
28305097246SAdrian Prantl // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion")
28405097246SAdrian Prantl // and later
285248a1305SKonrad Kleine if (dispatch_queue_offsets_symbol == nullptr) {
2868f3be7a3SJonas Devlieghere ModuleSpec libdispatch_module_spec(FileSpec("libdispatch.dylib"));
287b9c1b51eSKate Stone module_sp = m_process->GetTarget().GetImages().FindFirstModule(
288b9c1b51eSKate Stone libdispatch_module_spec);
2892fd83355SJason Molenda if (module_sp)
290b9c1b51eSKate Stone dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
291b9c1b51eSKate Stone g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
2922fd83355SJason Molenda }
2932fd83355SJason Molenda if (dispatch_queue_offsets_symbol)
294b9c1b51eSKate Stone m_dispatch_queue_offsets_addr =
295b9c1b51eSKate Stone dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
296a7b5afa9SJason Molenda }
297a7b5afa9SJason Molenda
ReadLibdispatchOffsets()298b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibdispatchOffsets() {
2992fd83355SJason Molenda if (m_libdispatch_offsets.IsValid())
3002fd83355SJason Molenda return;
3012fd83355SJason Molenda
3022fd83355SJason Molenda ReadLibdispatchOffsetsAddress();
3032fd83355SJason Molenda
3042fd83355SJason Molenda uint8_t memory_buffer[sizeof(struct LibdispatchOffsets)];
305b9c1b51eSKate Stone DataExtractor data(memory_buffer, sizeof(memory_buffer),
3062fd83355SJason Molenda m_process->GetByteOrder(),
3072fd83355SJason Molenda m_process->GetAddressByteSize());
3082fd83355SJason Molenda
30997206d57SZachary Turner Status error;
310b9c1b51eSKate Stone if (m_process->ReadMemory(m_dispatch_queue_offsets_addr, memory_buffer,
311b9c1b51eSKate Stone sizeof(memory_buffer),
312b9c1b51eSKate Stone error) == sizeof(memory_buffer)) {
3132fd83355SJason Molenda lldb::offset_t data_offset = 0;
3142fd83355SJason Molenda
315b9c1b51eSKate Stone // The struct LibdispatchOffsets is a series of uint16_t's - extract them
31605097246SAdrian Prantl // all in one big go.
317b9c1b51eSKate Stone data.GetU16(&data_offset, &m_libdispatch_offsets.dqo_version,
318b9c1b51eSKate Stone sizeof(struct LibdispatchOffsets) / sizeof(uint16_t));
3192fd83355SJason Molenda }
320a7b5afa9SJason Molenda }
321a7b5afa9SJason Molenda
ReadLibpthreadOffsetsAddress()322b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress() {
323705b1809SJason Molenda if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
324705b1809SJason Molenda return;
325705b1809SJason Molenda
326b9c1b51eSKate Stone static ConstString g_libpthread_layout_offsets_symbol_name(
327b9c1b51eSKate Stone "pthread_layout_offsets");
328248a1305SKonrad Kleine const Symbol *libpthread_layout_offsets_symbol = nullptr;
329705b1809SJason Molenda
3308f3be7a3SJonas Devlieghere ModuleSpec libpthread_module_spec(FileSpec("libsystem_pthread.dylib"));
331b9c1b51eSKate Stone ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
332b9c1b51eSKate Stone libpthread_module_spec));
333b9c1b51eSKate Stone if (module_sp) {
334b9c1b51eSKate Stone libpthread_layout_offsets_symbol =
335b9c1b51eSKate Stone module_sp->FindFirstSymbolWithNameAndType(
336b9c1b51eSKate Stone g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
337b9c1b51eSKate Stone if (libpthread_layout_offsets_symbol) {
338b9c1b51eSKate Stone m_libpthread_layout_offsets_addr =
339b9c1b51eSKate Stone libpthread_layout_offsets_symbol->GetLoadAddress(
340b9c1b51eSKate Stone &m_process->GetTarget());
341705b1809SJason Molenda }
342705b1809SJason Molenda }
343705b1809SJason Molenda }
344705b1809SJason Molenda
ReadLibpthreadOffsets()345b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibpthreadOffsets() {
346705b1809SJason Molenda if (m_libpthread_offsets.IsValid())
347705b1809SJason Molenda return;
348705b1809SJason Molenda
349705b1809SJason Molenda ReadLibpthreadOffsetsAddress();
350705b1809SJason Molenda
351b9c1b51eSKate Stone if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS) {
352705b1809SJason Molenda uint8_t memory_buffer[sizeof(struct LibpthreadOffsets)];
353b9c1b51eSKate Stone DataExtractor data(memory_buffer, sizeof(memory_buffer),
354705b1809SJason Molenda m_process->GetByteOrder(),
355705b1809SJason Molenda m_process->GetAddressByteSize());
35697206d57SZachary Turner Status error;
357b9c1b51eSKate Stone if (m_process->ReadMemory(m_libpthread_layout_offsets_addr, memory_buffer,
358b9c1b51eSKate Stone sizeof(memory_buffer),
359b9c1b51eSKate Stone error) == sizeof(memory_buffer)) {
360705b1809SJason Molenda lldb::offset_t data_offset = 0;
361705b1809SJason Molenda
362b9c1b51eSKate Stone // The struct LibpthreadOffsets is a series of uint16_t's - extract them
36305097246SAdrian Prantl // all in one big go.
364b9c1b51eSKate Stone data.GetU16(&data_offset, &m_libpthread_offsets.plo_version,
365b9c1b51eSKate Stone sizeof(struct LibpthreadOffsets) / sizeof(uint16_t));
366705b1809SJason Molenda }
367705b1809SJason Molenda }
368705b1809SJason Molenda }
369705b1809SJason Molenda
ReadLibdispatchTSDIndexesAddress()370b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress() {
371705b1809SJason Molenda if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
372705b1809SJason Molenda return;
373705b1809SJason Molenda
374b9c1b51eSKate Stone static ConstString g_libdispatch_tsd_indexes_symbol_name(
375b9c1b51eSKate Stone "dispatch_tsd_indexes");
376248a1305SKonrad Kleine const Symbol *libdispatch_tsd_indexes_symbol = nullptr;
377705b1809SJason Molenda
3788f3be7a3SJonas Devlieghere ModuleSpec libpthread_module_spec(FileSpec("libdispatch.dylib"));
379b9c1b51eSKate Stone ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
380b9c1b51eSKate Stone libpthread_module_spec));
381b9c1b51eSKate Stone if (module_sp) {
382b9c1b51eSKate Stone libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType(
383b9c1b51eSKate Stone g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
384b9c1b51eSKate Stone if (libdispatch_tsd_indexes_symbol) {
385b9c1b51eSKate Stone m_dispatch_tsd_indexes_addr =
386b9c1b51eSKate Stone libdispatch_tsd_indexes_symbol->GetLoadAddress(
387b9c1b51eSKate Stone &m_process->GetTarget());
388705b1809SJason Molenda }
389705b1809SJason Molenda }
390705b1809SJason Molenda }
391705b1809SJason Molenda
ReadLibdispatchTSDIndexes()392b9c1b51eSKate Stone void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
393705b1809SJason Molenda if (m_libdispatch_tsd_indexes.IsValid())
394705b1809SJason Molenda return;
395705b1809SJason Molenda
396705b1809SJason Molenda ReadLibdispatchTSDIndexesAddress();
397705b1809SJason Molenda
398b9c1b51eSKate Stone if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
39959ac67e9SJason Molenda
400b9c1b51eSKate Stone // We don't need to check the version number right now, it will be at least 2,
40105097246SAdrian Prantl // but keep this code around to fetch just the version # for the future where
40205097246SAdrian Prantl // we need to fetch alternate versions of the struct.
40359ac67e9SJason Molenda #if 0
404705b1809SJason Molenda uint16_t dti_version = 2;
40559ac67e9SJason Molenda Address dti_struct_addr;
406705b1809SJason Molenda if (m_process->GetTarget().ResolveLoadAddress (m_dispatch_tsd_indexes_addr, dti_struct_addr))
407705b1809SJason Molenda {
40897206d57SZachary Turner Status error;
409705b1809SJason Molenda uint16_t version = m_process->GetTarget().ReadUnsignedIntegerFromMemory (dti_struct_addr, false, 2, UINT16_MAX, error);
410705b1809SJason Molenda if (error.Success() && dti_version != UINT16_MAX)
411705b1809SJason Molenda {
412705b1809SJason Molenda dti_version = version;
413705b1809SJason Molenda }
414705b1809SJason Molenda }
41559ac67e9SJason Molenda #endif
416705b1809SJason Molenda
4176e3b0cc2SRaphael Isemann TypeSystemClang *ast_ctx =
418594308c7SRaphael Isemann ScratchTypeSystemClang::GetForTarget(m_process->GetTarget());
419f9f49d35SRaphael Isemann if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
420b9c1b51eSKate Stone CompilerType uint16 =
421b9c1b51eSKate Stone ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
422b9c1b51eSKate Stone CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(
423143d507cSAdrian Prantl nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
424143d507cSAdrian Prantl "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct,
425143d507cSAdrian Prantl lldb::eLanguageTypeC);
426d8d4a57bSGreg Clayton
4276e3b0cc2SRaphael Isemann TypeSystemClang::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
4286e3b0cc2SRaphael Isemann TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,
429b9c1b51eSKate Stone "dti_version", uint16,
430b9c1b51eSKate Stone lldb::eAccessPublic, 0);
4316e3b0cc2SRaphael Isemann TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,
432b9c1b51eSKate Stone "dti_queue_index", uint16,
433b9c1b51eSKate Stone lldb::eAccessPublic, 0);
4346e3b0cc2SRaphael Isemann TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,
435b9c1b51eSKate Stone "dti_voucher_index", uint16,
436b9c1b51eSKate Stone lldb::eAccessPublic, 0);
4376e3b0cc2SRaphael Isemann TypeSystemClang::AddFieldToRecordType(dispatch_tsd_indexes_s,
438b9c1b51eSKate Stone "dti_qos_class_index", uint16,
439b9c1b51eSKate Stone lldb::eAccessPublic, 0);
4406e3b0cc2SRaphael Isemann TypeSystemClang::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);
441705b1809SJason Molenda
442b9c1b51eSKate Stone ProcessStructReader struct_reader(m_process, m_dispatch_tsd_indexes_addr,
443b9c1b51eSKate Stone dispatch_tsd_indexes_s);
44459ac67e9SJason Molenda
445b9c1b51eSKate Stone m_libdispatch_tsd_indexes.dti_version =
446b9c1b51eSKate Stone struct_reader.GetField<uint16_t>(ConstString("dti_version"));
447b9c1b51eSKate Stone m_libdispatch_tsd_indexes.dti_queue_index =
448b9c1b51eSKate Stone struct_reader.GetField<uint16_t>(ConstString("dti_queue_index"));
449b9c1b51eSKate Stone m_libdispatch_tsd_indexes.dti_voucher_index =
450b9c1b51eSKate Stone struct_reader.GetField<uint16_t>(ConstString("dti_voucher_index"));
451b9c1b51eSKate Stone m_libdispatch_tsd_indexes.dti_qos_class_index =
452b9c1b51eSKate Stone struct_reader.GetField<uint16_t>(ConstString("dti_qos_class_index"));
453705b1809SJason Molenda }
454705b1809SJason Molenda }
455705b1809SJason Molenda }
456705b1809SJason Molenda
GetExtendedBacktraceThread(ThreadSP real_thread,ConstString type)457b9c1b51eSKate Stone ThreadSP SystemRuntimeMacOSX::GetExtendedBacktraceThread(ThreadSP real_thread,
458b9c1b51eSKate Stone ConstString type) {
4592fd83355SJason Molenda ThreadSP originating_thread_sp;
46005cfdb0eSRaphael Isemann if (BacktraceRecordingHeadersInitialized() && type == "libdispatch") {
46197206d57SZachary Turner Status error;
4622fd83355SJason Molenda
463b9c1b51eSKate Stone // real_thread is either an actual, live thread (in which case we need to
46405097246SAdrian Prantl // call into libBacktraceRecording to find its originator) or it is an
46505097246SAdrian Prantl // extended backtrace itself, in which case we get the token from it and
46605097246SAdrian Prantl // call into libBacktraceRecording to find the originator of that token.
4672fd83355SJason Molenda
468b9c1b51eSKate Stone if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS) {
469b9c1b51eSKate Stone originating_thread_sp = GetExtendedBacktraceFromItemRef(
470b9c1b51eSKate Stone real_thread->GetExtendedBacktraceToken());
471b9c1b51eSKate Stone } else {
472b9c1b51eSKate Stone ThreadSP cur_thread_sp(
473b9c1b51eSKate Stone m_process->GetThreadList().GetExpressionExecutionThread());
474b9c1b51eSKate Stone AppleGetThreadItemInfoHandler::GetThreadItemInfoReturnInfo ret =
475b9c1b51eSKate Stone m_get_thread_item_info_handler.GetThreadItemInfo(
476b9c1b51eSKate Stone *cur_thread_sp.get(), real_thread->GetID(), m_page_to_free,
477b9c1b51eSKate Stone m_page_to_free_size, error);
4782a6c252dSJason Molenda m_page_to_free = LLDB_INVALID_ADDRESS;
4792a6c252dSJason Molenda m_page_to_free_size = 0;
480b9c1b51eSKate Stone if (ret.item_buffer_ptr != 0 &&
481b9c1b51eSKate Stone ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
482b9c1b51eSKate Stone ret.item_buffer_size > 0) {
4832fd83355SJason Molenda DataBufferHeap data(ret.item_buffer_size, 0);
484b9c1b51eSKate Stone if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
485b9c1b51eSKate Stone ret.item_buffer_size, error) &&
486b9c1b51eSKate Stone error.Success()) {
487b9c1b51eSKate Stone DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
488b9c1b51eSKate Stone m_process->GetByteOrder(),
489b9c1b51eSKate Stone m_process->GetAddressByteSize());
4902fd83355SJason Molenda ItemInfo item = ExtractItemInfoFromBuffer(extractor);
491796ac80bSJonas Devlieghere originating_thread_sp = std::make_shared<HistoryThread>(
49286df61ccSAlex Langford *m_process, item.enqueuing_thread_id, item.enqueuing_callstack);
493b9c1b51eSKate Stone originating_thread_sp->SetExtendedBacktraceToken(
494b9c1b51eSKate Stone item.item_that_enqueued_this);
495b9c1b51eSKate Stone originating_thread_sp->SetQueueName(
496b9c1b51eSKate Stone item.enqueuing_queue_label.c_str());
4972fd83355SJason Molenda originating_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
498b9c1b51eSKate Stone // originating_thread_sp->SetThreadName
499b9c1b51eSKate Stone // (item.enqueuing_thread_label.c_str());
5002fd83355SJason Molenda }
501da276f90SJason Molenda m_page_to_free = ret.item_buffer_ptr;
502da276f90SJason Molenda m_page_to_free_size = ret.item_buffer_size;
5032fd83355SJason Molenda }
5042fd83355SJason Molenda }
5052fd83355SJason Molenda }
5062fd83355SJason Molenda return originating_thread_sp;
5072fd83355SJason Molenda }
5082fd83355SJason Molenda
5092fd83355SJason Molenda ThreadSP
GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref)510b9c1b51eSKate Stone SystemRuntimeMacOSX::GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref) {
5112fd83355SJason Molenda ThreadSP return_thread_sp;
5122fd83355SJason Molenda
5132fd83355SJason Molenda AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
514b9c1b51eSKate Stone ThreadSP cur_thread_sp(
515b9c1b51eSKate Stone m_process->GetThreadList().GetExpressionExecutionThread());
51697206d57SZachary Turner Status error;
517b9c1b51eSKate Stone ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
518b9c1b51eSKate Stone m_page_to_free, m_page_to_free_size,
519b9c1b51eSKate Stone error);
5202a6c252dSJason Molenda m_page_to_free = LLDB_INVALID_ADDRESS;
5212a6c252dSJason Molenda m_page_to_free_size = 0;
522b9c1b51eSKate Stone if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
523b9c1b51eSKate Stone ret.item_buffer_size > 0) {
5242fd83355SJason Molenda DataBufferHeap data(ret.item_buffer_size, 0);
525b9c1b51eSKate Stone if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
526b9c1b51eSKate Stone ret.item_buffer_size, error) &&
527b9c1b51eSKate Stone error.Success()) {
528b9c1b51eSKate Stone DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
529b9c1b51eSKate Stone m_process->GetByteOrder(),
530b9c1b51eSKate Stone m_process->GetAddressByteSize());
5312fd83355SJason Molenda ItemInfo item = ExtractItemInfoFromBuffer(extractor);
532796ac80bSJonas Devlieghere return_thread_sp = std::make_shared<HistoryThread>(
53386df61ccSAlex Langford *m_process, item.enqueuing_thread_id, item.enqueuing_callstack);
5342fd83355SJason Molenda return_thread_sp->SetExtendedBacktraceToken(item.item_that_enqueued_this);
5352fd83355SJason Molenda return_thread_sp->SetQueueName(item.enqueuing_queue_label.c_str());
5362fd83355SJason Molenda return_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
537b9c1b51eSKate Stone // return_thread_sp->SetThreadName
538b9c1b51eSKate Stone // (item.enqueuing_thread_label.c_str());
5392fd83355SJason Molenda
540da276f90SJason Molenda m_page_to_free = ret.item_buffer_ptr;
541da276f90SJason Molenda m_page_to_free_size = ret.item_buffer_size;
5422fd83355SJason Molenda }
5432fd83355SJason Molenda }
5442fd83355SJason Molenda return return_thread_sp;
5452fd83355SJason Molenda }
5462fd83355SJason Molenda
5472fd83355SJason Molenda ThreadSP
GetExtendedBacktraceForQueueItem(QueueItemSP queue_item_sp,ConstString type)548b9c1b51eSKate Stone SystemRuntimeMacOSX::GetExtendedBacktraceForQueueItem(QueueItemSP queue_item_sp,
549b9c1b51eSKate Stone ConstString type) {
5502fd83355SJason Molenda ThreadSP extended_thread_sp;
55105cfdb0eSRaphael Isemann if (type != "libdispatch")
5522fd83355SJason Molenda return extended_thread_sp;
5532fd83355SJason Molenda
554796ac80bSJonas Devlieghere extended_thread_sp = std::make_shared<HistoryThread>(
555796ac80bSJonas Devlieghere *m_process, queue_item_sp->GetEnqueueingThreadID(),
55686df61ccSAlex Langford queue_item_sp->GetEnqueueingBacktrace());
557b9c1b51eSKate Stone extended_thread_sp->SetExtendedBacktraceToken(
558b9c1b51eSKate Stone queue_item_sp->GetItemThatEnqueuedThis());
5592fd83355SJason Molenda extended_thread_sp->SetQueueName(queue_item_sp->GetQueueLabel().c_str());
5602fd83355SJason Molenda extended_thread_sp->SetQueueID(queue_item_sp->GetEnqueueingQueueID());
561b9c1b51eSKate Stone // extended_thread_sp->SetThreadName
562b9c1b51eSKate Stone // (queue_item_sp->GetThreadLabel().c_str());
5632fd83355SJason Molenda
5642fd83355SJason Molenda return extended_thread_sp;
5652fd83355SJason Molenda }
5662fd83355SJason Molenda
5672fd83355SJason Molenda /* Returns true if we were able to get the version / offset information
5682fd83355SJason Molenda * out of libBacktraceRecording. false means we were unable to retrieve
5692fd83355SJason Molenda * this; the queue_info_version field will be 0.
5702fd83355SJason Molenda */
571a7b5afa9SJason Molenda
BacktraceRecordingHeadersInitialized()572b9c1b51eSKate Stone bool SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized() {
5732fd83355SJason Molenda if (m_lib_backtrace_recording_info.queue_info_version != 0)
5742fd83355SJason Molenda return true;
575a7b5afa9SJason Molenda
5762fd83355SJason Molenda addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
5772fd83355SJason Molenda addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
5782fd83355SJason Molenda addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
5792fd83355SJason Molenda addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
5802fd83355SJason Molenda Target &target = m_process->GetTarget();
5812fd83355SJason Molenda
582b9c1b51eSKate Stone static ConstString introspection_dispatch_queue_info_version(
583b9c1b51eSKate Stone "__introspection_dispatch_queue_info_version");
584a7b5afa9SJason Molenda SymbolContextList sc_list;
5851ad655e2SAdrian Prantl m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
5861ad655e2SAdrian Prantl introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list);
5871ad655e2SAdrian Prantl if (!sc_list.IsEmpty()) {
588a7b5afa9SJason Molenda SymbolContext sc;
589a7b5afa9SJason Molenda sc_list.GetContextAtIndex(0, sc);
590a7b5afa9SJason Molenda AddressRange addr_range;
591a7b5afa9SJason Molenda sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
592b9c1b51eSKate Stone queue_info_version_address =
593b9c1b51eSKate Stone addr_range.GetBaseAddress().GetLoadAddress(&target);
5942fd83355SJason Molenda }
5952fd83355SJason Molenda sc_list.Clear();
596a7b5afa9SJason Molenda
597b9c1b51eSKate Stone static ConstString introspection_dispatch_queue_info_data_offset(
598b9c1b51eSKate Stone "__introspection_dispatch_queue_info_data_offset");
5991ad655e2SAdrian Prantl m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
6001ad655e2SAdrian Prantl introspection_dispatch_queue_info_data_offset, eSymbolTypeData, sc_list);
6011ad655e2SAdrian Prantl if (!sc_list.IsEmpty()) {
6022fd83355SJason Molenda SymbolContext sc;
6032fd83355SJason Molenda sc_list.GetContextAtIndex(0, sc);
6042fd83355SJason Molenda AddressRange addr_range;
6052fd83355SJason Molenda sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
606b9c1b51eSKate Stone queue_info_data_offset_address =
607b9c1b51eSKate Stone addr_range.GetBaseAddress().GetLoadAddress(&target);
6082fd83355SJason Molenda }
6092fd83355SJason Molenda sc_list.Clear();
6102fd83355SJason Molenda
611b9c1b51eSKate Stone static ConstString introspection_dispatch_item_info_version(
612b9c1b51eSKate Stone "__introspection_dispatch_item_info_version");
6131ad655e2SAdrian Prantl m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
6141ad655e2SAdrian Prantl introspection_dispatch_item_info_version, eSymbolTypeData, sc_list);
6151ad655e2SAdrian Prantl if (!sc_list.IsEmpty()) {
6162fd83355SJason Molenda SymbolContext sc;
6172fd83355SJason Molenda sc_list.GetContextAtIndex(0, sc);
6182fd83355SJason Molenda AddressRange addr_range;
6192fd83355SJason Molenda sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
620b9c1b51eSKate Stone item_info_version_address =
621b9c1b51eSKate Stone addr_range.GetBaseAddress().GetLoadAddress(&target);
6222fd83355SJason Molenda }
6232fd83355SJason Molenda sc_list.Clear();
6242fd83355SJason Molenda
625b9c1b51eSKate Stone static ConstString introspection_dispatch_item_info_data_offset(
626b9c1b51eSKate Stone "__introspection_dispatch_item_info_data_offset");
6271ad655e2SAdrian Prantl m_process->GetTarget().GetImages().FindSymbolsWithNameAndType(
6281ad655e2SAdrian Prantl introspection_dispatch_item_info_data_offset, eSymbolTypeData, sc_list);
6291ad655e2SAdrian Prantl if (!sc_list.IsEmpty()) {
6302fd83355SJason Molenda SymbolContext sc;
6312fd83355SJason Molenda sc_list.GetContextAtIndex(0, sc);
6322fd83355SJason Molenda AddressRange addr_range;
6332fd83355SJason Molenda sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
634b9c1b51eSKate Stone item_info_data_offset_address =
635b9c1b51eSKate Stone addr_range.GetBaseAddress().GetLoadAddress(&target);
6362fd83355SJason Molenda }
6372fd83355SJason Molenda
638b9c1b51eSKate Stone if (queue_info_version_address != LLDB_INVALID_ADDRESS &&
639b9c1b51eSKate Stone queue_info_data_offset_address != LLDB_INVALID_ADDRESS &&
640b9c1b51eSKate Stone item_info_version_address != LLDB_INVALID_ADDRESS &&
641b9c1b51eSKate Stone item_info_data_offset_address != LLDB_INVALID_ADDRESS) {
64297206d57SZachary Turner Status error;
643b9c1b51eSKate Stone m_lib_backtrace_recording_info.queue_info_version =
644b9c1b51eSKate Stone m_process->ReadUnsignedIntegerFromMemory(queue_info_version_address, 2,
645b9c1b51eSKate Stone 0, error);
646b9c1b51eSKate Stone if (error.Success()) {
647b9c1b51eSKate Stone m_lib_backtrace_recording_info.queue_info_data_offset =
648b9c1b51eSKate Stone m_process->ReadUnsignedIntegerFromMemory(
649b9c1b51eSKate Stone queue_info_data_offset_address, 2, 0, error);
650b9c1b51eSKate Stone if (error.Success()) {
651b9c1b51eSKate Stone m_lib_backtrace_recording_info.item_info_version =
652b9c1b51eSKate Stone m_process->ReadUnsignedIntegerFromMemory(item_info_version_address,
653b9c1b51eSKate Stone 2, 0, error);
654b9c1b51eSKate Stone if (error.Success()) {
655b9c1b51eSKate Stone m_lib_backtrace_recording_info.item_info_data_offset =
656b9c1b51eSKate Stone m_process->ReadUnsignedIntegerFromMemory(
657b9c1b51eSKate Stone item_info_data_offset_address, 2, 0, error);
658b9c1b51eSKate Stone if (!error.Success()) {
6592fd83355SJason Molenda m_lib_backtrace_recording_info.queue_info_version = 0;
6602fd83355SJason Molenda }
661b9c1b51eSKate Stone } else {
6622fd83355SJason Molenda m_lib_backtrace_recording_info.queue_info_version = 0;
663a6e9130dSJason Molenda }
664b9c1b51eSKate Stone } else {
6652fd83355SJason Molenda m_lib_backtrace_recording_info.queue_info_version = 0;
666a7b5afa9SJason Molenda }
667a7b5afa9SJason Molenda }
668a7b5afa9SJason Molenda }
669a7b5afa9SJason Molenda
6702fd83355SJason Molenda return m_lib_backtrace_recording_info.queue_info_version != 0;
671a7b5afa9SJason Molenda }
672a7b5afa9SJason Molenda
673a7b5afa9SJason Molenda const std::vector<ConstString> &
GetExtendedBacktraceTypes()674b9c1b51eSKate Stone SystemRuntimeMacOSX::GetExtendedBacktraceTypes() {
675b9c1b51eSKate Stone if (m_types.size() == 0) {
676a7b5afa9SJason Molenda m_types.push_back(ConstString("libdispatch"));
6772fd83355SJason Molenda // We could have pthread as another type in the future if we have a way of
6782fd83355SJason Molenda // gathering that information & it's useful to distinguish between them.
679a7b5afa9SJason Molenda }
680a7b5afa9SJason Molenda return m_types;
681a7b5afa9SJason Molenda }
682a7b5afa9SJason Molenda
PopulateQueueList(lldb_private::QueueList & queue_list)683b9c1b51eSKate Stone void SystemRuntimeMacOSX::PopulateQueueList(
684b9c1b51eSKate Stone lldb_private::QueueList &queue_list) {
685b9c1b51eSKate Stone if (BacktraceRecordingHeadersInitialized()) {
6862fd83355SJason Molenda AppleGetQueuesHandler::GetQueuesReturnInfo queue_info_pointer;
687b9c1b51eSKate Stone ThreadSP cur_thread_sp(
688b9c1b51eSKate Stone m_process->GetThreadList().GetExpressionExecutionThread());
689b9c1b51eSKate Stone if (cur_thread_sp) {
69097206d57SZachary Turner Status error;
691b9c1b51eSKate Stone queue_info_pointer = m_get_queues_handler.GetCurrentQueues(
692b9c1b51eSKate Stone *cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
6932fd83355SJason Molenda m_page_to_free = LLDB_INVALID_ADDRESS;
6942fd83355SJason Molenda m_page_to_free_size = 0;
695b9c1b51eSKate Stone if (error.Success()) {
6965e8dce4dSJason Molenda
697b9c1b51eSKate Stone if (queue_info_pointer.count > 0 &&
698b9c1b51eSKate Stone queue_info_pointer.queues_buffer_size > 0 &&
699b9c1b51eSKate Stone queue_info_pointer.queues_buffer_ptr != 0 &&
700b9c1b51eSKate Stone queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS) {
701b9c1b51eSKate Stone PopulateQueuesUsingLibBTR(queue_info_pointer.queues_buffer_ptr,
702b9c1b51eSKate Stone queue_info_pointer.queues_buffer_size,
703b9c1b51eSKate Stone queue_info_pointer.count, queue_list);
7042fd83355SJason Molenda }
7052fd83355SJason Molenda }
7062fd83355SJason Molenda }
7072fd83355SJason Molenda }
708b9ffa98cSJason Molenda
709b9c1b51eSKate Stone // We either didn't have libBacktraceRecording (and need to create the queues
71005097246SAdrian Prantl // list based on threads) or we did get the queues list from
71105097246SAdrian Prantl // libBacktraceRecording but some special queues may not be included in its
71205097246SAdrian Prantl // information. This is needed because libBacktraceRecording will only list
71305097246SAdrian Prantl // queues with pending or running items by default - but the magic com.apple
71405097246SAdrian Prantl // .main-thread queue on thread 1 is always around.
715b9ffa98cSJason Molenda
716b9c1b51eSKate Stone for (ThreadSP thread_sp : m_process->Threads()) {
717b9c1b51eSKate Stone if (thread_sp->GetAssociatedWithLibdispatchQueue() != eLazyBoolNo) {
718b9c1b51eSKate Stone if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID) {
719248a1305SKonrad Kleine if (queue_list.FindQueueByID(thread_sp->GetQueueID()).get() ==
720248a1305SKonrad Kleine nullptr) {
721b9c1b51eSKate Stone QueueSP queue_sp(new Queue(m_process->shared_from_this(),
722b9c1b51eSKate Stone thread_sp->GetQueueID(),
723b9c1b51eSKate Stone thread_sp->GetQueueName()));
724b9c1b51eSKate Stone if (thread_sp->ThreadHasQueueInformation()) {
72577f89352SJason Molenda queue_sp->SetKind(thread_sp->GetQueueKind());
726b9c1b51eSKate Stone queue_sp->SetLibdispatchQueueAddress(
727b9c1b51eSKate Stone thread_sp->GetQueueLibdispatchQueueAddress());
72877f89352SJason Molenda queue_list.AddQueue(queue_sp);
729b9c1b51eSKate Stone } else {
730b9c1b51eSKate Stone queue_sp->SetKind(
731b9c1b51eSKate Stone GetQueueKind(thread_sp->GetQueueLibdispatchQueueAddress()));
732b9c1b51eSKate Stone queue_sp->SetLibdispatchQueueAddress(
733b9c1b51eSKate Stone thread_sp->GetQueueLibdispatchQueueAddress());
734b9ffa98cSJason Molenda queue_list.AddQueue(queue_sp);
735b9ffa98cSJason Molenda }
736b9ffa98cSJason Molenda }
737b9ffa98cSJason Molenda }
7382fd83355SJason Molenda }
73977f89352SJason Molenda }
74077f89352SJason Molenda }
7412fd83355SJason Molenda
742b9c1b51eSKate Stone // Returns either an array of introspection_dispatch_item_info_ref's for the
74305097246SAdrian Prantl // pending items on a queue or an array introspection_dispatch_item_info_ref's
74405097246SAdrian Prantl // and code addresses for the pending items on a queue. The information about
74505097246SAdrian Prantl // each of these pending items then needs to be fetched individually by passing
74605097246SAdrian Prantl // the ref to libBacktraceRecording.
74737e9b5abSJason Molenda
74837e9b5abSJason Molenda SystemRuntimeMacOSX::PendingItemsForQueue
GetPendingItemRefsForQueue(lldb::addr_t queue)749b9c1b51eSKate Stone SystemRuntimeMacOSX::GetPendingItemRefsForQueue(lldb::addr_t queue) {
750*4871dfc6SSlava Gurevich PendingItemsForQueue pending_item_refs = {};
75137e9b5abSJason Molenda AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer;
752b9c1b51eSKate Stone ThreadSP cur_thread_sp(
753b9c1b51eSKate Stone m_process->GetThreadList().GetExpressionExecutionThread());
754b9c1b51eSKate Stone if (cur_thread_sp) {
75597206d57SZachary Turner Status error;
756b9c1b51eSKate Stone pending_items_pointer = m_get_pending_items_handler.GetPendingItems(
757b9c1b51eSKate Stone *cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size,
758b9c1b51eSKate Stone error);
75937e9b5abSJason Molenda m_page_to_free = LLDB_INVALID_ADDRESS;
76037e9b5abSJason Molenda m_page_to_free_size = 0;
761b9c1b51eSKate Stone if (error.Success()) {
762b9c1b51eSKate Stone if (pending_items_pointer.count > 0 &&
763b9c1b51eSKate Stone pending_items_pointer.items_buffer_size > 0 &&
764b9c1b51eSKate Stone pending_items_pointer.items_buffer_ptr != 0 &&
765b9c1b51eSKate Stone pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS) {
76637e9b5abSJason Molenda DataBufferHeap data(pending_items_pointer.items_buffer_size, 0);
767b9c1b51eSKate Stone if (m_process->ReadMemory(
768b9c1b51eSKate Stone pending_items_pointer.items_buffer_ptr, data.GetBytes(),
769b9c1b51eSKate Stone pending_items_pointer.items_buffer_size, error)) {
770b9c1b51eSKate Stone DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
771b9c1b51eSKate Stone m_process->GetByteOrder(),
772b9c1b51eSKate Stone m_process->GetAddressByteSize());
77337e9b5abSJason Molenda
77437e9b5abSJason Molenda // We either have an array of
77537e9b5abSJason Molenda // void* item_ref
77637e9b5abSJason Molenda // (old style) or we have a structure returned which looks like
77737e9b5abSJason Molenda //
77837e9b5abSJason Molenda // struct introspection_dispatch_pending_item_info_s {
77937e9b5abSJason Molenda // void *item_ref;
78037e9b5abSJason Molenda // void *function_or_block;
78137e9b5abSJason Molenda // };
78237e9b5abSJason Molenda //
78337e9b5abSJason Molenda // struct introspection_dispatch_pending_items_array_s {
78437e9b5abSJason Molenda // uint32_t version;
78537e9b5abSJason Molenda // uint32_t size_of_item_info;
78637e9b5abSJason Molenda // introspection_dispatch_pending_item_info_s items[];
78737e9b5abSJason Molenda // }
78837e9b5abSJason Molenda
78937e9b5abSJason Molenda offset_t offset = 0;
79037e9b5abSJason Molenda int i = 0;
79137e9b5abSJason Molenda uint32_t version = extractor.GetU32(&offset);
792b9c1b51eSKate Stone if (version == 1) {
79337e9b5abSJason Molenda pending_item_refs.new_style = true;
79437e9b5abSJason Molenda uint32_t item_size = extractor.GetU32(&offset);
79537e9b5abSJason Molenda uint32_t start_of_array_offset = offset;
7963985c8c6SSaleem Abdulrasool while (offset < pending_items_pointer.items_buffer_size &&
797b9c1b51eSKate Stone static_cast<size_t>(i) < pending_items_pointer.count) {
79837e9b5abSJason Molenda offset = start_of_array_offset + (i * item_size);
79937e9b5abSJason Molenda ItemRefAndCodeAddress item;
8000863f675SPavel Labath item.item_ref = extractor.GetAddress(&offset);
8010863f675SPavel Labath item.code_address = extractor.GetAddress(&offset);
80237e9b5abSJason Molenda pending_item_refs.item_refs_and_code_addresses.push_back(item);
80337e9b5abSJason Molenda i++;
80437e9b5abSJason Molenda }
805b9c1b51eSKate Stone } else {
80637e9b5abSJason Molenda offset = 0;
80737e9b5abSJason Molenda pending_item_refs.new_style = false;
8083985c8c6SSaleem Abdulrasool while (offset < pending_items_pointer.items_buffer_size &&
809b9c1b51eSKate Stone static_cast<size_t>(i) < pending_items_pointer.count) {
81037e9b5abSJason Molenda ItemRefAndCodeAddress item;
8110863f675SPavel Labath item.item_ref = extractor.GetAddress(&offset);
81237e9b5abSJason Molenda item.code_address = LLDB_INVALID_ADDRESS;
81337e9b5abSJason Molenda pending_item_refs.item_refs_and_code_addresses.push_back(item);
81437e9b5abSJason Molenda i++;
81537e9b5abSJason Molenda }
81637e9b5abSJason Molenda }
81737e9b5abSJason Molenda }
81837e9b5abSJason Molenda m_page_to_free = pending_items_pointer.items_buffer_ptr;
81937e9b5abSJason Molenda m_page_to_free_size = pending_items_pointer.items_buffer_size;
82037e9b5abSJason Molenda }
82137e9b5abSJason Molenda }
82237e9b5abSJason Molenda }
82337e9b5abSJason Molenda return pending_item_refs;
82437e9b5abSJason Molenda }
82537e9b5abSJason Molenda
PopulatePendingItemsForQueue(Queue * queue)826b9c1b51eSKate Stone void SystemRuntimeMacOSX::PopulatePendingItemsForQueue(Queue *queue) {
827b9c1b51eSKate Stone if (BacktraceRecordingHeadersInitialized()) {
828b9c1b51eSKate Stone PendingItemsForQueue pending_item_refs =
829b9c1b51eSKate Stone GetPendingItemRefsForQueue(queue->GetLibdispatchQueueAddress());
830b9c1b51eSKate Stone for (ItemRefAndCodeAddress pending_item :
831b9c1b51eSKate Stone pending_item_refs.item_refs_and_code_addresses) {
832e32cd191SJason Molenda Address addr;
833b9c1b51eSKate Stone m_process->GetTarget().ResolveLoadAddress(pending_item.code_address,
834b9c1b51eSKate Stone addr);
835b9c1b51eSKate Stone QueueItemSP queue_item_sp(new QueueItem(queue->shared_from_this(),
836b9c1b51eSKate Stone m_process->shared_from_this(),
837b9c1b51eSKate Stone pending_item.item_ref, addr));
838e32cd191SJason Molenda queue->PushPendingQueueItem(queue_item_sp);
839e32cd191SJason Molenda }
840e32cd191SJason Molenda }
841e32cd191SJason Molenda }
842e32cd191SJason Molenda
CompleteQueueItem(QueueItem * queue_item,addr_t item_ref)843b9c1b51eSKate Stone void SystemRuntimeMacOSX::CompleteQueueItem(QueueItem *queue_item,
844b9c1b51eSKate Stone addr_t item_ref) {
8452fd83355SJason Molenda AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
846e32cd191SJason Molenda
847b9c1b51eSKate Stone ThreadSP cur_thread_sp(
848b9c1b51eSKate Stone m_process->GetThreadList().GetExpressionExecutionThread());
84997206d57SZachary Turner Status error;
850b9c1b51eSKate Stone ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
851b9c1b51eSKate Stone m_page_to_free, m_page_to_free_size,
852b9c1b51eSKate Stone error);
8532a6c252dSJason Molenda m_page_to_free = LLDB_INVALID_ADDRESS;
8542a6c252dSJason Molenda m_page_to_free_size = 0;
855b9c1b51eSKate Stone if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
856b9c1b51eSKate Stone ret.item_buffer_size > 0) {
8572fd83355SJason Molenda DataBufferHeap data(ret.item_buffer_size, 0);
858b9c1b51eSKate Stone if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
859b9c1b51eSKate Stone ret.item_buffer_size, error) &&
860b9c1b51eSKate Stone error.Success()) {
861b9c1b51eSKate Stone DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
862b9c1b51eSKate Stone m_process->GetByteOrder(),
863b9c1b51eSKate Stone m_process->GetAddressByteSize());
8642fd83355SJason Molenda ItemInfo item = ExtractItemInfoFromBuffer(extractor);
865e32cd191SJason Molenda queue_item->SetItemThatEnqueuedThis(item.item_that_enqueued_this);
866e32cd191SJason Molenda queue_item->SetEnqueueingThreadID(item.enqueuing_thread_id);
867e32cd191SJason Molenda queue_item->SetEnqueueingQueueID(item.enqueuing_queue_serialnum);
868e32cd191SJason Molenda queue_item->SetStopID(item.stop_id);
869e32cd191SJason Molenda queue_item->SetEnqueueingBacktrace(item.enqueuing_callstack);
870e32cd191SJason Molenda queue_item->SetThreadLabel(item.enqueuing_thread_label);
871e32cd191SJason Molenda queue_item->SetQueueLabel(item.enqueuing_queue_label);
872e32cd191SJason Molenda queue_item->SetTargetQueueLabel(item.target_queue_label);
8732fd83355SJason Molenda }
8740d6a1ff2SJason Molenda m_page_to_free = ret.item_buffer_ptr;
8750d6a1ff2SJason Molenda m_page_to_free_size = ret.item_buffer_size;
8762fd83355SJason Molenda }
8772fd83355SJason Molenda }
8782fd83355SJason Molenda
PopulateQueuesUsingLibBTR(lldb::addr_t queues_buffer,uint64_t queues_buffer_size,uint64_t count,lldb_private::QueueList & queue_list)879b9c1b51eSKate Stone void SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR(
880b9c1b51eSKate Stone lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count,
881b9c1b51eSKate Stone lldb_private::QueueList &queue_list) {
88297206d57SZachary Turner Status error;
8832fd83355SJason Molenda DataBufferHeap data(queues_buffer_size, 0);
884a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::SystemRuntime);
885b9c1b51eSKate Stone if (m_process->ReadMemory(queues_buffer, data.GetBytes(), queues_buffer_size,
886b9c1b51eSKate Stone error) == queues_buffer_size &&
887b9c1b51eSKate Stone error.Success()) {
888b9c1b51eSKate Stone // We've read the information out of inferior memory; free it on the next
889b9c1b51eSKate Stone // call we make
8902fd83355SJason Molenda m_page_to_free = queues_buffer;
8912fd83355SJason Molenda m_page_to_free_size = queues_buffer_size;
8922fd83355SJason Molenda
893b9c1b51eSKate Stone DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
894b9c1b51eSKate Stone m_process->GetByteOrder(),
895b9c1b51eSKate Stone m_process->GetAddressByteSize());
8962fd83355SJason Molenda offset_t offset = 0;
8972fd83355SJason Molenda uint64_t queues_read = 0;
8982fd83355SJason Molenda
89905097246SAdrian Prantl // The information about the queues is stored in this format (v1): typedef
90005097246SAdrian Prantl // struct introspection_dispatch_queue_info_s {
9012fd83355SJason Molenda // uint32_t offset_to_next;
9022fd83355SJason Molenda // dispatch_queue_t queue;
903b9c1b51eSKate Stone // uint64_t serialnum; // queue's serialnum in the process, as
904b9c1b51eSKate Stone // provided by libdispatch
9052fd83355SJason Molenda // uint32_t running_work_items_count;
9062fd83355SJason Molenda // uint32_t pending_work_items_count;
9072fd83355SJason Molenda //
9082fd83355SJason Molenda // char data[]; // Starting here, we have variable-length data:
9092fd83355SJason Molenda // // char queue_label[];
9102fd83355SJason Molenda // } introspection_dispatch_queue_info_s;
9112fd83355SJason Molenda
912b9c1b51eSKate Stone while (queues_read < count && offset < queues_buffer_size) {
9132fd83355SJason Molenda offset_t start_of_this_item = offset;
9142fd83355SJason Molenda
9152fd83355SJason Molenda uint32_t offset_to_next = extractor.GetU32(&offset);
916d84f606dSJason Molenda
917d84f606dSJason Molenda offset += 4; // Skip over the 4 bytes of reserved space
9180863f675SPavel Labath addr_t queue = extractor.GetAddress(&offset);
9192fd83355SJason Molenda uint64_t serialnum = extractor.GetU64(&offset);
9202fd83355SJason Molenda uint32_t running_work_items_count = extractor.GetU32(&offset);
9212fd83355SJason Molenda uint32_t pending_work_items_count = extractor.GetU32(&offset);
9222fd83355SJason Molenda
9232fd83355SJason Molenda // Read the first field of the variable length data
924b9c1b51eSKate Stone offset = start_of_this_item +
925b9c1b51eSKate Stone m_lib_backtrace_recording_info.queue_info_data_offset;
9262fd83355SJason Molenda const char *queue_label = extractor.GetCStr(&offset);
927248a1305SKonrad Kleine if (queue_label == nullptr)
9282fd83355SJason Molenda queue_label = "";
9292fd83355SJason Molenda
9302fd83355SJason Molenda offset_t start_of_next_item = start_of_this_item + offset_to_next;
9312fd83355SJason Molenda offset = start_of_next_item;
9322fd83355SJason Molenda
93363e5fb76SJonas Devlieghere LLDB_LOGF(log,
93463e5fb76SJonas Devlieghere "SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added "
935b9c1b51eSKate Stone "queue with dispatch_queue_t 0x%" PRIx64
936b9c1b51eSKate Stone ", serial number 0x%" PRIx64
937b9c1b51eSKate Stone ", running items %d, pending items %d, name '%s'",
938b9c1b51eSKate Stone queue, serialnum, running_work_items_count,
939b9c1b51eSKate Stone pending_work_items_count, queue_label);
940d84f606dSJason Molenda
941b9c1b51eSKate Stone QueueSP queue_sp(
942b9c1b51eSKate Stone new Queue(m_process->shared_from_this(), serialnum, queue_label));
9432fd83355SJason Molenda queue_sp->SetNumRunningWorkItems(running_work_items_count);
9442fd83355SJason Molenda queue_sp->SetNumPendingWorkItems(pending_work_items_count);
9452fd83355SJason Molenda queue_sp->SetLibdispatchQueueAddress(queue);
946aac16e0fSJason Molenda queue_sp->SetKind(GetQueueKind(queue));
9472fd83355SJason Molenda queue_list.AddQueue(queue_sp);
9482fd83355SJason Molenda queues_read++;
9492fd83355SJason Molenda }
9502fd83355SJason Molenda }
9512fd83355SJason Molenda }
9522fd83355SJason Molenda
ExtractItemInfoFromBuffer(lldb_private::DataExtractor & extractor)953b9c1b51eSKate Stone SystemRuntimeMacOSX::ItemInfo SystemRuntimeMacOSX::ExtractItemInfoFromBuffer(
954b9c1b51eSKate Stone lldb_private::DataExtractor &extractor) {
9552fd83355SJason Molenda ItemInfo item;
9562fd83355SJason Molenda
9572fd83355SJason Molenda offset_t offset = 0;
9582fd83355SJason Molenda
9590863f675SPavel Labath item.item_that_enqueued_this = extractor.GetAddress(&offset);
9600863f675SPavel Labath item.function_or_block = extractor.GetAddress(&offset);
9612fd83355SJason Molenda item.enqueuing_thread_id = extractor.GetU64(&offset);
9622fd83355SJason Molenda item.enqueuing_queue_serialnum = extractor.GetU64(&offset);
9632fd83355SJason Molenda item.target_queue_serialnum = extractor.GetU64(&offset);
9642fd83355SJason Molenda item.enqueuing_callstack_frame_count = extractor.GetU32(&offset);
9652fd83355SJason Molenda item.stop_id = extractor.GetU32(&offset);
9662fd83355SJason Molenda
9672fd83355SJason Molenda offset = m_lib_backtrace_recording_info.item_info_data_offset;
9682fd83355SJason Molenda
969b9c1b51eSKate Stone for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++) {
9700863f675SPavel Labath item.enqueuing_callstack.push_back(extractor.GetAddress(&offset));
9712fd83355SJason Molenda }
9722fd83355SJason Molenda item.enqueuing_thread_label = extractor.GetCStr(&offset);
9732fd83355SJason Molenda item.enqueuing_queue_label = extractor.GetCStr(&offset);
9742fd83355SJason Molenda item.target_queue_label = extractor.GetCStr(&offset);
9752fd83355SJason Molenda
9762fd83355SJason Molenda return item;
9772fd83355SJason Molenda }
978a7b5afa9SJason Molenda
Initialize()979b9c1b51eSKate Stone void SystemRuntimeMacOSX::Initialize() {
98049481b53SPavel Labath PluginManager::RegisterPlugin(
98149481b53SPavel Labath GetPluginNameStatic(),
98249481b53SPavel Labath "System runtime plugin for Mac OS X native libraries.", CreateInstance);
983a7b5afa9SJason Molenda }
984a7b5afa9SJason Molenda
Terminate()985b9c1b51eSKate Stone void SystemRuntimeMacOSX::Terminate() {
986a7b5afa9SJason Molenda PluginManager::UnregisterPlugin(CreateInstance);
987a7b5afa9SJason Molenda }
988