LLDB  mainline
SystemRuntimeMacOSX.cpp
Go to the documentation of this file.
1 //===-- SystemRuntimeMacOSX.cpp ---------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
11 #include "lldb/Core/Module.h"
12 #include "lldb/Core/ModuleSpec.h"
14 #include "lldb/Core/Section.h"
16 #include "lldb/Symbol/ObjectFile.h"
18 #include "lldb/Target/Process.h"
20 #include "lldb/Target/Queue.h"
21 #include "lldb/Target/QueueList.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Target/Thread.h"
26 #include "lldb/Utility/FileSpec.h"
27 #include "lldb/Utility/Log.h"
29 
30 #include "SystemRuntimeMacOSX.h"
31 
32 #include <memory>
33 
34 using namespace lldb;
35 using namespace lldb_private;
36 
37 // Create an instance of this class. This function is filled into the plugin
38 // info class that gets handed out by the plugin factory and allows the lldb to
39 // instantiate an instance of this class.
41  bool create = false;
42  if (!create) {
43  create = true;
44  Module *exe_module = process->GetTarget().GetExecutableModulePointer();
45  if (exe_module) {
46  ObjectFile *object_file = exe_module->GetObjectFile();
47  if (object_file) {
48  create = (object_file->GetStrata() == ObjectFile::eStrataUser);
49  }
50  }
51 
52  if (create) {
53  const llvm::Triple &triple_ref =
54  process->GetTarget().GetArchitecture().GetTriple();
55  switch (triple_ref.getOS()) {
56  case llvm::Triple::Darwin:
57  case llvm::Triple::MacOSX:
58  case llvm::Triple::IOS:
59  case llvm::Triple::TvOS:
60  case llvm::Triple::WatchOS:
61  // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
62  create = triple_ref.getVendor() == llvm::Triple::Apple;
63  break;
64  default:
65  create = false;
66  break;
67  }
68  }
69  }
70 
71  if (create)
72  return new SystemRuntimeMacOSX(process);
73  return NULL;
74 }
75 
76 // Constructor
78  : SystemRuntime(process), m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
79  m_get_queues_handler(process), m_get_pending_items_handler(process),
80  m_get_item_info_handler(process), m_get_thread_item_info_handler(process),
81  m_page_to_free(LLDB_INVALID_ADDRESS), m_page_to_free_size(0),
82  m_lib_backtrace_recording_info(),
83  m_dispatch_queue_offsets_addr(LLDB_INVALID_ADDRESS),
84  m_libdispatch_offsets(),
85  m_libpthread_layout_offsets_addr(LLDB_INVALID_ADDRESS),
86  m_libpthread_offsets(), m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
87  m_libdispatch_tsd_indexes(),
88  m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
89  m_libdispatch_voucher_offsets() {}
90 
91 // Destructor
93 
95  m_get_queues_handler.Detach();
96  m_get_pending_items_handler.Detach();
97  m_get_item_info_handler.Detach();
98  m_get_thread_item_info_handler.Detach();
99 }
100 
101 // Clear out the state of this class.
102 void SystemRuntimeMacOSX::Clear(bool clear_process) {
103  std::lock_guard<std::recursive_mutex> guard(m_mutex);
104 
107 
108  if (clear_process)
109  m_process = NULL;
111 }
112 
113 std::string
115  std::string dispatch_queue_name;
116  if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
117  return "";
118 
119  ReadLibdispatchOffsets();
120  if (m_libdispatch_offsets.IsValid()) {
121  // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
122  // thread - deref it to get the address of the dispatch_queue_t structure
123  // for this thread's queue.
124  Status error;
125  addr_t dispatch_queue_addr =
126  m_process->ReadPointerFromMemory(dispatch_qaddr, error);
127  if (error.Success()) {
128  if (m_libdispatch_offsets.dqo_version >= 4) {
129  // libdispatch versions 4+, pointer to dispatch name is in the queue
130  // structure.
131  addr_t pointer_to_label_address =
132  dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
133  addr_t label_addr =
134  m_process->ReadPointerFromMemory(pointer_to_label_address, error);
135  if (error.Success()) {
136  m_process->ReadCStringFromMemory(label_addr, dispatch_queue_name,
137  error);
138  }
139  } else {
140  // libdispatch versions 1-3, dispatch name is a fixed width char array
141  // in the queue structure.
142  addr_t label_addr =
143  dispatch_queue_addr + m_libdispatch_offsets.dqo_label;
144  dispatch_queue_name.resize(m_libdispatch_offsets.dqo_label_size, '\0');
145  size_t bytes_read =
146  m_process->ReadMemory(label_addr, &dispatch_queue_name[0],
147  m_libdispatch_offsets.dqo_label_size, error);
148  if (bytes_read < m_libdispatch_offsets.dqo_label_size)
149  dispatch_queue_name.erase(bytes_read);
150  }
151  }
152  }
153  return dispatch_queue_name;
154 }
155 
157  addr_t dispatch_qaddr) {
158  addr_t libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
159  Status error;
160  libdispatch_queue_t_address =
161  m_process->ReadPointerFromMemory(dispatch_qaddr, error);
162  if (!error.Success()) {
163  libdispatch_queue_t_address = LLDB_INVALID_ADDRESS;
164  }
165  return libdispatch_queue_t_address;
166 }
167 
169  if (dispatch_queue_addr == LLDB_INVALID_ADDRESS || dispatch_queue_addr == 0)
170  return eQueueKindUnknown;
171 
173  ReadLibdispatchOffsets();
174  if (m_libdispatch_offsets.IsValid() &&
175  m_libdispatch_offsets.dqo_version >= 4) {
176  Status error;
177  uint64_t width = m_process->ReadUnsignedIntegerFromMemory(
178  dispatch_queue_addr + m_libdispatch_offsets.dqo_width,
179  m_libdispatch_offsets.dqo_width_size, 0, error);
180  if (error.Success()) {
181  if (width == 1) {
182  kind = eQueueKindSerial;
183  }
184  if (width > 1) {
185  kind = eQueueKindConcurrent;
186  }
187  }
188  }
189  return kind;
190 }
191 
194  StructuredData::Dictionary *dict = dict_sp->GetAsDictionary();
195  if (dict) {
196  ReadLibpthreadOffsets();
197  if (m_libpthread_offsets.IsValid()) {
198  dict->AddIntegerItem("plo_pthread_tsd_base_offset",
199  m_libpthread_offsets.plo_pthread_tsd_base_offset);
200  dict->AddIntegerItem(
201  "plo_pthread_tsd_base_address_offset",
202  m_libpthread_offsets.plo_pthread_tsd_base_address_offset);
203  dict->AddIntegerItem("plo_pthread_tsd_entry_size",
204  m_libpthread_offsets.plo_pthread_tsd_entry_size);
205  }
206 
207  ReadLibdispatchTSDIndexes();
208  if (m_libdispatch_tsd_indexes.IsValid()) {
209  dict->AddIntegerItem("dti_queue_index",
210  m_libdispatch_tsd_indexes.dti_queue_index);
211  dict->AddIntegerItem("dti_voucher_index",
212  m_libdispatch_tsd_indexes.dti_voucher_index);
213  dict->AddIntegerItem("dti_qos_class_index",
214  m_libdispatch_tsd_indexes.dti_qos_class_index);
215  }
216  }
217 }
218 
220  if (thread_sp && thread_sp->GetStackFrameCount() > 0 &&
221  thread_sp->GetFrameWithConcreteFrameIndex(0)) {
222  const SymbolContext sym_ctx(
223  thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext(
224  eSymbolContextSymbol));
225  static ConstString g_select_symbol("__select");
226  if (sym_ctx.GetFunctionName() == g_select_symbol) {
227  return false;
228  }
229  }
230  return true;
231 }
232 
236 
237  if (dispatch_qaddr == LLDB_INVALID_ADDRESS || dispatch_qaddr == 0)
238  return queue_id;
239 
240  ReadLibdispatchOffsets();
241  if (m_libdispatch_offsets.IsValid()) {
242  // dispatch_qaddr is from a thread_info(THREAD_IDENTIFIER_INFO) call for a
243  // thread - deref it to get the address of the dispatch_queue_t structure
244  // for this thread's queue.
245  Status error;
246  uint64_t dispatch_queue_addr =
247  m_process->ReadPointerFromMemory(dispatch_qaddr, error);
248  if (error.Success()) {
249  addr_t serialnum_address =
250  dispatch_queue_addr + m_libdispatch_offsets.dqo_serialnum;
252  serialnum_address, m_libdispatch_offsets.dqo_serialnum_size,
253  LLDB_INVALID_QUEUE_ID, error);
254  if (error.Success()) {
255  queue_id = serialnum;
256  }
257  }
258  }
259 
260  return queue_id;
261 }
262 
263 void SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress() {
264  if (m_dispatch_queue_offsets_addr != LLDB_INVALID_ADDRESS)
265  return;
266 
267  static ConstString g_dispatch_queue_offsets_symbol_name(
268  "dispatch_queue_offsets");
269  const Symbol *dispatch_queue_offsets_symbol = NULL;
270 
271  // libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6
272  // ("Snow Leopard")
273  ModuleSpec libSystem_module_spec(FileSpec("libSystem.B.dylib"));
274  ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
275  libSystem_module_spec));
276  if (module_sp)
277  dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
278  g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
279 
280  // libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion")
281  // and later
282  if (dispatch_queue_offsets_symbol == NULL) {
283  ModuleSpec libdispatch_module_spec(FileSpec("libdispatch.dylib"));
284  module_sp = m_process->GetTarget().GetImages().FindFirstModule(
285  libdispatch_module_spec);
286  if (module_sp)
287  dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType(
288  g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
289  }
290  if (dispatch_queue_offsets_symbol)
291  m_dispatch_queue_offsets_addr =
292  dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
293 }
294 
295 void SystemRuntimeMacOSX::ReadLibdispatchOffsets() {
296  if (m_libdispatch_offsets.IsValid())
297  return;
298 
299  ReadLibdispatchOffsetsAddress();
300 
301  uint8_t memory_buffer[sizeof(struct LibdispatchOffsets)];
302  DataExtractor data(memory_buffer, sizeof(memory_buffer),
305 
306  Status error;
307  if (m_process->ReadMemory(m_dispatch_queue_offsets_addr, memory_buffer,
308  sizeof(memory_buffer),
309  error) == sizeof(memory_buffer)) {
310  lldb::offset_t data_offset = 0;
311 
312  // The struct LibdispatchOffsets is a series of uint16_t's - extract them
313  // all in one big go.
314  data.GetU16(&data_offset, &m_libdispatch_offsets.dqo_version,
315  sizeof(struct LibdispatchOffsets) / sizeof(uint16_t));
316  }
317 }
318 
319 void SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress() {
320  if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS)
321  return;
322 
323  static ConstString g_libpthread_layout_offsets_symbol_name(
324  "pthread_layout_offsets");
325  const Symbol *libpthread_layout_offsets_symbol = NULL;
326 
327  ModuleSpec libpthread_module_spec(FileSpec("libsystem_pthread.dylib"));
328  ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
329  libpthread_module_spec));
330  if (module_sp) {
331  libpthread_layout_offsets_symbol =
332  module_sp->FindFirstSymbolWithNameAndType(
333  g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
334  if (libpthread_layout_offsets_symbol) {
335  m_libpthread_layout_offsets_addr =
336  libpthread_layout_offsets_symbol->GetLoadAddress(
337  &m_process->GetTarget());
338  }
339  }
340 }
341 
342 void SystemRuntimeMacOSX::ReadLibpthreadOffsets() {
343  if (m_libpthread_offsets.IsValid())
344  return;
345 
346  ReadLibpthreadOffsetsAddress();
347 
348  if (m_libpthread_layout_offsets_addr != LLDB_INVALID_ADDRESS) {
349  uint8_t memory_buffer[sizeof(struct LibpthreadOffsets)];
350  DataExtractor data(memory_buffer, sizeof(memory_buffer),
353  Status error;
354  if (m_process->ReadMemory(m_libpthread_layout_offsets_addr, memory_buffer,
355  sizeof(memory_buffer),
356  error) == sizeof(memory_buffer)) {
357  lldb::offset_t data_offset = 0;
358 
359  // The struct LibpthreadOffsets is a series of uint16_t's - extract them
360  // all in one big go.
361  data.GetU16(&data_offset, &m_libpthread_offsets.plo_version,
362  sizeof(struct LibpthreadOffsets) / sizeof(uint16_t));
363  }
364  }
365 }
366 
367 void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress() {
368  if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS)
369  return;
370 
371  static ConstString g_libdispatch_tsd_indexes_symbol_name(
372  "dispatch_tsd_indexes");
373  const Symbol *libdispatch_tsd_indexes_symbol = NULL;
374 
375  ModuleSpec libpthread_module_spec(FileSpec("libdispatch.dylib"));
376  ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
377  libpthread_module_spec));
378  if (module_sp) {
379  libdispatch_tsd_indexes_symbol = module_sp->FindFirstSymbolWithNameAndType(
380  g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
381  if (libdispatch_tsd_indexes_symbol) {
382  m_dispatch_tsd_indexes_addr =
383  libdispatch_tsd_indexes_symbol->GetLoadAddress(
384  &m_process->GetTarget());
385  }
386  }
387 }
388 
389 void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
390  if (m_libdispatch_tsd_indexes.IsValid())
391  return;
392 
393  ReadLibdispatchTSDIndexesAddress();
394 
395  if (m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
396 
397 // We don't need to check the version number right now, it will be at least 2,
398 // but keep this code around to fetch just the version # for the future where
399 // we need to fetch alternate versions of the struct.
400 #if 0
401  uint16_t dti_version = 2;
402  Address dti_struct_addr;
403  if (m_process->GetTarget().ResolveLoadAddress (m_dispatch_tsd_indexes_addr, dti_struct_addr))
404  {
405  Status error;
406  uint16_t version = m_process->GetTarget().ReadUnsignedIntegerFromMemory (dti_struct_addr, false, 2, UINT16_MAX, error);
407  if (error.Success() && dti_version != UINT16_MAX)
408  {
409  dti_version = version;
410  }
411  }
412 #endif
413 
414  ClangASTContext *ast_ctx =
416  if (ast_ctx->getASTContext() &&
417  m_dispatch_tsd_indexes_addr != LLDB_INVALID_ADDRESS) {
418  CompilerType uint16 =
420  CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType(
421  nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s",
422  clang::TTK_Struct, lldb::eLanguageTypeC);
423 
424  ClangASTContext::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
425  ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
426  "dti_version", uint16,
428  ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
429  "dti_queue_index", uint16,
431  ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
432  "dti_voucher_index", uint16,
434  ClangASTContext::AddFieldToRecordType(dispatch_tsd_indexes_s,
435  "dti_qos_class_index", uint16,
437  ClangASTContext::CompleteTagDeclarationDefinition(dispatch_tsd_indexes_s);
438 
439  ProcessStructReader struct_reader(m_process, m_dispatch_tsd_indexes_addr,
440  dispatch_tsd_indexes_s);
441 
442  m_libdispatch_tsd_indexes.dti_version =
443  struct_reader.GetField<uint16_t>(ConstString("dti_version"));
444  m_libdispatch_tsd_indexes.dti_queue_index =
445  struct_reader.GetField<uint16_t>(ConstString("dti_queue_index"));
446  m_libdispatch_tsd_indexes.dti_voucher_index =
447  struct_reader.GetField<uint16_t>(ConstString("dti_voucher_index"));
448  m_libdispatch_tsd_indexes.dti_qos_class_index =
449  struct_reader.GetField<uint16_t>(ConstString("dti_qos_class_index"));
450  }
451  }
452 }
453 
455  ConstString type) {
456  ThreadSP originating_thread_sp;
457  if (BacktraceRecordingHeadersInitialized() && type == "libdispatch") {
458  Status error;
459 
460  // real_thread is either an actual, live thread (in which case we need to
461  // call into libBacktraceRecording to find its originator) or it is an
462  // extended backtrace itself, in which case we get the token from it and
463  // call into libBacktraceRecording to find the originator of that token.
464 
465  if (real_thread->GetExtendedBacktraceToken() != LLDB_INVALID_ADDRESS) {
466  originating_thread_sp = GetExtendedBacktraceFromItemRef(
467  real_thread->GetExtendedBacktraceToken());
468  } else {
469  ThreadSP cur_thread_sp(
472  m_get_thread_item_info_handler.GetThreadItemInfo(
473  *cur_thread_sp.get(), real_thread->GetID(), m_page_to_free,
474  m_page_to_free_size, error);
475  m_page_to_free = LLDB_INVALID_ADDRESS;
476  m_page_to_free_size = 0;
477  if (ret.item_buffer_ptr != 0 &&
478  ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
479  ret.item_buffer_size > 0) {
480  DataBufferHeap data(ret.item_buffer_size, 0);
481  if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
482  ret.item_buffer_size, error) &&
483  error.Success()) {
484  DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
487  ItemInfo item = ExtractItemInfoFromBuffer(extractor);
488  bool stop_id_is_valid = true;
489  if (item.stop_id == 0)
490  stop_id_is_valid = false;
491  originating_thread_sp = std::make_shared<HistoryThread>(
492  *m_process, item.enqueuing_thread_id, item.enqueuing_callstack,
493  item.stop_id, stop_id_is_valid);
494  originating_thread_sp->SetExtendedBacktraceToken(
495  item.item_that_enqueued_this);
496  originating_thread_sp->SetQueueName(
497  item.enqueuing_queue_label.c_str());
498  originating_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
499  // originating_thread_sp->SetThreadName
500  // (item.enqueuing_thread_label.c_str());
501  }
502  m_page_to_free = ret.item_buffer_ptr;
503  m_page_to_free_size = ret.item_buffer_size;
504  }
505  }
506  }
507  return originating_thread_sp;
508 }
509 
510 ThreadSP
512  ThreadSP return_thread_sp;
513 
515  ThreadSP cur_thread_sp(
517  Status error;
518  ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
519  m_page_to_free, m_page_to_free_size,
520  error);
521  m_page_to_free = LLDB_INVALID_ADDRESS;
522  m_page_to_free_size = 0;
523  if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
524  ret.item_buffer_size > 0) {
525  DataBufferHeap data(ret.item_buffer_size, 0);
526  if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
527  ret.item_buffer_size, error) &&
528  error.Success()) {
529  DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
532  ItemInfo item = ExtractItemInfoFromBuffer(extractor);
533  bool stop_id_is_valid = true;
534  if (item.stop_id == 0)
535  stop_id_is_valid = false;
536  return_thread_sp = std::make_shared<HistoryThread>(
537  *m_process, item.enqueuing_thread_id, item.enqueuing_callstack,
538  item.stop_id, stop_id_is_valid);
539  return_thread_sp->SetExtendedBacktraceToken(item.item_that_enqueued_this);
540  return_thread_sp->SetQueueName(item.enqueuing_queue_label.c_str());
541  return_thread_sp->SetQueueID(item.enqueuing_queue_serialnum);
542  // return_thread_sp->SetThreadName
543  // (item.enqueuing_thread_label.c_str());
544 
545  m_page_to_free = ret.item_buffer_ptr;
546  m_page_to_free_size = ret.item_buffer_size;
547  }
548  }
549  return return_thread_sp;
550 }
551 
552 ThreadSP
554  ConstString type) {
555  ThreadSP extended_thread_sp;
556  if (type != "libdispatch")
557  return extended_thread_sp;
558 
559  bool stop_id_is_valid = true;
560  if (queue_item_sp->GetStopID() == 0)
561  stop_id_is_valid = false;
562 
563  extended_thread_sp = std::make_shared<HistoryThread>(
564  *m_process, queue_item_sp->GetEnqueueingThreadID(),
565  queue_item_sp->GetEnqueueingBacktrace(), queue_item_sp->GetStopID(),
566  stop_id_is_valid);
567  extended_thread_sp->SetExtendedBacktraceToken(
568  queue_item_sp->GetItemThatEnqueuedThis());
569  extended_thread_sp->SetQueueName(queue_item_sp->GetQueueLabel().c_str());
570  extended_thread_sp->SetQueueID(queue_item_sp->GetEnqueueingQueueID());
571  // extended_thread_sp->SetThreadName
572  // (queue_item_sp->GetThreadLabel().c_str());
573 
574  return extended_thread_sp;
575 }
576 
577 /* Returns true if we were able to get the version / offset information
578  * out of libBacktraceRecording. false means we were unable to retrieve
579  * this; the queue_info_version field will be 0.
580  */
581 
582 bool SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized() {
583  if (m_lib_backtrace_recording_info.queue_info_version != 0)
584  return true;
585 
586  addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
587  addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
588  addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
589  addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
590  Target &target = m_process->GetTarget();
591 
592  static ConstString introspection_dispatch_queue_info_version(
593  "__introspection_dispatch_queue_info_version");
594  SymbolContextList sc_list;
596  introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list) >
597  0) {
598  SymbolContext sc;
599  sc_list.GetContextAtIndex(0, sc);
600  AddressRange addr_range;
601  sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
602  queue_info_version_address =
603  addr_range.GetBaseAddress().GetLoadAddress(&target);
604  }
605  sc_list.Clear();
606 
607  static ConstString introspection_dispatch_queue_info_data_offset(
608  "__introspection_dispatch_queue_info_data_offset");
610  introspection_dispatch_queue_info_data_offset, eSymbolTypeData,
611  sc_list) > 0) {
612  SymbolContext sc;
613  sc_list.GetContextAtIndex(0, sc);
614  AddressRange addr_range;
615  sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
616  queue_info_data_offset_address =
617  addr_range.GetBaseAddress().GetLoadAddress(&target);
618  }
619  sc_list.Clear();
620 
621  static ConstString introspection_dispatch_item_info_version(
622  "__introspection_dispatch_item_info_version");
624  introspection_dispatch_item_info_version, eSymbolTypeData, sc_list) >
625  0) {
626  SymbolContext sc;
627  sc_list.GetContextAtIndex(0, sc);
628  AddressRange addr_range;
629  sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
630  item_info_version_address =
631  addr_range.GetBaseAddress().GetLoadAddress(&target);
632  }
633  sc_list.Clear();
634 
635  static ConstString introspection_dispatch_item_info_data_offset(
636  "__introspection_dispatch_item_info_data_offset");
638  introspection_dispatch_item_info_data_offset, eSymbolTypeData,
639  sc_list) > 0) {
640  SymbolContext sc;
641  sc_list.GetContextAtIndex(0, sc);
642  AddressRange addr_range;
643  sc.GetAddressRange(eSymbolContextSymbol, 0, false, addr_range);
644  item_info_data_offset_address =
645  addr_range.GetBaseAddress().GetLoadAddress(&target);
646  }
647 
648  if (queue_info_version_address != LLDB_INVALID_ADDRESS &&
649  queue_info_data_offset_address != LLDB_INVALID_ADDRESS &&
650  item_info_version_address != LLDB_INVALID_ADDRESS &&
651  item_info_data_offset_address != LLDB_INVALID_ADDRESS) {
652  Status error;
653  m_lib_backtrace_recording_info.queue_info_version =
654  m_process->ReadUnsignedIntegerFromMemory(queue_info_version_address, 2,
655  0, error);
656  if (error.Success()) {
657  m_lib_backtrace_recording_info.queue_info_data_offset =
659  queue_info_data_offset_address, 2, 0, error);
660  if (error.Success()) {
661  m_lib_backtrace_recording_info.item_info_version =
662  m_process->ReadUnsignedIntegerFromMemory(item_info_version_address,
663  2, 0, error);
664  if (error.Success()) {
665  m_lib_backtrace_recording_info.item_info_data_offset =
667  item_info_data_offset_address, 2, 0, error);
668  if (!error.Success()) {
669  m_lib_backtrace_recording_info.queue_info_version = 0;
670  }
671  } else {
672  m_lib_backtrace_recording_info.queue_info_version = 0;
673  }
674  } else {
675  m_lib_backtrace_recording_info.queue_info_version = 0;
676  }
677  }
678  }
679 
680  return m_lib_backtrace_recording_info.queue_info_version != 0;
681 }
682 
683 const std::vector<ConstString> &
685  if (m_types.size() == 0) {
686  m_types.push_back(ConstString("libdispatch"));
687  // We could have pthread as another type in the future if we have a way of
688  // gathering that information & it's useful to distinguish between them.
689  }
690  return m_types;
691 }
692 
694  lldb_private::QueueList &queue_list) {
695  if (BacktraceRecordingHeadersInitialized()) {
697  ThreadSP cur_thread_sp(
699  if (cur_thread_sp) {
700  Status error;
701  queue_info_pointer = m_get_queues_handler.GetCurrentQueues(
702  *cur_thread_sp.get(), m_page_to_free, m_page_to_free_size, error);
703  m_page_to_free = LLDB_INVALID_ADDRESS;
704  m_page_to_free_size = 0;
705  if (error.Success()) {
706 
707  if (queue_info_pointer.count > 0 &&
708  queue_info_pointer.queues_buffer_size > 0 &&
709  queue_info_pointer.queues_buffer_ptr != 0 &&
710  queue_info_pointer.queues_buffer_ptr != LLDB_INVALID_ADDRESS) {
711  PopulateQueuesUsingLibBTR(queue_info_pointer.queues_buffer_ptr,
712  queue_info_pointer.queues_buffer_size,
713  queue_info_pointer.count, queue_list);
714  }
715  }
716  }
717  }
718 
719  // We either didn't have libBacktraceRecording (and need to create the queues
720  // list based on threads) or we did get the queues list from
721  // libBacktraceRecording but some special queues may not be included in its
722  // information. This is needed because libBacktraceRecording will only list
723  // queues with pending or running items by default - but the magic com.apple
724  // .main-thread queue on thread 1 is always around.
725 
726  for (ThreadSP thread_sp : m_process->Threads()) {
727  if (thread_sp->GetAssociatedWithLibdispatchQueue() != eLazyBoolNo) {
728  if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID) {
729  if (queue_list.FindQueueByID(thread_sp->GetQueueID()).get() == NULL) {
730  QueueSP queue_sp(new Queue(m_process->shared_from_this(),
731  thread_sp->GetQueueID(),
732  thread_sp->GetQueueName()));
733  if (thread_sp->ThreadHasQueueInformation()) {
734  queue_sp->SetKind(thread_sp->GetQueueKind());
735  queue_sp->SetLibdispatchQueueAddress(
736  thread_sp->GetQueueLibdispatchQueueAddress());
737  queue_list.AddQueue(queue_sp);
738  } else {
739  queue_sp->SetKind(
740  GetQueueKind(thread_sp->GetQueueLibdispatchQueueAddress()));
741  queue_sp->SetLibdispatchQueueAddress(
742  thread_sp->GetQueueLibdispatchQueueAddress());
743  queue_list.AddQueue(queue_sp);
744  }
745  }
746  }
747  }
748  }
749 }
750 
751 // Returns either an array of introspection_dispatch_item_info_ref's for the
752 // pending items on a queue or an array introspection_dispatch_item_info_ref's
753 // and code addresses for the pending items on a queue. The information about
754 // each of these pending items then needs to be fetched individually by passing
755 // the ref to libBacktraceRecording.
756 
757 SystemRuntimeMacOSX::PendingItemsForQueue
758 SystemRuntimeMacOSX::GetPendingItemRefsForQueue(lldb::addr_t queue) {
759  PendingItemsForQueue pending_item_refs;
761  ThreadSP cur_thread_sp(
763  if (cur_thread_sp) {
764  Status error;
765  pending_items_pointer = m_get_pending_items_handler.GetPendingItems(
766  *cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size,
767  error);
768  m_page_to_free = LLDB_INVALID_ADDRESS;
769  m_page_to_free_size = 0;
770  if (error.Success()) {
771  if (pending_items_pointer.count > 0 &&
772  pending_items_pointer.items_buffer_size > 0 &&
773  pending_items_pointer.items_buffer_ptr != 0 &&
774  pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS) {
775  DataBufferHeap data(pending_items_pointer.items_buffer_size, 0);
776  if (m_process->ReadMemory(
777  pending_items_pointer.items_buffer_ptr, data.GetBytes(),
778  pending_items_pointer.items_buffer_size, error)) {
779  DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
782 
783  // We either have an array of
784  // void* item_ref
785  // (old style) or we have a structure returned which looks like
786  //
787  // struct introspection_dispatch_pending_item_info_s {
788  // void *item_ref;
789  // void *function_or_block;
790  // };
791  //
792  // struct introspection_dispatch_pending_items_array_s {
793  // uint32_t version;
794  // uint32_t size_of_item_info;
795  // introspection_dispatch_pending_item_info_s items[];
796  // }
797 
798  offset_t offset = 0;
799  int i = 0;
800  uint32_t version = extractor.GetU32(&offset);
801  if (version == 1) {
802  pending_item_refs.new_style = true;
803  uint32_t item_size = extractor.GetU32(&offset);
804  uint32_t start_of_array_offset = offset;
805  while (offset < pending_items_pointer.items_buffer_size &&
806  static_cast<size_t>(i) < pending_items_pointer.count) {
807  offset = start_of_array_offset + (i * item_size);
808  ItemRefAndCodeAddress item;
809  item.item_ref = extractor.GetPointer(&offset);
810  item.code_address = extractor.GetPointer(&offset);
811  pending_item_refs.item_refs_and_code_addresses.push_back(item);
812  i++;
813  }
814  } else {
815  offset = 0;
816  pending_item_refs.new_style = false;
817  while (offset < pending_items_pointer.items_buffer_size &&
818  static_cast<size_t>(i) < pending_items_pointer.count) {
819  ItemRefAndCodeAddress item;
820  item.item_ref = extractor.GetPointer(&offset);
821  item.code_address = LLDB_INVALID_ADDRESS;
822  pending_item_refs.item_refs_and_code_addresses.push_back(item);
823  i++;
824  }
825  }
826  }
827  m_page_to_free = pending_items_pointer.items_buffer_ptr;
828  m_page_to_free_size = pending_items_pointer.items_buffer_size;
829  }
830  }
831  }
832  return pending_item_refs;
833 }
834 
836  if (BacktraceRecordingHeadersInitialized()) {
837  PendingItemsForQueue pending_item_refs =
838  GetPendingItemRefsForQueue(queue->GetLibdispatchQueueAddress());
839  for (ItemRefAndCodeAddress pending_item :
840  pending_item_refs.item_refs_and_code_addresses) {
841  Address addr;
842  m_process->GetTarget().ResolveLoadAddress(pending_item.code_address,
843  addr);
844  QueueItemSP queue_item_sp(new QueueItem(queue->shared_from_this(),
845  m_process->shared_from_this(),
846  pending_item.item_ref, addr));
847  queue->PushPendingQueueItem(queue_item_sp);
848  }
849  }
850 }
851 
853  addr_t item_ref) {
855 
856  ThreadSP cur_thread_sp(
858  Status error;
859  ret = m_get_item_info_handler.GetItemInfo(*cur_thread_sp.get(), item_ref,
860  m_page_to_free, m_page_to_free_size,
861  error);
862  m_page_to_free = LLDB_INVALID_ADDRESS;
863  m_page_to_free_size = 0;
864  if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS &&
865  ret.item_buffer_size > 0) {
866  DataBufferHeap data(ret.item_buffer_size, 0);
867  if (m_process->ReadMemory(ret.item_buffer_ptr, data.GetBytes(),
868  ret.item_buffer_size, error) &&
869  error.Success()) {
870  DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
873  ItemInfo item = ExtractItemInfoFromBuffer(extractor);
874  queue_item->SetItemThatEnqueuedThis(item.item_that_enqueued_this);
875  queue_item->SetEnqueueingThreadID(item.enqueuing_thread_id);
876  queue_item->SetEnqueueingQueueID(item.enqueuing_queue_serialnum);
877  queue_item->SetStopID(item.stop_id);
878  queue_item->SetEnqueueingBacktrace(item.enqueuing_callstack);
879  queue_item->SetThreadLabel(item.enqueuing_thread_label);
880  queue_item->SetQueueLabel(item.enqueuing_queue_label);
881  queue_item->SetTargetQueueLabel(item.target_queue_label);
882  }
883  m_page_to_free = ret.item_buffer_ptr;
884  m_page_to_free_size = ret.item_buffer_size;
885  }
886 }
887 
889  lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count,
890  lldb_private::QueueList &queue_list) {
891  Status error;
892  DataBufferHeap data(queues_buffer_size, 0);
894  if (m_process->ReadMemory(queues_buffer, data.GetBytes(), queues_buffer_size,
895  error) == queues_buffer_size &&
896  error.Success()) {
897  // We've read the information out of inferior memory; free it on the next
898  // call we make
899  m_page_to_free = queues_buffer;
900  m_page_to_free_size = queues_buffer_size;
901 
902  DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
905  offset_t offset = 0;
906  uint64_t queues_read = 0;
907 
908  // The information about the queues is stored in this format (v1): typedef
909  // struct introspection_dispatch_queue_info_s {
910  // uint32_t offset_to_next;
911  // dispatch_queue_t queue;
912  // uint64_t serialnum; // queue's serialnum in the process, as
913  // provided by libdispatch
914  // uint32_t running_work_items_count;
915  // uint32_t pending_work_items_count;
916  //
917  // char data[]; // Starting here, we have variable-length data:
918  // // char queue_label[];
919  // } introspection_dispatch_queue_info_s;
920 
921  while (queues_read < count && offset < queues_buffer_size) {
922  offset_t start_of_this_item = offset;
923 
924  uint32_t offset_to_next = extractor.GetU32(&offset);
925 
926  offset += 4; // Skip over the 4 bytes of reserved space
927  addr_t queue = extractor.GetPointer(&offset);
928  uint64_t serialnum = extractor.GetU64(&offset);
929  uint32_t running_work_items_count = extractor.GetU32(&offset);
930  uint32_t pending_work_items_count = extractor.GetU32(&offset);
931 
932  // Read the first field of the variable length data
933  offset = start_of_this_item +
934  m_lib_backtrace_recording_info.queue_info_data_offset;
935  const char *queue_label = extractor.GetCStr(&offset);
936  if (queue_label == NULL)
937  queue_label = "";
938 
939  offset_t start_of_next_item = start_of_this_item + offset_to_next;
940  offset = start_of_next_item;
941 
942  if (log)
943  log->Printf("SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR added "
944  "queue with dispatch_queue_t 0x%" PRIx64
945  ", serial number 0x%" PRIx64
946  ", running items %d, pending items %d, name '%s'",
947  queue, serialnum, running_work_items_count,
948  pending_work_items_count, queue_label);
949 
950  QueueSP queue_sp(
951  new Queue(m_process->shared_from_this(), serialnum, queue_label));
952  queue_sp->SetNumRunningWorkItems(running_work_items_count);
953  queue_sp->SetNumPendingWorkItems(pending_work_items_count);
954  queue_sp->SetLibdispatchQueueAddress(queue);
955  queue_sp->SetKind(GetQueueKind(queue));
956  queue_list.AddQueue(queue_sp);
957  queues_read++;
958  }
959  }
960 }
961 
962 SystemRuntimeMacOSX::ItemInfo SystemRuntimeMacOSX::ExtractItemInfoFromBuffer(
963  lldb_private::DataExtractor &extractor) {
964  ItemInfo item;
965 
966  offset_t offset = 0;
967 
968  item.item_that_enqueued_this = extractor.GetPointer(&offset);
969  item.function_or_block = extractor.GetPointer(&offset);
970  item.enqueuing_thread_id = extractor.GetU64(&offset);
971  item.enqueuing_queue_serialnum = extractor.GetU64(&offset);
972  item.target_queue_serialnum = extractor.GetU64(&offset);
973  item.enqueuing_callstack_frame_count = extractor.GetU32(&offset);
974  item.stop_id = extractor.GetU32(&offset);
975 
976  offset = m_lib_backtrace_recording_info.item_info_data_offset;
977 
978  for (uint32_t i = 0; i < item.enqueuing_callstack_frame_count; i++) {
979  item.enqueuing_callstack.push_back(extractor.GetPointer(&offset));
980  }
981  item.enqueuing_thread_label = extractor.GetCStr(&offset);
982  item.enqueuing_queue_label = extractor.GetCStr(&offset);
983  item.target_queue_label = extractor.GetCStr(&offset);
984 
985  return item;
986 }
987 
989  PluginManager::RegisterPlugin(GetPluginNameStatic(),
991 }
992 
994  PluginManager::UnregisterPlugin(CreateInstance);
995 }
996 
998  static ConstString g_name("systemruntime-macosx");
999  return g_name;
1000 }
1001 
1003  return "System runtime plugin for Mac OS X native libraries.";
1004 }
1005 
1006 // PluginInterface protocol
1008  return GetPluginNameStatic();
1009 }
1010 
void SetEnqueueingBacktrace(std::vector< lldb::addr_t > backtrace)
Definition: QueueItem.h:116
#define LIBLLDB_LOG_SYSTEM_RUNTIME
Definition: Logging.h:40
An data extractor class.
Definition: DataExtractor.h:47
std::string GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) override
Get the queue name for a thread given a thread&#39;s dispatch_qaddr.
Defines a list of symbol context objects.
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const ArchSpec & GetArchitecture() const
Definition: Target.h:941
void AddQueue(lldb::QueueSP queue)
Add a Queue to the QueueList.
Definition: QueueList.cpp:40
const char * GetCStr(lldb::offset_t *offset_ptr) const
Extract a C string from *offset_ptr.
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
void SetStopID(uint32_t stop_id)
Definition: QueueItem.h:112
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
clang::ASTContext * getASTContext()
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:292
lldb::QueueSP FindQueueByID(lldb::queue_id_t qid)
Find a queue in the QueueList by QueueID.
Definition: QueueList.cpp:47
CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size) override
virtual ObjectFile * GetObjectFile()
Get the object file representation for the current architecture.
Definition: Module.cpp:1251
lldb::addr_t GetLoadAddress(Target *target) const
Definition: Symbol.cpp:487
void AddThreadExtendedInfoPacketHints(lldb_private::StructuredData::ObjectSP dict) override
Add key-value pairs to the StructuredData dictionary object with information debugserver may need whe...
A file utility class.
Definition: FileSpec.h:55
ThreadList & GetThreadList()
Definition: Process.h:2045
#define LLDB_INVALID_QUEUE_ID
Definition: lldb-defines.h:98
size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr, size_t cstr_max_len, Status &error)
Read a NULL terminated C string from memory.
Definition: Process.cpp:2080
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:58
std::recursive_mutex m_mutex
lldb::ByteOrder GetByteOrder() const
Definition: Process.cpp:3366
lldb::addr_t GetLibdispatchQueueAddressFromThreadQAddress(lldb::addr_t dispatch_qaddr) override
Get the libdispatch_queue_t address for the queue given the thread&#39;s dispatch_qaddr.
void Detach() override
Called before detaching from a process.
Module * GetExecutableModulePointer()
Definition: Target.cpp:1394
A subclass of DataBuffer that stores a data buffer on the heap.
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
CompilerType CreateRecordType(clang::DeclContext *decl_ctx, lldb::AccessType access_type, const char *name, int kind, lldb::LanguageType language, ClangASTMetadata *metadata=nullptr)
GetQueuesReturnInfo GetCurrentQueues(Thread &thread, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Status &error)
Get the list of queues that exist (with any active or pending items) via a call to introspection_get_...
static const char * GetPluginDescriptionStatic()
uint32_t GetPluginVersion() override
void CompleteQueueItem(lldb_private::QueueItem *queue_item, lldb::addr_t item_ref) override
Complete the fields in a QueueItem.
lldb::ThreadSP GetExtendedBacktraceFromItemRef(lldb::addr_t item_ref)
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
lldb_private::ConstString GetPluginName() override
void SetEnqueueingThreadID(lldb::tid_t tid)
Definition: QueueItem.h:100
void SetItemThatEnqueuedThis(lldb::addr_t address_of_item)
Definition: QueueItem.h:94
uint32_t GetStopID() const
Definition: Process.h:1337
uint64_t offset_t
Definition: lldb-types.h:87
bool SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) override
Determine whether it is safe to run an expression on a given thread.
const std::vector< lldb_private::ConstString > & GetExtendedBacktraceTypes() override
Return a list of thread origin extended backtraces that may be available.
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
uint64_t ReadUnsignedIntegerFromMemory(const Address &addr, bool prefer_file_cache, size_t integer_byte_size, uint64_t fail_value, Status &error)
Definition: Target.cpp:1957
void SetTargetQueueLabel(std::string queue_name)
Definition: QueueItem.h:130
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:109
lldb::addr_t GetLibdispatchQueueAddress() const
Get the dispatch_queue_t structure address for this Queue.
Definition: Queue.cpp:73
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:599
lldb::QueueKind GetQueueKind(lldb::addr_t dispatch_queue_addr) override
Retrieve the Queue kind for the queue at a thread&#39;s dispatch_qaddr.
void SetThreadLabel(std::string thread_name)
Definition: QueueItem.h:122
size_t FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list, bool append=false) const
Definition: ModuleList.cpp:457
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3370
void Clear()
Clear the object&#39;s state.
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
lldb::user_id_t m_break_id
bool Success() const
Test for success condition.
Definition: Status.cpp:287
A section + offset based address class.
Definition: Address.h:80
GetItemInfoReturnInfo GetItemInfo(Thread &thread, lldb::addr_t item, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Status &error)
Get the information about a work item by calling __introspection_dispatch_queue_item_get_info.
lldb::ThreadSP GetExtendedBacktraceThread(lldb::ThreadSP thread, lldb_private::ConstString type) override
Return a Thread which shows the origin of this thread&#39;s creation.
uint64_t queue_id_t
Definition: lldb-types.h:91
ClangASTContext * GetScratchClangASTContext(bool create_on_demand=true)
Definition: Target.cpp:2299
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:899
std::vector< ConstString > m_types
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2172
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1194
void PopulateQueueList(lldb_private::QueueList &queue_list) override
Populate the Process&#39; QueueList with libdispatch / GCD queues that exist.
uint64_t addr_t
Definition: lldb-types.h:83
A uniqued constant string class.
Definition: ConstString.h:38
virtual bool IsAlive()
Check if a process is still alive.
Definition: Process.cpp:1182
Non-standardized C, such as K&R.
void PopulatePendingItemsForQueue(lldb_private::Queue *queue) override
Get the pending work items for a libdispatch Queue.
Definition: SBAddress.h:15
void SetQueueLabel(std::string queue_name)
Definition: QueueItem.h:126
std::shared_ptr< Object > ObjectSP
bool GetAddressRange(uint32_t scope, uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const
Get the address range contained within a symbol context.
GetThreadItemInfoReturnInfo GetThreadItemInfo(Thread &thread, lldb::tid_t thread_id, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Status &error)
Get the information about a work item by calling __introspection_dispatch_thread_get_item_info.
void SetEnqueueingQueueID(lldb::queue_id_t qid)
Definition: QueueItem.h:104
uint8_t * GetBytes() override
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:220
#define LLDB_INVALID_BREAK_ID
Definition: lldb-defines.h:49
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow)
Definition: Target.cpp:2746
void PushPendingQueueItem(lldb::QueueItemSP item)
Definition: Queue.h:125
lldb::ThreadSP GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp, lldb_private::ConstString type) override
Get the extended backtrace thread for a QueueItem.
GetPendingItemsReturnInfo GetPendingItems(Thread &thread, lldb::addr_t queue, lldb::addr_t page_to_free, uint64_t page_to_free_size, lldb_private::Status &error)
Get the list of pending items for a given queue via a call to __introspection_dispatch_queue_get_pend...
lldb::offset_t GetByteSize() const override
uint64_t ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Status &error)
Reads an unsigned integer of the specified byte size from process memory.
Definition: Process.cpp:2150
#define LLDB_BREAK_ID_IS_VALID(bid)
Definition: lldb-defines.h:51
static lldb_private::ConstString GetPluginNameStatic()
lldb::queue_id_t GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) override
Get the QueueID for the libdispatch queue given the thread&#39;s dispatch_qaddr.
void PopulateQueuesUsingLibBTR(lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count, lldb_private::QueueList &queue_list)
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
A section + offset based address range class.
Definition: AddressRange.h:32
uint64_t GetPointer(lldb::offset_t *offset_ptr) const
Extract an pointer from *offset_ptr.
Status ClearBreakpointSiteByID(lldb::user_id_t break_id)
Definition: Process.cpp:1621
void Clear(bool clear_process)
RetType GetField(ConstString name, RetType fail_value=RetType())
lldb::ThreadSP GetExpressionExecutionThread()
Definition: ThreadList.cpp:59
void AddIntegerItem(llvm::StringRef key, uint64_t value)
ThreadList::ThreadIterable Threads()
Definition: Process.h:2053
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
An error handling class.
Definition: Status.h:44
A plug-in interface definition class for system runtimes.
Definition: SystemRuntime.h:42
static lldb_private::SystemRuntime * CreateInstance(lldb_private::Process *process)
SystemRuntimeMacOSX(lldb_private::Process *process)
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition: Process.cpp:1966