LLDB  mainline
StructuredDataDarwinLog.cpp
Go to the documentation of this file.
1 //===-- StructuredDataDarwinLog.cpp ---------------------------------------===//
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 
10 
11 #include <cstring>
12 
13 #include <memory>
14 #include <sstream>
15 
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/Module.h"
20 #include "lldb/Host/OptionParser.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/Target.h"
31 #include "lldb/Utility/LLDBLog.h"
32 #include "lldb/Utility/Log.h"
34 
35 #define DARWIN_LOG_TYPE_VALUE "DarwinLog"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
41 
42 #pragma mark -
43 #pragma mark Anonymous Namespace
44 
45 // Anonymous namespace
46 
48 const uint64_t NANOS_PER_MICRO = 1000;
49 const uint64_t NANOS_PER_MILLI = NANOS_PER_MICRO * 1000;
50 const uint64_t NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;
51 const uint64_t NANOS_PER_MINUTE = NANOS_PER_SECOND * 60;
52 const uint64_t NANOS_PER_HOUR = NANOS_PER_MINUTE * 60;
53 
55 
56 /// Global, sticky enable switch. If true, the user has explicitly
57 /// run the enable command. When a process launches or is attached to,
58 /// we will enable DarwinLog if either the settings for auto-enable is
59 /// on, or if the user had explicitly run enable at some point prior
60 /// to the launch/attach.
62 
63 class EnableOptions;
64 using EnableOptionsSP = std::shared_ptr<EnableOptions>;
65 
66 using OptionsMap =
67  std::map<DebuggerWP, EnableOptionsSP, std::owner_less<DebuggerWP>>;
68 
70  static OptionsMap s_options_map;
71  return s_options_map;
72 }
73 
74 static std::mutex &GetGlobalOptionsMapLock() {
75  static std::mutex s_options_map_lock;
76  return s_options_map_lock;
77 }
78 
79 EnableOptionsSP GetGlobalEnableOptions(const DebuggerSP &debugger_sp) {
80  if (!debugger_sp)
81  return EnableOptionsSP();
82 
83  std::lock_guard<std::mutex> locker(GetGlobalOptionsMapLock());
84  OptionsMap &options_map = GetGlobalOptionsMap();
85  DebuggerWP debugger_wp(debugger_sp);
86  auto find_it = options_map.find(debugger_wp);
87  if (find_it != options_map.end())
88  return find_it->second;
89  else
90  return EnableOptionsSP();
91 }
92 
93 void SetGlobalEnableOptions(const DebuggerSP &debugger_sp,
94  const EnableOptionsSP &options_sp) {
95  std::lock_guard<std::mutex> locker(GetGlobalOptionsMapLock());
96  OptionsMap &options_map = GetGlobalOptionsMap();
97  DebuggerWP debugger_wp(debugger_sp);
98  auto find_it = options_map.find(debugger_wp);
99  if (find_it != options_map.end())
100  find_it->second = options_sp;
101  else
102  options_map.insert(std::make_pair(debugger_wp, options_sp));
103 }
104 
105 #pragma mark -
106 #pragma mark Settings Handling
107 
108 /// Code to handle the StructuredDataDarwinLog settings
109 
110 #define LLDB_PROPERTIES_darwinlog
111 #include "StructuredDataDarwinLogProperties.inc"
112 
113 enum {
114 #define LLDB_PROPERTIES_darwinlog
115 #include "StructuredDataDarwinLogPropertiesEnum.inc"
116 };
117 
119 public:
121  static ConstString g_setting_name("darwin-log");
122  return g_setting_name;
123  }
124 
126  m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
127  m_collection_sp->Initialize(g_darwinlog_properties);
128  }
129 
130  ~StructuredDataDarwinLogProperties() override = default;
131 
132  bool GetEnableOnStartup() const {
133  const uint32_t idx = ePropertyEnableOnStartup;
134  return m_collection_sp->GetPropertyAtIndexAsBoolean(
135  nullptr, idx, g_darwinlog_properties[idx].default_uint_value != 0);
136  }
137 
138  llvm::StringRef GetAutoEnableOptions() const {
139  const uint32_t idx = ePropertyAutoEnableOptions;
140  return m_collection_sp->GetPropertyAtIndexAsString(
141  nullptr, idx, g_darwinlog_properties[idx].default_cstr_value);
142  }
143 
144  const char *GetLoggingModuleName() const { return "libsystem_trace.dylib"; }
145 };
146 
148  static StructuredDataDarwinLogProperties g_settings;
149  return g_settings;
150 }
151 
152 const char *const s_filter_attributes[] = {
153  "activity", // current activity
154  "activity-chain", // entire activity chain, each level separated by ':'
155  "category", // category of the log message
156  "message", // message contents, fully expanded
157  "subsystem" // subsystem of the log message
158 
159  // Consider implementing this action as it would be cheaper to filter.
160  // "message" requires always formatting the message, which is a waste of
161  // cycles if it ends up being rejected. "format", // format string
162  // used to format message text
163 };
164 
166  static const ConstString s_key_name("DarwinLog");
167  return s_key_name;
168 }
169 
171  static const ConstString s_event_type("log");
172  return s_event_type;
173 }
174 
175 class FilterRule;
176 using FilterRuleSP = std::shared_ptr<FilterRule>;
177 
178 class FilterRule {
179 public:
180  virtual ~FilterRule() = default;
181 
182  using OperationCreationFunc =
183  std::function<FilterRuleSP(bool accept, size_t attribute_index,
184  const std::string &op_arg, Status &error)>;
185 
186  static void RegisterOperation(ConstString operation,
187  const OperationCreationFunc &creation_func) {
188  GetCreationFuncMap().insert(std::make_pair(operation, creation_func));
189  }
190 
191  static FilterRuleSP CreateRule(bool match_accepts, size_t attribute,
192  ConstString operation,
193  const std::string &op_arg, Status &error) {
194  // Find the creation func for this type of filter rule.
195  auto map = GetCreationFuncMap();
196  auto find_it = map.find(operation);
197  if (find_it == map.end()) {
198  error.SetErrorStringWithFormat("unknown filter operation \""
199  "%s\"",
200  operation.GetCString());
201  return FilterRuleSP();
202  }
203 
204  return find_it->second(match_accepts, attribute, op_arg, error);
205  }
206 
209 
210  // Indicate whether this is an accept or reject rule.
211  dict_p->AddBooleanItem("accept", m_accept);
212 
213  // Indicate which attribute of the message this filter references. This can
214  // drop into the rule-specific DoSerialization if we get to the point where
215  // not all FilterRule derived classes work on an attribute. (e.g. logical
216  // and/or and other compound operations).
217  dict_p->AddStringItem("attribute", s_filter_attributes[m_attribute_index]);
218 
219  // Indicate the type of the rule.
220  dict_p->AddStringItem("type", GetOperationType().GetCString());
221 
222  // Let the rule add its own specific details here.
223  DoSerialization(*dict_p);
224 
225  return StructuredData::ObjectSP(dict_p);
226  }
227 
228  virtual void Dump(Stream &stream) const = 0;
229 
230  ConstString GetOperationType() const { return m_operation; }
231 
232 protected:
233  FilterRule(bool accept, size_t attribute_index, ConstString operation)
234  : m_accept(accept), m_attribute_index(attribute_index),
235  m_operation(operation) {}
236 
237  virtual void DoSerialization(StructuredData::Dictionary &dict) const = 0;
238 
239  bool GetMatchAccepts() const { return m_accept; }
240 
241  const char *GetFilterAttribute() const {
242  return s_filter_attributes[m_attribute_index];
243  }
244 
245 private:
246  using CreationFuncMap = std::map<ConstString, OperationCreationFunc>;
247 
249  static CreationFuncMap s_map;
250  return s_map;
251  }
252 
253  const bool m_accept;
254  const size_t m_attribute_index;
256 };
257 
258 using FilterRules = std::vector<FilterRuleSP>;
259 
260 class RegexFilterRule : public FilterRule {
261 public:
262  static void RegisterOperation() {
263  FilterRule::RegisterOperation(StaticGetOperation(), CreateOperation);
264  }
265 
266  void Dump(Stream &stream) const override {
267  stream.Printf("%s %s regex %s", GetMatchAccepts() ? "accept" : "reject",
268  GetFilterAttribute(), m_regex_text.c_str());
269  }
270 
271 protected:
272  void DoSerialization(StructuredData::Dictionary &dict) const override {
273  dict.AddStringItem("regex", m_regex_text);
274  }
275 
276 private:
277  static FilterRuleSP CreateOperation(bool accept, size_t attribute_index,
278  const std::string &op_arg,
279  Status &error) {
280  // We treat the op_arg as a regex. Validate it.
281  if (op_arg.empty()) {
282  error.SetErrorString("regex filter type requires a regex "
283  "argument");
284  return FilterRuleSP();
285  }
286 
287  // Instantiate the regex so we can report any errors.
288  auto regex = RegularExpression(op_arg);
289  if (llvm::Error err = regex.GetError()) {
290  error.SetErrorString(llvm::toString(std::move(err)));
291  return FilterRuleSP();
292  }
293 
294  // We passed all our checks, this appears fine.
295  error.Clear();
296  return FilterRuleSP(new RegexFilterRule(accept, attribute_index, op_arg));
297  }
298 
300  static ConstString s_operation("regex");
301  return s_operation;
302  }
303 
304  RegexFilterRule(bool accept, size_t attribute_index,
305  const std::string &regex_text)
306  : FilterRule(accept, attribute_index, StaticGetOperation()),
307  m_regex_text(regex_text) {}
308 
310 };
311 
313 public:
314  static void RegisterOperation() {
315  FilterRule::RegisterOperation(StaticGetOperation(), CreateOperation);
316  }
317 
318  void Dump(Stream &stream) const override {
319  stream.Printf("%s %s match %s", GetMatchAccepts() ? "accept" : "reject",
320  GetFilterAttribute(), m_match_text.c_str());
321  }
322 
323 protected:
324  void DoSerialization(StructuredData::Dictionary &dict) const override {
325  dict.AddStringItem("exact_text", m_match_text);
326  }
327 
328 private:
329  static FilterRuleSP CreateOperation(bool accept, size_t attribute_index,
330  const std::string &op_arg,
331  Status &error) {
332  if (op_arg.empty()) {
333  error.SetErrorString("exact match filter type requires an "
334  "argument containing the text that must "
335  "match the specified message attribute.");
336  return FilterRuleSP();
337  }
338 
339  error.Clear();
340  return FilterRuleSP(
341  new ExactMatchFilterRule(accept, attribute_index, op_arg));
342  }
343 
345  static ConstString s_operation("match");
346  return s_operation;
347  }
348 
349  ExactMatchFilterRule(bool accept, size_t attribute_index,
350  const std::string &match_text)
351  : FilterRule(accept, attribute_index, StaticGetOperation()),
352  m_match_text(match_text) {}
353 
355 };
356 
358  ExactMatchFilterRule::RegisterOperation();
359  RegexFilterRule::RegisterOperation();
360 }
361 
362 // =========================================================================
363 // Commands
364 // =========================================================================
365 
366 /// Provides the main on-off switch for enabling darwin logging.
367 ///
368 /// It is valid to run the enable command when logging is already enabled.
369 /// This resets the logging with whatever settings are currently set.
370 
372  // Source stream include/exclude options (the first-level filter). This one
373  // should be made as small as possible as everything that goes through here
374  // must be processed by the process monitor.
375  {LLDB_OPT_SET_ALL, false, "any-process", 'a', OptionParser::eNoArgument,
376  nullptr, {}, 0, eArgTypeNone,
377  "Specifies log messages from other related processes should be "
378  "included."},
379  {LLDB_OPT_SET_ALL, false, "debug", 'd', OptionParser::eNoArgument, nullptr,
380  {}, 0, eArgTypeNone,
381  "Specifies debug-level log messages should be included. Specifying"
382  " --debug implies --info."},
383  {LLDB_OPT_SET_ALL, false, "info", 'i', OptionParser::eNoArgument, nullptr,
384  {}, 0, eArgTypeNone,
385  "Specifies info-level log messages should be included."},
386  {LLDB_OPT_SET_ALL, false, "filter", 'f', OptionParser::eRequiredArgument,
387  nullptr, {}, 0, eArgRawInput,
388  // There doesn't appear to be a great way for me to have these multi-line,
389  // formatted tables in help. This looks mostly right but there are extra
390  // linefeeds added at seemingly random spots, and indentation isn't
391  // handled properly on those lines.
392  "Appends a filter rule to the log message filter chain. Multiple "
393  "rules may be added by specifying this option multiple times, "
394  "once per filter rule. Filter rules are processed in the order "
395  "they are specified, with the --no-match-accepts setting used "
396  "for any message that doesn't match one of the rules.\n"
397  "\n"
398  " Filter spec format:\n"
399  "\n"
400  " --filter \"{action} {attribute} {op}\"\n"
401  "\n"
402  " {action} :=\n"
403  " accept |\n"
404  " reject\n"
405  "\n"
406  " {attribute} :=\n"
407  " activity | // message's most-derived activity\n"
408  " activity-chain | // message's {parent}:{child} activity\n"
409  " category | // message's category\n"
410  " message | // message's expanded contents\n"
411  " subsystem | // message's subsystem\n"
412  "\n"
413  " {op} :=\n"
414  " match {exact-match-text} |\n"
415  " regex {search-regex}\n"
416  "\n"
417  "The regex flavor used is the C++ std::regex ECMAScript format. "
418  "Prefer character classes like [[:digit:]] to \\d and the like, as "
419  "getting the backslashes escaped through properly is error-prone."},
420  {LLDB_OPT_SET_ALL, false, "live-stream", 'l',
421  OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
422  "Specify whether logging events are live-streamed or buffered. "
423  "True indicates live streaming, false indicates buffered. The "
424  "default is true (live streaming). Live streaming will deliver "
425  "log messages with less delay, but buffered capture mode has less "
426  "of an observer effect."},
427  {LLDB_OPT_SET_ALL, false, "no-match-accepts", 'n',
428  OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
429  "Specify whether a log message that doesn't match any filter rule "
430  "is accepted or rejected, where true indicates accept. The "
431  "default is true."},
432  {LLDB_OPT_SET_ALL, false, "echo-to-stderr", 'e',
433  OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
434  "Specify whether os_log()/NSLog() messages are echoed to the "
435  "target program's stderr. When DarwinLog is enabled, we shut off "
436  "the mirroring of os_log()/NSLog() to the program's stderr. "
437  "Setting this flag to true will restore the stderr mirroring."
438  "The default is false."},
439  {LLDB_OPT_SET_ALL, false, "broadcast-events", 'b',
440  OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
441  "Specify if the plugin should broadcast events. Broadcasting "
442  "log events is a requirement for displaying the log entries in "
443  "LLDB command-line. It is also required if LLDB clients want to "
444  "process log events. The default is true."},
445  // Message formatting options
446  {LLDB_OPT_SET_ALL, false, "timestamp-relative", 'r',
447  OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone,
448  "Include timestamp in the message header when printing a log "
449  "message. The timestamp is relative to the first displayed "
450  "message."},
451  {LLDB_OPT_SET_ALL, false, "subsystem", 's', OptionParser::eNoArgument,
452  nullptr, {}, 0, eArgTypeNone,
453  "Include the subsystem in the message header when displaying "
454  "a log message."},
455  {LLDB_OPT_SET_ALL, false, "category", 'c', OptionParser::eNoArgument,
456  nullptr, {}, 0, eArgTypeNone,
457  "Include the category in the message header when displaying "
458  "a log message."},
459  {LLDB_OPT_SET_ALL, false, "activity-chain", 'C', OptionParser::eNoArgument,
460  nullptr, {}, 0, eArgTypeNone,
461  "Include the activity parent-child chain in the message header "
462  "when displaying a log message. The activity hierarchy is "
463  "displayed as {grandparent-activity}:"
464  "{parent-activity}:{activity}[:...]."},
465  {LLDB_OPT_SET_ALL, false, "all-fields", 'A', OptionParser::eNoArgument,
466  nullptr, {}, 0, eArgTypeNone,
467  "Shortcut to specify that all header fields should be displayed."}};
468 
469 class EnableOptions : public Options {
470 public:
472  : Options(),
473  m_filter_fall_through_accepts(DEFAULT_FILTER_FALLTHROUGH_ACCEPTS),
474  m_filter_rules() {}
475 
476  void OptionParsingStarting(ExecutionContext *execution_context) override {
477  m_include_debug_level = false;
478  m_include_info_level = false;
479  m_include_any_process = false;
480  m_filter_fall_through_accepts = DEFAULT_FILTER_FALLTHROUGH_ACCEPTS;
481  m_echo_to_stderr = false;
482  m_display_timestamp_relative = false;
483  m_display_subsystem = false;
484  m_display_category = false;
485  m_display_activity_chain = false;
486  m_broadcast_events = true;
487  m_live_stream = true;
488  m_filter_rules.clear();
489  }
490 
491  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
492  ExecutionContext *execution_context) override {
493  Status error;
494 
495  const int short_option = m_getopt_table[option_idx].val;
496  switch (short_option) {
497  case 'a':
498  m_include_any_process = true;
499  break;
500 
501  case 'A':
502  m_display_timestamp_relative = true;
503  m_display_category = true;
504  m_display_subsystem = true;
505  m_display_activity_chain = true;
506  break;
507 
508  case 'b':
509  m_broadcast_events =
510  OptionArgParser::ToBoolean(option_arg, true, nullptr);
511  break;
512 
513  case 'c':
514  m_display_category = true;
515  break;
516 
517  case 'C':
518  m_display_activity_chain = true;
519  break;
520 
521  case 'd':
522  m_include_debug_level = true;
523  break;
524 
525  case 'e':
526  m_echo_to_stderr = OptionArgParser::ToBoolean(option_arg, false, nullptr);
527  break;
528 
529  case 'f':
530  return ParseFilterRule(option_arg);
531 
532  case 'i':
533  m_include_info_level = true;
534  break;
535 
536  case 'l':
537  m_live_stream = OptionArgParser::ToBoolean(option_arg, false, nullptr);
538  break;
539 
540  case 'n':
541  m_filter_fall_through_accepts =
542  OptionArgParser::ToBoolean(option_arg, true, nullptr);
543  break;
544 
545  case 'r':
546  m_display_timestamp_relative = true;
547  break;
548 
549  case 's':
550  m_display_subsystem = true;
551  break;
552 
553  default:
554  error.SetErrorStringWithFormat("unsupported option '%c'", short_option);
555  }
556  return error;
557  }
558 
559  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
560  return llvm::makeArrayRef(g_enable_option_table);
561  }
562 
565 
566  // Set the basic enabled state.
567  config_sp->AddBooleanItem("enabled", enabled);
568 
569  // If we're disabled, there's nothing more to add.
570  if (!enabled)
571  return config_sp;
572 
573  // Handle source stream flags.
574  auto source_flags_sp =
576  config_sp->AddItem("source-flags", source_flags_sp);
577 
578  source_flags_sp->AddBooleanItem("any-process", m_include_any_process);
579  source_flags_sp->AddBooleanItem("debug-level", m_include_debug_level);
580  // The debug-level flag, if set, implies info-level.
581  source_flags_sp->AddBooleanItem("info-level", m_include_info_level ||
582  m_include_debug_level);
583  source_flags_sp->AddBooleanItem("live-stream", m_live_stream);
584 
585  // Specify default filter rule (the fall-through)
586  config_sp->AddBooleanItem("filter-fall-through-accepts",
587  m_filter_fall_through_accepts);
588 
589  // Handle filter rules
590  if (!m_filter_rules.empty()) {
591  auto json_filter_rules_sp =
593  config_sp->AddItem("filter-rules", json_filter_rules_sp);
594  for (auto &rule_sp : m_filter_rules) {
595  if (!rule_sp)
596  continue;
597  json_filter_rules_sp->AddItem(rule_sp->Serialize());
598  }
599  }
600  return config_sp;
601  }
602 
603  bool GetIncludeDebugLevel() const { return m_include_debug_level; }
604 
605  bool GetIncludeInfoLevel() const {
606  // Specifying debug level implies info level.
607  return m_include_info_level || m_include_debug_level;
608  }
609 
610  const FilterRules &GetFilterRules() const { return m_filter_rules; }
611 
612  bool GetFallthroughAccepts() const { return m_filter_fall_through_accepts; }
613 
614  bool GetEchoToStdErr() const { return m_echo_to_stderr; }
615 
617  return m_display_timestamp_relative;
618  }
619 
620  bool GetDisplaySubsystem() const { return m_display_subsystem; }
621  bool GetDisplayCategory() const { return m_display_category; }
622  bool GetDisplayActivityChain() const { return m_display_activity_chain; }
623 
625  return m_display_timestamp_relative || m_display_activity_chain ||
626  m_display_subsystem || m_display_category;
627  }
628 
629  bool GetBroadcastEvents() const { return m_broadcast_events; }
630 
631 private:
632  Status ParseFilterRule(llvm::StringRef rule_text) {
633  Status error;
634 
635  if (rule_text.empty()) {
636  error.SetErrorString("invalid rule_text");
637  return error;
638  }
639 
640  // filter spec format:
641  //
642  // {action} {attribute} {op}
643  //
644  // {action} :=
645  // accept |
646  // reject
647  //
648  // {attribute} :=
649  // category |
650  // subsystem |
651  // activity |
652  // activity-chain |
653  // message |
654  // format
655  //
656  // {op} :=
657  // match {exact-match-text} |
658  // regex {search-regex}
659 
660  // Parse action.
661  auto action_end_pos = rule_text.find(' ');
662  if (action_end_pos == std::string::npos) {
663  error.SetErrorStringWithFormat("could not parse filter rule "
664  "action from \"%s\"",
665  rule_text.str().c_str());
666  return error;
667  }
668  auto action = rule_text.substr(0, action_end_pos);
669  bool accept;
670  if (action == "accept")
671  accept = true;
672  else if (action == "reject")
673  accept = false;
674  else {
675  error.SetErrorString("filter action must be \"accept\" or \"deny\"");
676  return error;
677  }
678 
679  // parse attribute
680  auto attribute_end_pos = rule_text.find(" ", action_end_pos + 1);
681  if (attribute_end_pos == std::string::npos) {
682  error.SetErrorStringWithFormat("could not parse filter rule "
683  "attribute from \"%s\"",
684  rule_text.str().c_str());
685  return error;
686  }
687  auto attribute = rule_text.substr(action_end_pos + 1,
688  attribute_end_pos - (action_end_pos + 1));
689  auto attribute_index = MatchAttributeIndex(attribute);
690  if (attribute_index < 0) {
691  error.SetErrorStringWithFormat("filter rule attribute unknown: "
692  "%s",
693  attribute.str().c_str());
694  return error;
695  }
696 
697  // parse operation
698  auto operation_end_pos = rule_text.find(" ", attribute_end_pos + 1);
699  auto operation = rule_text.substr(
700  attribute_end_pos + 1, operation_end_pos - (attribute_end_pos + 1));
701 
702  // add filter spec
703  auto rule_sp = FilterRule::CreateRule(
704  accept, attribute_index, ConstString(operation),
705  std::string(rule_text.substr(operation_end_pos + 1)), error);
706 
707  if (rule_sp && error.Success())
708  m_filter_rules.push_back(rule_sp);
709 
710  return error;
711  }
712 
713  int MatchAttributeIndex(llvm::StringRef attribute_name) const {
714  for (const auto &Item : llvm::enumerate(s_filter_attributes)) {
715  if (attribute_name == Item.value())
716  return Item.index();
717  }
718 
719  // We didn't match anything.
720  return -1;
721  }
722 
723  bool m_include_debug_level = false;
724  bool m_include_info_level = false;
725  bool m_include_any_process = false;
727  bool m_echo_to_stderr = false;
728  bool m_display_timestamp_relative = false;
729  bool m_display_subsystem = false;
730  bool m_display_category = false;
731  bool m_display_activity_chain = false;
732  bool m_broadcast_events = true;
733  bool m_live_stream = true;
735 };
736 
738 public:
739  EnableCommand(CommandInterpreter &interpreter, bool enable, const char *name,
740  const char *help, const char *syntax)
741  : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable),
742  m_options_sp(enable ? new EnableOptions() : nullptr) {}
743 
744 protected:
746  const char *source_name) {
747  if (!source_name)
748  return;
749 
750  // Check if we're *not* using strict sources. If not, then the user is
751  // going to get debug-level info anyways, probably not what they're
752  // expecting. Unfortunately we can only fix this by adding an env var,
753  // which would have had to have happened already. Thus, a warning is the
754  // best we can do here.
755  StreamString stream;
756  stream.Printf("darwin-log source settings specify to exclude "
757  "%s messages, but setting "
758  "'plugin.structured-data.darwin-log."
759  "strict-sources' is disabled. This process will "
760  "automatically have %s messages included. Enable"
761  " the property and relaunch the target binary to have"
762  " these messages excluded.",
763  source_name, source_name);
764  result.AppendWarning(stream.GetString());
765  }
766 
767  bool DoExecute(Args &command, CommandReturnObject &result) override {
768  // First off, set the global sticky state of enable/disable based on this
769  // command execution.
770  s_is_explicitly_enabled = m_enable;
771 
772  // Next, if this is an enable, save off the option data. We will need it
773  // later if a process hasn't been launched or attached yet.
774  if (m_enable) {
775  // Save off enabled configuration so we can apply these parsed options
776  // the next time an attach or launch occurs.
777  DebuggerSP debugger_sp =
778  GetCommandInterpreter().GetDebugger().shared_from_this();
779  SetGlobalEnableOptions(debugger_sp, m_options_sp);
780  }
781 
782  // Now check if we have a running process. If so, we should instruct the
783  // process monitor to enable/disable DarwinLog support now.
784  Target &target = GetSelectedOrDummyTarget();
785 
786  // Grab the active process.
787  auto process_sp = target.GetProcessSP();
788  if (!process_sp) {
789  // No active process, so there is nothing more to do right now.
791  return true;
792  }
793 
794  // If the process is no longer alive, we can't do this now. We'll catch it
795  // the next time the process is started up.
796  if (!process_sp->IsAlive()) {
798  return true;
799  }
800 
801  // Get the plugin for the process.
802  auto plugin_sp =
803  process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
804  if (!plugin_sp || (plugin_sp->GetPluginName() !=
805  StructuredDataDarwinLog::GetStaticPluginName())) {
806  result.AppendError("failed to get StructuredDataPlugin for "
807  "the process");
808  }
809  StructuredDataDarwinLog &plugin =
810  *static_cast<StructuredDataDarwinLog *>(plugin_sp.get());
811 
812  if (m_enable) {
813  // Hook up the breakpoint for the process that detects when libtrace has
814  // been sufficiently initialized to really start the os_log stream. This
815  // is insurance to assure us that logging is really enabled. Requesting
816  // that logging be enabled for a process before libtrace is initialized
817  // results in a scenario where no errors occur, but no logging is
818  // captured, either. This step is to eliminate that possibility.
819  plugin.AddInitCompletionHook(*process_sp);
820  }
821 
822  // Send configuration to the feature by way of the process. Construct the
823  // options we will use.
824  auto config_sp = m_options_sp->BuildConfigurationData(m_enable);
825  const Status error =
826  process_sp->ConfigureStructuredData(GetDarwinLogTypeName(), config_sp);
827 
828  // Report results.
829  if (!error.Success()) {
830  result.AppendError(error.AsCString());
831  // Our configuration failed, so we're definitely disabled.
832  plugin.SetEnabled(false);
833  } else {
835  // Our configuration succeeded, so we're enabled/disabled per whichever
836  // one this command is setup to do.
837  plugin.SetEnabled(m_enable);
838  }
839  return result.Succeeded();
840  }
841 
842  Options *GetOptions() override {
843  // We don't have options when this represents disable.
844  return m_enable ? m_options_sp.get() : nullptr;
845  }
846 
847 private:
848  const bool m_enable;
850 };
851 
852 /// Provides the status command.
854 public:
856  : CommandObjectParsed(interpreter, "status",
857  "Show whether Darwin log supported is available"
858  " and enabled.",
859  "plugin structured-data darwin-log status") {}
860 
861 protected:
862  bool DoExecute(Args &command, CommandReturnObject &result) override {
863  auto &stream = result.GetOutputStream();
864 
865  // Figure out if we've got a process. If so, we can tell if DarwinLog is
866  // available for that process.
867  Target &target = GetSelectedOrDummyTarget();
868  auto process_sp = target.GetProcessSP();
869  if (!process_sp) {
870  stream.PutCString("Availability: unknown (requires process)\n");
871  stream.PutCString("Enabled: not applicable "
872  "(requires process)\n");
873  } else {
874  auto plugin_sp =
875  process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
876  stream.Printf("Availability: %s\n",
877  plugin_sp ? "available" : "unavailable");
878  llvm::StringRef plugin_name = StructuredDataDarwinLog::GetStaticPluginName();
879  const bool enabled =
880  plugin_sp ? plugin_sp->GetEnabled(ConstString(plugin_name)) : false;
881  stream.Printf("Enabled: %s\n", enabled ? "true" : "false");
882  }
883 
884  // Display filter settings.
885  DebuggerSP debugger_sp =
886  GetCommandInterpreter().GetDebugger().shared_from_this();
887  auto options_sp = GetGlobalEnableOptions(debugger_sp);
888  if (!options_sp) {
889  // Nothing more to do.
891  return true;
892  }
893 
894  // Print filter rules
895  stream.PutCString("DarwinLog filter rules:\n");
896 
897  stream.IndentMore();
898 
899  if (options_sp->GetFilterRules().empty()) {
900  stream.Indent();
901  stream.PutCString("none\n");
902  } else {
903  // Print each of the filter rules.
904  int rule_number = 0;
905  for (auto rule_sp : options_sp->GetFilterRules()) {
906  ++rule_number;
907  if (!rule_sp)
908  continue;
909 
910  stream.Indent();
911  stream.Printf("%02d: ", rule_number);
912  rule_sp->Dump(stream);
913  stream.PutChar('\n');
914  }
915  }
916  stream.IndentLess();
917 
918  // Print no-match handling.
919  stream.Indent();
920  stream.Printf("no-match behavior: %s\n",
921  options_sp->GetFallthroughAccepts() ? "accept" : "reject");
922 
924  return true;
925  }
926 };
927 
928 /// Provides the darwin-log base command
930 public:
932  : CommandObjectMultiword(interpreter, "plugin structured-data darwin-log",
933  "Commands for configuring Darwin os_log "
934  "support.",
935  "") {
936  // enable
937  auto enable_help = "Enable Darwin log collection, or re-enable "
938  "with modified configuration.";
939  auto enable_syntax = "plugin structured-data darwin-log enable";
940  auto enable_cmd_sp = CommandObjectSP(
941  new EnableCommand(interpreter,
942  true, // enable
943  "enable", enable_help, enable_syntax));
944  LoadSubCommand("enable", enable_cmd_sp);
945 
946  // disable
947  auto disable_help = "Disable Darwin log collection.";
948  auto disable_syntax = "plugin structured-data darwin-log disable";
949  auto disable_cmd_sp = CommandObjectSP(
950  new EnableCommand(interpreter,
951  false, // disable
952  "disable", disable_help, disable_syntax));
953  LoadSubCommand("disable", disable_cmd_sp);
954 
955  // status
956  auto status_cmd_sp = CommandObjectSP(new StatusCommand(interpreter));
957  LoadSubCommand("status", status_cmd_sp);
958  }
959 };
960 
962  Log *log = GetLog(LLDBLog::Process);
963  // We are abusing the options data model here so that we can parse options
964  // without requiring the Debugger instance.
965 
966  // We have an empty execution context at this point. We only want to parse
967  // options, and we don't need any context to do this here. In fact, we want
968  // to be able to parse the enable options before having any context.
969  ExecutionContext exe_ctx;
970 
971  EnableOptionsSP options_sp(new EnableOptions());
972  options_sp->NotifyOptionParsingStarting(&exe_ctx);
973 
974  CommandReturnObject result(debugger.GetUseColor());
975 
976  // Parse the arguments.
977  auto options_property_sp =
978  debugger.GetPropertyValue(nullptr, "plugin.structured-data.darwin-log."
979  "auto-enable-options",
980  false, error);
981  if (!error.Success())
982  return EnableOptionsSP();
983  if (!options_property_sp) {
984  error.SetErrorString("failed to find option setting for "
985  "plugin.structured-data.darwin-log.");
986  return EnableOptionsSP();
987  }
988 
989  const char *enable_options =
990  options_property_sp->GetAsString()->GetCurrentValue();
991  Args args(enable_options);
992  if (args.GetArgumentCount() > 0) {
993  // Eliminate the initial '--' that would be required to set the settings
994  // that themselves include '-' and/or '--'.
995  const char *first_arg = args.GetArgumentAtIndex(0);
996  if (first_arg && (strcmp(first_arg, "--") == 0))
997  args.Shift();
998  }
999 
1000  bool require_validation = false;
1001  llvm::Expected<Args> args_or =
1002  options_sp->Parse(args, &exe_ctx, PlatformSP(), require_validation);
1003  if (!args_or) {
1005  log, args_or.takeError(),
1006  "Parsing plugin.structured-data.darwin-log.auto-enable-options value "
1007  "failed: {0}");
1008  return EnableOptionsSP();
1009  }
1010 
1011  if (!options_sp->VerifyOptions(result))
1012  return EnableOptionsSP();
1013 
1014  // We successfully parsed and validated the options.
1015  return options_sp;
1016 }
1017 
1019  StreamString command_stream;
1020 
1021  command_stream << "plugin structured-data darwin-log enable";
1022  auto enable_options = GetGlobalProperties().GetAutoEnableOptions();
1023  if (!enable_options.empty()) {
1024  command_stream << ' ';
1025  command_stream << enable_options;
1026  }
1027 
1028  // Run the command.
1029  CommandReturnObject return_object(interpreter.GetDebugger().GetUseColor());
1030  interpreter.HandleCommand(command_stream.GetData(), eLazyBoolNo,
1031  return_object);
1032  return return_object.Succeeded();
1033 }
1034 }
1035 using namespace sddarwinlog_private;
1036 
1037 #pragma mark -
1038 #pragma mark Public static API
1039 
1040 // Public static API
1041 
1042 void StructuredDataDarwinLog::Initialize() {
1044  PluginManager::RegisterPlugin(
1045  GetStaticPluginName(), "Darwin os_log() and os_activity() support",
1046  &CreateInstance, &DebuggerInitialize, &FilterLaunchInfo);
1047 }
1048 
1049 void StructuredDataDarwinLog::Terminate() {
1050  PluginManager::UnregisterPlugin(&CreateInstance);
1051 }
1052 
1053 #pragma mark -
1054 #pragma mark StructuredDataPlugin API
1055 
1056 // StructuredDataPlugin API
1057 
1058 bool StructuredDataDarwinLog::SupportsStructuredDataType(
1059  ConstString type_name) {
1060  return type_name == GetDarwinLogTypeName();
1061 }
1062 
1063 void StructuredDataDarwinLog::HandleArrivalOfStructuredData(
1064  Process &process, ConstString type_name,
1065  const StructuredData::ObjectSP &object_sp) {
1066  Log *log = GetLog(LLDBLog::Process);
1067  if (log) {
1068  StreamString json_stream;
1069  if (object_sp)
1070  object_sp->Dump(json_stream);
1071  else
1072  json_stream.PutCString("<null>");
1073  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called with json: %s",
1074  __FUNCTION__, json_stream.GetData());
1075  }
1076 
1077  // Ignore empty structured data.
1078  if (!object_sp) {
1079  LLDB_LOGF(log,
1080  "StructuredDataDarwinLog::%s() StructuredData object "
1081  "is null",
1082  __FUNCTION__);
1083  return;
1084  }
1085 
1086  // Ignore any data that isn't for us.
1087  if (type_name != GetDarwinLogTypeName()) {
1088  LLDB_LOGF(log,
1089  "StructuredDataDarwinLog::%s() StructuredData type "
1090  "expected to be %s but was %s, ignoring",
1091  __FUNCTION__, GetDarwinLogTypeName().AsCString(),
1092  type_name.AsCString());
1093  return;
1094  }
1095 
1096  // Broadcast the structured data event if we have that enabled. This is the
1097  // way that the outside world (all clients) get access to this data. This
1098  // plugin sets policy as to whether we do that.
1099  DebuggerSP debugger_sp = process.GetTarget().GetDebugger().shared_from_this();
1100  auto options_sp = GetGlobalEnableOptions(debugger_sp);
1101  if (options_sp && options_sp->GetBroadcastEvents()) {
1102  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() broadcasting event",
1103  __FUNCTION__);
1104  process.BroadcastStructuredData(object_sp, shared_from_this());
1105  }
1106 
1107  // Later, hang on to a configurable amount of these and allow commands to
1108  // inspect, including showing backtraces.
1109 }
1110 
1111 static void SetErrorWithJSON(Status &error, const char *message,
1112  StructuredData::Object &object) {
1113  if (!message) {
1114  error.SetErrorString("Internal error: message not set.");
1115  return;
1116  }
1117 
1118  StreamString object_stream;
1119  object.Dump(object_stream);
1120  object_stream.Flush();
1121 
1122  error.SetErrorStringWithFormat("%s: %s", message, object_stream.GetData());
1123 }
1124 
1125 Status StructuredDataDarwinLog::GetDescription(
1126  const StructuredData::ObjectSP &object_sp, lldb_private::Stream &stream) {
1127  Status error;
1128 
1129  if (!object_sp) {
1130  error.SetErrorString("No structured data.");
1131  return error;
1132  }
1133 
1134  // Log message payload objects will be dictionaries.
1135  const StructuredData::Dictionary *dictionary = object_sp->GetAsDictionary();
1136  if (!dictionary) {
1137  SetErrorWithJSON(error, "Structured data should have been a dictionary "
1138  "but wasn't",
1139  *object_sp);
1140  return error;
1141  }
1142 
1143  // Validate this is really a message for our plugin.
1144  ConstString type_name;
1145  if (!dictionary->GetValueForKeyAsString("type", type_name)) {
1146  SetErrorWithJSON(error, "Structured data doesn't contain mandatory "
1147  "type field",
1148  *object_sp);
1149  return error;
1150  }
1151 
1152  if (type_name != GetDarwinLogTypeName()) {
1153  // This is okay - it simply means the data we received is not a log
1154  // message. We'll just format it as is.
1155  object_sp->Dump(stream);
1156  return error;
1157  }
1158 
1159  // DarwinLog dictionaries store their data
1160  // in an array with key name "events".
1161  StructuredData::Array *events = nullptr;
1162  if (!dictionary->GetValueForKeyAsArray("events", events) || !events) {
1163  SetErrorWithJSON(error, "Log structured data is missing mandatory "
1164  "'events' field, expected to be an array",
1165  *object_sp);
1166  return error;
1167  }
1168 
1169  events->ForEach(
1170  [&stream, &error, &object_sp, this](StructuredData::Object *object) {
1171  if (!object) {
1172  // Invalid. Stop iterating.
1173  SetErrorWithJSON(error, "Log event entry is null", *object_sp);
1174  return false;
1175  }
1176 
1177  auto event = object->GetAsDictionary();
1178  if (!event) {
1179  // Invalid, stop iterating.
1180  SetErrorWithJSON(error, "Log event is not a dictionary", *object_sp);
1181  return false;
1182  }
1183 
1184  // If we haven't already grabbed the first timestamp value, do that
1185  // now.
1186  if (!m_recorded_first_timestamp) {
1187  uint64_t timestamp = 0;
1188  if (event->GetValueForKeyAsInteger("timestamp", timestamp)) {
1189  m_first_timestamp_seen = timestamp;
1190  m_recorded_first_timestamp = true;
1191  }
1192  }
1193 
1194  HandleDisplayOfEvent(*event, stream);
1195  return true;
1196  });
1197 
1198  stream.Flush();
1199  return error;
1200 }
1201 
1202 bool StructuredDataDarwinLog::GetEnabled(ConstString type_name) const {
1203  if (type_name.GetStringRef() == GetStaticPluginName())
1204  return m_is_enabled;
1205  else
1206  return false;
1207 }
1208 
1209 void StructuredDataDarwinLog::SetEnabled(bool enabled) {
1210  m_is_enabled = enabled;
1211 }
1212 
1213 void StructuredDataDarwinLog::ModulesDidLoad(Process &process,
1214  ModuleList &module_list) {
1215  Log *log = GetLog(LLDBLog::Process);
1216  LLDB_LOGF(log, "StructuredDataDarwinLog::%s called (process uid %u)",
1217  __FUNCTION__, process.GetUniqueID());
1218 
1219  // Check if we should enable the darwin log support on startup/attach.
1220  if (!GetGlobalProperties().GetEnableOnStartup() &&
1222  // We're neither auto-enabled or explicitly enabled, so we shouldn't try to
1223  // enable here.
1224  LLDB_LOGF(log,
1225  "StructuredDataDarwinLog::%s not applicable, we're not "
1226  "enabled (process uid %u)",
1227  __FUNCTION__, process.GetUniqueID());
1228  return;
1229  }
1230 
1231  // If we already added the breakpoint, we've got nothing left to do.
1232  {
1233  std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
1234  if (m_added_breakpoint) {
1235  LLDB_LOGF(log,
1236  "StructuredDataDarwinLog::%s process uid %u's "
1237  "post-libtrace-init breakpoint is already set",
1238  __FUNCTION__, process.GetUniqueID());
1239  return;
1240  }
1241  }
1242 
1243  // The logging support module name, specifies the name of the image name that
1244  // must be loaded into the debugged process before we can try to enable
1245  // logging.
1246  const char *logging_module_cstr =
1248  if (!logging_module_cstr || (logging_module_cstr[0] == 0)) {
1249  // We need this. Bail.
1250  LLDB_LOGF(log,
1251  "StructuredDataDarwinLog::%s no logging module name "
1252  "specified, we don't know where to set a breakpoint "
1253  "(process uid %u)",
1254  __FUNCTION__, process.GetUniqueID());
1255  return;
1256  }
1257 
1258  const ConstString logging_module_name = ConstString(logging_module_cstr);
1259 
1260  // We need to see libtrace in the list of modules before we can enable
1261  // tracing for the target process.
1262  bool found_logging_support_module = false;
1263  for (size_t i = 0; i < module_list.GetSize(); ++i) {
1264  auto module_sp = module_list.GetModuleAtIndex(i);
1265  if (!module_sp)
1266  continue;
1267 
1268  auto &file_spec = module_sp->GetFileSpec();
1269  found_logging_support_module =
1270  (file_spec.GetLastPathComponent() == logging_module_name);
1271  if (found_logging_support_module)
1272  break;
1273  }
1274 
1275  if (!found_logging_support_module) {
1276  LLDB_LOGF(log,
1277  "StructuredDataDarwinLog::%s logging module %s "
1278  "has not yet been loaded, can't set a breakpoint "
1279  "yet (process uid %u)",
1280  __FUNCTION__, logging_module_name.AsCString(),
1281  process.GetUniqueID());
1282  return;
1283  }
1284 
1285  // Time to enqueue the breakpoint so we can wait for logging support to be
1286  // initialized before we try to tap the libtrace stream.
1287  AddInitCompletionHook(process);
1288  LLDB_LOGF(log,
1289  "StructuredDataDarwinLog::%s post-init hook breakpoint "
1290  "set for logging module %s (process uid %u)",
1291  __FUNCTION__, logging_module_name.AsCString(),
1292  process.GetUniqueID());
1293 
1294  // We need to try the enable here as well, which will succeed in the event
1295  // that we're attaching to (rather than launching) the process and the
1296  // process is already past initialization time. In that case, the completion
1297  // breakpoint will never get hit and therefore won't start that way. It
1298  // doesn't hurt much beyond a bit of bandwidth if we end up doing this twice.
1299  // It hurts much more if we don't get the logging enabled when the user
1300  // expects it.
1301  EnableNow();
1302 }
1303 
1304 // public destructor
1305 
1306 StructuredDataDarwinLog::~StructuredDataDarwinLog() {
1307  if (m_breakpoint_id != LLDB_INVALID_BREAK_ID) {
1308  ProcessSP process_sp(GetProcess());
1309  if (process_sp) {
1310  process_sp->GetTarget().RemoveBreakpointByID(m_breakpoint_id);
1311  m_breakpoint_id = LLDB_INVALID_BREAK_ID;
1312  }
1313  }
1314 }
1315 
1316 #pragma mark -
1317 #pragma mark Private instance methods
1318 
1319 // Private constructors
1320 
1321 StructuredDataDarwinLog::StructuredDataDarwinLog(const ProcessWP &process_wp)
1322  : StructuredDataPlugin(process_wp), m_recorded_first_timestamp(false),
1323  m_first_timestamp_seen(0), m_is_enabled(false),
1324  m_added_breakpoint_mutex(), m_added_breakpoint(),
1325  m_breakpoint_id(LLDB_INVALID_BREAK_ID) {}
1326 
1327 // Private static methods
1328 
1329 StructuredDataPluginSP
1331  // Currently only Apple targets support the os_log/os_activity protocol.
1332  if (process.GetTarget().GetArchitecture().GetTriple().getVendor() ==
1333  llvm::Triple::VendorType::Apple) {
1334  auto process_wp = ProcessWP(process.shared_from_this());
1335  return StructuredDataPluginSP(new StructuredDataDarwinLog(process_wp));
1336  } else {
1337  return StructuredDataPluginSP();
1338  }
1339 }
1340 
1342  // Setup parent class first.
1344 
1345  // Get parent command.
1346  auto &interpreter = debugger.GetCommandInterpreter();
1347  llvm::StringRef parent_command_text = "plugin structured-data";
1348  auto parent_command =
1349  interpreter.GetCommandObjectForCommand(parent_command_text);
1350  if (!parent_command) {
1351  // Ut oh, parent failed to create parent command.
1352  // TODO log
1353  return;
1354  }
1355 
1356  auto command_name = "darwin-log";
1357  auto command_sp = CommandObjectSP(new BaseCommand(interpreter));
1358  bool result = parent_command->LoadSubCommand(command_name, command_sp);
1359  if (!result) {
1360  // TODO log it once we setup structured data logging
1361  }
1362 
1364  debugger, StructuredDataDarwinLogProperties::GetSettingName())) {
1365  const bool is_global_setting = true;
1367  debugger, GetGlobalProperties().GetValueProperties(),
1368  ConstString("Properties for the darwin-log"
1369  " plug-in."),
1370  is_global_setting);
1371  }
1372 }
1373 
1375  Target *target) {
1376  Status error;
1377 
1378  // If we're not debugging this launched process, there's nothing for us to do
1379  // here.
1380  if (!launch_info.GetFlags().AnySet(eLaunchFlagDebug))
1381  return error;
1382 
1383  // Darwin os_log() support automatically adds debug-level and info-level
1384  // messages when a debugger is attached to a process. However, with
1385  // integrated support for debugging built into the command-line LLDB, the
1386  // user may specifically set to *not* include debug-level and info-level
1387  // content. When the user is using the integrated log support, we want to
1388  // put the kabosh on that automatic adding of info and debug level. This is
1389  // done by adding an environment variable to the process on launch. (This
1390  // also means it is not possible to suppress this behavior if attaching to an
1391  // already-running app).
1392  // Log *log = GetLog(LLDBLog::Platform);
1393 
1394  // If the target architecture is not one that supports DarwinLog, we have
1395  // nothing to do here.
1396  auto &triple = target ? target->GetArchitecture().GetTriple()
1397  : launch_info.GetArchitecture().GetTriple();
1398  if (triple.getVendor() != llvm::Triple::Apple) {
1399  return error;
1400  }
1401 
1402  // If DarwinLog is not enabled (either by explicit user command or via the
1403  // auto-enable option), then we have nothing to do.
1404  if (!GetGlobalProperties().GetEnableOnStartup() &&
1406  // Nothing to do, DarwinLog is not enabled.
1407  return error;
1408  }
1409 
1410  // If we don't have parsed configuration info, that implies we have enable-
1411  // on-startup set up, but we haven't yet attempted to run the enable command.
1412  if (!target) {
1413  // We really can't do this without a target. We need to be able to get to
1414  // the debugger to get the proper options to do this right.
1415  // TODO log.
1416  error.SetErrorString("requires a target to auto-enable DarwinLog.");
1417  return error;
1418  }
1419 
1420  DebuggerSP debugger_sp = target->GetDebugger().shared_from_this();
1421  auto options_sp = GetGlobalEnableOptions(debugger_sp);
1422  if (!options_sp && debugger_sp) {
1423  options_sp = ParseAutoEnableOptions(error, *debugger_sp.get());
1424  if (!options_sp || !error.Success())
1425  return error;
1426 
1427  // We already parsed the options, save them now so we don't generate them
1428  // again until the user runs the command manually.
1429  SetGlobalEnableOptions(debugger_sp, options_sp);
1430  }
1431 
1432  if (!options_sp->GetEchoToStdErr()) {
1433  // The user doesn't want to see os_log/NSLog messages echo to stderr. That
1434  // mechanism is entirely separate from the DarwinLog support. By default we
1435  // don't want to get it via stderr, because that would be in duplicate of
1436  // the explicit log support here.
1437 
1438  // Here we need to strip out any OS_ACTIVITY_DT_MODE setting to prevent
1439  // echoing of os_log()/NSLog() to stderr in the target program.
1440  launch_info.GetEnvironment().erase("OS_ACTIVITY_DT_MODE");
1441 
1442  // We will also set the env var that tells any downstream launcher from
1443  // adding OS_ACTIVITY_DT_MODE.
1444  launch_info.GetEnvironment()["IDE_DISABLED_OS_ACTIVITY_DT_MODE"] = "1";
1445  }
1446 
1447  // Set the OS_ACTIVITY_MODE env var appropriately to enable/disable debug and
1448  // info level messages.
1449  const char *env_var_value;
1450  if (options_sp->GetIncludeDebugLevel())
1451  env_var_value = "debug";
1452  else if (options_sp->GetIncludeInfoLevel())
1453  env_var_value = "info";
1454  else
1455  env_var_value = "default";
1456 
1457  launch_info.GetEnvironment()["OS_ACTIVITY_MODE"] = env_var_value;
1458 
1459  return error;
1460 }
1461 
1463  void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
1464  lldb::user_id_t break_loc_id) {
1465  // We hit the init function. We now want to enqueue our new thread plan,
1466  // which will in turn enqueue a StepOut thread plan. When the StepOut
1467  // finishes and control returns to our new thread plan, that is the time when
1468  // we can execute our logic to enable the logging support.
1469 
1470  Log *log = GetLog(LLDBLog::Process);
1471  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__);
1472 
1473  // Get the current thread.
1474  if (!context) {
1475  LLDB_LOGF(log,
1476  "StructuredDataDarwinLog::%s() warning: no context, "
1477  "ignoring",
1478  __FUNCTION__);
1479  return false;
1480  }
1481 
1482  // Get the plugin from the process.
1483  auto process_sp = context->exe_ctx_ref.GetProcessSP();
1484  if (!process_sp) {
1485  LLDB_LOGF(log,
1486  "StructuredDataDarwinLog::%s() warning: invalid "
1487  "process in context, ignoring",
1488  __FUNCTION__);
1489  return false;
1490  }
1491  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() call is for process uid %d",
1492  __FUNCTION__, process_sp->GetUniqueID());
1493 
1494  auto plugin_sp = process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName());
1495  if (!plugin_sp) {
1496  LLDB_LOGF(log,
1497  "StructuredDataDarwinLog::%s() warning: no plugin for "
1498  "feature %s in process uid %u",
1499  __FUNCTION__, GetDarwinLogTypeName().AsCString(),
1500  process_sp->GetUniqueID());
1501  return false;
1502  }
1503 
1504  // Create the callback for when the thread plan completes.
1505  bool called_enable_method = false;
1506  const auto process_uid = process_sp->GetUniqueID();
1507 
1508  std::weak_ptr<StructuredDataPlugin> plugin_wp(plugin_sp);
1510  [plugin_wp, &called_enable_method, log, process_uid]() {
1511  LLDB_LOGF(log,
1512  "StructuredDataDarwinLog::post-init callback: "
1513  "called (process uid %u)",
1514  process_uid);
1515 
1516  auto strong_plugin_sp = plugin_wp.lock();
1517  if (!strong_plugin_sp) {
1518  LLDB_LOGF(log,
1519  "StructuredDataDarwinLog::post-init callback: "
1520  "plugin no longer exists, ignoring (process "
1521  "uid %u)",
1522  process_uid);
1523  return;
1524  }
1525  // Make sure we only call it once, just in case the thread plan hits
1526  // the breakpoint twice.
1527  if (!called_enable_method) {
1528  LLDB_LOGF(log,
1529  "StructuredDataDarwinLog::post-init callback: "
1530  "calling EnableNow() (process uid %u)",
1531  process_uid);
1532  static_cast<StructuredDataDarwinLog *>(strong_plugin_sp.get())
1533  ->EnableNow();
1534  called_enable_method = true;
1535  } else {
1536  // Our breakpoint was hit more than once. Unexpected but no harm
1537  // done. Log it.
1538  LLDB_LOGF(log,
1539  "StructuredDataDarwinLog::post-init callback: "
1540  "skipping EnableNow(), already called by "
1541  "callback [we hit this more than once] "
1542  "(process uid %u)",
1543  process_uid);
1544  }
1545  };
1546 
1547  // Grab the current thread.
1548  auto thread_sp = context->exe_ctx_ref.GetThreadSP();
1549  if (!thread_sp) {
1550  LLDB_LOGF(log,
1551  "StructuredDataDarwinLog::%s() warning: failed to "
1552  "retrieve the current thread from the execution "
1553  "context, nowhere to run the thread plan (process uid "
1554  "%u)",
1555  __FUNCTION__, process_sp->GetUniqueID());
1556  return false;
1557  }
1558 
1559  // Queue the thread plan.
1560  auto thread_plan_sp =
1561  ThreadPlanSP(new ThreadPlanCallOnFunctionExit(*thread_sp, callback));
1562  const bool abort_other_plans = false;
1563  thread_sp->QueueThreadPlan(thread_plan_sp, abort_other_plans);
1564  LLDB_LOGF(log,
1565  "StructuredDataDarwinLog::%s() queuing thread plan on "
1566  "trace library init method entry (process uid %u)",
1567  __FUNCTION__, process_sp->GetUniqueID());
1568 
1569  // We return false here to indicate that it isn't a public stop.
1570  return false;
1571 }
1572 
1574  Log *log = GetLog(LLDBLog::Process);
1575  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called (process uid %u)",
1576  __FUNCTION__, process.GetUniqueID());
1577 
1578  // Make sure we haven't already done this.
1579  {
1580  std::lock_guard<std::mutex> locker(m_added_breakpoint_mutex);
1581  if (m_added_breakpoint) {
1582  LLDB_LOGF(log,
1583  "StructuredDataDarwinLog::%s() ignoring request, "
1584  "breakpoint already set (process uid %u)",
1585  __FUNCTION__, process.GetUniqueID());
1586  return;
1587  }
1588 
1589  // We're about to do this, don't let anybody else try to do it.
1590  m_added_breakpoint = true;
1591  }
1592 
1593  // Set a breakpoint for the process that will kick in when libtrace has
1594  // finished its initialization.
1595  Target &target = process.GetTarget();
1596 
1597  // Build up the module list.
1598  FileSpecList module_spec_list;
1599  auto module_file_spec =
1600  FileSpec(GetGlobalProperties().GetLoggingModuleName());
1601  module_spec_list.Append(module_file_spec);
1602 
1603  // We aren't specifying a source file set.
1604  FileSpecList *source_spec_list = nullptr;
1605 
1606  const char *func_name = "_libtrace_init";
1607  const lldb::addr_t offset = 0;
1608  const LazyBool skip_prologue = eLazyBoolCalculate;
1609  // This is an internal breakpoint - the user shouldn't see it.
1610  const bool internal = true;
1611  const bool hardware = false;
1612 
1613  auto breakpoint_sp = target.CreateBreakpoint(
1614  &module_spec_list, source_spec_list, func_name, eFunctionNameTypeFull,
1615  eLanguageTypeC, offset, skip_prologue, internal, hardware);
1616  if (!breakpoint_sp) {
1617  // Huh? Bail here.
1618  LLDB_LOGF(log,
1619  "StructuredDataDarwinLog::%s() failed to set "
1620  "breakpoint in module %s, function %s (process uid %u)",
1621  __FUNCTION__, GetGlobalProperties().GetLoggingModuleName(),
1622  func_name, process.GetUniqueID());
1623  return;
1624  }
1625 
1626  // Set our callback.
1627  breakpoint_sp->SetCallback(InitCompletionHookCallback, nullptr);
1628  m_breakpoint_id = breakpoint_sp->GetID();
1629  LLDB_LOGF(log,
1630  "StructuredDataDarwinLog::%s() breakpoint set in module %s,"
1631  "function %s (process uid %u)",
1632  __FUNCTION__, GetGlobalProperties().GetLoggingModuleName(),
1633  func_name, process.GetUniqueID());
1634 }
1635 
1637  uint64_t timestamp) {
1638  const uint64_t delta_nanos = timestamp - m_first_timestamp_seen;
1639 
1640  const uint64_t hours = delta_nanos / NANOS_PER_HOUR;
1641  uint64_t nanos_remaining = delta_nanos % NANOS_PER_HOUR;
1642 
1643  const uint64_t minutes = nanos_remaining / NANOS_PER_MINUTE;
1644  nanos_remaining = nanos_remaining % NANOS_PER_MINUTE;
1645 
1646  const uint64_t seconds = nanos_remaining / NANOS_PER_SECOND;
1647  nanos_remaining = nanos_remaining % NANOS_PER_SECOND;
1648 
1649  stream.Printf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 ".%09" PRIu64, hours,
1650  minutes, seconds, nanos_remaining);
1651 }
1652 
1653 size_t
1655  const StructuredData::Dictionary &event) {
1656  StreamString stream;
1657 
1658  ProcessSP process_sp = GetProcess();
1659  if (!process_sp) {
1660  // TODO log
1661  return 0;
1662  }
1663 
1664  DebuggerSP debugger_sp =
1665  process_sp->GetTarget().GetDebugger().shared_from_this();
1666  if (!debugger_sp) {
1667  // TODO log
1668  return 0;
1669  }
1670 
1671  auto options_sp = GetGlobalEnableOptions(debugger_sp);
1672  if (!options_sp) {
1673  // TODO log
1674  return 0;
1675  }
1676 
1677  // Check if we should even display a header.
1678  if (!options_sp->GetDisplayAnyHeaderFields())
1679  return 0;
1680 
1681  stream.PutChar('[');
1682 
1683  int header_count = 0;
1684  if (options_sp->GetDisplayTimestampRelative()) {
1685  uint64_t timestamp = 0;
1686  if (event.GetValueForKeyAsInteger("timestamp", timestamp)) {
1687  DumpTimestamp(stream, timestamp);
1688  ++header_count;
1689  }
1690  }
1691 
1692  if (options_sp->GetDisplayActivityChain()) {
1693  llvm::StringRef activity_chain;
1694  if (event.GetValueForKeyAsString("activity-chain", activity_chain) &&
1695  !activity_chain.empty()) {
1696  if (header_count > 0)
1697  stream.PutChar(',');
1698 
1699  // Display the activity chain, from parent-most to child-most activity,
1700  // separated by a colon (:).
1701  stream.PutCString("activity-chain=");
1702  stream.PutCString(activity_chain);
1703  ++header_count;
1704  }
1705  }
1706 
1707  if (options_sp->GetDisplaySubsystem()) {
1708  llvm::StringRef subsystem;
1709  if (event.GetValueForKeyAsString("subsystem", subsystem) &&
1710  !subsystem.empty()) {
1711  if (header_count > 0)
1712  stream.PutChar(',');
1713  stream.PutCString("subsystem=");
1714  stream.PutCString(subsystem);
1715  ++header_count;
1716  }
1717  }
1718 
1719  if (options_sp->GetDisplayCategory()) {
1720  llvm::StringRef category;
1721  if (event.GetValueForKeyAsString("category", category) &&
1722  !category.empty()) {
1723  if (header_count > 0)
1724  stream.PutChar(',');
1725  stream.PutCString("category=");
1726  stream.PutCString(category);
1727  ++header_count;
1728  }
1729  }
1730  stream.PutCString("] ");
1731 
1732  output_stream.PutCString(stream.GetString());
1733 
1734  return stream.GetSize();
1735 }
1736 
1738  const StructuredData::Dictionary &event, Stream &stream) {
1739  // Check the type of the event.
1740  ConstString event_type;
1741  if (!event.GetValueForKeyAsString("type", event_type)) {
1742  // Hmm, we expected to get events that describe what they are. Continue
1743  // anyway.
1744  return 0;
1745  }
1746 
1747  if (event_type != GetLogEventType())
1748  return 0;
1749 
1750  size_t total_bytes = 0;
1751 
1752  // Grab the message content.
1753  llvm::StringRef message;
1754  if (!event.GetValueForKeyAsString("message", message))
1755  return true;
1756 
1757  // Display the log entry.
1758  const auto len = message.size();
1759 
1760  total_bytes += DumpHeader(stream, event);
1761 
1762  stream.Write(message.data(), len);
1763  total_bytes += len;
1764 
1765  // Add an end of line.
1766  stream.PutChar('\n');
1767  total_bytes += sizeof(char);
1768 
1769  return total_bytes;
1770 }
1771 
1773  Log *log = GetLog(LLDBLog::Process);
1774  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() called", __FUNCTION__);
1775 
1776  // Run the enable command.
1777  auto process_sp = GetProcess();
1778  if (!process_sp) {
1779  // Nothing to do.
1780  LLDB_LOGF(log,
1781  "StructuredDataDarwinLog::%s() warning: failed to get "
1782  "valid process, skipping",
1783  __FUNCTION__);
1784  return;
1785  }
1786  LLDB_LOGF(log, "StructuredDataDarwinLog::%s() call is for process uid %u",
1787  __FUNCTION__, process_sp->GetUniqueID());
1788 
1789  // If we have configuration data, we can directly enable it now. Otherwise,
1790  // we need to run through the command interpreter to parse the auto-run
1791  // options (which is the only way we get here without having already-parsed
1792  // configuration data).
1793  DebuggerSP debugger_sp =
1794  process_sp->GetTarget().GetDebugger().shared_from_this();
1795  if (!debugger_sp) {
1796  LLDB_LOGF(log,
1797  "StructuredDataDarwinLog::%s() warning: failed to get "
1798  "debugger shared pointer, skipping (process uid %u)",
1799  __FUNCTION__, process_sp->GetUniqueID());
1800  return;
1801  }
1802 
1803  auto options_sp = GetGlobalEnableOptions(debugger_sp);
1804  if (!options_sp) {
1805  // We haven't run the enable command yet. Just do that now, it'll take
1806  // care of the rest.
1807  auto &interpreter = debugger_sp->GetCommandInterpreter();
1808  const bool success = RunEnableCommand(interpreter);
1809  if (log) {
1810  if (success)
1811  LLDB_LOGF(log,
1812  "StructuredDataDarwinLog::%s() ran enable command "
1813  "successfully for (process uid %u)",
1814  __FUNCTION__, process_sp->GetUniqueID());
1815  else
1816  LLDB_LOGF(log,
1817  "StructuredDataDarwinLog::%s() error: running "
1818  "enable command failed (process uid %u)",
1819  __FUNCTION__, process_sp->GetUniqueID());
1820  }
1821  Debugger::ReportError("failed to configure DarwinLog support",
1822  debugger_sp->GetID());
1823  return;
1824  }
1825 
1826  // We've previously been enabled. We will re-enable now with the previously
1827  // specified options.
1828  auto config_sp = options_sp->BuildConfigurationData(true);
1829  if (!config_sp) {
1830  LLDB_LOGF(log,
1831  "StructuredDataDarwinLog::%s() warning: failed to "
1832  "build configuration data for enable options, skipping "
1833  "(process uid %u)",
1834  __FUNCTION__, process_sp->GetUniqueID());
1835  return;
1836  }
1837 
1838  // We can run it directly.
1839  // Send configuration to the feature by way of the process.
1840  const Status error =
1841  process_sp->ConfigureStructuredData(GetDarwinLogTypeName(), config_sp);
1842 
1843  // Report results.
1844  if (!error.Success()) {
1845  LLDB_LOGF(log,
1846  "StructuredDataDarwinLog::%s() "
1847  "ConfigureStructuredData() call failed "
1848  "(process uid %u): %s",
1849  __FUNCTION__, process_sp->GetUniqueID(), error.AsCString());
1850  Debugger::ReportError("failed to configure DarwinLog support",
1851  debugger_sp->GetID());
1852  m_is_enabled = false;
1853  } else {
1854  m_is_enabled = true;
1855  LLDB_LOGF(log,
1856  "StructuredDataDarwinLog::%s() success via direct "
1857  "configuration (process uid %u)",
1858  __FUNCTION__, process_sp->GetUniqueID());
1859  }
1860 }
lldb_private::toString
const char * toString(AppleArm64ExceptionClass EC)
Definition: AppleArm64ExceptionClass.h:38
sddarwinlog_private::EnableOptions::GetIncludeDebugLevel
bool GetIncludeDebugLevel() const
Definition: StructuredDataDarwinLog.cpp:603
RegularExpression.h
sddarwinlog_private::StructuredDataDarwinLogProperties
Definition: StructuredDataDarwinLog.cpp:118
lldb_private::CommandObjectParsed
Definition: CommandObject.h:389
lldb_private::StructuredDataDarwinLog::CreateInstance
static lldb::StructuredDataPluginSP CreateInstance(Process &process)
Definition: StructuredDataDarwinLog.cpp:1330
sddarwinlog_private::StructuredDataDarwinLogProperties::GetEnableOnStartup
bool GetEnableOnStartup() const
Definition: StructuredDataDarwinLog.cpp:132
sddarwinlog_private::GetDarwinLogTypeName
static ConstString GetDarwinLogTypeName()
Definition: StructuredDataDarwinLog.cpp:165
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
StructuredDataDarwinLog.h
lldb_private::StructuredDataDarwinLog::HandleDisplayOfEvent
size_t HandleDisplayOfEvent(const StructuredData::Dictionary &event, Stream &stream)
Definition: StructuredDataDarwinLog.cpp:1737
sddarwinlog_private::ParseAutoEnableOptions
EnableOptionsSP ParseAutoEnableOptions(Status &error, Debugger &debugger)
Definition: StructuredDataDarwinLog.cpp:961
lldb_private::StructuredData::Dictionary
Definition: StructuredData.h:352
sddarwinlog_private::NANOS_PER_MICRO
const uint64_t NANOS_PER_MICRO
Definition: StructuredDataDarwinLog.cpp:48
sddarwinlog_private::ExactMatchFilterRule::ExactMatchFilterRule
ExactMatchFilterRule(bool accept, size_t attribute_index, const std::string &match_text)
Definition: StructuredDataDarwinLog.cpp:349
sddarwinlog_private::EnableOptions::GetIncludeInfoLevel
bool GetIncludeInfoLevel() const
Definition: StructuredDataDarwinLog.cpp:605
lldb_private::RegularExpression
Definition: RegularExpression.h:18
SetErrorWithJSON
static void SetErrorWithJSON(Status &error, const char *message, StructuredData::Object &object)
Definition: StructuredDataDarwinLog.cpp:1111
lldb_private::StoppointCallbackContext
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
Definition: StoppointCallbackContext.h:26
sddarwinlog_private::FilterRule::FilterRule
FilterRule(bool accept, size_t attribute_index, ConstString operation)
Definition: StructuredDataDarwinLog.cpp:233
lldb_private::ThreadPlanCallOnFunctionExit
This thread plan calls a function object when the current function exits.
Definition: ThreadPlanCallOnFunctionExit.h:22
lldb_private::StructuredDataDarwinLog::m_added_breakpoint
bool m_added_breakpoint
Definition: StructuredDataDarwinLog.h:111
sddarwinlog_private::FilterRule::RegisterOperation
static void RegisterOperation(ConstString operation, const OperationCreationFunc &creation_func)
Definition: StructuredDataDarwinLog.cpp:186
lldb_private::Flags::AnySet
bool AnySet(ValueType mask) const
Test one or more flags.
Definition: Flags.h:90
lldb_private::StructuredDataDarwinLog::m_added_breakpoint_mutex
std::mutex m_added_breakpoint_mutex
Definition: StructuredDataDarwinLog.h:110
lldb_private::StructuredData::Array
Definition: StructuredData.h:165
lldb_private::CommandInterpreter::GetCommandObjectForCommand
CommandObject * GetCommandObjectForCommand(llvm::StringRef &command_line)
sddarwinlog_private::FilterRule::OperationCreationFunc
std::function< FilterRuleSP(bool accept, size_t attribute_index, const std::string &op_arg, Status &error)> OperationCreationFunc
Definition: StructuredDataDarwinLog.cpp:184
sddarwinlog_private::NANOS_PER_HOUR
const uint64_t NANOS_PER_HOUR
Definition: StructuredDataDarwinLog.cpp:52
lldb_private::Debugger::GetCommandInterpreter
CommandInterpreter & GetCommandInterpreter()
Definition: Debugger.h:173
sddarwinlog_private::StructuredDataDarwinLogProperties::GetSettingName
static ConstString & GetSettingName()
Definition: StructuredDataDarwinLog.cpp:120
lldb_private::CommandInterpreter::HandleCommand
bool HandleCommand(const char *command_line, LazyBool add_to_history, const ExecutionContext &override_context, CommandReturnObject &result)
sddarwinlog_private::EnableOptions::ParseFilterRule
Status ParseFilterRule(llvm::StringRef rule_text)
Definition: StructuredDataDarwinLog.cpp:632
sddarwinlog_private::EnableOptions::GetDisplayActivityChain
bool GetDisplayActivityChain() const
Definition: StructuredDataDarwinLog.cpp:622
sddarwinlog_private::ExactMatchFilterRule::CreateOperation
static FilterRuleSP CreateOperation(bool accept, size_t attribute_index, const std::string &op_arg, Status &error)
Definition: StructuredDataDarwinLog.cpp:329
lldb_private::StructuredDataDarwinLog::FilterLaunchInfo
static Status FilterLaunchInfo(ProcessLaunchInfo &launch_info, Target *target)
Definition: StructuredDataDarwinLog.cpp:1374
sddarwinlog_private::FilterRule::m_operation
const ConstString m_operation
Definition: StructuredDataDarwinLog.cpp:255
lldb_private::ExecutionContextRef::GetThreadSP
lldb::ThreadSP GetThreadSP() const
Get accessor that creates a strong reference from the weak thread reference contained in this object.
Definition: ExecutionContext.cpp:574
sddarwinlog_private::NANOS_PER_MINUTE
const uint64_t NANOS_PER_MINUTE
Definition: StructuredDataDarwinLog.cpp:51
lldb_private::Args::Shift
void Shift()
Shifts the first argument C string value of the array off the argument array.
Definition: Args.cpp:281
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:343
lldb_private::StructuredDataPlugin::InitializeBasePluginForDebugger
static void InitializeBasePluginForDebugger(Debugger &debugger)
Derived classes must call this before attempting to hook up commands to the 'plugin structured-data' ...
Definition: StructuredDataPlugin.cpp:45
lldb_private::Process
Definition: Process.h:338
sddarwinlog_private::GetGlobalProperties
static StructuredDataDarwinLogProperties & GetGlobalProperties()
Definition: StructuredDataDarwinLog.cpp:147
Module.h
lldb_private::StoppointCallbackContext::exe_ctx_ref
ExecutionContextRef exe_ctx_ref
Definition: StoppointCallbackContext.h:43
lldb_private::Process::GetTarget
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1197
sddarwinlog_private::FilterRule::GetFilterAttribute
const char * GetFilterAttribute() const
Definition: StructuredDataDarwinLog.cpp:241
StoppointCallbackContext.h
sddarwinlog_private::EnableOptions::GetFilterRules
const FilterRules & GetFilterRules() const
Definition: StructuredDataDarwinLog.cpp:610
lldb_private::Stream::Flush
virtual void Flush()=0
Flush the stream.
sddarwinlog_private::ExactMatchFilterRule::RegisterOperation
static void RegisterOperation()
Definition: StructuredDataDarwinLog.cpp:314
OptionArgParser.h
lldb_private::ConstString::AsCString
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:193
sddarwinlog_private::EnableCommand::AppendStrictSourcesWarning
void AppendStrictSourcesWarning(CommandReturnObject &result, const char *source_name)
Definition: StructuredDataDarwinLog.cpp:745
lldb_private::ProcessLaunchInfo::GetFlags
Flags & GetFlags()
Definition: ProcessLaunchInfo.h:64
lldb_private::Stream
Definition: Stream.h:28
lldb_private::Args
Definition: Args.h:33
lldb_private::Target::CreateBreakpoint
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
Definition: Target.cpp:351
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:455
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::CommandReturnObject::Succeeded
bool Succeeded() const
Definition: CommandReturnObject.cpp:131
lldb_private::LazyBool
LazyBool
Definition: lldb-private-enumerations.h:115
sddarwinlog_private::EnableOptions::GetDisplaySubsystem
bool GetDisplaySubsystem() const
Definition: StructuredDataDarwinLog.cpp:620
lldb_private::Target::GetDebugger
Debugger & GetDebugger()
Definition: Target.h:1020
CommandReturnObject.h
Debugger.h
lldb_private::Target
Definition: Target.h:467
lldb_private::StructuredDataDarwinLog::m_is_enabled
bool m_is_enabled
Definition: StructuredDataDarwinLog.h:109
sddarwinlog_private::EnableCommand::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: StructuredDataDarwinLog.cpp:767
lldb_private::StreamString::GetString
llvm::StringRef GetString() const
Definition: StreamString.cpp:51
sddarwinlog_private::ExactMatchFilterRule::Dump
void Dump(Stream &stream) const override
Definition: StructuredDataDarwinLog.cpp:318
Process.h
lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
Definition: StructuredData.h:413
lldb_private::StructuredData::Dictionary::AddBooleanItem
void AddBooleanItem(llvm::StringRef key, bool value)
Definition: StructuredData.h:521
sddarwinlog_private::EnableCommand
Definition: StructuredDataDarwinLog.cpp:737
lldb::eReturnStatusSuccessFinishNoResult
@ eReturnStatusSuccessFinishNoResult
Definition: lldb-enumerations.h:260
sddarwinlog_private::RegexFilterRule::StaticGetOperation
static ConstString StaticGetOperation()
Definition: StructuredDataDarwinLog.cpp:299
sddarwinlog_private::EnableCommand::GetOptions
Options * GetOptions() override
Definition: StructuredDataDarwinLog.cpp:842
Target.h
lldb_private::Properties
Definition: UserSettingsController.h:33
lldb_private::StructuredDataDarwinLog::AddInitCompletionHook
void AddInitCompletionHook(Process &process)
Definition: StructuredDataDarwinLog.cpp:1573
lldb_private::Properties::GetPropertyValue
virtual lldb::OptionValueSP GetPropertyValue(const ExecutionContext *exe_ctx, llvm::StringRef property_path, bool will_modify, Status &error) const
Definition: UserSettingsController.cpp:34
sddarwinlog_private::EnableOptionsSP
std::shared_ptr< EnableOptions > EnableOptionsSP
Definition: StructuredDataDarwinLog.cpp:64
lldb_private::FileSpec
Definition: FileSpec.h:56
sddarwinlog_private::EnableOptions::BuildConfigurationData
StructuredData::DictionarySP BuildConfigurationData(bool enabled)
Definition: StructuredDataDarwinLog.cpp:563
lldb_private::CommandObjectMultiword
Definition: CommandObjectMultiword.h:19
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::StreamString::GetSize
size_t GetSize() const
Definition: StreamString.cpp:38
lldb_private::ModuleList::GetSize
size_t GetSize() const
Gets the size of the module list.
Definition: ModuleList.cpp:635
lldb_private::StructuredDataPlugin
Plugin that supports process-related structured data sent asynchronously from the debug monitor (e....
Definition: StructuredDataPlugin.h:40
sddarwinlog_private::RegisterFilterOperations
static void RegisterFilterOperations()
Definition: StructuredDataDarwinLog.cpp:357
lldb_private::Options
Definition: Options.h:57
sddarwinlog_private::EnableOptions::SetOptionValue
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
Definition: StructuredDataDarwinLog.cpp:491
sddarwinlog_private::StructuredDataDarwinLogProperties::GetAutoEnableOptions
llvm::StringRef GetAutoEnableOptions() const
Definition: StructuredDataDarwinLog.cpp:138
lldb_private::ProcessLaunchInfo
Definition: ProcessLaunchInfo.h:31
lldb_private::ModuleList
Definition: ModuleList.h:82
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
sddarwinlog_private::EnableOptions::GetDisplayTimestampRelative
bool GetDisplayTimestampRelative() const
Definition: StructuredDataDarwinLog.cpp:616
sddarwinlog_private::DEFAULT_FILTER_FALLTHROUGH_ACCEPTS
static bool DEFAULT_FILTER_FALLTHROUGH_ACCEPTS
Definition: StructuredDataDarwinLog.cpp:54
sddarwinlog_private::s_filter_attributes
const char *const s_filter_attributes[]
Definition: StructuredDataDarwinLog.cpp:152
sddarwinlog_private::GetGlobalOptionsMap
static OptionsMap & GetGlobalOptionsMap()
Definition: StructuredDataDarwinLog.cpp:69
Log.h
sddarwinlog_private::SetGlobalEnableOptions
void SetGlobalEnableOptions(const DebuggerSP &debugger_sp, const EnableOptionsSP &options_sp)
Definition: StructuredDataDarwinLog.cpp:93
lldb_private::StructuredDataDarwinLog::EnableNow
void EnableNow()
Call the enable command again, using whatever settings were initially made.
Definition: StructuredDataDarwinLog.cpp:1772
sddarwinlog_private::ExactMatchFilterRule::StaticGetOperation
static ConstString StaticGetOperation()
Definition: StructuredDataDarwinLog.cpp:344
sddarwinlog_private::FilterRule::Serialize
StructuredData::ObjectSP Serialize() const
Definition: StructuredDataDarwinLog.cpp:207
lldb_private::CommandReturnObject::SetStatus
void SetStatus(lldb::ReturnStatus status)
Definition: CommandReturnObject.cpp:127
sddarwinlog_private::NANOS_PER_MILLI
const uint64_t NANOS_PER_MILLI
Definition: StructuredDataDarwinLog.cpp:49
sddarwinlog_private::StructuredDataDarwinLogProperties::StructuredDataDarwinLogProperties
StructuredDataDarwinLogProperties()
Definition: StructuredDataDarwinLog.cpp:125
sddarwinlog_private::EnableCommand::m_options_sp
EnableOptionsSP m_options_sp
Definition: StructuredDataDarwinLog.cpp:849
lldb_private::StructuredData::ObjectSP
std::shared_ptr< Object > ObjectSP
Definition: StructuredData.h:59
lldb_private::StreamString::GetData
const char * GetData() const
Definition: StreamString.h:43
sddarwinlog_private::FilterRule::m_attribute_index
const size_t m_attribute_index
Definition: StructuredDataDarwinLog.cpp:254
lldb_private::LLDBLog::Process
@ Process
sddarwinlog_private::StatusCommand::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: StructuredDataDarwinLog.cpp:862
lldb_private::CommandReturnObject::GetOutputStream
Stream & GetOutputStream()
Definition: CommandReturnObject.h:46
LLDB_OPT_SET_ALL
#define LLDB_OPT_SET_ALL
Definition: lldb-defines.h:101
Property.h
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::StreamString
Definition: StreamString.h:23
sddarwinlog_private::FilterRules
std::vector< FilterRuleSP > FilterRules
Definition: StructuredDataDarwinLog.cpp:258
sddarwinlog_private::FilterRule::CreationFuncMap
std::map< ConstString, OperationCreationFunc > CreationFuncMap
Definition: StructuredDataDarwinLog.cpp:246
sddarwinlog_private::RegexFilterRule::Dump
void Dump(Stream &stream) const override
Definition: StructuredDataDarwinLog.cpp:266
sddarwinlog_private::FilterRule::GetOperationType
ConstString GetOperationType() const
Definition: StructuredDataDarwinLog.cpp:230
lldb_private::CommandInterpreter
Definition: CommandInterpreter.h:214
sddarwinlog_private::FilterRuleSP
std::shared_ptr< FilterRule > FilterRuleSP
Definition: StructuredDataDarwinLog.cpp:176
CommandObjectMultiword.h
lldb_private::StructuredData::DictionarySP
std::shared_ptr< Dictionary > DictionarySP
Definition: StructuredData.h:67
lldb_private::Debugger
Definition: Debugger.h:74
lldb_private::StructuredDataDarwinLog::InitCompletionHookCallback
static bool InitCompletionHookCallback(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
Definition: StructuredDataDarwinLog.cpp:1462
lldb_private::StructuredDataDarwinLog::DumpTimestamp
void DumpTimestamp(Stream &stream, uint64_t timestamp)
Definition: StructuredDataDarwinLog.cpp:1636
sddarwinlog_private::RegexFilterRule::m_regex_text
const std::string m_regex_text
Definition: StructuredDataDarwinLog.cpp:309
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
sddarwinlog_private::FilterRule
Definition: StructuredDataDarwinLog.cpp:178
sddarwinlog_private::RegexFilterRule
Definition: StructuredDataDarwinLog.cpp:260
OptionValueString.h
lldb_private::StructuredDataDarwinLog::m_first_timestamp_seen
uint64_t m_first_timestamp_seen
Definition: StructuredDataDarwinLog.h:108
lldb_private::Stream::PutChar
size_t PutChar(char ch)
Definition: Stream.cpp:104
sddarwinlog_private::BaseCommand
Provides the darwin-log base command.
Definition: StructuredDataDarwinLog.cpp:929
sddarwinlog_private::EnableOptions
Definition: StructuredDataDarwinLog.cpp:469
lldb_private::StructuredDataDarwinLog::StructuredDataDarwinLog
StructuredDataDarwinLog(const lldb::ProcessWP &process_wp)
Definition: StructuredDataDarwinLog.cpp:1321
sddarwinlog_private::EnableOptions::m_filter_rules
FilterRules m_filter_rules
Definition: StructuredDataDarwinLog.cpp:734
lldb_private::StructuredDataDarwinLog::m_breakpoint_id
lldb::user_id_t m_breakpoint_id
Definition: StructuredDataDarwinLog.h:112
OptionValueProperties.h
sddarwinlog_private::RegexFilterRule::RegexFilterRule
RegexFilterRule(bool accept, size_t attribute_index, const std::string &regex_text)
Definition: StructuredDataDarwinLog.cpp:304
lldb_private::StructuredDataDarwinLog::DebuggerInitialize
static void DebuggerInitialize(Debugger &debugger)
Definition: StructuredDataDarwinLog.cpp:1341
sddarwinlog_private::GetGlobalEnableOptions
EnableOptionsSP GetGlobalEnableOptions(const DebuggerSP &debugger_sp)
Definition: StructuredDataDarwinLog.cpp:79
sddarwinlog_private::GetGlobalOptionsMapLock
static std::mutex & GetGlobalOptionsMapLock()
Definition: StructuredDataDarwinLog.cpp:74
LLDB_INVALID_BREAK_ID
#define LLDB_INVALID_BREAK_ID
Definition: lldb-defines.h:37
sddarwinlog_private::EnableOptions::GetDisplayAnyHeaderFields
bool GetDisplayAnyHeaderFields() const
Definition: StructuredDataDarwinLog.cpp:624
sddarwinlog_private::EnableOptions::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *execution_context) override
Definition: StructuredDataDarwinLog.cpp:476
lldb_private::Target::GetProcessSP
const lldb::ProcessSP & GetProcessSP() const
Definition: Target.cpp:217
sddarwinlog_private::EnableOptions::GetDisplayCategory
bool GetDisplayCategory() const
Definition: StructuredDataDarwinLog.cpp:621
sddarwinlog_private::OptionsMap
std::map< DebuggerWP, EnableOptionsSP, std::owner_less< DebuggerWP > > OptionsMap
Definition: StructuredDataDarwinLog.cpp:67
lldb_private::Target::GetArchitecture
const ArchSpec & GetArchitecture() const
Definition: Target.h:984
sddarwinlog_private::EnableOptions::GetFallthroughAccepts
bool GetFallthroughAccepts() const
Definition: StructuredDataDarwinLog.cpp:612
lldb_private::Process::GetUniqueID
uint32_t GetUniqueID() const
Definition: Process.h:533
sddarwinlog_private::EnableOptions::MatchAttributeIndex
int MatchAttributeIndex(llvm::StringRef attribute_name) const
Definition: StructuredDataDarwinLog.cpp:713
lldb_private::ThreadPlanCallOnFunctionExit::Callback
std::function< void()> Callback
Definition for the callback made when the currently executing thread finishes executing its function.
Definition: ThreadPlanCallOnFunctionExit.h:26
lldb_private::Status
Definition: Status.h:44
sddarwinlog_private::RegexFilterRule::CreateOperation
static FilterRuleSP CreateOperation(bool accept, size_t attribute_index, const std::string &op_arg, Status &error)
Definition: StructuredDataDarwinLog.cpp:277
sddarwinlog_private
Definition: StructuredDataDarwinLog.cpp:47
lldb_private::Args::GetArgumentAtIndex
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition: Args.cpp:259
sddarwinlog_private::NANOS_PER_SECOND
const uint64_t NANOS_PER_SECOND
Definition: StructuredDataDarwinLog.cpp:50
sddarwinlog_private::EnableOptions::m_filter_fall_through_accepts
bool m_filter_fall_through_accepts
Definition: StructuredDataDarwinLog.cpp:726
lldb_private::CommandReturnObject
Definition: CommandReturnObject.h:26
message
message(FATAL_ERROR "invalid libipt include path provided") endif() include_directories($
Definition: Plugins/Trace/intel-pt/CMakeLists.txt:6
uint32_t
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
sddarwinlog_private::s_is_explicitly_enabled
static bool s_is_explicitly_enabled
Global, sticky enable switch.
Definition: StructuredDataDarwinLog.cpp:61
lldb_private::CommandInterpreter::GetDebugger
Debugger & GetDebugger()
Definition: CommandInterpreter.h:437
sddarwinlog_private::StatusCommand::StatusCommand
StatusCommand(CommandInterpreter &interpreter)
Definition: StructuredDataDarwinLog.cpp:855
lldb::eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishResult
Definition: lldb-enumerations.h:261
sddarwinlog_private::g_enable_option_table
static constexpr OptionDefinition g_enable_option_table[]
Provides the main on-off switch for enabling darwin logging.
Definition: StructuredDataDarwinLog.cpp:371
lldb_private::ProcessInfo::GetEnvironment
Environment & GetEnvironment()
Definition: ProcessInfo.h:87
sddarwinlog_private::StructuredDataDarwinLogProperties::GetLoggingModuleName
const char * GetLoggingModuleName() const
Definition: StructuredDataDarwinLog.cpp:144
lldb::eArgTypeNone
@ eArgTypeNone
Definition: lldb-enumerations.h:595
lldb_private::CommandReturnObject::AppendWarning
void void AppendWarning(llvm::StringRef in_string)
Definition: CommandReturnObject.cpp:94
lldb_private::StructuredData::Object::GetAsDictionary
Dictionary * GetAsDictionary()
Definition: StructuredData.h:91
ThreadPlanCallOnFunctionExit.h
sddarwinlog_private::BaseCommand::BaseCommand
BaseCommand(CommandInterpreter &interpreter)
Definition: StructuredDataDarwinLog.cpp:931
lldb_private::StructuredDataDarwinLog
Definition: StructuredDataDarwinLog.h:23
lldb::eArgTypeBoolean
@ eArgTypeBoolean
Definition: lldb-enumerations.h:521
sddarwinlog_private::EnableCommand::m_enable
const bool m_enable
Definition: StructuredDataDarwinLog.cpp:848
PluginManager.h
lldb_private::ConstString::GetCString
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
lldb_private::StructuredData::Dictionary::AddStringItem
void AddStringItem(llvm::StringRef key, llvm::StringRef value)
Definition: StructuredData.h:517
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
sddarwinlog_private::ExactMatchFilterRule::m_match_text
const std::string m_match_text
Definition: StructuredDataDarwinLog.cpp:354
lldb_private::PluginManager::CreateSettingForStructuredDataPlugin
static bool CreateSettingForStructuredDataPlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, bool is_global_property)
Definition: PluginManager.cpp:1638
lldb_private::Debugger::GetUseColor
bool GetUseColor() const
Definition: Debugger.cpp:371
sddarwinlog_private::ExactMatchFilterRule::DoSerialization
void DoSerialization(StructuredData::Dictionary &dict) const override
Definition: StructuredDataDarwinLog.cpp:324
lldb_private::StructuredDataPlugin::GetProcess
lldb::ProcessSP GetProcess() const
Definition: StructuredDataPlugin.cpp:41
lldb::user_id_t
uint64_t user_id_t
Definition: lldb-types.h:84
OptionParser.h
sddarwinlog_private::EnableOptions::EnableOptions
EnableOptions()
Definition: StructuredDataDarwinLog.cpp:471
lldb::eLanguageTypeC
@ eLanguageTypeC
Non-standardized C, such as K&R.
Definition: lldb-enumerations.h:439
sddarwinlog_private::FilterRule::GetCreationFuncMap
static CreationFuncMap & GetCreationFuncMap()
Definition: StructuredDataDarwinLog.cpp:248
lldb_private::ProcessInfo::GetArchitecture
ArchSpec & GetArchitecture()
Definition: ProcessInfo.h:61
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::eLazyBoolCalculate
@ eLazyBoolCalculate
Definition: lldb-private-enumerations.h:115
sddarwinlog_private::RegexFilterRule::DoSerialization
void DoSerialization(StructuredData::Dictionary &dict) const override
Definition: StructuredDataDarwinLog.cpp:272
sddarwinlog_private::EnableOptions::GetDefinitions
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Definition: StructuredDataDarwinLog.cpp:559
sddarwinlog_private::FilterRule::CreateRule
static FilterRuleSP CreateRule(bool match_accepts, size_t attribute, ConstString operation, const std::string &op_arg, Status &error)
Definition: StructuredDataDarwinLog.cpp:191
lldb_private::OptionDefinition
Definition: OptionDefinition.h:20
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:30
lldb_private::ModuleList::GetModuleAtIndex
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
Definition: ModuleList.cpp:411
sddarwinlog_private::RunEnableCommand
bool RunEnableCommand(CommandInterpreter &interpreter)
Definition: StructuredDataDarwinLog.cpp:1018
lldb_private::Stream::Write
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
Definition: Stream.h:101
CommandInterpreter.h
lldb_private::StreamString::Flush
void Flush() override
Flush the stream.
Definition: StreamString.cpp:22
lldb_private::StructuredDataDarwinLog::SetEnabled
void SetEnabled(bool enabled)
Definition: StructuredDataDarwinLog.cpp:1209
lldb_private::Debugger::ReportError
static void ReportError(std::string messsage, llvm::Optional< lldb::user_id_t > debugger_id=llvm::None, std::once_flag *once=nullptr)
Report error events.
Definition: Debugger.cpp:1409
sddarwinlog_private::EnableOptions::GetBroadcastEvents
bool GetBroadcastEvents() const
Definition: StructuredDataDarwinLog.cpp:629
LLDB_PLUGIN_DEFINE
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
lldb_private::Log
Definition: Log.h:115
lldb_private::StructuredData::ArraySP
std::shared_ptr< Array > ArraySP
Definition: StructuredData.h:62
lldb_private::Stream::PutCString
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
lldb_private::StructuredData::Dictionary::GetValueForKeyAsString
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
Definition: StructuredData.h:433
lldb_private::StructuredData::Dictionary::GetValueForKeyAsArray
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
Definition: StructuredData.h:488
sddarwinlog_private::EnableCommand::EnableCommand
EnableCommand(CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax)
Definition: StructuredDataDarwinLog.cpp:739
sddarwinlog_private::EnableOptions::GetEchoToStdErr
bool GetEchoToStdErr() const
Definition: StructuredDataDarwinLog.cpp:614
lldb_private::ExecutionContextRef::GetProcessSP
lldb::ProcessSP GetProcessSP() const
Get accessor that creates a strong reference from the weak process reference contained in this object...
Definition: ExecutionContext.cpp:567
lldb::eArgRawInput
@ eArgRawInput
Definition: lldb-enumerations.h:600
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:308
sddarwinlog_private::RegexFilterRule::RegisterOperation
static void RegisterOperation()
Definition: StructuredDataDarwinLog.cpp:262
lldb_private::CommandReturnObject::AppendError
void void AppendError(llvm::StringRef in_string)
Definition: CommandReturnObject.cpp:100
sddarwinlog_private::StatusCommand
Provides the status command.
Definition: StructuredDataDarwinLog.cpp:853
sddarwinlog_private::FilterRule::GetMatchAccepts
bool GetMatchAccepts() const
Definition: StructuredDataDarwinLog.cpp:239
lldb_private::Args::GetArgumentCount
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.h:118
sddarwinlog_private::FilterRule::m_accept
const bool m_accept
Definition: StructuredDataDarwinLog.cpp:253
lldb_private::StructuredDataDarwinLog::DumpHeader
size_t DumpHeader(Stream &stream, const StructuredData::Dictionary &event)
Definition: StructuredDataDarwinLog.cpp:1654
sddarwinlog_private::ExactMatchFilterRule
Definition: StructuredDataDarwinLog.cpp:312
lldb_private::StructuredData::Object
Definition: StructuredData.h:70
lldb
Definition: SBAddress.h:15
LLDB_LOG_ERROR
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:359
lldb_private::Process::BroadcastStructuredData
void BroadcastStructuredData(const StructuredData::ObjectSP &object_sp, const lldb::StructuredDataPluginSP &plugin_sp)
Broadcasts the given structured data object from the given plugin.
Definition: Process.cpp:4239
LLDBLog.h
lldb_private::StructuredData::Array::ForEach
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
Definition: StructuredData.h:172
lldb_private::PluginManager::GetSettingForPlatformPlugin
static lldb::OptionValuePropertiesSP GetSettingForPlatformPlugin(Debugger &debugger, ConstString setting_name)
Definition: PluginManager.cpp:1518
sddarwinlog_private::GetLogEventType
static ConstString GetLogEventType()
Definition: StructuredDataDarwinLog.cpp:170