[Lldb-commits] [PATCH] D153489: [lldb] Print hint if object description is requested but not implemented

2023-07-06 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added inline comments.



Comment at: lldb/include/lldb/Target/Target.h:496
 
+  std::once_flag target_once_flag;
   // These two functions fill out the Broadcaster interface:

kastiglione wrote:
> did you mean to use this, or should it be deleted?
Leftover from a different implementation, I'll delete it.



Comment at: lldb/source/Commands/CommandObjectDWIMPrint.cpp:129-130
+  static llvm::SmallPtrSet targets_warned;
+  if (targets_warned.contains(target_ptr))
+return;
+

kastiglione wrote:
> question: would people want to be warned once per target, or once per type?
> 
> If I do like the warning, I might want to know every time I `po` a type that 
> doesn't support it.
In my opinion once per target should be enough, if we do it for every type that 
could potentially be too noisy, and hopefully after seeing the hint a few times 
users will start remembering to try `p` too.



Comment at: lldb/source/Commands/CommandObjectDWIMPrint.cpp:158-162
+StreamString temp_result_stream;
+valobj_sp->Dump(temp_result_stream, dump_options);
+llvm::StringRef output = temp_result_stream.GetString();
+maybe_add_hint(output);
+result.GetOutputStream() << output;

kastiglione wrote:
> what do you think of passing in the `result`'s stream into `maybe_add_hint`? 
> Perhaps I am overlooking something, but I wonder if it would simplify the 
> code to reuse the one stream, instead of separating and then combining two 
> streams.
I need the two streams to print it in the correct order (hint first, result 
later)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153489/new/

https://reviews.llvm.org/D153489

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D153489: [lldb] Print hint if object description is requested but not implemented

2023-07-27 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 marked an inline comment as done.
augusto2112 added inline comments.



Comment at: lldb/source/Commands/CommandObjectDWIMPrint.cpp:133-135
+  << "note: object description requested, but type doesn't implement "
+ "a custom object description. Consider using \"p\" instead of "
+ "\"po\"\n";

kastiglione wrote:
> ok, I have a new suggestion. Since lldb will warn only once per target, and 
> not per type, I think this note should be reworded to focus the guidance on 
> the format of the output, not the type.
> 
> My concern is lldb emits basically "this type doesn't need a `po`", but then 
> the diagnostic is printed for only one type, and never tells you about other 
> types. How will people know that other types should use `p` not `po`?
> 
> If the message were on the format, and not the type, then I think it makes 
> more sense as a once per target message.
> 
> A possible rewording:
> > note: this `po` used the default object description, which shows none of 
> > the objects properties. When you output like this, consider using `p` 
> > instead of `po` when you see such output.
Personally I find the new message a bit more confusing for users to understand. 
Maybe: 

```
note: object description requested, but type doesn't implement a custom object 
description. Consider using "p" instead of  "po" (this warning will only be 
displayed once per debug session).
```

What do you think?



Comment at: lldb/source/Commands/CommandObjectDWIMPrint.cpp:158-162
+StreamString temp_result_stream;
+valobj_sp->Dump(temp_result_stream, dump_options);
+llvm::StringRef output = temp_result_stream.GetString();
+maybe_add_hint(output);
+result.GetOutputStream() << output;

kastiglione wrote:
> augusto2112 wrote:
> > kastiglione wrote:
> > > what do you think of passing in the `result`'s stream into 
> > > `maybe_add_hint`? Perhaps I am overlooking something, but I wonder if it 
> > > would simplify the code to reuse the one stream, instead of separating 
> > > and then combining two streams.
> > I need the two streams to print it in the correct order (hint first, result 
> > later)
> do we have a precedent for before vs after? Maybe I need to see some 
> examples, but I think it should be after. My logic is "here's the output you 
> requested, and then here's a note about it". Also the note would be next to 
> the next prompt, so maybe closer to the eyes? Just figured it was worth 
> hashing out.
DWIM print will add the note beforehand, I don't have strong feelings about 
this either way though. We'd probably still need 2 streams though, since we 
only want to match what's added by the value object's `Dump`, and nothing that 
may already be on the stream.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153489/new/

https://reviews.llvm.org/D153489

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D153489: [lldb] Print hint if object description is requested but not implemented

2023-08-01 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 546275.
augusto2112 added a comment.

Addressed comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153489/new/

https://reviews.llvm.org/D153489

Files:
  lldb/include/lldb/Core/Debugger.h
  lldb/source/Commands/CommandObjectDWIMPrint.cpp
  lldb/source/Core/CoreProperties.td
  lldb/source/Core/Debugger.cpp
  lldb/test/API/lang/objc/objc-po-hint/Makefile
  lldb/test/API/lang/objc/objc-po-hint/TestObjcPoHint.py
  lldb/test/API/lang/objc/objc-po-hint/main.m

Index: lldb/test/API/lang/objc/objc-po-hint/main.m
===
--- /dev/null
+++ lldb/test/API/lang/objc/objc-po-hint/main.m
@@ -0,0 +1,22 @@
+#import 
+
+@interface Foo : NSObject {}
+
+-(id) init;
+
+@end
+
+@implementation Foo
+
+-(id) init
+{
+return self = [super init];
+}
+@end
+
+int main()
+{
+Foo *foo = [Foo new];
+NSLog(@"a"); // Set breakpoint here.
+return 0;
+}
Index: lldb/test/API/lang/objc/objc-po-hint/TestObjcPoHint.py
===
--- /dev/null
+++ lldb/test/API/lang/objc/objc-po-hint/TestObjcPoHint.py
@@ -0,0 +1,49 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestObjcPoHint(TestBase):
+NO_DEBUG_INFO_TESTCASE = True
+
+def test_show_po_hint(self):
+### Test that the po hint is shown once with the DWIM print command
+self.build()
+_, _, _, _ = lldbutil.run_to_source_breakpoint(
+self, "Set breakpoint here", lldb.SBFileSpec("main.m")
+)
+# Make sure the hint is printed the first time
+self.expect(
+"dwim-print -O -- foo",
+substrs=[
+"note: object description requested, but type doesn't implement "
+'a custom object description. Consider using "p" instead of "po"',
+"(
+  idx, g_debugger_properties[idx].default_uint_value != 0);
+}
+
 bool Debugger::GetUseSourceCache() const {
   const uint32_t idx = ePropertyUseSourceCache;
   return GetPropertyAtIndexAs(
Index: lldb/source/Core/CoreProperties.td
===
--- lldb/source/Core/CoreProperties.td
+++ lldb/source/Core/CoreProperties.td
@@ -195,6 +195,10 @@
 Global,
 DefaultStringValue<"${ansi.normal}">,
 Desc<"When displaying suggestion in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the suggestion.">;
+  def ShowDontUsePoHint: Property<"show-dont-use-po-hint", "Boolean">,
+Global,
+DefaultTrue,
+Desc<"If true, and object description was requested for a type that does not implement it, LLDB will print a hint telling the user to consider using p instead.">;
   def DWIMPrintVerbosity: Property<"dwim-print-verbosity", "Enum">,
 Global,
 DefaultEnumValue<"eDWIMPrintVerbosityNone">,
Index: lldb/source/Commands/CommandObjectDWIMPrint.cpp
===
--- lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -25,6 +25,8 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FormatVariadic.h"
 
+#include 
+
 using namespace llvm;
 using namespace lldb;
 using namespace lldb_private;
@@ -95,8 +97,46 @@
   m_expr_options.m_verbosity, m_format_options.GetFormat());
   dump_options.SetHideRootName(suppress_result);
 
+  bool is_po = m_varobj_options.use_objc;
+
   StackFrame *frame = m_exe_ctx.GetFramePtr();
 
+  // Either Swift was explicitly specified, or the frame is Swift.
+  lldb::LanguageType language = m_expr_options.language;
+  if (language == lldb::eLanguageTypeUnknown && frame)
+language = frame->GuessLanguage();
+
+  // Add a hint if object description was requested, but no description
+  // function was implemented.
+  auto maybe_add_hint = [&](llvm::StringRef output) {
+// Identify the default output of object description for Swift and
+// Objective-C
+// ". The regex is:
+// - Start with "<".
+// - Followed by 1 or more non-whitespace characters.
+// - Followed by ": 0x".
+// - Followed by 5 or more hex digits.
+// - Followed by ">".
+// - End with zero or more whitespace characters.
+const std::regex swift_class_regex("^<\\S+: 0x[[:xdigit:]]{5,}>\\s*$");
+
+if (GetDebugger().GetShowDontUsePoHint() && target_ptr &&
+(language == lldb::eLanguageTypeSwift ||
+ language == lldb::eLanguageTypeObjC) &&
+std::regex_match(output.data(), swift_class_regex)) {
+
+  static bool note_shown = false;
+  if (note_shown)
+return;
+
+  result.GetOutputStream()
+  << "note: object description requested, but type doesn't implement "
+ "a custom object description. Consider using \"p\" instead

[Lldb-commits] [PATCH] D153489: [lldb] Print hint if object description is requested but not implemented

2023-08-02 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5f45a87bf029: [lldb] Print hint if object description is 
requested but not implemented (authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153489/new/

https://reviews.llvm.org/D153489

Files:
  lldb/include/lldb/Core/Debugger.h
  lldb/source/Commands/CommandObjectDWIMPrint.cpp
  lldb/source/Core/CoreProperties.td
  lldb/source/Core/Debugger.cpp
  lldb/test/API/lang/objc/objc-po-hint/Makefile
  lldb/test/API/lang/objc/objc-po-hint/TestObjcPoHint.py
  lldb/test/API/lang/objc/objc-po-hint/main.m

Index: lldb/test/API/lang/objc/objc-po-hint/main.m
===
--- /dev/null
+++ lldb/test/API/lang/objc/objc-po-hint/main.m
@@ -0,0 +1,22 @@
+#import 
+
+@interface Foo : NSObject {}
+
+-(id) init;
+
+@end
+
+@implementation Foo
+
+-(id) init
+{
+return self = [super init];
+}
+@end
+
+int main()
+{
+Foo *foo = [Foo new];
+NSLog(@"a"); // Set breakpoint here.
+return 0;
+}
Index: lldb/test/API/lang/objc/objc-po-hint/TestObjcPoHint.py
===
--- /dev/null
+++ lldb/test/API/lang/objc/objc-po-hint/TestObjcPoHint.py
@@ -0,0 +1,49 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestObjcPoHint(TestBase):
+NO_DEBUG_INFO_TESTCASE = True
+
+def test_show_po_hint(self):
+### Test that the po hint is shown once with the DWIM print command
+self.build()
+_, _, _, _ = lldbutil.run_to_source_breakpoint(
+self, "Set breakpoint here", lldb.SBFileSpec("main.m")
+)
+# Make sure the hint is printed the first time
+self.expect(
+"dwim-print -O -- foo",
+substrs=[
+"note: object description requested, but type doesn't implement "
+'a custom object description. Consider using "p" instead of "po"',
+"(
+  idx, g_debugger_properties[idx].default_uint_value != 0);
+}
+
 bool Debugger::GetUseSourceCache() const {
   const uint32_t idx = ePropertyUseSourceCache;
   return GetPropertyAtIndexAs(
Index: lldb/source/Core/CoreProperties.td
===
--- lldb/source/Core/CoreProperties.td
+++ lldb/source/Core/CoreProperties.td
@@ -195,6 +195,10 @@
 Global,
 DefaultStringValue<"${ansi.normal}">,
 Desc<"When displaying suggestion in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the suggestion.">;
+  def ShowDontUsePoHint: Property<"show-dont-use-po-hint", "Boolean">,
+Global,
+DefaultTrue,
+Desc<"If true, and object description was requested for a type that does not implement it, LLDB will print a hint telling the user to consider using p instead.">;
   def DWIMPrintVerbosity: Property<"dwim-print-verbosity", "Enum">,
 Global,
 DefaultEnumValue<"eDWIMPrintVerbosityNone">,
Index: lldb/source/Commands/CommandObjectDWIMPrint.cpp
===
--- lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -25,6 +25,8 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FormatVariadic.h"
 
+#include 
+
 using namespace llvm;
 using namespace lldb;
 using namespace lldb_private;
@@ -95,8 +97,46 @@
   m_expr_options.m_verbosity, m_format_options.GetFormat());
   dump_options.SetHideRootName(suppress_result);
 
+  bool is_po = m_varobj_options.use_objc;
+
   StackFrame *frame = m_exe_ctx.GetFramePtr();
 
+  // Either Swift was explicitly specified, or the frame is Swift.
+  lldb::LanguageType language = m_expr_options.language;
+  if (language == lldb::eLanguageTypeUnknown && frame)
+language = frame->GuessLanguage();
+
+  // Add a hint if object description was requested, but no description
+  // function was implemented.
+  auto maybe_add_hint = [&](llvm::StringRef output) {
+// Identify the default output of object description for Swift and
+// Objective-C
+// ". The regex is:
+// - Start with "<".
+// - Followed by 1 or more non-whitespace characters.
+// - Followed by ": 0x".
+// - Followed by 5 or more hex digits.
+// - Followed by ">".
+// - End with zero or more whitespace characters.
+const std::regex swift_class_regex("^<\\S+: 0x[[:xdigit:]]{5,}>\\s*$");
+
+if (GetDebugger().GetShowDontUsePoHint() && target_ptr &&
+(language == lldb::eLanguageTypeSwift ||
+ language == lldb::eLanguageTypeObjC) &&
+std::regex_match(output.data(), swift_class_regex)) {
+
+  static bool note_shown = false;
+  if (note_shown)
+return;
+
+  result.GetOutputStream()
+  << "note: object description requ

[Lldb-commits] [PATCH] D157041: [lldb] Protect OptionValue accesses from data races

2023-08-03 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: JDevlieghere, aprantl, jingham.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Thread sanitizer is catching data races in OptionValue, protect accesses
to OptionValue with a mutex.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157041

Files:
  lldb/include/lldb/Interpreter/OptionValue.h
  lldb/source/Interpreter/OptionValue.cpp

Index: lldb/source/Interpreter/OptionValue.cpp
===
--- lldb/source/Interpreter/OptionValue.cpp
+++ lldb/source/Interpreter/OptionValue.cpp
@@ -15,249 +15,310 @@
 using namespace lldb;
 using namespace lldb_private;
 
+
+OptionValue::OptionValue(const OptionValue &other) {
+  std::lock_guard lock(other.m_mutex);
+
+  m_parent_wp = other.m_parent_wp;
+  m_callback = other.m_callback;
+  m_value_was_set = other.m_value_was_set;
+
+}
+
+OptionValue& OptionValue::operator=(const OptionValue &other) {
+  std::scoped_lock lock(m_mutex, other.m_mutex);
+
+  m_parent_wp = other.m_parent_wp;
+  m_callback = other.m_callback;
+  m_value_was_set = other.m_value_was_set;
+
+  return *this;
+}
+
 Status OptionValue::SetSubValue(const ExecutionContext *exe_ctx,
 VarSetOperationType op, llvm::StringRef name,
 llvm::StringRef value) {
+  std::lock_guard lock(m_mutex);
   Status error;
   error.SetErrorString("SetSubValue is not supported");
   return error;
 }
 
 OptionValueBoolean *OptionValue::GetAsBoolean() {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeBoolean)
 return static_cast(this);
   return nullptr;
 }
 
 const OptionValueBoolean *OptionValue::GetAsBoolean() const {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeBoolean)
 return static_cast(this);
   return nullptr;
 }
 
 const OptionValueChar *OptionValue::GetAsChar() const {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeChar)
 return static_cast(this);
   return nullptr;
 }
 
 OptionValueChar *OptionValue::GetAsChar() {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeChar)
 return static_cast(this);
   return nullptr;
 }
 
 OptionValueFileSpec *OptionValue::GetAsFileSpec() {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeFileSpec)
 return static_cast(this);
   return nullptr;
 }
 
 const OptionValueFileSpec *OptionValue::GetAsFileSpec() const {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeFileSpec)
 return static_cast(this);
   return nullptr;
 }
 
 OptionValueFileSpecList *OptionValue::GetAsFileSpecList() {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeFileSpecList)
 return static_cast(this);
   return nullptr;
 }
 
 const OptionValueFileSpecList *OptionValue::GetAsFileSpecList() const {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeFileSpecList)
 return static_cast(this);
   return nullptr;
 }
 
 OptionValueArch *OptionValue::GetAsArch() {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeArch)
 return static_cast(this);
   return nullptr;
 }
 
 const OptionValueArch *OptionValue::GetAsArch() const {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeArch)
 return static_cast(this);
   return nullptr;
 }
 
 OptionValueArray *OptionValue::GetAsArray() {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeArray)
 return static_cast(this);
   return nullptr;
 }
 
 const OptionValueArray *OptionValue::GetAsArray() const {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeArray)
 return static_cast(this);
   return nullptr;
 }
 
 OptionValueArgs *OptionValue::GetAsArgs() {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeArgs)
 return static_cast(this);
   return nullptr;
 }
 
 const OptionValueArgs *OptionValue::GetAsArgs() const {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeArgs)
 return static_cast(this);
   return nullptr;
 }
 
 OptionValueDictionary *OptionValue::GetAsDictionary() {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeDictionary)
 return static_cast(this);
   return nullptr;
 }
 
 const OptionValueDictionary *OptionValue::GetAsDictionary() const {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeDictionary)
 return static_cast(this);
   return nullptr;
 }
 
 OptionValueEnumeration *OptionValue::GetAsEnumeration() {
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeEnum)
 return static_cast(this);
   return nullptr;
 }
 
 const OptionValueEnumeration *OptionValue::GetAsEnumeration() const {
+  std::lock_guard lock(m_mutex);
   if (GetType() == O

[Lldb-commits] [PATCH] D157041: [lldb] Protect OptionValue accesses from data races

2023-08-03 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

> Do all of these need to be protected with a mutex? In your description you're 
> saying TSan is detecting data races. What piece of data are you observing the 
> data race on?

Only SetAsBoolean/GetAsBoolean are being caught when running our test suite at 
the moment.

> Do we need a recursive mutex? I assume that these operations might call into 
> each other, but if not it would be nice to just have it be a std::mutex.

If we want to protect all accesses then yes, since these functions call each 
other. It we decide to only lock against what's being caught by tsan then we 
can get by with a regular mutex.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157041/new/

https://reviews.llvm.org/D157041

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157041: [lldb] Protect OptionValue accesses from data races

2023-08-03 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 marked 2 inline comments as done.
augusto2112 added inline comments.



Comment at: lldb/source/Interpreter/OptionValue.cpp:49
+  std::lock_guard lock(m_mutex);
   if (GetType() == OptionValue::eTypeBoolean)
 return static_cast(this);

kastiglione wrote:
> do these GetAsX functions need to lock?
Hmm, I think we can get away with just locking GetXValue and SetXValue, and 
replace the lock with a non recursive one.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157041/new/

https://reviews.llvm.org/D157041

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157041: [lldb] Protect OptionValue accesses from data races

2023-08-04 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 547284.
augusto2112 added a comment.

Addressed comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157041/new/

https://reviews.llvm.org/D157041

Files:
  lldb/include/lldb/Interpreter/OptionValue.h
  lldb/source/Interpreter/OptionValue.cpp

Index: lldb/source/Interpreter/OptionValue.cpp
===
--- lldb/source/Interpreter/OptionValue.cpp
+++ lldb/source/Interpreter/OptionValue.cpp
@@ -15,6 +15,26 @@
 using namespace lldb;
 using namespace lldb_private;
 
+
+OptionValue::OptionValue(const OptionValue &other) {
+  std::lock_guard lock(other.m_mutex);
+
+  m_parent_wp = other.m_parent_wp;
+  m_callback = other.m_callback;
+  m_value_was_set = other.m_value_was_set;
+
+}
+
+OptionValue& OptionValue::operator=(const OptionValue &other) {
+  std::scoped_lock lock(m_mutex, other.m_mutex);
+
+  m_parent_wp = other.m_parent_wp;
+  m_callback = other.m_callback;
+  m_value_was_set = other.m_value_was_set;
+
+  return *this;
+}
+
 Status OptionValue::SetSubValue(const ExecutionContext *exe_ctx,
 VarSetOperationType op, llvm::StringRef name,
 llvm::StringRef value) {
@@ -216,6 +236,7 @@
 }
 
 OptionValueString *OptionValue::GetAsString() {
+  
   if (GetType() == OptionValue::eTypeString)
 return static_cast(this);
   return nullptr;
@@ -252,12 +273,14 @@
 }
 
 std::optional OptionValue::GetBooleanValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueBoolean *option_value = GetAsBoolean())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetBooleanValue(bool new_value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueBoolean *option_value = GetAsBoolean()) {
 option_value->SetCurrentValue(new_value);
 return true;
@@ -266,12 +289,14 @@
 }
 
 std::optional OptionValue::GetCharValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueChar *option_value = GetAsChar())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetCharValue(char new_value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueChar *option_value = GetAsChar()) {
 option_value->SetCurrentValue(new_value);
 return true;
@@ -280,12 +305,14 @@
 }
 
 std::optional OptionValue::GetEnumerationValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueEnumeration *option_value = GetAsEnumeration())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetEnumerationValue(int64_t value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueEnumeration *option_value = GetAsEnumeration()) {
 option_value->SetCurrentValue(value);
 return true;
@@ -294,12 +321,14 @@
 }
 
 std::optional OptionValue::GetFileSpecValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFileSpec *option_value = GetAsFileSpec())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetFileSpecValue(FileSpec file_spec) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueFileSpec *option_value = GetAsFileSpec()) {
 option_value->SetCurrentValue(file_spec, false);
 return true;
@@ -308,6 +337,7 @@
 }
 
 bool OptionValue::AppendFileSpecValue(FileSpec file_spec) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueFileSpecList *option_value = GetAsFileSpecList()) {
 option_value->AppendCurrentValue(file_spec);
 return true;
@@ -316,18 +346,21 @@
 }
 
 std::optional OptionValue::GetFileSpecListValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFileSpecList *option_value = GetAsFileSpecList())
 return option_value->GetCurrentValue();
   return {};
 }
 
 std::optional OptionValue::GetFormatValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFormat *option_value = GetAsFormat())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetFormatValue(lldb::Format new_value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueFormat *option_value = GetAsFormat()) {
 option_value->SetCurrentValue(new_value);
 return true;
@@ -336,12 +369,14 @@
 }
 
 std::optional OptionValue::GetLanguageValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueLanguage *option_value = GetAsLanguage())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetLanguageValue(lldb::LanguageType new_language) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueLanguage *option_value = GetAsLanguage()) {
 option_value->SetCurrentValue(new_language);
 return true;
@@ -350,24 +385,30 @@
 }
 
 const FormatEntity::Entry *OptionValue::GetFormatEntity() const {
+  std::lock_guard lock(m_mutex);
+
   if (const OptionValueFormatEntity *option_value = GetAsFormatEntity())
 return &option_value->GetCurrentValue();
   return nullptr;

[Lldb-commits] [PATCH] D157041: [lldb] Protect OptionValue accesses from data races

2023-08-04 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 547318.
augusto2112 added a comment.

Remove lock from DeepCopy


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157041/new/

https://reviews.llvm.org/D157041

Files:
  lldb/include/lldb/Interpreter/OptionValue.h
  lldb/source/Interpreter/OptionValue.cpp

Index: lldb/source/Interpreter/OptionValue.cpp
===
--- lldb/source/Interpreter/OptionValue.cpp
+++ lldb/source/Interpreter/OptionValue.cpp
@@ -15,6 +15,25 @@
 using namespace lldb;
 using namespace lldb_private;
 
+OptionValue::OptionValue(const OptionValue &other) {
+  std::lock_guard lock(other.m_mutex);
+
+  m_parent_wp = other.m_parent_wp;
+  m_callback = other.m_callback;
+  m_value_was_set = other.m_value_was_set;
+
+}
+
+OptionValue& OptionValue::operator=(const OptionValue &other) {
+  std::scoped_lock lock(m_mutex, other.m_mutex);
+
+  m_parent_wp = other.m_parent_wp;
+  m_callback = other.m_callback;
+  m_value_was_set = other.m_value_was_set;
+
+  return *this;
+}
+
 Status OptionValue::SetSubValue(const ExecutionContext *exe_ctx,
 VarSetOperationType op, llvm::StringRef name,
 llvm::StringRef value) {
@@ -252,12 +271,14 @@
 }
 
 std::optional OptionValue::GetBooleanValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueBoolean *option_value = GetAsBoolean())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetBooleanValue(bool new_value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueBoolean *option_value = GetAsBoolean()) {
 option_value->SetCurrentValue(new_value);
 return true;
@@ -266,12 +287,14 @@
 }
 
 std::optional OptionValue::GetCharValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueChar *option_value = GetAsChar())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetCharValue(char new_value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueChar *option_value = GetAsChar()) {
 option_value->SetCurrentValue(new_value);
 return true;
@@ -280,12 +303,14 @@
 }
 
 std::optional OptionValue::GetEnumerationValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueEnumeration *option_value = GetAsEnumeration())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetEnumerationValue(int64_t value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueEnumeration *option_value = GetAsEnumeration()) {
 option_value->SetCurrentValue(value);
 return true;
@@ -294,12 +319,14 @@
 }
 
 std::optional OptionValue::GetFileSpecValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFileSpec *option_value = GetAsFileSpec())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetFileSpecValue(FileSpec file_spec) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueFileSpec *option_value = GetAsFileSpec()) {
 option_value->SetCurrentValue(file_spec, false);
 return true;
@@ -308,6 +335,7 @@
 }
 
 bool OptionValue::AppendFileSpecValue(FileSpec file_spec) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueFileSpecList *option_value = GetAsFileSpecList()) {
 option_value->AppendCurrentValue(file_spec);
 return true;
@@ -316,18 +344,21 @@
 }
 
 std::optional OptionValue::GetFileSpecListValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFileSpecList *option_value = GetAsFileSpecList())
 return option_value->GetCurrentValue();
   return {};
 }
 
 std::optional OptionValue::GetFormatValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFormat *option_value = GetAsFormat())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetFormatValue(lldb::Format new_value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueFormat *option_value = GetAsFormat()) {
 option_value->SetCurrentValue(new_value);
 return true;
@@ -336,12 +367,14 @@
 }
 
 std::optional OptionValue::GetLanguageValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueLanguage *option_value = GetAsLanguage())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetLanguageValue(lldb::LanguageType new_language) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueLanguage *option_value = GetAsLanguage()) {
 option_value->SetCurrentValue(new_language);
 return true;
@@ -350,24 +383,28 @@
 }
 
 const FormatEntity::Entry *OptionValue::GetFormatEntity() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFormatEntity *option_value = GetAsFormatEntity())
 return &option_value->GetCurrentValue();
   return nullptr;
 }
 
 const RegularExpression *OptionValue::GetRegexValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueRegex *option_value = GetAsRegex())
 ret

[Lldb-commits] [PATCH] D157041: [lldb] Protect OptionValue accesses from data races

2023-08-04 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG318f600722e3: [lldb] Protect OptionValue accesses from data 
races (authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157041/new/

https://reviews.llvm.org/D157041

Files:
  lldb/include/lldb/Interpreter/OptionValue.h
  lldb/source/Interpreter/OptionValue.cpp

Index: lldb/source/Interpreter/OptionValue.cpp
===
--- lldb/source/Interpreter/OptionValue.cpp
+++ lldb/source/Interpreter/OptionValue.cpp
@@ -15,6 +15,25 @@
 using namespace lldb;
 using namespace lldb_private;
 
+OptionValue::OptionValue(const OptionValue &other) {
+  std::lock_guard lock(other.m_mutex);
+
+  m_parent_wp = other.m_parent_wp;
+  m_callback = other.m_callback;
+  m_value_was_set = other.m_value_was_set;
+
+}
+
+OptionValue& OptionValue::operator=(const OptionValue &other) {
+  std::scoped_lock lock(m_mutex, other.m_mutex);
+
+  m_parent_wp = other.m_parent_wp;
+  m_callback = other.m_callback;
+  m_value_was_set = other.m_value_was_set;
+
+  return *this;
+}
+
 Status OptionValue::SetSubValue(const ExecutionContext *exe_ctx,
 VarSetOperationType op, llvm::StringRef name,
 llvm::StringRef value) {
@@ -252,12 +271,14 @@
 }
 
 std::optional OptionValue::GetBooleanValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueBoolean *option_value = GetAsBoolean())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetBooleanValue(bool new_value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueBoolean *option_value = GetAsBoolean()) {
 option_value->SetCurrentValue(new_value);
 return true;
@@ -266,12 +287,14 @@
 }
 
 std::optional OptionValue::GetCharValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueChar *option_value = GetAsChar())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetCharValue(char new_value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueChar *option_value = GetAsChar()) {
 option_value->SetCurrentValue(new_value);
 return true;
@@ -280,12 +303,14 @@
 }
 
 std::optional OptionValue::GetEnumerationValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueEnumeration *option_value = GetAsEnumeration())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetEnumerationValue(int64_t value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueEnumeration *option_value = GetAsEnumeration()) {
 option_value->SetCurrentValue(value);
 return true;
@@ -294,12 +319,14 @@
 }
 
 std::optional OptionValue::GetFileSpecValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFileSpec *option_value = GetAsFileSpec())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetFileSpecValue(FileSpec file_spec) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueFileSpec *option_value = GetAsFileSpec()) {
 option_value->SetCurrentValue(file_spec, false);
 return true;
@@ -308,6 +335,7 @@
 }
 
 bool OptionValue::AppendFileSpecValue(FileSpec file_spec) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueFileSpecList *option_value = GetAsFileSpecList()) {
 option_value->AppendCurrentValue(file_spec);
 return true;
@@ -316,18 +344,21 @@
 }
 
 std::optional OptionValue::GetFileSpecListValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFileSpecList *option_value = GetAsFileSpecList())
 return option_value->GetCurrentValue();
   return {};
 }
 
 std::optional OptionValue::GetFormatValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFormat *option_value = GetAsFormat())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetFormatValue(lldb::Format new_value) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueFormat *option_value = GetAsFormat()) {
 option_value->SetCurrentValue(new_value);
 return true;
@@ -336,12 +367,14 @@
 }
 
 std::optional OptionValue::GetLanguageValue() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueLanguage *option_value = GetAsLanguage())
 return option_value->GetCurrentValue();
   return {};
 }
 
 bool OptionValue::SetLanguageValue(lldb::LanguageType new_language) {
+  std::lock_guard lock(m_mutex);
   if (OptionValueLanguage *option_value = GetAsLanguage()) {
 option_value->SetCurrentValue(new_language);
 return true;
@@ -350,24 +383,28 @@
 }
 
 const FormatEntity::Entry *OptionValue::GetFormatEntity() const {
+  std::lock_guard lock(m_mutex);
   if (const OptionValueFormatEntity *option_value = GetAsFormatEntity())
 return &option_value->GetCurrentValue();
   return nullptr;
 }
 
 const RegularExpression *OptionValue::GetRegexValue() const {
+  std::lock_guard loc

[Lldb-commits] [PATCH] D157153: [lldb] Fix ThreadList::Update not locking the rhs's mutex

2023-08-04 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: jingham, JDevlieghere.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

ThreadList::Update is being caught by thread sanitizer. There's even a
comment on the function that both mutexes should be lock (even though
only the "this" mutex was actually being locked). Fix this by locking
both mutexes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157153

Files:
  lldb/source/Target/ThreadList.cpp


Index: lldb/source/Target/ThreadList.cpp
===
--- lldb/source/Target/ThreadList.cpp
+++ lldb/source/Target/ThreadList.cpp
@@ -736,7 +736,7 @@
   if (this != &rhs) {
 // Lock both mutexes to make sure neither side changes anyone on us while
 // the assignment occurs
-std::lock_guard guard(GetMutex());
+std::scoped_lock guard(GetMutex(), rhs.GetMutex());
 
 m_process = rhs.m_process;
 m_stop_id = rhs.m_stop_id;


Index: lldb/source/Target/ThreadList.cpp
===
--- lldb/source/Target/ThreadList.cpp
+++ lldb/source/Target/ThreadList.cpp
@@ -736,7 +736,7 @@
   if (this != &rhs) {
 // Lock both mutexes to make sure neither side changes anyone on us while
 // the assignment occurs
-std::lock_guard guard(GetMutex());
+std::scoped_lock guard(GetMutex(), rhs.GetMutex());
 
 m_process = rhs.m_process;
 m_stop_id = rhs.m_stop_id;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157153: [lldb] Fix ThreadList::Update not locking the rhs's mutex

2023-08-04 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd75dc9a8a86c: [lldb] Fix ThreadList::Update not locking the 
rhs's mutex (authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157153/new/

https://reviews.llvm.org/D157153

Files:
  lldb/source/Target/ThreadList.cpp


Index: lldb/source/Target/ThreadList.cpp
===
--- lldb/source/Target/ThreadList.cpp
+++ lldb/source/Target/ThreadList.cpp
@@ -736,7 +736,7 @@
   if (this != &rhs) {
 // Lock both mutexes to make sure neither side changes anyone on us while
 // the assignment occurs
-std::lock_guard guard(GetMutex());
+std::scoped_lock guard(GetMutex(), rhs.GetMutex());
 
 m_process = rhs.m_process;
 m_stop_id = rhs.m_stop_id;


Index: lldb/source/Target/ThreadList.cpp
===
--- lldb/source/Target/ThreadList.cpp
+++ lldb/source/Target/ThreadList.cpp
@@ -736,7 +736,7 @@
   if (this != &rhs) {
 // Lock both mutexes to make sure neither side changes anyone on us while
 // the assignment occurs
-std::lock_guard guard(GetMutex());
+std::scoped_lock guard(GetMutex(), rhs.GetMutex());
 
 m_process = rhs.m_process;
 m_stop_id = rhs.m_stop_id;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157159: [lldb] Properly protect the Communication class with reader/writer lock

2023-08-04 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 accepted this revision.
augusto2112 added a comment.
This revision is now accepted and ready to land.

On the description you mention `unique_ptr` but I only see `shared_ptr` here. 
Was that a typo or do you mean that users of this class kept it behind a 
`unique_ptr`?

In any case I think this change is great.




Comment at: lldb/source/Core/Communication.cpp:43
 
+  std::unique_lock guard(m_shared_mutex);
   LLDB_LOG(GetLog(LLDBLog::Communication),

Do you think it's possible that between the call to `Clear` and this lock 
someone acquires the lock?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157159/new/

https://reviews.llvm.org/D157159

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157347: [lldb] Fix data race in ConnectionFileDescriptor

2023-08-07 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 accepted this revision.
augusto2112 added a comment.
This revision is now accepted and ready to land.

LGTM


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157347/new/

https://reviews.llvm.org/D157347

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157347: [lldb] Fix data race in NativeFile

2023-08-09 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 accepted this revision.
augusto2112 added a comment.

I have one nit that I'll leave up to you whether it should be addressed now or 
not.




Comment at: lldb/source/Host/common/File.cpp:545
   num_bytes = bytes_read;
-  } else if (StreamIsValid()) {
+  } else if (ValueGuard file_lock = StreamIsValid()) {
 bytes_read = ::fread(buf, 1, num_bytes, m_stream);

I believe `descriptor_guard` will still be in scope in the else branch (weird 
scoping rules), but 



Comment at: lldb/source/Host/common/File.cpp:609
   num_bytes = bytes_written;
-  } else if (StreamIsValid()) {
+  } else if (ValueGuard stream_guard = StreamIsValid()) {
 bytes_written = ::fwrite(buf, 1, num_bytes, m_stream);

One thing that's not super obvious for people reading this is that 
`descriptor_guard` is still in scope in the else branch (due to C++'s weird 
scoping rules when it comes to declaring variables inside `if` statements), and 
will keep the descriptor mutex locked which is probably not what you intended. 
I don't think this affects the correctness of this implementation at the 
moment, but could be dangerous with further changes on top of this one.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157347/new/

https://reviews.llvm.org/D157347

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157347: [lldb] Fix data race in NativeFile

2023-08-09 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added inline comments.



Comment at: lldb/source/Host/common/File.cpp:609
   num_bytes = bytes_written;
-  } else if (StreamIsValid()) {
+  } else if (ValueGuard stream_guard = StreamIsValid()) {
 bytes_written = ::fwrite(buf, 1, num_bytes, m_stream);

bulbazord wrote:
> augusto2112 wrote:
> > One thing that's not super obvious for people reading this is that 
> > `descriptor_guard` is still in scope in the else branch (due to C++'s weird 
> > scoping rules when it comes to declaring variables inside `if` statements), 
> > and will keep the descriptor mutex locked which is probably not what you 
> > intended. I don't think this affects the correctness of this implementation 
> > at the moment, but could be dangerous with further changes on top of this 
> > one.
> If that's true, then this change needs further adjustment. `GetStream` 
> acquires the `ValueGuard`s in the opposite order, meaning Thread 1 can call 
> this function and acquire `descriptor_guard` while Thread 2 can call 
> `GetStream` and acquire `stream_guard` at the same time. Then they're both 
> waiting on the other lock (deadlock).
You're right, nice catch.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157347/new/

https://reviews.llvm.org/D157347

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157648: [lldb] Fix data race in Process

2023-08-10 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: bulbazord, JDevlieghere.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Thread sanitizer reports a data race in Process.cpp in the usage of
m_process_input_reader. Fix this data race by introducing a mutex
guarding the access to this variable.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157648

Files:
  lldb/include/lldb/Target/Process.h
  lldb/source/Target/Process.cpp

Index: lldb/source/Target/Process.cpp
===
--- lldb/source/Target/Process.cpp
+++ lldb/source/Target/Process.cpp
@@ -630,6 +630,7 @@
 const Timeout &timeout) {
   // don't sync (potentially context switch) in case where there is no process
   // IO
+  std::lock_guard guard(m_process_input_reader_mutex);
   if (!m_process_input_reader)
 return;
 
@@ -2505,7 +2506,11 @@
   m_jit_loaders_up.reset();
   m_system_runtime_up.reset();
   m_os_up.reset();
-  m_process_input_reader.reset();
+
+  {
+std::lock_guard guard(m_process_input_reader_mutex);
+m_process_input_reader.reset();
+  }
 
   Module *exe_module = GetTarget().GetExecutableModulePointer();
 
@@ -2803,7 +2808,10 @@
 
 Status Process::Attach(ProcessAttachInfo &attach_info) {
   m_abi_sp.reset();
-  m_process_input_reader.reset();
+  {
+std::lock_guard guard(m_process_input_reader_mutex);
+m_process_input_reader.reset();
+  }
   m_dyld_up.reset();
   m_jit_loaders_up.reset();
   m_system_runtime_up.reset();
@@ -3054,7 +3062,10 @@
 
 Status Process::ConnectRemote(llvm::StringRef remote_url) {
   m_abi_sp.reset();
-  m_process_input_reader.reset();
+  {
+std::lock_guard guard(m_process_input_reader_mutex);
+m_process_input_reader.reset();
+  }
 
   // Find the process and its architecture.  Make sure it matches the
   // architecture of the current Target, and if not adjust it.
@@ -3342,10 +3353,13 @@
 m_stdio_communication.Disconnect();
 m_stdin_forward = false;
 
-if (m_process_input_reader) {
-  m_process_input_reader->SetIsDone(true);
-  m_process_input_reader->Cancel();
-  m_process_input_reader.reset();
+{
+  std::lock_guard guard(m_process_input_reader_mutex);
+  if (m_process_input_reader) {
+m_process_input_reader->SetIsDone(true);
+m_process_input_reader->Cancel();
+m_process_input_reader.reset();
+  }
 }
 
 // If we exited when we were waiting for a process to stop, then forward
@@ -4523,20 +4537,25 @@
 m_stdio_communication.StartReadThread();
 
 // Now read thread is set up, set up input reader.
-
-if (!m_process_input_reader)
-  m_process_input_reader =
-  std::make_shared(this, fd);
+{
+  std::lock_guard guard(m_process_input_reader_mutex);
+  if (!m_process_input_reader)
+m_process_input_reader =
+std::make_shared(this, fd);
+}
   }
 }
 
 bool Process::ProcessIOHandlerIsActive() {
+  std::lock_guard guard(m_process_input_reader_mutex);
   IOHandlerSP io_handler_sp(m_process_input_reader);
   if (io_handler_sp)
 return GetTarget().GetDebugger().IsTopIOHandler(io_handler_sp);
   return false;
 }
+
 bool Process::PushProcessIOHandler() {
+  std::lock_guard guard(m_process_input_reader_mutex);
   IOHandlerSP io_handler_sp(m_process_input_reader);
   if (io_handler_sp) {
 Log *log = GetLog(LLDBLog::Process);
@@ -4556,6 +4575,7 @@
 }
 
 bool Process::PopProcessIOHandler() {
+  std::lock_guard guard(m_process_input_reader_mutex);
   IOHandlerSP io_handler_sp(m_process_input_reader);
   if (io_handler_sp)
 return GetTarget().GetDebugger().RemoveIOHandler(io_handler_sp);
Index: lldb/include/lldb/Target/Process.h
===
--- lldb/include/lldb/Target/Process.h
+++ lldb/include/lldb/Target/Process.h
@@ -2992,6 +2992,7 @@
   m_unix_signals_sp; /// This is the current signal set for this process.
   lldb::ABISP m_abi_sp;
   lldb::IOHandlerSP m_process_input_reader;
+  mutable std::mutex m_process_input_reader_mutex;
   ThreadedCommunication m_stdio_communication;
   std::recursive_mutex m_stdio_communication_mutex;
   bool m_stdin_forward; /// Remember if stdin must be forwarded to remote debug
@@ -3117,6 +3118,7 @@
   bool ProcessIOHandlerIsActive();
 
   bool ProcessIOHandlerExists() const {
+std::lock_guard guard(m_process_input_reader_mutex);
 return static_cast(m_process_input_reader);
   }
 
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157654: [lldb] Fix data race in PipePosix

2023-08-10 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: JDevlieghere, bulbazord.
Herald added a subscriber: kristof.beyls.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Thread sanitizer reports the following data race:

  WARNING: ThreadSanitizer: data race (pid=43201)
Write of size 4 at 0x00010520c474 by thread T1 (mutexes: write M0, write 
M1):
  #0 lldb_private::PipePosix::CloseWriteFileDescriptor() PipePosix.cpp:242 
(liblldb.18.0.0git.dylib:arm64+0x414700) (BuildId: 
2983976beb2637b5943bff32fd12eb89320021000e00)
  #1 lldb_private::PipePosix::Close() PipePosix.cpp:217 
(liblldb.18.0.0git.dylib:arm64+0x4144e8) (BuildId: 
2983976beb2637b5943bff32fd12eb89320021000e00)
  #2 
lldb_private::ConnectionFileDescriptor::Disconnect(lldb_private::Status*) 
ConnectionFileDescriptorPosix.cpp:239 (liblldb.18.0.0git.dylib:arm64+0x40a620) 
(BuildId: 2983976beb2637b5943bff32fd12eb89320021000e00)
  #3 lldb_private::Communication::Disconnect(lldb_private::Status*) 
Communication.cpp:61 (liblldb.18.0.0git.dylib:arm64+0x2a9318) (BuildId: 
2983976beb2637b5943bff32fd12eb89320021000e00)
  #4 lldb_private::process_gdb_remote::ProcessGDBRemote::DidExit() 
ProcessGDBRemote.cpp:1167 (liblldb.18.0.0git.dylib:arm64+0x8ed984) (BuildId: 
2983976beb2637b5943bff32fd12eb89320021000e00)
  
Previous read of size 4 at 0x00010520c474 by main thread (mutexes: write 
M2, write M3):
  #0 lldb_private::PipePosix::CanWrite() const PipePosix.cpp:229 
(liblldb.18.0.0git.dylib:arm64+0x4145e4) (BuildId: 
2983976beb2637b5943bff32fd12eb89320021000e00)
  #1 
lldb_private::ConnectionFileDescriptor::Disconnect(lldb_private::Status*) 
ConnectionFileDescriptorPosix.cpp:212 (liblldb.18.0.0git.dylib:arm64+0x40a4a8) 
(BuildId: 2983976beb2637b5943bff32fd12eb89320021000e00)
  #2 lldb_private::Communication::Disconnect(lldb_private::Status*) 
Communication.cpp:61 (liblldb.18.0.0git.dylib:arm64+0x2a9318) (BuildId: 
2983976beb2637b5943bff32fd12eb89320021000e00)
  #3 
lldb_private::process_gdb_remote::GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote&,
 lldb_private::Timeout>, bool) 
GDBRemoteCommunication.cpp:373 (liblldb.18.0.0git.dylib:arm64+0x8b9c48) 
(BuildId: 2983976beb2637b5943bff32fd12eb89320021000e00)
  #4 
lldb_private::process_gdb_remote::GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote&,
 lldb_private::Timeout>, bool) 
GDBRemoteCommunication.cpp:243 (liblldb.18.0.0git.dylib:arm64+0x8b9904) 
(BuildId: 2983976beb2637b5943bff32fd12eb89320021000e00)

Fix this by adding a mutex to PipePosix.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157654

Files:
  lldb/include/lldb/Host/posix/PipePosix.h
  lldb/source/Host/posix/PipePosix.cpp

Index: lldb/source/Host/posix/PipePosix.cpp
===
--- lldb/source/Host/posix/PipePosix.cpp
+++ lldb/source/Host/posix/PipePosix.cpp
@@ -66,15 +66,17 @@
 
 PipePosix &PipePosix::operator=(PipePosix &&pipe_posix) {
   PipeBase::operator=(std::move(pipe_posix));
-  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptor();
-  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptor();
+  std::lock_guard guard(m_lock);
+  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptorUnlocked();
+  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptorUnlocked();
   return *this;
 }
 
 PipePosix::~PipePosix() { Close(); }
 
 Status PipePosix::CreateNew(bool child_processes_inherit) {
-  if (CanRead() || CanWrite())
+  std::lock_guard guard(m_lock);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status(EINVAL, eErrorTypePOSIX);
 
   Status error;
@@ -87,7 +89,7 @@
 if (!child_processes_inherit) {
   if (!SetCloexecFlag(m_fds[0]) || !SetCloexecFlag(m_fds[1])) {
 error.SetErrorToErrno();
-Close();
+CloseUnlocked();
 return error;
   }
 }
@@ -103,7 +105,8 @@
 }
 
 Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  std::lock_guard guard(m_lock);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   Status error;
@@ -140,7 +143,8 @@
 
 Status PipePosix::OpenAsReader(llvm::StringRef name,
bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  std::lock_guard guard(m_lock);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   int flags = O_RDONLY | O_NONBLOCK;
@@ -161,7 +165,8 @@
 PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
bool child_process_inherit,
const s

[Lldb-commits] [PATCH] D157648: [lldb] Fix data race in Process

2023-08-10 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D157648#4578420 , @JDevlieghere 
wrote:

> Is the reported race specifically about the shared pointer being accessed 
> concurrently or operations on the `IOHandler`?

I believe it's the shared pointer being accessed. Here's an example of what's 
being reported:

  WARNING: ThreadSanitizer: data race (pid=52249)
Read of size 8 at 0x00010731ce38 by thread T3:
  #0 lldb_private::Process::PopProcessIOHandler() Process.cpp:4559 
(liblldb.18.0.0git.dylib:arm64+0x53a5a4) (BuildId: 
6e77321523b936d2955d63d4d25df7cd320021000e00)
  #1 
lldb_private::Process::HandlePrivateEvent(std::__1::shared_ptr&)
 Process.cpp:3775 (liblldb.18.0.0git.dylib:arm64+0x54204c) (BuildId: 
6e77321523b936d2955d63d4d25df7cd320021000e00)
  #2 lldb_private::Process::RunPrivateStateThread(bool) Process.cpp:3904 
(liblldb.18.0.0git.dylib:arm64+0x54874c) (BuildId: 
6e77321523b936d2955d63d4d25df7cd320021000e00)
  #3 
std::__1::__function::__func, 
void* ()>::operator()() function.h:356 (liblldb.18.0.0git.dylib:arm64+0x555de4) 
(BuildId: 6e77321523b936d2955d63d4d25df7cd320021000e00)
  #4 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*) 
HostNativeThreadBase.cpp:62 (liblldb.18.0.0git.dylib:arm64+0x3e83fc) (BuildId: 
6e77321523b936d2955d63d4d25df7cd320021000e00)
  #5 lldb_private::HostThreadMacOSX::ThreadCreateTrampoline(void*) 
HostThreadMacOSX.mm:18 (liblldb.18.0.0git.dylib:arm64+0x175056c) (BuildId: 
6e77321523b936d2955d63d4d25df7cd320021000e00)
  
Previous write of size 8 at 0x00010731ce38 by main thread (mutexes: write 
M0):
  #0 lldb_private::Process::SetSTDIOFileDescriptor(int) Process.cpp:4528 
(liblldb.18.0.0git.dylib:arm64+0x54aa5c) (BuildId: 
6e77321523b936d2955d63d4d25df7cd320021000e00)
  #1 lldb_private::Platform::DebugProcess(lldb_private::ProcessLaunchInfo&, 
lldb_private::Debugger&, lldb_private::Target&, lldb_private::Status&) 
Platform.cpp:1120 (liblldb.18.0.0git.dylib:arm64+0x52bc54) (BuildId: 
6e77321523b936d2955d63d4d25df7cd320021000e00)
  #2 
lldb_private::PlatformDarwin::DebugProcess(lldb_private::ProcessLaunchInfo&, 
lldb_private::Debugger&, lldb_private::Target&, lldb_private::Status&) 
PlatformDarwin.cpp:711 (liblldb.18.0.0git.dylib:arm64+0x872cc8) (BuildId: 
6e77321523b936d2955d63d4d25df7cd320021000e00)
  #3 lldb_private::Target::Launch(lldb_private::ProcessLaunchInfo&, 
lldb_private::Stream*) Target.cpp:3235 (liblldb.18.0.0git.dylib:arm64+0x5b118c) 
(BuildId: 6e77321523b936d2955d63d4d25df7cd320021000e00)

Line 4559 is

  IOHandlerSP io_handler_sp(m_process_input_reader);

Line 4528 is

  m_process_input_reader =
  std::make_shared(this, fd);


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157648/new/

https://reviews.llvm.org/D157648

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157654: [lldb] Fix data race in PipePosix

2023-08-11 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added inline comments.



Comment at: lldb/source/Host/posix/PipePosix.cpp:69
   PipeBase::operator=(std::move(pipe_posix));
-  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptor();
-  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptor();
+  std::lock_guard guard(m_lock);
+  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptorUnlocked();

bulbazord wrote:
> I think this lock needs to be at the beginning. Scenario:
> 
> Thread 1 calls the move assign operator and performs the base move assign. 
> Gets unscheduled before acquiring lock.
> Thread 2 calls the move assign operator and performs the base move assign. 
> Acquires the lock, fills in `m_fds`, and returns.
> Thread 1 is scheduled again, grabs the lock, and fills in `m_fds`.
> `this` will have its `PipeBase` members filled in by the Thread 2 call while 
> `m_fds` will be filled in by the Thread 1 call. Granted, one thread may be 
> surprised that suddenly the thing didn't get moved in as expected, but at 
> least `this` will be in a consistent state.
> 
> I think you also need to lock the mutex of `pipe_posix` at the same time. 
> Imagine Thread 1 is trying to access something from `pipe_posix` while Thread 
> 2 is trying to move it into another `PipePosix` object. (Not sure how likely 
> this scenario is but I'd rather be safe than sorry).
> I think you also need to lock the mutex of pipe_posix at the same time. 
> Imagine Thread 1 is trying to access something from pipe_posix while Thread 2 
> is trying to move it into another PipePosix object. (Not sure how likely this 
> scenario is but I'd rather be safe than sorry).

Yeah I thought about this too, since `pipe_posix` is an rvalue reference I was 
thinking this shouldn't be necessary, but you're right, I'll lock it anyway.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157654/new/

https://reviews.llvm.org/D157654

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157654: [lldb] Fix data race in PipePosix

2023-08-11 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 549454.
augusto2112 added a comment.

Lock earlier in operator=


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157654/new/

https://reviews.llvm.org/D157654

Files:
  lldb/include/lldb/Host/posix/PipePosix.h
  lldb/source/Host/posix/PipePosix.cpp

Index: lldb/source/Host/posix/PipePosix.cpp
===
--- lldb/source/Host/posix/PipePosix.cpp
+++ lldb/source/Host/posix/PipePosix.cpp
@@ -65,16 +65,19 @@
 pipe_posix.ReleaseWriteFileDescriptor()} {}
 
 PipePosix &PipePosix::operator=(PipePosix &&pipe_posix) {
+  std::scoped_lock guard(m_lock, pipe_posix.m_lock);
+
   PipeBase::operator=(std::move(pipe_posix));
-  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptor();
-  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptor();
+  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptorUnlocked();
+  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptorUnlocked();
   return *this;
 }
 
 PipePosix::~PipePosix() { Close(); }
 
 Status PipePosix::CreateNew(bool child_processes_inherit) {
-  if (CanRead() || CanWrite())
+  std::lock_guard guard(m_lock);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status(EINVAL, eErrorTypePOSIX);
 
   Status error;
@@ -87,7 +90,7 @@
 if (!child_processes_inherit) {
   if (!SetCloexecFlag(m_fds[0]) || !SetCloexecFlag(m_fds[1])) {
 error.SetErrorToErrno();
-Close();
+CloseUnlocked();
 return error;
   }
 }
@@ -103,7 +106,8 @@
 }
 
 Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  std::lock_guard guard(m_lock);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   Status error;
@@ -140,7 +144,8 @@
 
 Status PipePosix::OpenAsReader(llvm::StringRef name,
bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  std::lock_guard guard(m_lock);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   int flags = O_RDONLY | O_NONBLOCK;
@@ -161,7 +166,8 @@
 PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
bool child_process_inherit,
const std::chrono::microseconds &timeout) {
-  if (CanRead() || CanWrite())
+  std::lock_guard guard(m_lock);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   int flags = O_WRONLY | O_NONBLOCK;
@@ -171,7 +177,7 @@
   using namespace std::chrono;
   const auto finish_time = Now() + timeout;
 
-  while (!CanWrite()) {
+  while (!CanWriteUnlocked()) {
 if (timeout != microseconds::zero()) {
   const auto dur = duration_cast(finish_time - Now()).count();
   if (dur <= 0)
@@ -196,25 +202,54 @@
   return Status();
 }
 
-int PipePosix::GetReadFileDescriptor() const { return m_fds[READ]; }
+int PipePosix::GetReadFileDescriptor() const {
+  std::lock_guard guard(m_lock);
+  return GetReadFileDescriptorUnlocked();
+}
+
+int PipePosix::GetReadFileDescriptorUnlocked() const {
+  return m_fds[READ];
+}
+
+int PipePosix::GetWriteFileDescriptor() const {
+  std::lock_guard guard(m_lock);
+  return GetWriteFileDescriptorUnlocked();
+}
 
-int PipePosix::GetWriteFileDescriptor() const { return m_fds[WRITE]; }
+int PipePosix::GetWriteFileDescriptorUnlocked() const {
+  return m_fds[WRITE];
+}
 
 int PipePosix::ReleaseReadFileDescriptor() {
+  std::lock_guard guard(m_lock);
+  return ReleaseReadFileDescriptorUnlocked();
+}
+
+int PipePosix::ReleaseReadFileDescriptorUnlocked() {
   const int fd = m_fds[READ];
   m_fds[READ] = PipePosix::kInvalidDescriptor;
   return fd;
 }
 
 int PipePosix::ReleaseWriteFileDescriptor() {
+  std::lock_guard guard(m_lock);
+  return ReleaseWriteFileDescriptorUnlocked();
+}
+
+int PipePosix::ReleaseWriteFileDescriptorUnlocked() {
   const int fd = m_fds[WRITE];
   m_fds[WRITE] = PipePosix::kInvalidDescriptor;
   return fd;
 }
 
 void PipePosix::Close() {
-  CloseReadFileDescriptor();
-  CloseWriteFileDescriptor();
+  std::lock_guard guard(m_lock);
+  CloseUnlocked();
+}
+
+void PipePosix::CloseUnlocked() {
+  CloseReadFileDescriptorUnlocked();
+  CloseWriteFileDescriptorUnlocked();
 }
 
 Status PipePosix::Delete(llvm::StringRef name) {
@@ -222,22 +257,41 @@
 }
 
 bool PipePosix::CanRead() const {
+  std::lock_guard guard(m_lock);
+  return CanReadUnlocked();
+}
+
+bool PipePosix::CanReadUnlocked() const {
   return m_fds[READ] != PipePosix::kInvalidDescriptor;
 }
 
 bool PipePosix::CanWrite() const {
+  std::lock_guard guard(m_lock);
+  return CanWriteUnlocked();
+}
+
+bool PipePosix::CanWriteUnlocked() const {
   return m_fds[WRITE] != PipePosix::kInvalidDescriptor;
 }
 
 void PipePosix::CloseReadFileDescriptor() {
-  if (CanRead()) {
+  std::lock_guard guard(m_lock);
+  CloseReadFileDescriptorUnlocked();
+}
+void Pi

[Lldb-commits] [PATCH] D157760: [lldb] Properly protect the Communication class with reader/writer lock

2023-08-11 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: JDevlieghere, bulbazord.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

This patch picks up where https://reviews.llvm.org/D157159 left of, but
allows for concurrent reads/writes, but protects setting up and tearing
down the underlying Connection object.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157760

Files:
  lldb/include/lldb/Core/Communication.h
  lldb/include/lldb/Core/ThreadedCommunication.h
  lldb/source/Core/Communication.cpp
  lldb/source/Core/ThreadedCommunication.cpp
  lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp

Index: lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
===
--- lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -557,7 +557,6 @@
 }
   }
   StopAsyncThread();
-  m_comm.Clear();
 
   SetPrivateState(eStateDetached);
   ResumePrivateStateThread();
Index: lldb/source/Core/ThreadedCommunication.cpp
===
--- lldb/source/Core/ThreadedCommunication.cpp
+++ lldb/source/Core/ThreadedCommunication.cpp
@@ -61,11 +61,6 @@
this, GetBroadcasterName());
 }
 
-void ThreadedCommunication::Clear() {
-  SetReadThreadBytesReceivedCallback(nullptr, nullptr);
-  StopReadThread(nullptr);
-  Communication::Clear();
-}
 
 ConnectionStatus ThreadedCommunication::Disconnect(Status *error_ptr) {
   assert((!m_read_thread_enabled || m_read_thread_did_exit) &&
@@ -77,6 +72,7 @@
const Timeout &timeout,
ConnectionStatus &status,
Status *error_ptr) {
+  std::shared_lock guard(m_connection_mutex);
   Log *log = GetLog(LLDBLog::Communication);
   LLDB_LOG(
   log,
@@ -152,7 +148,7 @@
 
   // We aren't using a read thread, just read the data synchronously in this
   // thread.
-  return Communication::Read(dst, dst_len, timeout, status, error_ptr);
+  return Communication::ReadUnlocked(dst, dst_len, timeout, status, error_ptr);
 }
 
 bool ThreadedCommunication::StartReadThread(Status *error_ptr) {
@@ -273,46 +269,50 @@
   ConnectionStatus status = eConnectionStatusSuccess;
   bool done = false;
   bool disconnect = false;
-  while (!done && m_read_thread_enabled) {
-size_t bytes_read = ReadFromConnection(
-buf, sizeof(buf), std::chrono::seconds(5), status, &error);
-if (bytes_read > 0 || status == eConnectionStatusEndOfFile)
-  AppendBytesToCache(buf, bytes_read, true, status);
-
-switch (status) {
-case eConnectionStatusSuccess:
-  break;
-
-case eConnectionStatusEndOfFile:
-  done = true;
-  disconnect = GetCloseOnEOF();
-  break;
-case eConnectionStatusError: // Check GetError() for details
-  if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) {
-// EIO on a pipe is usually caused by remote shutdown
+
+  {
+std::shared_lock guard(m_connection_mutex);
+while (!done && m_read_thread_enabled) {
+  size_t bytes_read = ReadUnlocked(buf, sizeof(buf),
+   std::chrono::seconds(5), status, &error);
+  if (bytes_read > 0 || status == eConnectionStatusEndOfFile)
+AppendBytesToCache(buf, bytes_read, true, status);
+
+  switch (status) {
+  case eConnectionStatusSuccess:
+break;
+
+  case eConnectionStatusEndOfFile:
+done = true;
 disconnect = GetCloseOnEOF();
+break;
+  case eConnectionStatusError: // Check GetError() for details
+if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) {
+  // EIO on a pipe is usually caused by remote shutdown
+  disconnect = GetCloseOnEOF();
+  done = true;
+}
+if (error.Fail())
+  LLDB_LOG(log, "error: {0}, status = {1}", error,
+   ThreadedCommunication::ConnectionStatusAsString(status));
+break;
+  case eConnectionStatusInterrupted: // Synchronization signal from
+ // SynchronizeWithReadThread()
+// The connection returns eConnectionStatusInterrupted only when there
+// is no input pending to be read, so we can signal that.
+BroadcastEvent(eBroadcastBitNoMorePendingInput);
+break;
+  case eConnectionStatusNoConnection:   // No connection
+  case eConnectionStatusLostConnection: // Lost connection while connected
+// to a valid connection
 done = true;
+[[fallthrough]];
+  case eConnectionStatusTimedOut: // Request timed out
+if (error.Fail())
+  LLDB_LOG(log, "error: {0}, status = {1}", error,
+   ThreadedCommuni

[Lldb-commits] [PATCH] D157654: [lldb] Fix data race in PipePosix

2023-08-11 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 549539.
augusto2112 added a comment.

Update to two shared mutexes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157654/new/

https://reviews.llvm.org/D157654

Files:
  lldb/include/lldb/Host/posix/PipePosix.h
  lldb/source/Host/posix/PipePosix.cpp

Index: lldb/source/Host/posix/PipePosix.cpp
===
--- lldb/source/Host/posix/PipePosix.cpp
+++ lldb/source/Host/posix/PipePosix.cpp
@@ -65,16 +65,21 @@
 pipe_posix.ReleaseWriteFileDescriptor()} {}
 
 PipePosix &PipePosix::operator=(PipePosix &&pipe_posix) {
+  std::scoped_lock guard(m_read_mutex, m_write_mutex, pipe_posix.m_read_mutex,
+ pipe_posix.m_write_mutex);
+
   PipeBase::operator=(std::move(pipe_posix));
-  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptor();
-  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptor();
+  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptorUnlocked();
+  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptorUnlocked();
   return *this;
 }
 
 PipePosix::~PipePosix() { Close(); }
 
 Status PipePosix::CreateNew(bool child_processes_inherit) {
-  if (CanRead() || CanWrite())
+  // Lock both mutexes in exclusive mode.
+  std::scoped_lock guard(m_read_mutex, m_write_mutex);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status(EINVAL, eErrorTypePOSIX);
 
   Status error;
@@ -87,7 +92,7 @@
 if (!child_processes_inherit) {
   if (!SetCloexecFlag(m_fds[0]) || !SetCloexecFlag(m_fds[1])) {
 error.SetErrorToErrno();
-Close();
+CloseUnlocked();
 return error;
   }
 }
@@ -103,7 +108,11 @@
 }
 
 Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  // Lock both mutexes in shared mode.
+  std::shared_lock read_guard(m_read_mutex, std::defer_lock);
+  std::shared_lock write_guard(m_write_mutex, std::defer_lock);
+  std::lock(read_guard, write_guard);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   Status error;
@@ -140,7 +149,13 @@
 
 Status PipePosix::OpenAsReader(llvm::StringRef name,
bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  // Lock read mutex in exclusive mode and write mutex in shared mode, since we
+  // only write the read file descriptor.
+  std::unique_lock read_guard(m_read_mutex, std::defer_lock);
+  std::shared_lock write_guard(m_write_mutex, std::defer_lock);
+  std::lock(read_guard, write_guard);
+
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   int flags = O_RDONLY | O_NONBLOCK;
@@ -161,7 +176,8 @@
 PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
bool child_process_inherit,
const std::chrono::microseconds &timeout) {
-  if (CanRead() || CanWrite())
+  std::unique_lock guard(m_write_mutex);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   int flags = O_WRONLY | O_NONBLOCK;
@@ -171,7 +187,7 @@
   using namespace std::chrono;
   const auto finish_time = Now() + timeout;
 
-  while (!CanWrite()) {
+  while (!CanWriteUnlocked()) {
 if (timeout != microseconds::zero()) {
   const auto dur = duration_cast(finish_time - Now()).count();
   if (dur <= 0)
@@ -196,25 +212,54 @@
   return Status();
 }
 
-int PipePosix::GetReadFileDescriptor() const { return m_fds[READ]; }
+int PipePosix::GetReadFileDescriptor() const {
+  std::shared_lock guad(m_read_mutex);
+  return GetReadFileDescriptorUnlocked();
+}
+
+int PipePosix::GetReadFileDescriptorUnlocked() const {
+  return m_fds[READ];
+}
 
-int PipePosix::GetWriteFileDescriptor() const { return m_fds[WRITE]; }
+int PipePosix::GetWriteFileDescriptor() const {
+  std::shared_lock guard(m_write_mutex);
+  return GetWriteFileDescriptorUnlocked();
+}
+
+int PipePosix::GetWriteFileDescriptorUnlocked() const {
+  return m_fds[WRITE];
+}
 
 int PipePosix::ReleaseReadFileDescriptor() {
+  std::unique_lock guard(m_read_mutex);
+  return ReleaseReadFileDescriptorUnlocked();
+}
+
+int PipePosix::ReleaseReadFileDescriptorUnlocked() {
   const int fd = m_fds[READ];
   m_fds[READ] = PipePosix::kInvalidDescriptor;
   return fd;
 }
 
 int PipePosix::ReleaseWriteFileDescriptor() {
+  std::unique_lock guard(m_write_mutex);
+  return ReleaseWriteFileDescriptorUnlocked();
+}
+
+int PipePosix::ReleaseWriteFileDescriptorUnlocked() {
   const int fd = m_fds[WRITE];
   m_fds[WRITE] = PipePosix::kInvalidDescriptor;
   return fd;
 }
 
 void PipePosix::Close() {
-  CloseReadFileDescriptor();
-  CloseWriteFileDescriptor();
+  std::scoped_lock guard(m_read_mutex, m_write_mutex);
+  CloseUnlocked();
+}
+
+void PipePosix::CloseUnlocked() {
+  CloseReadFileDescriptorUnlocked();
+  CloseWriteFileDescriptorUnlocked();
 }
 
 St

[Lldb-commits] [PATCH] D157654: [lldb] Fix data race in PipePosix

2023-08-11 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

@JDevlieghere I updated this to two shared mutexes because I'm assuming you can 
have more than one concurrent read and more than one concurrent write. If this 
is wrong I can go back to two regular mutexes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157654/new/

https://reviews.llvm.org/D157654

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157654: [lldb] Fix data race in PipePosix

2023-08-11 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 549548.
augusto2112 added a comment.

Changed to regular mutex


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157654/new/

https://reviews.llvm.org/D157654

Files:
  lldb/include/lldb/Host/posix/PipePosix.h
  lldb/source/Host/posix/PipePosix.cpp

Index: lldb/source/Host/posix/PipePosix.cpp
===
--- lldb/source/Host/posix/PipePosix.cpp
+++ lldb/source/Host/posix/PipePosix.cpp
@@ -65,16 +65,20 @@
 pipe_posix.ReleaseWriteFileDescriptor()} {}
 
 PipePosix &PipePosix::operator=(PipePosix &&pipe_posix) {
+  std::scoped_lock guard(m_read_mutex, m_write_mutex, pipe_posix.m_read_mutex,
+ pipe_posix.m_write_mutex);
+
   PipeBase::operator=(std::move(pipe_posix));
-  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptor();
-  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptor();
+  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptorUnlocked();
+  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptorUnlocked();
   return *this;
 }
 
 PipePosix::~PipePosix() { Close(); }
 
 Status PipePosix::CreateNew(bool child_processes_inherit) {
-  if (CanRead() || CanWrite())
+  std::scoped_lock guard(m_read_mutex, m_write_mutex);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status(EINVAL, eErrorTypePOSIX);
 
   Status error;
@@ -87,7 +91,7 @@
 if (!child_processes_inherit) {
   if (!SetCloexecFlag(m_fds[0]) || !SetCloexecFlag(m_fds[1])) {
 error.SetErrorToErrno();
-Close();
+CloseUnlocked();
 return error;
   }
 }
@@ -103,7 +107,8 @@
 }
 
 Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  std::scoped_lock (m_read_mutex, m_write_mutex);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   Status error;
@@ -140,7 +145,9 @@
 
 Status PipePosix::OpenAsReader(llvm::StringRef name,
bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  std::scoped_lock (m_read_mutex, m_write_mutex);
+
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   int flags = O_RDONLY | O_NONBLOCK;
@@ -161,7 +168,8 @@
 PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
bool child_process_inherit,
const std::chrono::microseconds &timeout) {
-  if (CanRead() || CanWrite())
+  std::lock_guard guard(m_write_mutex);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   int flags = O_WRONLY | O_NONBLOCK;
@@ -171,7 +179,7 @@
   using namespace std::chrono;
   const auto finish_time = Now() + timeout;
 
-  while (!CanWrite()) {
+  while (!CanWriteUnlocked()) {
 if (timeout != microseconds::zero()) {
   const auto dur = duration_cast(finish_time - Now()).count();
   if (dur <= 0)
@@ -196,25 +204,54 @@
   return Status();
 }
 
-int PipePosix::GetReadFileDescriptor() const { return m_fds[READ]; }
+int PipePosix::GetReadFileDescriptor() const {
+  std::lock_guard guard(m_read_mutex);
+  return GetReadFileDescriptorUnlocked();
+}
+
+int PipePosix::GetReadFileDescriptorUnlocked() const {
+  return m_fds[READ];
+}
 
-int PipePosix::GetWriteFileDescriptor() const { return m_fds[WRITE]; }
+int PipePosix::GetWriteFileDescriptor() const {
+  std::lock_guard guard(m_write_mutex);
+  return GetWriteFileDescriptorUnlocked();
+}
+
+int PipePosix::GetWriteFileDescriptorUnlocked() const {
+  return m_fds[WRITE];
+}
 
 int PipePosix::ReleaseReadFileDescriptor() {
+  std::lock_guard guard(m_read_mutex);
+  return ReleaseReadFileDescriptorUnlocked();
+}
+
+int PipePosix::ReleaseReadFileDescriptorUnlocked() {
   const int fd = m_fds[READ];
   m_fds[READ] = PipePosix::kInvalidDescriptor;
   return fd;
 }
 
 int PipePosix::ReleaseWriteFileDescriptor() {
+  std::lock_guard guard(m_write_mutex);
+  return ReleaseWriteFileDescriptorUnlocked();
+}
+
+int PipePosix::ReleaseWriteFileDescriptorUnlocked() {
   const int fd = m_fds[WRITE];
   m_fds[WRITE] = PipePosix::kInvalidDescriptor;
   return fd;
 }
 
 void PipePosix::Close() {
-  CloseReadFileDescriptor();
-  CloseWriteFileDescriptor();
+  std::scoped_lock guard(m_read_mutex, m_write_mutex);
+  CloseUnlocked();
+}
+
+void PipePosix::CloseUnlocked() {
+  CloseReadFileDescriptorUnlocked();
+  CloseWriteFileDescriptorUnlocked();
 }
 
 Status PipePosix::Delete(llvm::StringRef name) {
@@ -222,22 +259,41 @@
 }
 
 bool PipePosix::CanRead() const {
+  std::lock_guard guard(m_read_mutex);
+  return CanReadUnlocked();
+}
+
+bool PipePosix::CanReadUnlocked() const {
   return m_fds[READ] != PipePosix::kInvalidDescriptor;
 }
 
 bool PipePosix::CanWrite() const {
+  std::lock_guard guard(m_write_mutex);
+  return CanWriteUnlocked();
+}
+
+bool PipePosix::CanWriteUnlocked() const {
   ret

[Lldb-commits] [PATCH] D157760: [lldb] Properly protect the Communication class with reader/writer lock

2023-08-14 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added inline comments.



Comment at: lldb/include/lldb/Core/Communication.h:86-89
+  lldb_private::Connection *GetConnection() {
+std::shared_lock guard(m_connection_mutex);
+return m_connection_sp.get();
+  }

bulbazord wrote:
> This isn't necessarily introduced by your patch, but I don't think this lock 
> does much other than make sure nobody can change `m_connection_sp` in between 
> you calling `GetConnection` and you actually receiving the `Connection` 
> pointer. It still comes with all the pitfalls of handing out a raw pointer 
> (instead of a `shared_ptr`).
> 
> As a follow-up or maybe even precursor, we should probably stop handing out 
> the raw connection pointer...
I agree. I think we should do it after this patch though.



Comment at: lldb/include/lldb/Core/Communication.h:172-174
   std::mutex
   m_write_mutex; ///< Don't let multiple threads write at the same time...
+  mutable std::shared_mutex m_connection_mutex;

JDevlieghere wrote:
> Why do we need both? Can't we use `m_connection_mutex` in write mode instead 
> of `m_write_mutex`?
If we use `m_connection_mutex` in write mode instead of m_write_mutex then we 
can't have concurrent reads and writes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157760/new/

https://reviews.llvm.org/D157760

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157654: [lldb] Fix data race in PipePosix

2023-08-15 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG22413641e236: [lldb] Fix data race in PipePosix (authored by 
augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157654/new/

https://reviews.llvm.org/D157654

Files:
  lldb/include/lldb/Host/posix/PipePosix.h
  lldb/source/Host/posix/PipePosix.cpp

Index: lldb/source/Host/posix/PipePosix.cpp
===
--- lldb/source/Host/posix/PipePosix.cpp
+++ lldb/source/Host/posix/PipePosix.cpp
@@ -65,16 +65,20 @@
 pipe_posix.ReleaseWriteFileDescriptor()} {}
 
 PipePosix &PipePosix::operator=(PipePosix &&pipe_posix) {
+  std::scoped_lock guard(m_read_mutex, m_write_mutex, pipe_posix.m_read_mutex,
+ pipe_posix.m_write_mutex);
+
   PipeBase::operator=(std::move(pipe_posix));
-  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptor();
-  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptor();
+  m_fds[READ] = pipe_posix.ReleaseReadFileDescriptorUnlocked();
+  m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptorUnlocked();
   return *this;
 }
 
 PipePosix::~PipePosix() { Close(); }
 
 Status PipePosix::CreateNew(bool child_processes_inherit) {
-  if (CanRead() || CanWrite())
+  std::scoped_lock guard(m_read_mutex, m_write_mutex);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status(EINVAL, eErrorTypePOSIX);
 
   Status error;
@@ -87,7 +91,7 @@
 if (!child_processes_inherit) {
   if (!SetCloexecFlag(m_fds[0]) || !SetCloexecFlag(m_fds[1])) {
 error.SetErrorToErrno();
-Close();
+CloseUnlocked();
 return error;
   }
 }
@@ -103,7 +107,8 @@
 }
 
 Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  std::scoped_lock (m_read_mutex, m_write_mutex);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   Status error;
@@ -140,7 +145,9 @@
 
 Status PipePosix::OpenAsReader(llvm::StringRef name,
bool child_process_inherit) {
-  if (CanRead() || CanWrite())
+  std::scoped_lock (m_read_mutex, m_write_mutex);
+
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   int flags = O_RDONLY | O_NONBLOCK;
@@ -161,7 +168,8 @@
 PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
bool child_process_inherit,
const std::chrono::microseconds &timeout) {
-  if (CanRead() || CanWrite())
+  std::lock_guard guard(m_write_mutex);
+  if (CanReadUnlocked() || CanWriteUnlocked())
 return Status("Pipe is already opened");
 
   int flags = O_WRONLY | O_NONBLOCK;
@@ -171,7 +179,7 @@
   using namespace std::chrono;
   const auto finish_time = Now() + timeout;
 
-  while (!CanWrite()) {
+  while (!CanWriteUnlocked()) {
 if (timeout != microseconds::zero()) {
   const auto dur = duration_cast(finish_time - Now()).count();
   if (dur <= 0)
@@ -196,25 +204,54 @@
   return Status();
 }
 
-int PipePosix::GetReadFileDescriptor() const { return m_fds[READ]; }
+int PipePosix::GetReadFileDescriptor() const {
+  std::lock_guard guard(m_read_mutex);
+  return GetReadFileDescriptorUnlocked();
+}
+
+int PipePosix::GetReadFileDescriptorUnlocked() const {
+  return m_fds[READ];
+}
 
-int PipePosix::GetWriteFileDescriptor() const { return m_fds[WRITE]; }
+int PipePosix::GetWriteFileDescriptor() const {
+  std::lock_guard guard(m_write_mutex);
+  return GetWriteFileDescriptorUnlocked();
+}
+
+int PipePosix::GetWriteFileDescriptorUnlocked() const {
+  return m_fds[WRITE];
+}
 
 int PipePosix::ReleaseReadFileDescriptor() {
+  std::lock_guard guard(m_read_mutex);
+  return ReleaseReadFileDescriptorUnlocked();
+}
+
+int PipePosix::ReleaseReadFileDescriptorUnlocked() {
   const int fd = m_fds[READ];
   m_fds[READ] = PipePosix::kInvalidDescriptor;
   return fd;
 }
 
 int PipePosix::ReleaseWriteFileDescriptor() {
+  std::lock_guard guard(m_write_mutex);
+  return ReleaseWriteFileDescriptorUnlocked();
+}
+
+int PipePosix::ReleaseWriteFileDescriptorUnlocked() {
   const int fd = m_fds[WRITE];
   m_fds[WRITE] = PipePosix::kInvalidDescriptor;
   return fd;
 }
 
 void PipePosix::Close() {
-  CloseReadFileDescriptor();
-  CloseWriteFileDescriptor();
+  std::scoped_lock guard(m_read_mutex, m_write_mutex);
+  CloseUnlocked();
+}
+
+void PipePosix::CloseUnlocked() {
+  CloseReadFileDescriptorUnlocked();
+  CloseWriteFileDescriptorUnlocked();
 }
 
 Status PipePosix::Delete(llvm::StringRef name) {
@@ -222,22 +259,41 @@
 }
 
 bool PipePosix::CanRead() const {
+  std::lock_guard guard(m_read_mutex);
+  return CanReadUnlocked();
+}
+
+bool PipePosix::CanReadUnlocked() const {
   return m_fds[READ] != PipePosix::kInvalidDescriptor;
 }
 
 bool PipePosix::CanWrite() const {
+  std::lock_guard guard(m_write_mutex);
+  return CanWriteUnlo

[Lldb-commits] [PATCH] D157648: [lldb] Fix data race in Process

2023-08-15 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

@JDevlieghere do you have any opinions on this?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157648/new/

https://reviews.llvm.org/D157648

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D157760: [lldb] Properly protect the Communication class with reader/writer lock

2023-08-15 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5d16957207ce: [lldb] Properly protect the Communication 
class with reader/writer lock (authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157760/new/

https://reviews.llvm.org/D157760

Files:
  lldb/include/lldb/Core/Communication.h
  lldb/include/lldb/Core/ThreadedCommunication.h
  lldb/source/Core/Communication.cpp
  lldb/source/Core/ThreadedCommunication.cpp
  lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp

Index: lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
===
--- lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -557,7 +557,6 @@
 }
   }
   StopAsyncThread();
-  m_comm.Clear();
 
   SetPrivateState(eStateDetached);
   ResumePrivateStateThread();
Index: lldb/source/Core/ThreadedCommunication.cpp
===
--- lldb/source/Core/ThreadedCommunication.cpp
+++ lldb/source/Core/ThreadedCommunication.cpp
@@ -61,11 +61,6 @@
this, GetBroadcasterName());
 }
 
-void ThreadedCommunication::Clear() {
-  SetReadThreadBytesReceivedCallback(nullptr, nullptr);
-  StopReadThread(nullptr);
-  Communication::Clear();
-}
 
 ConnectionStatus ThreadedCommunication::Disconnect(Status *error_ptr) {
   assert((!m_read_thread_enabled || m_read_thread_did_exit) &&
@@ -77,6 +72,7 @@
const Timeout &timeout,
ConnectionStatus &status,
Status *error_ptr) {
+  std::shared_lock guard(m_connection_mutex);
   Log *log = GetLog(LLDBLog::Communication);
   LLDB_LOG(
   log,
@@ -152,7 +148,7 @@
 
   // We aren't using a read thread, just read the data synchronously in this
   // thread.
-  return Communication::Read(dst, dst_len, timeout, status, error_ptr);
+  return Communication::ReadUnlocked(dst, dst_len, timeout, status, error_ptr);
 }
 
 bool ThreadedCommunication::StartReadThread(Status *error_ptr) {
@@ -273,46 +269,50 @@
   ConnectionStatus status = eConnectionStatusSuccess;
   bool done = false;
   bool disconnect = false;
-  while (!done && m_read_thread_enabled) {
-size_t bytes_read = ReadFromConnection(
-buf, sizeof(buf), std::chrono::seconds(5), status, &error);
-if (bytes_read > 0 || status == eConnectionStatusEndOfFile)
-  AppendBytesToCache(buf, bytes_read, true, status);
-
-switch (status) {
-case eConnectionStatusSuccess:
-  break;
-
-case eConnectionStatusEndOfFile:
-  done = true;
-  disconnect = GetCloseOnEOF();
-  break;
-case eConnectionStatusError: // Check GetError() for details
-  if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) {
-// EIO on a pipe is usually caused by remote shutdown
+
+  {
+std::shared_lock guard(m_connection_mutex);
+while (!done && m_read_thread_enabled) {
+  size_t bytes_read = ReadUnlocked(buf, sizeof(buf),
+   std::chrono::seconds(5), status, &error);
+  if (bytes_read > 0 || status == eConnectionStatusEndOfFile)
+AppendBytesToCache(buf, bytes_read, true, status);
+
+  switch (status) {
+  case eConnectionStatusSuccess:
+break;
+
+  case eConnectionStatusEndOfFile:
+done = true;
 disconnect = GetCloseOnEOF();
+break;
+  case eConnectionStatusError: // Check GetError() for details
+if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) {
+  // EIO on a pipe is usually caused by remote shutdown
+  disconnect = GetCloseOnEOF();
+  done = true;
+}
+if (error.Fail())
+  LLDB_LOG(log, "error: {0}, status = {1}", error,
+   ThreadedCommunication::ConnectionStatusAsString(status));
+break;
+  case eConnectionStatusInterrupted: // Synchronization signal from
+ // SynchronizeWithReadThread()
+// The connection returns eConnectionStatusInterrupted only when there
+// is no input pending to be read, so we can signal that.
+BroadcastEvent(eBroadcastBitNoMorePendingInput);
+break;
+  case eConnectionStatusNoConnection:   // No connection
+  case eConnectionStatusLostConnection: // Lost connection while connected
+// to a valid connection
 done = true;
+[[fallthrough]];
+  case eConnectionStatusTimedOut: // Request timed out
+if (error.Fail())
+  LLDB_LOG(log, "error: {0}, status = {1}", error,
+   ThreadedCommunication::ConnectionStatusAsString(status));
+break;
 

[Lldb-commits] [PATCH] D158034: [lldb] Fix data race in ThreadList

2023-08-15 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
Herald added a subscriber: kristof.beyls.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

ThreadSanitizer reports the following issue:

  Write of size 8 at 0x00010a70abb0 by thread T3 (mutexes: write M0):
#0 lldb_private::ThreadList::Update(lldb_private::ThreadList&) 
ThreadList.cpp:741 (liblldb.18.0.0git.dylib:arm64+0x5dedf4) (BuildId: 
9bced2aafa373580ae9d750d9cf79a8f320021000e00)
#1 lldb_private::Process::UpdateThreadListIfNeeded() Process.cpp:1212 
(liblldb.18.0.0git.dylib:arm64+0x53bbec) (BuildId: 
9bced2aafa373580ae9d750d9cf79a8f320021000e00)
  
  Previous read of size 8 at 0x00010a70abb0 by main thread (mutexes: write M1):
#0 lldb_private::ThreadList::GetMutex() const ThreadList.cpp:785 
(liblldb.18.0.0git.dylib:arm64+0x5df138) (BuildId: 
9bced2aafa373580ae9d750d9cf79a8f320021000e00)
#1 lldb_private::ThreadList::DidResume() ThreadList.cpp:656 
(liblldb.18.0.0git.dylib:arm64+0x5de5c0) (BuildId: 
9bced2aafa373580ae9d750d9cf79a8f320021000e00)
#2 lldb_private::Process::PrivateResume() Process.cpp:3130 
(liblldb.18.0.0git.dylib:arm64+0x53cd7c) (BuildId: 
9bced2aafa373580ae9d750d9cf79a8f320021000e00)

Fix this by only using the mutex in ThreadList and removing the one in
process entirely.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158034

Files:
  lldb/include/lldb/Target/Process.h
  lldb/include/lldb/Target/ThreadCollection.h
  lldb/include/lldb/Target/ThreadList.h
  lldb/source/Target/Process.cpp
  lldb/source/Target/ThreadList.cpp


Index: lldb/source/Target/ThreadList.cpp
===
--- lldb/source/Target/ThreadList.cpp
+++ lldb/source/Target/ThreadList.cpp
@@ -736,7 +736,8 @@
   if (this != &rhs) {
 // Lock both mutexes to make sure neither side changes anyone on us while
 // the assignment occurs
-std::scoped_lock 
guard(GetMutex(), rhs.GetMutex());
+std::scoped_lock guard(
+GetMutex(), rhs.GetMutex());
 
 m_process = rhs.m_process;
 m_stop_id = rhs.m_stop_id;
@@ -781,10 +782,6 @@
 (*pos)->Flush();
 }
 
-std::recursive_mutex &ThreadList::GetMutex() const {
-  return m_process->m_thread_mutex;
-}
-
 ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher(
 lldb::ThreadSP thread_sp)
 : m_thread_list(nullptr), m_tid(LLDB_INVALID_THREAD_ID) {
Index: lldb/source/Target/Process.cpp
===
--- lldb/source/Target/Process.cpp
+++ lldb/source/Target/Process.cpp
@@ -435,7 +435,7 @@
   Listener::MakeListener("lldb.process.internal_state_listener")),
   m_mod_id(), m_process_unique_id(0), m_thread_index_id(0),
   m_thread_id_to_index_id_map(), m_exit_status(-1), m_exit_string(),
-  m_exit_status_mutex(), m_thread_mutex(), m_thread_list_real(this),
+  m_exit_status_mutex(), m_thread_list_real(this),
   m_thread_list(this), m_thread_plans(*this), m_extended_thread_list(this),
   m_extended_thread_stop_id(0), m_queue_list(this), 
m_queue_list_stop_id(0),
   m_notifications(), m_image_tokens(), m_listener_sp(listener_sp),
@@ -2457,7 +2457,7 @@
 }
 
 void Process::LoadOperatingSystemPlugin(bool flush) {
-  std::lock_guard guard(m_thread_mutex);
+  std::lock_guard guard(GetThreadList().GetMutex());
   if (flush)
 m_thread_list.Clear();
   m_os_up.reset(OperatingSystem::FindPlugin(this, nullptr));
Index: lldb/include/lldb/Target/ThreadList.h
===
--- lldb/include/lldb/Target/ThreadList.h
+++ lldb/include/lldb/Target/ThreadList.h
@@ -133,8 +133,6 @@
 
   void SetStopID(uint32_t stop_id);
 
-  std::recursive_mutex &GetMutex() const override;
-
   void Update(ThreadList &rhs);
 
 protected:
Index: lldb/include/lldb/Target/ThreadCollection.h
===
--- lldb/include/lldb/Target/ThreadCollection.h
+++ lldb/include/lldb/Target/ThreadCollection.h
@@ -47,7 +47,7 @@
 return ThreadIterable(m_threads, GetMutex());
   }
 
-  virtual std::recursive_mutex &GetMutex() const { return m_mutex; }
+  std::recursive_mutex &GetMutex() const { return m_mutex; }
 
 protected:
   collection m_threads;
Index: lldb/include/lldb/Target/Process.h
===
--- lldb/include/lldb/Target/Process.h
+++ lldb/include/lldb/Target/Process.h
@@ -2957,7 +2957,6 @@
   std::string m_exit_string; ///< A textual description of why a process 
exited.
   std::mutex m_exit_status_mutex; ///< Mutex so m_exit_status m_exit_string can
   ///be safely accessed from multiple threads
-  std::recursive_mutex m_thread_mutex;
   ThreadList m_thread_list_real; ///< T

[Lldb-commits] [PATCH] D158035: [lldb] Protect RNBRemote from a data race

2023-08-15 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: JDevlieghere, bulbazord, jingham.
Herald added a subscriber: kristof.beyls.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Thread sanitizer reports the following data race:

  Write of size 8 at 0x000103303e70 by thread T1 (mutexes: write M0):
#0 RNBRemote::CommDataReceived(std::__1::basic_string, std::__1::allocator> const&) 
RNBRemote.cpp:1075 (debugserver:arm64+0x100038db8) (BuildId: 
f130b34f693c4f3eba96139104af2b71320021000e00)
#1 RNBRemote::ThreadFunctionReadRemoteData(void*) RNBRemote.cpp:1180 
(debugserver:arm64+0x1000391dc) (BuildId: 
f130b34f693c4f3eba96139104af2b71320021000e00)
  
  Previous read of size 8 at 0x000103303e70 by main thread:
#0 RNBRemote::GetPacketPayload(std::__1::basic_string, std::__1::allocator>&) RNBRemote.cpp:797 
(debugserver:arm64+0x100037c5c) (BuildId: 
f130b34f693c4f3eba96139104af2b71320021000e00)
#1 RNBRemote::GetPacket(std::__1::basic_string, std::__1::allocator>&, RNBRemote::Packet&, 
bool) RNBRemote.cpp:907 (debugserver:arm64+0x1000378cc) (BuildId: 
f130b34f693c4f3eba96139104af2b71320021000e00)

RNBRemote already has a mutex, extend its usage to protect the read of
m_rx_packets.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158035

Files:
  lldb/tools/debugserver/source/RNBRemote.cpp


Index: lldb/tools/debugserver/source/RNBRemote.cpp
===
--- lldb/tools/debugserver/source/RNBRemote.cpp
+++ lldb/tools/debugserver/source/RNBRemote.cpp
@@ -792,12 +792,12 @@
   // m_rx_packets.size());
   return_packet.swap(m_rx_packets.front());
   m_rx_packets.pop_front();
-  locker.Reset(); // Release our lock on the mutex
 
   if (m_rx_packets.empty()) {
 // Reset the remote command available event if we have no more packets
 m_ctx.Events().ResetEvents(RNBContext::event_read_packet_available);
   }
+  locker.Reset(); // Release our lock on the mutex
 
   // DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s: '%s'",
   // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__,


Index: lldb/tools/debugserver/source/RNBRemote.cpp
===
--- lldb/tools/debugserver/source/RNBRemote.cpp
+++ lldb/tools/debugserver/source/RNBRemote.cpp
@@ -792,12 +792,12 @@
   // m_rx_packets.size());
   return_packet.swap(m_rx_packets.front());
   m_rx_packets.pop_front();
-  locker.Reset(); // Release our lock on the mutex
 
   if (m_rx_packets.empty()) {
 // Reset the remote command available event if we have no more packets
 m_ctx.Events().ResetEvents(RNBContext::event_read_packet_available);
   }
+  locker.Reset(); // Release our lock on the mutex
 
   // DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s: '%s'",
   // (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__,
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D158034: [lldb] Fix data race in ThreadList

2023-08-18 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbb9006324970: [lldb] Fix data race in ThreadList (authored 
by augusto2112).

Changed prior to commit:
  https://reviews.llvm.org/D158034?vs=550519&id=551673#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158034/new/

https://reviews.llvm.org/D158034

Files:
  lldb/include/lldb/Target/Process.h
  lldb/include/lldb/Target/ThreadCollection.h
  lldb/include/lldb/Target/ThreadList.h
  lldb/source/Target/Process.cpp
  lldb/source/Target/ThreadList.cpp


Index: lldb/source/Target/ThreadList.cpp
===
--- lldb/source/Target/ThreadList.cpp
+++ lldb/source/Target/ThreadList.cpp
@@ -736,7 +736,8 @@
   if (this != &rhs) {
 // Lock both mutexes to make sure neither side changes anyone on us while
 // the assignment occurs
-std::scoped_lock 
guard(GetMutex(), rhs.GetMutex());
+std::scoped_lock guard(
+GetMutex(), rhs.GetMutex());
 
 m_process = rhs.m_process;
 m_stop_id = rhs.m_stop_id;
@@ -781,10 +782,6 @@
 (*pos)->Flush();
 }
 
-std::recursive_mutex &ThreadList::GetMutex() const {
-  return m_process->m_thread_mutex;
-}
-
 ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher(
 lldb::ThreadSP thread_sp)
 : m_thread_list(nullptr), m_tid(LLDB_INVALID_THREAD_ID) {
Index: lldb/source/Target/Process.cpp
===
--- lldb/source/Target/Process.cpp
+++ lldb/source/Target/Process.cpp
@@ -435,7 +435,7 @@
   Listener::MakeListener("lldb.process.internal_state_listener")),
   m_mod_id(), m_process_unique_id(0), m_thread_index_id(0),
   m_thread_id_to_index_id_map(), m_exit_status(-1), m_exit_string(),
-  m_exit_status_mutex(), m_thread_mutex(), m_thread_list_real(this),
+  m_exit_status_mutex(), m_thread_list_real(this),
   m_thread_list(this), m_thread_plans(*this), m_extended_thread_list(this),
   m_extended_thread_stop_id(0), m_queue_list(this), 
m_queue_list_stop_id(0),
   m_notifications(), m_image_tokens(),
@@ -2456,7 +2456,7 @@
 }
 
 void Process::LoadOperatingSystemPlugin(bool flush) {
-  std::lock_guard guard(m_thread_mutex);
+  std::lock_guard guard(GetThreadList().GetMutex());
   if (flush)
 m_thread_list.Clear();
   m_os_up.reset(OperatingSystem::FindPlugin(this, nullptr));
Index: lldb/include/lldb/Target/ThreadList.h
===
--- lldb/include/lldb/Target/ThreadList.h
+++ lldb/include/lldb/Target/ThreadList.h
@@ -133,8 +133,6 @@
 
   void SetStopID(uint32_t stop_id);
 
-  std::recursive_mutex &GetMutex() const override;
-
   void Update(ThreadList &rhs);
 
 protected:
Index: lldb/include/lldb/Target/ThreadCollection.h
===
--- lldb/include/lldb/Target/ThreadCollection.h
+++ lldb/include/lldb/Target/ThreadCollection.h
@@ -47,7 +47,7 @@
 return ThreadIterable(m_threads, GetMutex());
   }
 
-  virtual std::recursive_mutex &GetMutex() const { return m_mutex; }
+  std::recursive_mutex &GetMutex() const { return m_mutex; }
 
 protected:
   collection m_threads;
Index: lldb/include/lldb/Target/Process.h
===
--- lldb/include/lldb/Target/Process.h
+++ lldb/include/lldb/Target/Process.h
@@ -2970,7 +2970,6 @@
   std::string m_exit_string; ///< A textual description of why a process 
exited.
   std::mutex m_exit_status_mutex; ///< Mutex so m_exit_status m_exit_string can
   ///be safely accessed from multiple threads
-  std::recursive_mutex m_thread_mutex;
   ThreadList m_thread_list_real; ///< The threads for this process as are known
  ///to the protocol we are debugging with
   ThreadList m_thread_list; ///< The threads for this process as the user will


Index: lldb/source/Target/ThreadList.cpp
===
--- lldb/source/Target/ThreadList.cpp
+++ lldb/source/Target/ThreadList.cpp
@@ -736,7 +736,8 @@
   if (this != &rhs) {
 // Lock both mutexes to make sure neither side changes anyone on us while
 // the assignment occurs
-std::scoped_lock guard(GetMutex(), rhs.GetMutex());
+std::scoped_lock guard(
+GetMutex(), rhs.GetMutex());
 
 m_process = rhs.m_process;
 m_stop_id = rhs.m_stop_id;
@@ -781,10 +782,6 @@
 (*pos)->Flush();
 }
 
-std::recursive_mutex &ThreadList::GetMutex() const {
-  return m_process->m_thread_mutex;
-}
-
 ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher(
 lldb::ThreadSP thread_sp)
 : m_thread_list(nullptr), m_tid(LLDB_INVALID_THREAD_ID) {
Index: lldb/source/Target/Process.cpp
===
--- lldb/source/Target/P

[Lldb-commits] [PATCH] D157648: [lldb] Fix data race in Process

2023-08-18 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG79a8e006dbc4: [lldb] Fix data race in Process (authored by 
augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157648/new/

https://reviews.llvm.org/D157648

Files:
  lldb/include/lldb/Target/Process.h
  lldb/source/Target/Process.cpp

Index: lldb/source/Target/Process.cpp
===
--- lldb/source/Target/Process.cpp
+++ lldb/source/Target/Process.cpp
@@ -629,6 +629,7 @@
 const Timeout &timeout) {
   // don't sync (potentially context switch) in case where there is no process
   // IO
+  std::lock_guard guard(m_process_input_reader_mutex);
   if (!m_process_input_reader)
 return;
 
@@ -2504,7 +2505,11 @@
   m_jit_loaders_up.reset();
   m_system_runtime_up.reset();
   m_os_up.reset();
-  m_process_input_reader.reset();
+
+  {
+std::lock_guard guard(m_process_input_reader_mutex);
+m_process_input_reader.reset();
+  }
 
   Module *exe_module = GetTarget().GetExecutableModulePointer();
 
@@ -2802,7 +2807,10 @@
 
 Status Process::Attach(ProcessAttachInfo &attach_info) {
   m_abi_sp.reset();
-  m_process_input_reader.reset();
+  {
+std::lock_guard guard(m_process_input_reader_mutex);
+m_process_input_reader.reset();
+  }
   m_dyld_up.reset();
   m_jit_loaders_up.reset();
   m_system_runtime_up.reset();
@@ -3053,7 +3061,10 @@
 
 Status Process::ConnectRemote(llvm::StringRef remote_url) {
   m_abi_sp.reset();
-  m_process_input_reader.reset();
+  {
+std::lock_guard guard(m_process_input_reader_mutex);
+m_process_input_reader.reset();
+  }
 
   // Find the process and its architecture.  Make sure it matches the
   // architecture of the current Target, and if not adjust it.
@@ -3341,10 +3352,13 @@
 m_stdio_communication.Disconnect();
 m_stdin_forward = false;
 
-if (m_process_input_reader) {
-  m_process_input_reader->SetIsDone(true);
-  m_process_input_reader->Cancel();
-  m_process_input_reader.reset();
+{
+  std::lock_guard guard(m_process_input_reader_mutex);
+  if (m_process_input_reader) {
+m_process_input_reader->SetIsDone(true);
+m_process_input_reader->Cancel();
+m_process_input_reader.reset();
+  }
 }
 
 // If we exited when we were waiting for a process to stop, then forward
@@ -4522,20 +4536,25 @@
 m_stdio_communication.StartReadThread();
 
 // Now read thread is set up, set up input reader.
-
-if (!m_process_input_reader)
-  m_process_input_reader =
-  std::make_shared(this, fd);
+{
+  std::lock_guard guard(m_process_input_reader_mutex);
+  if (!m_process_input_reader)
+m_process_input_reader =
+std::make_shared(this, fd);
+}
   }
 }
 
 bool Process::ProcessIOHandlerIsActive() {
+  std::lock_guard guard(m_process_input_reader_mutex);
   IOHandlerSP io_handler_sp(m_process_input_reader);
   if (io_handler_sp)
 return GetTarget().GetDebugger().IsTopIOHandler(io_handler_sp);
   return false;
 }
+
 bool Process::PushProcessIOHandler() {
+  std::lock_guard guard(m_process_input_reader_mutex);
   IOHandlerSP io_handler_sp(m_process_input_reader);
   if (io_handler_sp) {
 Log *log = GetLog(LLDBLog::Process);
@@ -4555,6 +4574,7 @@
 }
 
 bool Process::PopProcessIOHandler() {
+  std::lock_guard guard(m_process_input_reader_mutex);
   IOHandlerSP io_handler_sp(m_process_input_reader);
   if (io_handler_sp)
 return GetTarget().GetDebugger().RemoveIOHandler(io_handler_sp);
Index: lldb/include/lldb/Target/Process.h
===
--- lldb/include/lldb/Target/Process.h
+++ lldb/include/lldb/Target/Process.h
@@ -3007,6 +3007,7 @@
   m_unix_signals_sp; /// This is the current signal set for this process.
   lldb::ABISP m_abi_sp;
   lldb::IOHandlerSP m_process_input_reader;
+  mutable std::mutex m_process_input_reader_mutex;
   ThreadedCommunication m_stdio_communication;
   std::recursive_mutex m_stdio_communication_mutex;
   bool m_stdin_forward; /// Remember if stdin must be forwarded to remote debug
@@ -3132,6 +3133,7 @@
   bool ProcessIOHandlerIsActive();
 
   bool ProcessIOHandlerExists() const {
+std::lock_guard guard(m_process_input_reader_mutex);
 return static_cast(m_process_input_reader);
   }
 
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D115723: [lldb] Fix ABIMacOSX_arm64::PrepareTrivialCall logging

2021-12-14 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
Herald added subscribers: pengfei, kristof.beyls.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Make the logging message print ABIMacOSX_arm64 instead of ABISysV_x86_64.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115723

Files:
  lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp


Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
===
--- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -86,7 +86,7 @@
   eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
 
   // x0 - x7 contain first 8 simple args
-  if (args.size() > 8) // TODO handle more than 8 arguments
+  if (args.size() > 8) // TODO handle more than 6 arguments
 return false;
 
   for (size_t i = 0; i < args.size(); ++i) {
@@ -402,7 +402,7 @@
 // volatile (and specifically only the lower 8 bytes of these regs), the rest
 // of the fp/SIMD registers are volatile.
 //
-// v. https://github.com/ARM-software/abi-aa/blob/main/aapcs64/
+// v. https://github.com/ARM-software/abi-aa/blob/master/aapcs64/
 
 // We treat x29 as callee preserved also, else the unwinder won't try to
 // retrieve fp saves.
@@ -817,16 +817,6 @@
 
 lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
   lldb::addr_t pac_sign_extension = 0x0080ULL;
-  // Darwin systems originally couldn't determine the proper value
-  // dynamically, so the most common value was hardcoded.  This has
-  // largely been cleaned up, but there are still a handful of
-  // environments that assume the default value is set to this value
-  // and there's no dynamic value to correct it.
-  // When no mask is specified, set it to 39 bits of addressing (0..38).
-  if (mask == 0) {
-// ~((1ULL<<39)-1)
-mask = 0xff80;
-  }
   return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
 }
 
@@ -838,3 +828,12 @@
 void ABIMacOSX_arm64::Terminate() {
   PluginManager::UnregisterPlugin(CreateInstance);
 }
+
+// PluginInterface protocol
+
+ConstString ABIMacOSX_arm64::GetPluginNameStatic() {
+  static ConstString g_plugin_name("ABIMacOSX_arm64");
+  return g_plugin_name;
+}
+
+uint32_t ABIMacOSX_arm64::GetPluginVersion() { return 1; }


Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
===
--- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -86,7 +86,7 @@
   eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
 
   // x0 - x7 contain first 8 simple args
-  if (args.size() > 8) // TODO handle more than 8 arguments
+  if (args.size() > 8) // TODO handle more than 6 arguments
 return false;
 
   for (size_t i = 0; i < args.size(); ++i) {
@@ -402,7 +402,7 @@
 // volatile (and specifically only the lower 8 bytes of these regs), the rest
 // of the fp/SIMD registers are volatile.
 //
-// v. https://github.com/ARM-software/abi-aa/blob/main/aapcs64/
+// v. https://github.com/ARM-software/abi-aa/blob/master/aapcs64/
 
 // We treat x29 as callee preserved also, else the unwinder won't try to
 // retrieve fp saves.
@@ -817,16 +817,6 @@
 
 lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
   lldb::addr_t pac_sign_extension = 0x0080ULL;
-  // Darwin systems originally couldn't determine the proper value
-  // dynamically, so the most common value was hardcoded.  This has
-  // largely been cleaned up, but there are still a handful of
-  // environments that assume the default value is set to this value
-  // and there's no dynamic value to correct it.
-  // When no mask is specified, set it to 39 bits of addressing (0..38).
-  if (mask == 0) {
-// ~((1ULL<<39)-1)
-mask = 0xff80;
-  }
   return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
 }
 
@@ -838,3 +828,12 @@
 void ABIMacOSX_arm64::Terminate() {
   PluginManager::UnregisterPlugin(CreateInstance);
 }
+
+// PluginInterface protocol
+
+ConstString ABIMacOSX_arm64::GetPluginNameStatic() {
+  static ConstString g_plugin_name("ABIMacOSX_arm64");
+  return g_plugin_name;
+}
+
+uint32_t ABIMacOSX_arm64::GetPluginVersion() { return 1; }
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D115723: [lldb] Fix ABIMacOSX_arm64::PrepareTrivialCall logging

2021-12-14 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 abandoned this revision.
augusto2112 added a comment.

Looks like this was already fixed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115723/new/

https://reviews.llvm.org/D115723

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D116491: [lldb] Compute fully qualified command names in FindCommandsForApropos

2022-01-05 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 accepted this revision.
augusto2112 added a comment.
This revision is now accepted and ready to land.

I liked the small cleanups in the code as well!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116491/new/

https://reviews.llvm.org/D116491

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D118265: [lldb] Make ReadCStringFromMemory default to read from the file-cache.

2022-01-26 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: jasonmolenda, aprantl.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D118265

Files:
  lldb/include/lldb/Target/Target.h
  lldb/source/Target/Target.cpp


Index: lldb/source/Target/Target.cpp
===
--- lldb/source/Target/Target.cpp
+++ lldb/source/Target/Target.cpp
@@ -1829,13 +1829,14 @@
 }
 
 size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,
- Status &error) {
+ Status &error, bool force_live_memory) {
   char buf[256];
   out_str.clear();
   addr_t curr_addr = addr.GetLoadAddress(this);
   Address address(addr);
   while (true) {
-size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error);
+size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error,
+  force_live_memory);
 if (length == 0)
   break;
 out_str.append(buf, length);
@@ -1851,7 +1852,8 @@
 }
 
 size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
- size_t dst_max_len, Status &result_error) 
{
+ size_t dst_max_len, Status &result_error,
+ bool force_live_memory) {
   size_t total_cstr_len = 0;
   if (dst && dst_max_len) {
 result_error.Clear();
@@ -1874,8 +1876,8 @@
   cache_line_size - (curr_addr % cache_line_size);
   addr_t bytes_to_read =
   std::min(bytes_left, cache_line_bytes_left);
-  size_t bytes_read =
-  ReadMemory(address, curr_dst, bytes_to_read, error, true);
+  size_t bytes_read = ReadMemory(address, curr_dst, bytes_to_read, error,
+ force_live_memory);
 
   if (bytes_read == 0) {
 result_error = error;
Index: lldb/include/lldb/Target/Target.h
===
--- lldb/include/lldb/Target/Target.h
+++ lldb/include/lldb/Target/Target.h
@@ -1019,10 +1019,11 @@
 lldb::addr_t *load_addr_ptr = nullptr);
 
   size_t ReadCStringFromMemory(const Address &addr, std::string &out_str,
-   Status &error);
+   Status &error, bool force_live_memory = false);
 
   size_t ReadCStringFromMemory(const Address &addr, char *dst,
-   size_t dst_max_len, Status &result_error);
+   size_t dst_max_len, Status &result_error,
+   bool force_live_memory = false);
 
   /// Read a NULL terminated string from memory
   ///


Index: lldb/source/Target/Target.cpp
===
--- lldb/source/Target/Target.cpp
+++ lldb/source/Target/Target.cpp
@@ -1829,13 +1829,14 @@
 }
 
 size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,
- Status &error) {
+ Status &error, bool force_live_memory) {
   char buf[256];
   out_str.clear();
   addr_t curr_addr = addr.GetLoadAddress(this);
   Address address(addr);
   while (true) {
-size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error);
+size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error,
+  force_live_memory);
 if (length == 0)
   break;
 out_str.append(buf, length);
@@ -1851,7 +1852,8 @@
 }
 
 size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
- size_t dst_max_len, Status &result_error) {
+ size_t dst_max_len, Status &result_error,
+ bool force_live_memory) {
   size_t total_cstr_len = 0;
   if (dst && dst_max_len) {
 result_error.Clear();
@@ -1874,8 +1876,8 @@
   cache_line_size - (curr_addr % cache_line_size);
   addr_t bytes_to_read =
   std::min(bytes_left, cache_line_bytes_left);
-  size_t bytes_read =
-  ReadMemory(address, curr_dst, bytes_to_read, error, true);
+  size_t bytes_read = ReadMemory(address, curr_dst, bytes_to_read, error,
+ force_live_memory);
 
   if (bytes_read == 0) {
 result_error = error;
Index: lldb/include/lldb/Target/Target.h
===
--- lldb/include/lldb/Target/Target.h
+++ lldb/include/lldb/Target/Target.h
@@ -1019,10 +1019,11 @@
 lldb::addr_t *load_addr_ptr = nullptr);
 
   size_t ReadCStringFromMemory(const Address &addr, std::string &out_str,
-   Status &error);
+   

[Lldb-commits] [PATCH] D118265: [lldb] Make ReadCStringFromMemory default to read from the file-cache.

2022-01-28 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb414954a5f1c: [lldb] Make ReadCStringFromMemory default to 
read from the file-cache. (authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D118265/new/

https://reviews.llvm.org/D118265

Files:
  lldb/include/lldb/Target/Target.h
  lldb/source/Target/Target.cpp


Index: lldb/source/Target/Target.cpp
===
--- lldb/source/Target/Target.cpp
+++ lldb/source/Target/Target.cpp
@@ -1829,13 +1829,14 @@
 }
 
 size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,
- Status &error) {
+ Status &error, bool force_live_memory) {
   char buf[256];
   out_str.clear();
   addr_t curr_addr = addr.GetLoadAddress(this);
   Address address(addr);
   while (true) {
-size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error);
+size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error,
+  force_live_memory);
 if (length == 0)
   break;
 out_str.append(buf, length);
@@ -1851,7 +1852,8 @@
 }
 
 size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
- size_t dst_max_len, Status &result_error) 
{
+ size_t dst_max_len, Status &result_error,
+ bool force_live_memory) {
   size_t total_cstr_len = 0;
   if (dst && dst_max_len) {
 result_error.Clear();
@@ -1874,8 +1876,8 @@
   cache_line_size - (curr_addr % cache_line_size);
   addr_t bytes_to_read =
   std::min(bytes_left, cache_line_bytes_left);
-  size_t bytes_read =
-  ReadMemory(address, curr_dst, bytes_to_read, error, true);
+  size_t bytes_read = ReadMemory(address, curr_dst, bytes_to_read, error,
+ force_live_memory);
 
   if (bytes_read == 0) {
 result_error = error;
Index: lldb/include/lldb/Target/Target.h
===
--- lldb/include/lldb/Target/Target.h
+++ lldb/include/lldb/Target/Target.h
@@ -1019,10 +1019,11 @@
 lldb::addr_t *load_addr_ptr = nullptr);
 
   size_t ReadCStringFromMemory(const Address &addr, std::string &out_str,
-   Status &error);
+   Status &error, bool force_live_memory = false);
 
   size_t ReadCStringFromMemory(const Address &addr, char *dst,
-   size_t dst_max_len, Status &result_error);
+   size_t dst_max_len, Status &result_error,
+   bool force_live_memory = false);
 
   /// Read a NULL terminated string from memory
   ///


Index: lldb/source/Target/Target.cpp
===
--- lldb/source/Target/Target.cpp
+++ lldb/source/Target/Target.cpp
@@ -1829,13 +1829,14 @@
 }
 
 size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,
- Status &error) {
+ Status &error, bool force_live_memory) {
   char buf[256];
   out_str.clear();
   addr_t curr_addr = addr.GetLoadAddress(this);
   Address address(addr);
   while (true) {
-size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error);
+size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error,
+  force_live_memory);
 if (length == 0)
   break;
 out_str.append(buf, length);
@@ -1851,7 +1852,8 @@
 }
 
 size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
- size_t dst_max_len, Status &result_error) {
+ size_t dst_max_len, Status &result_error,
+ bool force_live_memory) {
   size_t total_cstr_len = 0;
   if (dst && dst_max_len) {
 result_error.Clear();
@@ -1874,8 +1876,8 @@
   cache_line_size - (curr_addr % cache_line_size);
   addr_t bytes_to_read =
   std::min(bytes_left, cache_line_bytes_left);
-  size_t bytes_read =
-  ReadMemory(address, curr_dst, bytes_to_read, error, true);
+  size_t bytes_read = ReadMemory(address, curr_dst, bytes_to_read, error,
+ force_live_memory);
 
   if (bytes_read == 0) {
 result_error = error;
Index: lldb/include/lldb/Target/Target.h
===
--- lldb/include/lldb/Target/Target.h
+++ lldb/include/lldb/Target/Target.h
@@ -1019,10 +1019,11 @@
 lldb::addr_t *load_addr_ptr = nullptr);
 
   size_t ReadCStringFromMemory(const Address &addr, std::string &o

[Lldb-commits] [PATCH] D118494: [lldb] Observe SG_READ_ONLY flag in MachO binaries

2022-01-28 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 requested changes to this revision.
augusto2112 added inline comments.
This revision now requires changes to proceed.



Comment at: lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp:1436
 result |= ePermissionsReadable;
-  if (seg_cmd.initprot & VM_PROT_WRITE)
+  if ((seg_cmd.initprot & VM_PROT_WRITE) && !(seg_cmd.flags & SG_READ_ONLY))
 result |= ePermissionsWritable;

Could we add a new value in the enumeration? Something like 
ePermissionsLinkerWritable? As it is right now this would be dangerous for the 
existing file-cache optimization as we'd happily read pointers that are 
supposed to be fixed by the linker from the file-cache.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D118494/new/

https://reviews.llvm.org/D118494

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D120578: [lldb] Implement ObjectFile::GetCStrFromSection

2022-02-25 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: aprantl, JDevlieghere.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D120578

Files:
  lldb/include/lldb/Symbol/ObjectFile.h
  lldb/source/Symbol/ObjectFile.cpp


Index: lldb/source/Symbol/ObjectFile.cpp
===
--- lldb/source/Symbol/ObjectFile.cpp
+++ lldb/source/Symbol/ObjectFile.cpp
@@ -553,6 +553,13 @@
   section_data);
 }
 
+const char *
+ObjectFile::GetCStrFromSection(Section *section,
+   lldb::offset_t section_offset) const {
+  offset_t offset = section->GetOffset() + section_offset;
+  return m_data.GetCStr(&offset);
+}
+
 bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object,
 FileSpec &archive_file,
 ConstString &archive_object,
Index: lldb/include/lldb/Symbol/ObjectFile.h
===
--- lldb/include/lldb/Symbol/ObjectFile.h
+++ lldb/include/lldb/Symbol/ObjectFile.h
@@ -673,6 +673,9 @@
   virtual size_t ReadSectionData(Section *section,
  DataExtractor §ion_data);
 
+  const char *GetCStrFromSection(Section *section,
+ lldb::offset_t section_offset) const;
+
   bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
 
   // Strip linker annotations (such as @@VERSION) from symbol names.


Index: lldb/source/Symbol/ObjectFile.cpp
===
--- lldb/source/Symbol/ObjectFile.cpp
+++ lldb/source/Symbol/ObjectFile.cpp
@@ -553,6 +553,13 @@
   section_data);
 }
 
+const char *
+ObjectFile::GetCStrFromSection(Section *section,
+   lldb::offset_t section_offset) const {
+  offset_t offset = section->GetOffset() + section_offset;
+  return m_data.GetCStr(&offset);
+}
+
 bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object,
 FileSpec &archive_file,
 ConstString &archive_object,
Index: lldb/include/lldb/Symbol/ObjectFile.h
===
--- lldb/include/lldb/Symbol/ObjectFile.h
+++ lldb/include/lldb/Symbol/ObjectFile.h
@@ -673,6 +673,9 @@
   virtual size_t ReadSectionData(Section *section,
  DataExtractor §ion_data);
 
+  const char *GetCStrFromSection(Section *section,
+ lldb::offset_t section_offset) const;
+
   bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
 
   // Strip linker annotations (such as @@VERSION) from symbol names.
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D120578: [lldb] Implement ObjectFile::GetCStrFromSection

2022-02-25 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added inline comments.



Comment at: lldb/include/lldb/Symbol/ObjectFile.h:677
+  const char *GetCStrFromSection(Section *section,
+ lldb::offset_t section_offset) const;
+

aprantl wrote:
> Should we call it `GetCStringFromSection`, or even better 
> `ReadCStringFromSection`?
I agree that `ReadCStringFromSection` sounds better.



Comment at: lldb/source/Symbol/ObjectFile.cpp:558
+ObjectFile::GetCStrFromSection(Section *section,
+   lldb::offset_t section_offset) const {
+  offset_t offset = section->GetOffset() + section_offset;

aprantl wrote:
> The fact that it's a C string seems to be not relevant to the function. It 
> seems to just convert a file address to a load address?
What do you mean? This function calls `m_data.GetCStr` and returns the result.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D120578/new/

https://reviews.llvm.org/D120578

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D129319: [lldb] Add comments to describe m_memory_addr and IsInMemory

2022-07-07 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added a reviewer: jasonmolenda.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129319

Files:
  lldb/include/lldb/Symbol/ObjectFile.h


Index: lldb/include/lldb/Symbol/ObjectFile.h
===
--- lldb/include/lldb/Symbol/ObjectFile.h
+++ lldb/include/lldb/Symbol/ObjectFile.h
@@ -673,6 +673,7 @@
   virtual size_t ReadSectionData(Section *section,
  DataExtractor §ion_data);
 
+  /// Returns true if the object file exists only in memory.
   bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
 
   // Strip linker annotations (such as @@VERSION) from symbol names.
@@ -736,6 +737,7 @@
   DataExtractor
   m_data; ///< The data for this object file so things can be parsed 
lazily.
   lldb::ProcessWP m_process_wp;
+  /// Set if the object file only exists in memory.
   const lldb::addr_t m_memory_addr;
   std::unique_ptr m_sections_up;
   std::unique_ptr m_symtab_up;


Index: lldb/include/lldb/Symbol/ObjectFile.h
===
--- lldb/include/lldb/Symbol/ObjectFile.h
+++ lldb/include/lldb/Symbol/ObjectFile.h
@@ -673,6 +673,7 @@
   virtual size_t ReadSectionData(Section *section,
  DataExtractor §ion_data);
 
+  /// Returns true if the object file exists only in memory.
   bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
 
   // Strip linker annotations (such as @@VERSION) from symbol names.
@@ -736,6 +737,7 @@
   DataExtractor
   m_data; ///< The data for this object file so things can be parsed lazily.
   lldb::ProcessWP m_process_wp;
+  /// Set if the object file only exists in memory.
   const lldb::addr_t m_memory_addr;
   std::unique_ptr m_sections_up;
   std::unique_ptr m_symtab_up;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D129319: [lldb] Add comments to describe m_memory_addr and IsInMemory

2022-07-07 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5ade38c28573: [lldb] Add comments to describe m_memory_addr 
and IsInMemory (authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D129319/new/

https://reviews.llvm.org/D129319

Files:
  lldb/include/lldb/Symbol/ObjectFile.h


Index: lldb/include/lldb/Symbol/ObjectFile.h
===
--- lldb/include/lldb/Symbol/ObjectFile.h
+++ lldb/include/lldb/Symbol/ObjectFile.h
@@ -673,6 +673,7 @@
   virtual size_t ReadSectionData(Section *section,
  DataExtractor §ion_data);
 
+  /// Returns true if the object file exists only in memory.
   bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
 
   // Strip linker annotations (such as @@VERSION) from symbol names.
@@ -736,6 +737,7 @@
   DataExtractor
   m_data; ///< The data for this object file so things can be parsed 
lazily.
   lldb::ProcessWP m_process_wp;
+  /// Set if the object file only exists in memory.
   const lldb::addr_t m_memory_addr;
   std::unique_ptr m_sections_up;
   std::unique_ptr m_symtab_up;


Index: lldb/include/lldb/Symbol/ObjectFile.h
===
--- lldb/include/lldb/Symbol/ObjectFile.h
+++ lldb/include/lldb/Symbol/ObjectFile.h
@@ -673,6 +673,7 @@
   virtual size_t ReadSectionData(Section *section,
  DataExtractor §ion_data);
 
+  /// Returns true if the object file exists only in memory.
   bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
 
   // Strip linker annotations (such as @@VERSION) from symbol names.
@@ -736,6 +737,7 @@
   DataExtractor
   m_data; ///< The data for this object file so things can be parsed lazily.
   lldb::ProcessWP m_process_wp;
+  /// Set if the object file only exists in memory.
   const lldb::addr_t m_memory_addr;
   std::unique_ptr m_sections_up;
   std::unique_ptr m_symtab_up;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D130803: [lldb] Allow SymbolTable regex search functions to match mangled name

2022-07-29 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: jingham, labath, aprantl.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

It may be useful to search symbol table entries by mangled instead
of demangled names. Add this optional functionality in the SymbolTable
functions.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130803

Files:
  lldb/include/lldb/Core/Module.h
  lldb/include/lldb/Symbol/Symtab.h
  lldb/source/Core/Module.cpp
  lldb/source/Symbol/Symtab.cpp

Index: lldb/source/Symbol/Symtab.cpp
===
--- lldb/source/Symbol/Symtab.cpp
+++ lldb/source/Symbol/Symtab.cpp
@@ -744,7 +744,7 @@
 
 uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
 const RegularExpression ®exp, SymbolType symbol_type,
-std::vector &indexes) {
+std::vector &indexes, bool match_against_demangled) {
   std::lock_guard guard(m_mutex);
 
   uint32_t prev_size = indexes.size();
@@ -753,7 +753,10 @@
   for (uint32_t i = 0; i < sym_end; i++) {
 if (symbol_type == eSymbolTypeAny ||
 m_symbols[i].GetType() == symbol_type) {
-  const char *name = m_symbols[i].GetName().AsCString();
+  const char *name =
+  match_against_demangled
+  ? m_symbols[i].GetMangled().GetMangledName().AsCString()
+  : m_symbols[i].GetName().AsCString();
   if (name) {
 if (regexp.Execute(name))
   indexes.push_back(i);
@@ -766,7 +769,7 @@
 uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
 const RegularExpression ®exp, SymbolType symbol_type,
 Debug symbol_debug_type, Visibility symbol_visibility,
-std::vector &indexes) {
+std::vector &indexes, bool match_against_demangled) {
   std::lock_guard guard(m_mutex);
 
   uint32_t prev_size = indexes.size();
@@ -778,7 +781,10 @@
   if (!CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
 continue;
 
-  const char *name = m_symbols[i].GetName().AsCString();
+  const char *name =
+  match_against_demangled
+  ? m_symbols[i].GetMangled().GetMangledName().AsCString()
+  : m_symbols[i].GetName().AsCString();
   if (name) {
 if (regexp.Execute(name))
   indexes.push_back(i);
@@ -847,11 +853,12 @@
 void Symtab::FindAllSymbolsMatchingRexExAndType(
 const RegularExpression ®ex, SymbolType symbol_type,
 Debug symbol_debug_type, Visibility symbol_visibility,
-std::vector &symbol_indexes) {
+std::vector &symbol_indexes, bool match_against_demangled) {
   std::lock_guard guard(m_mutex);
 
   AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type,
-  symbol_visibility, symbol_indexes);
+  symbol_visibility, symbol_indexes,
+  match_against_demangled);
 }
 
 Symbol *Symtab::FindFirstSymbolWithNameAndType(ConstString name,
Index: lldb/source/Core/Module.cpp
===
--- lldb/source/Core/Module.cpp
+++ lldb/source/Core/Module.cpp
@@ -1369,7 +1369,8 @@
 
 void Module::FindSymbolsMatchingRegExAndType(const RegularExpression ®ex,
  SymbolType symbol_type,
- SymbolContextList &sc_list) {
+ SymbolContextList &sc_list,
+ bool match_against_demangled) {
   // No need to protect this call using m_mutex all other method calls are
   // already thread safe.
   LLDB_SCOPED_TIMERF(
@@ -1379,7 +1380,7 @@
 std::vector symbol_indexes;
 symtab->FindAllSymbolsMatchingRexExAndType(
 regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
-symbol_indexes);
+symbol_indexes, match_against_demangled);
 SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
   }
 }
Index: lldb/include/lldb/Symbol/Symtab.h
===
--- lldb/include/lldb/Symbol/Symtab.h
+++ lldb/include/lldb/Symbol/Symtab.h
@@ -89,14 +89,13 @@
   Debug symbol_debug_type,
   Visibility symbol_visibility,
   std::vector &matches);
-  uint32_t
-  AppendSymbolIndexesMatchingRegExAndType(const RegularExpression ®ex,
-  lldb::SymbolType symbol_type,
-  std::vector &indexes);
+  uint32_t AppendSymbolIndexesMatchingRegExAndType(
+  const RegularExpression ®ex, lldb::SymbolType symbol_type,
+  std::vector &indexes, bool match_against_demangled = false);
   uint32_t AppendSymbolIndexesMatchingRegExAndTy

[Lldb-commits] [PATCH] D130803: [lldb] Allow SymbolTable regex search functions to match mangled name

2022-07-29 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

@aprantl do you mean dumping this with `lldb-test`?  I'm not seeing a way to do 
this. If you're thinking about `symbols` that reads the symbol file not the 
symbol table.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130803/new/

https://reviews.llvm.org/D130803

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D130803: [lldb] Allow SymbolTable regex search functions to match mangled name

2022-08-01 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D130803#3690754 , @labath wrote:

> Who sets this flag? How do you intend to use it?

I need this change downstream to search for certain swift mangled names by 
querying `Module::FindSymbolsMatchingRegExAndType`. It seemed general enough 
that we might want this upstream.




Comment at: lldb/include/lldb/Core/Module.h:267
+   SymbolContextList &sc_list,
+   bool match_against_demangled = false);
 

labath wrote:
> Could this be `Mangled::NamePreference` instead of `bool` ?
Ok! Wasn't aware of that enum. I'll change that.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130803/new/

https://reviews.llvm.org/D130803

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D130803: [lldb] Allow SymbolTable regex search functions to match mangled name

2022-08-02 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 449440.
augusto2112 added a comment.

Added test and updated functions to use Mangled::NamePreference instead of a 
bool


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130803/new/

https://reviews.llvm.org/D130803

Files:
  lldb/include/lldb/Core/Module.h
  lldb/include/lldb/Symbol/Symtab.h
  lldb/source/Core/Module.cpp
  lldb/source/Symbol/Symtab.cpp
  lldb/test/Shell/Symtab/Inputs/t.yaml
  lldb/test/Shell/Symtab/symtab-regex-demangled.test
  lldb/test/Shell/Symtab/symtab-regex-mangled.test
  lldb/tools/lldb-test/lldb-test.cpp

Index: lldb/tools/lldb-test/lldb-test.cpp
===
--- lldb/tools/lldb-test/lldb-test.cpp
+++ lldb/tools/lldb-test/lldb-test.cpp
@@ -22,6 +22,7 @@
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/Symtab.h"
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Symbol/VariableList.h"
@@ -57,6 +58,8 @@
 cl::SubCommand ObjectFileSubcommand("object-file",
 "Display LLDB object file information");
 cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
+cl::SubCommand SymTabSubcommand("symtab",
+"Test symbol table functionality");
 cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");
 cl::SubCommand AssertSubcommand("assert", "Test assert handling");
 
@@ -64,6 +67,7 @@
  cl::sub(BreakpointSubcommand),
  cl::sub(ObjectFileSubcommand),
  cl::sub(SymbolsSubcommand),
+ cl::sub(SymTabSubcommand),
  cl::sub(IRMemoryMapSubcommand));
 
 /// Create a target using the file pointed to by \p Filename, or abort.
@@ -102,6 +106,48 @@
  cl::sub(ObjectFileSubcommand));
 } // namespace object
 
+namespace symtab {
+
+/// The same enum as Mangled::NamePreference but with a default
+/// 'None' case. This is needed to disambiguate wheter "ManglingPreference" was
+/// explicitly set or not.
+enum class ManglingPreference {
+  None,
+  Mangled,
+  Demangled,
+  MangledWithoutArguments,
+};
+
+static cl::opt FindSymbolsByRegex(
+"find-symbols-by-regex",
+cl::desc(
+"Dump symbols found in the symbol table matching the specified regex."),
+cl::sub(SymTabSubcommand));
+
+static cl::opt ManglingPreference(
+"mangling-preference",
+cl::desc("Preference on mangling scheme the regex should match against and "
+ "dumped."),
+cl::values(
+clEnumValN(ManglingPreference::Mangled, "mangled", "Prefer mangled"),
+clEnumValN(ManglingPreference::Demangled, "demangled",
+   "Prefer demangled"),
+clEnumValN(ManglingPreference::MangledWithoutArguments,
+   "demangled-without-args", "Prefer mangled without args")),
+cl::sub(SymTabSubcommand));
+
+static cl::opt InputFile(cl::Positional, cl::desc(""),
+  cl::Required, cl::sub(SymTabSubcommand));
+
+/// Validate that the options passed make sense.
+static llvm::Optional validate();
+
+/// Transforms the selected mangling preference into a Mangled::NamePreference
+static Mangled::NamePreference getNamePreference();
+
+static int handleSymtabCommand(Debugger &Dbg);
+} // namespace symtab
+
 namespace symbols {
 static cl::opt InputFile(cl::Positional, cl::desc(""),
   cl::Required, cl::sub(SymbolsSubcommand));
@@ -814,6 +860,56 @@
   llvm_unreachable("Unsupported symbol action.");
 }
 
+llvm::Optional opts::symtab::validate() {
+  if (ManglingPreference != ManglingPreference::None &&
+  FindSymbolsByRegex.empty())
+return make_string_error("Mangling preference set but no regex specified.");
+
+  return {};
+}
+
+static Mangled::NamePreference opts::symtab::getNamePreference() {
+  switch (ManglingPreference) {
+  case ManglingPreference::None:
+  case ManglingPreference::Mangled:
+return Mangled::ePreferMangled;
+  case ManglingPreference::Demangled:
+return Mangled::ePreferDemangled;
+  case ManglingPreference::MangledWithoutArguments:
+return Mangled::ePreferDemangledWithoutArguments;
+  }
+}
+
+int opts::symtab::handleSymtabCommand(Debugger &Dbg) {
+  if (auto error = validate()) {
+logAllUnhandledErrors(std::move(error.getValue()), WithColor::error(), "");
+return 1;
+  }
+
+  if (!FindSymbolsByRegex.empty()) {
+ModuleSpec Spec{FileSpec(InputFile)};
+
+auto ModulePtr = std::make_shared(Spec);
+auto *Symtab = ModulePtr->GetSymtab();
+auto NamePreference = getNamePreference();
+std::vector Indexes;
+
+Symtab->FindAllSymbolsMatchingRexExAndType(
+RegularExpression(FindSymbolsByRegex), lldb::eSymbolTypeAny,
+Symtab::e

[Lldb-commits] [PATCH] D130803: [lldb] Allow SymbolTable regex search functions to match mangled name

2022-08-02 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 449483.
augusto2112 added a comment.

Removed __unwind_info and __eh_frame sections from test yaml file.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130803/new/

https://reviews.llvm.org/D130803

Files:
  lldb/include/lldb/Core/Module.h
  lldb/include/lldb/Symbol/Symtab.h
  lldb/source/Core/Module.cpp
  lldb/source/Symbol/Symtab.cpp
  lldb/test/Shell/Symtab/Inputs/t.yaml
  lldb/test/Shell/Symtab/symtab-regex-demangled.test
  lldb/test/Shell/Symtab/symtab-regex-mangled.test
  lldb/tools/lldb-test/lldb-test.cpp

Index: lldb/tools/lldb-test/lldb-test.cpp
===
--- lldb/tools/lldb-test/lldb-test.cpp
+++ lldb/tools/lldb-test/lldb-test.cpp
@@ -22,6 +22,7 @@
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/Symtab.h"
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Symbol/VariableList.h"
@@ -57,6 +58,8 @@
 cl::SubCommand ObjectFileSubcommand("object-file",
 "Display LLDB object file information");
 cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
+cl::SubCommand SymTabSubcommand("symtab",
+"Test symbol table functionality");
 cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");
 cl::SubCommand AssertSubcommand("assert", "Test assert handling");
 
@@ -64,6 +67,7 @@
  cl::sub(BreakpointSubcommand),
  cl::sub(ObjectFileSubcommand),
  cl::sub(SymbolsSubcommand),
+ cl::sub(SymTabSubcommand),
  cl::sub(IRMemoryMapSubcommand));
 
 /// Create a target using the file pointed to by \p Filename, or abort.
@@ -102,6 +106,48 @@
  cl::sub(ObjectFileSubcommand));
 } // namespace object
 
+namespace symtab {
+
+/// The same enum as Mangled::NamePreference but with a default
+/// 'None' case. This is needed to disambiguate wheter "ManglingPreference" was
+/// explicitly set or not.
+enum class ManglingPreference {
+  None,
+  Mangled,
+  Demangled,
+  MangledWithoutArguments,
+};
+
+static cl::opt FindSymbolsByRegex(
+"find-symbols-by-regex",
+cl::desc(
+"Dump symbols found in the symbol table matching the specified regex."),
+cl::sub(SymTabSubcommand));
+
+static cl::opt ManglingPreference(
+"mangling-preference",
+cl::desc("Preference on mangling scheme the regex should match against and "
+ "dumped."),
+cl::values(
+clEnumValN(ManglingPreference::Mangled, "mangled", "Prefer mangled"),
+clEnumValN(ManglingPreference::Demangled, "demangled",
+   "Prefer demangled"),
+clEnumValN(ManglingPreference::MangledWithoutArguments,
+   "demangled-without-args", "Prefer mangled without args")),
+cl::sub(SymTabSubcommand));
+
+static cl::opt InputFile(cl::Positional, cl::desc(""),
+  cl::Required, cl::sub(SymTabSubcommand));
+
+/// Validate that the options passed make sense.
+static llvm::Optional validate();
+
+/// Transforms the selected mangling preference into a Mangled::NamePreference
+static Mangled::NamePreference getNamePreference();
+
+static int handleSymtabCommand(Debugger &Dbg);
+} // namespace symtab
+
 namespace symbols {
 static cl::opt InputFile(cl::Positional, cl::desc(""),
   cl::Required, cl::sub(SymbolsSubcommand));
@@ -814,6 +860,56 @@
   llvm_unreachable("Unsupported symbol action.");
 }
 
+llvm::Optional opts::symtab::validate() {
+  if (ManglingPreference != ManglingPreference::None &&
+  FindSymbolsByRegex.empty())
+return make_string_error("Mangling preference set but no regex specified.");
+
+  return {};
+}
+
+static Mangled::NamePreference opts::symtab::getNamePreference() {
+  switch (ManglingPreference) {
+  case ManglingPreference::None:
+  case ManglingPreference::Mangled:
+return Mangled::ePreferMangled;
+  case ManglingPreference::Demangled:
+return Mangled::ePreferDemangled;
+  case ManglingPreference::MangledWithoutArguments:
+return Mangled::ePreferDemangledWithoutArguments;
+  }
+}
+
+int opts::symtab::handleSymtabCommand(Debugger &Dbg) {
+  if (auto error = validate()) {
+logAllUnhandledErrors(std::move(error.getValue()), WithColor::error(), "");
+return 1;
+  }
+
+  if (!FindSymbolsByRegex.empty()) {
+ModuleSpec Spec{FileSpec(InputFile)};
+
+auto ModulePtr = std::make_shared(Spec);
+auto *Symtab = ModulePtr->GetSymtab();
+auto NamePreference = getNamePreference();
+std::vector Indexes;
+
+Symtab->FindAllSymbolsMatchingRexExAndType(
+RegularExpression(FindSymbolsByRegex), lldb::eSymbolTypeAny,
+Symtab::eDebugAny, Symtab

[Lldb-commits] [PATCH] D130803: [lldb] Allow SymbolTable regex search functions to match mangled name

2022-08-03 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 449712.
augusto2112 added a comment.

Updated test to use elf object file.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130803/new/

https://reviews.llvm.org/D130803

Files:
  lldb/include/lldb/Core/Module.h
  lldb/include/lldb/Symbol/Symtab.h
  lldb/source/Core/Module.cpp
  lldb/source/Symbol/Symtab.cpp
  lldb/test/Shell/Symtab/Inputs/symbols.yaml
  lldb/test/Shell/Symtab/symtab-regex-demangled.test
  lldb/test/Shell/Symtab/symtab-regex-mangled.test
  lldb/tools/lldb-test/lldb-test.cpp

Index: lldb/tools/lldb-test/lldb-test.cpp
===
--- lldb/tools/lldb-test/lldb-test.cpp
+++ lldb/tools/lldb-test/lldb-test.cpp
@@ -22,6 +22,7 @@
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/Symtab.h"
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Symbol/VariableList.h"
@@ -57,6 +58,8 @@
 cl::SubCommand ObjectFileSubcommand("object-file",
 "Display LLDB object file information");
 cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
+cl::SubCommand SymTabSubcommand("symtab",
+"Test symbol table functionality");
 cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");
 cl::SubCommand AssertSubcommand("assert", "Test assert handling");
 
@@ -64,6 +67,7 @@
  cl::sub(BreakpointSubcommand),
  cl::sub(ObjectFileSubcommand),
  cl::sub(SymbolsSubcommand),
+ cl::sub(SymTabSubcommand),
  cl::sub(IRMemoryMapSubcommand));
 
 /// Create a target using the file pointed to by \p Filename, or abort.
@@ -102,6 +106,48 @@
  cl::sub(ObjectFileSubcommand));
 } // namespace object
 
+namespace symtab {
+
+/// The same enum as Mangled::NamePreference but with a default
+/// 'None' case. This is needed to disambiguate wheter "ManglingPreference" was
+/// explicitly set or not.
+enum class ManglingPreference {
+  None,
+  Mangled,
+  Demangled,
+  MangledWithoutArguments,
+};
+
+static cl::opt FindSymbolsByRegex(
+"find-symbols-by-regex",
+cl::desc(
+"Dump symbols found in the symbol table matching the specified regex."),
+cl::sub(SymTabSubcommand));
+
+static cl::opt ManglingPreference(
+"mangling-preference",
+cl::desc("Preference on mangling scheme the regex should match against and "
+ "dumped."),
+cl::values(
+clEnumValN(ManglingPreference::Mangled, "mangled", "Prefer mangled"),
+clEnumValN(ManglingPreference::Demangled, "demangled",
+   "Prefer demangled"),
+clEnumValN(ManglingPreference::MangledWithoutArguments,
+   "demangled-without-args", "Prefer mangled without args")),
+cl::sub(SymTabSubcommand));
+
+static cl::opt InputFile(cl::Positional, cl::desc(""),
+  cl::Required, cl::sub(SymTabSubcommand));
+
+/// Validate that the options passed make sense.
+static llvm::Optional validate();
+
+/// Transforms the selected mangling preference into a Mangled::NamePreference
+static Mangled::NamePreference getNamePreference();
+
+static int handleSymtabCommand(Debugger &Dbg);
+} // namespace symtab
+
 namespace symbols {
 static cl::opt InputFile(cl::Positional, cl::desc(""),
   cl::Required, cl::sub(SymbolsSubcommand));
@@ -814,6 +860,56 @@
   llvm_unreachable("Unsupported symbol action.");
 }
 
+llvm::Optional opts::symtab::validate() {
+  if (ManglingPreference != ManglingPreference::None &&
+  FindSymbolsByRegex.empty())
+return make_string_error("Mangling preference set but no regex specified.");
+
+  return {};
+}
+
+static Mangled::NamePreference opts::symtab::getNamePreference() {
+  switch (ManglingPreference) {
+  case ManglingPreference::None:
+  case ManglingPreference::Mangled:
+return Mangled::ePreferMangled;
+  case ManglingPreference::Demangled:
+return Mangled::ePreferDemangled;
+  case ManglingPreference::MangledWithoutArguments:
+return Mangled::ePreferDemangledWithoutArguments;
+  }
+}
+
+int opts::symtab::handleSymtabCommand(Debugger &Dbg) {
+  if (auto error = validate()) {
+logAllUnhandledErrors(std::move(error.getValue()), WithColor::error(), "");
+return 1;
+  }
+
+  if (!FindSymbolsByRegex.empty()) {
+ModuleSpec Spec{FileSpec(InputFile)};
+
+auto ModulePtr = std::make_shared(Spec);
+auto *Symtab = ModulePtr->GetSymtab();
+auto NamePreference = getNamePreference();
+std::vector Indexes;
+
+Symtab->FindAllSymbolsMatchingRexExAndType(
+RegularExpression(FindSymbolsByRegex), lldb::eSymbolTypeAny,
+Symtab::eDebugAny, Symtab::eVisibilityAny, Indexe

[Lldb-commits] [PATCH] D130803: [lldb] Allow SymbolTable regex search functions to match mangled name

2022-08-03 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG3aef968ec3fa: [lldb] Allow SymbolTable regex search 
functions to match mangled name (authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130803/new/

https://reviews.llvm.org/D130803

Files:
  lldb/include/lldb/Core/Module.h
  lldb/include/lldb/Symbol/Symtab.h
  lldb/source/Core/Module.cpp
  lldb/source/Symbol/Symtab.cpp
  lldb/test/Shell/Symtab/Inputs/symbols.yaml
  lldb/test/Shell/Symtab/symtab-regex-demangled.test
  lldb/test/Shell/Symtab/symtab-regex-mangled.test
  lldb/tools/lldb-test/lldb-test.cpp

Index: lldb/tools/lldb-test/lldb-test.cpp
===
--- lldb/tools/lldb-test/lldb-test.cpp
+++ lldb/tools/lldb-test/lldb-test.cpp
@@ -22,6 +22,7 @@
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/Symtab.h"
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Symbol/VariableList.h"
@@ -57,6 +58,8 @@
 cl::SubCommand ObjectFileSubcommand("object-file",
 "Display LLDB object file information");
 cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
+cl::SubCommand SymTabSubcommand("symtab",
+"Test symbol table functionality");
 cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");
 cl::SubCommand AssertSubcommand("assert", "Test assert handling");
 
@@ -64,6 +67,7 @@
  cl::sub(BreakpointSubcommand),
  cl::sub(ObjectFileSubcommand),
  cl::sub(SymbolsSubcommand),
+ cl::sub(SymTabSubcommand),
  cl::sub(IRMemoryMapSubcommand));
 
 /// Create a target using the file pointed to by \p Filename, or abort.
@@ -102,6 +106,48 @@
  cl::sub(ObjectFileSubcommand));
 } // namespace object
 
+namespace symtab {
+
+/// The same enum as Mangled::NamePreference but with a default
+/// 'None' case. This is needed to disambiguate wheter "ManglingPreference" was
+/// explicitly set or not.
+enum class ManglingPreference {
+  None,
+  Mangled,
+  Demangled,
+  MangledWithoutArguments,
+};
+
+static cl::opt FindSymbolsByRegex(
+"find-symbols-by-regex",
+cl::desc(
+"Dump symbols found in the symbol table matching the specified regex."),
+cl::sub(SymTabSubcommand));
+
+static cl::opt ManglingPreference(
+"mangling-preference",
+cl::desc("Preference on mangling scheme the regex should match against and "
+ "dumped."),
+cl::values(
+clEnumValN(ManglingPreference::Mangled, "mangled", "Prefer mangled"),
+clEnumValN(ManglingPreference::Demangled, "demangled",
+   "Prefer demangled"),
+clEnumValN(ManglingPreference::MangledWithoutArguments,
+   "demangled-without-args", "Prefer mangled without args")),
+cl::sub(SymTabSubcommand));
+
+static cl::opt InputFile(cl::Positional, cl::desc(""),
+  cl::Required, cl::sub(SymTabSubcommand));
+
+/// Validate that the options passed make sense.
+static llvm::Optional validate();
+
+/// Transforms the selected mangling preference into a Mangled::NamePreference
+static Mangled::NamePreference getNamePreference();
+
+static int handleSymtabCommand(Debugger &Dbg);
+} // namespace symtab
+
 namespace symbols {
 static cl::opt InputFile(cl::Positional, cl::desc(""),
   cl::Required, cl::sub(SymbolsSubcommand));
@@ -814,6 +860,56 @@
   llvm_unreachable("Unsupported symbol action.");
 }
 
+llvm::Optional opts::symtab::validate() {
+  if (ManglingPreference != ManglingPreference::None &&
+  FindSymbolsByRegex.empty())
+return make_string_error("Mangling preference set but no regex specified.");
+
+  return {};
+}
+
+static Mangled::NamePreference opts::symtab::getNamePreference() {
+  switch (ManglingPreference) {
+  case ManglingPreference::None:
+  case ManglingPreference::Mangled:
+return Mangled::ePreferMangled;
+  case ManglingPreference::Demangled:
+return Mangled::ePreferDemangled;
+  case ManglingPreference::MangledWithoutArguments:
+return Mangled::ePreferDemangledWithoutArguments;
+  }
+}
+
+int opts::symtab::handleSymtabCommand(Debugger &Dbg) {
+  if (auto error = validate()) {
+logAllUnhandledErrors(std::move(error.getValue()), WithColor::error(), "");
+return 1;
+  }
+
+  if (!FindSymbolsByRegex.empty()) {
+ModuleSpec Spec{FileSpec(InputFile)};
+
+auto ModulePtr = std::make_shared(Spec);
+auto *Symtab = ModulePtr->GetSymtab();
+auto NamePreference = getNamePreference();
+std::vector Indexes;
+
+Symtab->FindAllSymbolsMatchin

[Lldb-commits] [PATCH] D131531: [lldb] Allow DataFileCache to be constructed with a different policy

2022-08-09 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: clayborg, labath, jingham.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131531

Files:
  lldb/include/lldb/Core/DataFileCache.h
  lldb/source/Core/DataFileCache.cpp


Index: lldb/source/Core/DataFileCache.cpp
===
--- lldb/source/Core/DataFileCache.cpp
+++ lldb/source/Core/DataFileCache.cpp
@@ -20,8 +20,6 @@
 using namespace lldb_private;
 
 DataFileCache::DataFileCache(llvm::StringRef path) {
-  m_cache_dir.SetPath(path);
-
   // Prune the cache based off of the LLDB settings each time we create a cache
   // object.
   ModuleListProperties &properties =
@@ -40,6 +38,12 @@
   policy.Expiration =
   std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
   pruneCache(path, policy);
+  DataFileCache(path, policy);
+}
+
+DataFileCache::DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy 
policy) {
+  m_cache_dir.SetPath(path);
+  pruneCache(path, policy);
 
   // This lambda will get called when the data is gotten from the cache and
   // also after the data was set for a given key. We only need to take
Index: lldb/include/lldb/Core/DataFileCache.h
===
--- lldb/include/lldb/Core/DataFileCache.h
+++ lldb/include/lldb/Core/DataFileCache.h
@@ -14,6 +14,7 @@
 #include "lldb/Utility/UUID.h"
 #include "lldb/lldb-forward.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/CachePruning.h"
 #include "llvm/Support/Caching.h"
 #include 
 
@@ -40,12 +41,20 @@
 
 class DataFileCache {
 public:
-  /// Create a data file cache in the directory path that is specified.
+  /// Create a data file cache in the directory path that is specified, using
+  /// the "LLDBIndexCache" settings as  the basis for the policy.
   ///
   /// Data will be cached in files created in this directory when clients call
   /// DataFileCache::SetCacheData.
   DataFileCache(llvm::StringRef path);
 
+  /// Create a data file cache in the directory path that is specified, using
+  /// the specified policy.
+  ///
+  /// Data will be cached in files created in this directory when clients call
+  /// DataFileCache::SetCacheData.
+  DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy policy);
+
   /// Get cached data from the cache directory for the specified key.
   ///
   /// Keys must be unique for any given data. This function attempts to see if


Index: lldb/source/Core/DataFileCache.cpp
===
--- lldb/source/Core/DataFileCache.cpp
+++ lldb/source/Core/DataFileCache.cpp
@@ -20,8 +20,6 @@
 using namespace lldb_private;
 
 DataFileCache::DataFileCache(llvm::StringRef path) {
-  m_cache_dir.SetPath(path);
-
   // Prune the cache based off of the LLDB settings each time we create a cache
   // object.
   ModuleListProperties &properties =
@@ -40,6 +38,12 @@
   policy.Expiration =
   std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
   pruneCache(path, policy);
+  DataFileCache(path, policy);
+}
+
+DataFileCache::DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy policy) {
+  m_cache_dir.SetPath(path);
+  pruneCache(path, policy);
 
   // This lambda will get called when the data is gotten from the cache and
   // also after the data was set for a given key. We only need to take
Index: lldb/include/lldb/Core/DataFileCache.h
===
--- lldb/include/lldb/Core/DataFileCache.h
+++ lldb/include/lldb/Core/DataFileCache.h
@@ -14,6 +14,7 @@
 #include "lldb/Utility/UUID.h"
 #include "lldb/lldb-forward.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/CachePruning.h"
 #include "llvm/Support/Caching.h"
 #include 
 
@@ -40,12 +41,20 @@
 
 class DataFileCache {
 public:
-  /// Create a data file cache in the directory path that is specified.
+  /// Create a data file cache in the directory path that is specified, using
+  /// the "LLDBIndexCache" settings as  the basis for the policy.
   ///
   /// Data will be cached in files created in this directory when clients call
   /// DataFileCache::SetCacheData.
   DataFileCache(llvm::StringRef path);
 
+  /// Create a data file cache in the directory path that is specified, using
+  /// the specified policy.
+  ///
+  /// Data will be cached in files created in this directory when clients call
+  /// DataFileCache::SetCacheData.
+  DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy policy);
+
   /// Get cached data from the cache directory for the specified key.
   ///
   /// Keys must be unique for any given data. This function attempts to see if
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https

[Lldb-commits] [PATCH] D131531: [lldb] Allow DataFileCache to be constructed with a different policy

2022-08-10 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D131531#3711618 , @clayborg wrote:

> Is this new constructor going to be used elsewhere? It would be great to get 
> more description on why this is desired/needed?

I'm implementing a cache for swift type metadata for downstream lldb. I thought 
it made sense to separate its configuration from this index cache one, since we 
might want to enable either of them independently of the other, set different 
sizes, expiration dates, etc.




Comment at: lldb/source/Core/DataFileCache.cpp:23-39
   // Prune the cache based off of the LLDB settings each time we create a cache
   // object.
   ModuleListProperties &properties =
   ModuleList::GetGlobalModuleListProperties();
   llvm::CachePruningPolicy policy;
   // Only scan once an hour. If we have lots of debug sessions we don't want
   // to scan this directory too often. A timestamp file is written to the

JDevlieghere wrote:
> Would it make sense to extract this into a static function say 
> `DefaultCachePruningPolicy` and then have one constructor with an optional 
> policy argument? Something like this:
> 
> ```
> DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy policy = 
> DataFileCache::DefaultCachePruningPolicy);
> ```
> 
> In addition to having only one constructor, the new function also provides a 
> natural place to document the policy.
Sounds like a good idea!



Comment at: lldb/source/Core/DataFileCache.cpp:40
   std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
   pruneCache(path, policy);
+  DataFileCache(path, policy);

JDevlieghere wrote:
> Is it intentional that we now call this twice?
No! Thanks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131531/new/

https://reviews.llvm.org/D131531

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D131531: [lldb] Allow DataFileCache to be constructed with a different policy

2022-08-10 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 451549.
augusto2112 added a comment.

Added a static 'GetLLDBIndexCachePolicy' function, removed the constructor 
without any policies


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131531/new/

https://reviews.llvm.org/D131531

Files:
  lldb/include/lldb/Core/DataFileCache.h
  lldb/source/Core/DataFileCache.cpp

Index: lldb/source/Core/DataFileCache.cpp
===
--- lldb/source/Core/DataFileCache.cpp
+++ lldb/source/Core/DataFileCache.cpp
@@ -19,26 +19,34 @@
 
 using namespace lldb_private;
 
-DataFileCache::DataFileCache(llvm::StringRef path) {
-  m_cache_dir.SetPath(path);
 
-  // Prune the cache based off of the LLDB settings each time we create a cache
-  // object.
-  ModuleListProperties &properties =
-  ModuleList::GetGlobalModuleListProperties();
-  llvm::CachePruningPolicy policy;
-  // Only scan once an hour. If we have lots of debug sessions we don't want
-  // to scan this directory too often. A timestamp file is written to the
-  // directory to ensure different processes don't scan the directory too often.
-  // This setting doesn't mean that a thread will continually scan the cache
-  // directory within this process.
-  policy.Interval = std::chrono::hours(1);
-  // Get the user settings for pruning.
-  policy.MaxSizeBytes = properties.GetLLDBIndexCacheMaxByteSize();
-  policy.MaxSizePercentageOfAvailableSpace =
-  properties.GetLLDBIndexCacheMaxPercent();
-  policy.Expiration =
-  std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
+llvm::CachePruningPolicy DataFileCache::GetLLDBIndexCachePolicy() {
+  static llvm::CachePruningPolicy policy;
+  static llvm::once_flag once_flag;
+
+  llvm::call_once(once_flag, []() {
+// Prune the cache based off of the LLDB settings each time we create a
+// cache object.
+ModuleListProperties &properties =
+ModuleList::GetGlobalModuleListProperties();
+// Only scan once an hour. If we have lots of debug sessions we don't want
+// to scan this directory too often. A timestamp file is written to the
+// directory to ensure different processes don't scan the directory too
+// often. This setting doesn't mean that a thread will continually scan the
+// cache directory within this process.
+policy.Interval = std::chrono::hours(1);
+// Get the user settings for pruning.
+policy.MaxSizeBytes = properties.GetLLDBIndexCacheMaxByteSize();
+policy.MaxSizePercentageOfAvailableSpace =
+properties.GetLLDBIndexCacheMaxPercent();
+policy.Expiration =
+std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
+  });
+  return policy;
+}
+
+DataFileCache::DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy policy) {
+  m_cache_dir.SetPath(path);
   pruneCache(path, policy);
 
   // This lambda will get called when the data is gotten from the cache and
@@ -311,3 +319,4 @@
 return llvm::StringRef();
   return llvm::StringRef(m_data.data() + offset);
 }
+
Index: lldb/include/lldb/Core/DataFileCache.h
===
--- lldb/include/lldb/Core/DataFileCache.h
+++ lldb/include/lldb/Core/DataFileCache.h
@@ -14,6 +14,7 @@
 #include "lldb/Utility/UUID.h"
 #include "lldb/lldb-forward.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/CachePruning.h"
 #include "llvm/Support/Caching.h"
 #include 
 
@@ -40,11 +41,14 @@
 
 class DataFileCache {
 public:
-  /// Create a data file cache in the directory path that is specified.
+  /// Create a data file cache in the directory path that is specified, using
+  /// the specified policy.
   ///
   /// Data will be cached in files created in this directory when clients call
   /// DataFileCache::SetCacheData.
-  DataFileCache(llvm::StringRef path);
+  DataFileCache(llvm::StringRef path,
+llvm::CachePruningPolicy policy =
+DataFileCache::GetLLDBIndexCachePolicy());
 
   /// Get cached data from the cache directory for the specified key.
   ///
@@ -76,6 +80,9 @@
   Status RemoveCacheFile(llvm::StringRef key);
 
 private:
+  /// Gets the default LLDB index cache policy, which is s
+  static llvm::CachePruningPolicy GetLLDBIndexCachePolicy();
+
   /// Return the cache file that is associated with the key.
   FileSpec GetCacheFilePath(llvm::StringRef key);
 
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D131531: [lldb] Allow DataFileCache to be constructed with a different policy

2022-08-10 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 451565.
augusto2112 added a comment.

Made GetLLDBIndexCachePolicy public


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131531/new/

https://reviews.llvm.org/D131531

Files:
  lldb/include/lldb/Core/DataFileCache.h
  lldb/source/Core/DataFileCache.cpp


Index: lldb/source/Core/DataFileCache.cpp
===
--- lldb/source/Core/DataFileCache.cpp
+++ lldb/source/Core/DataFileCache.cpp
@@ -19,26 +19,34 @@
 
 using namespace lldb_private;
 
-DataFileCache::DataFileCache(llvm::StringRef path) {
-  m_cache_dir.SetPath(path);
 
-  // Prune the cache based off of the LLDB settings each time we create a cache
-  // object.
-  ModuleListProperties &properties =
-  ModuleList::GetGlobalModuleListProperties();
-  llvm::CachePruningPolicy policy;
-  // Only scan once an hour. If we have lots of debug sessions we don't want
-  // to scan this directory too often. A timestamp file is written to the
-  // directory to ensure different processes don't scan the directory too 
often.
-  // This setting doesn't mean that a thread will continually scan the cache
-  // directory within this process.
-  policy.Interval = std::chrono::hours(1);
-  // Get the user settings for pruning.
-  policy.MaxSizeBytes = properties.GetLLDBIndexCacheMaxByteSize();
-  policy.MaxSizePercentageOfAvailableSpace =
-  properties.GetLLDBIndexCacheMaxPercent();
-  policy.Expiration =
-  std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
+llvm::CachePruningPolicy DataFileCache::GetLLDBIndexCachePolicy() {
+  static llvm::CachePruningPolicy policy;
+  static llvm::once_flag once_flag;
+
+  llvm::call_once(once_flag, []() {
+// Prune the cache based off of the LLDB settings each time we create a
+// cache object.
+ModuleListProperties &properties =
+ModuleList::GetGlobalModuleListProperties();
+// Only scan once an hour. If we have lots of debug sessions we don't want
+// to scan this directory too often. A timestamp file is written to the
+// directory to ensure different processes don't scan the directory too
+// often. This setting doesn't mean that a thread will continually scan the
+// cache directory within this process.
+policy.Interval = std::chrono::hours(1);
+// Get the user settings for pruning.
+policy.MaxSizeBytes = properties.GetLLDBIndexCacheMaxByteSize();
+policy.MaxSizePercentageOfAvailableSpace =
+properties.GetLLDBIndexCacheMaxPercent();
+policy.Expiration =
+std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
+  });
+  return policy;
+}
+
+DataFileCache::DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy 
policy) {
+  m_cache_dir.SetPath(path);
   pruneCache(path, policy);
 
   // This lambda will get called when the data is gotten from the cache and
@@ -311,3 +319,4 @@
 return llvm::StringRef();
   return llvm::StringRef(m_data.data() + offset);
 }
+
Index: lldb/include/lldb/Core/DataFileCache.h
===
--- lldb/include/lldb/Core/DataFileCache.h
+++ lldb/include/lldb/Core/DataFileCache.h
@@ -14,6 +14,7 @@
 #include "lldb/Utility/UUID.h"
 #include "lldb/lldb-forward.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/CachePruning.h"
 #include "llvm/Support/Caching.h"
 #include 
 
@@ -40,11 +41,18 @@
 
 class DataFileCache {
 public:
-  /// Create a data file cache in the directory path that is specified.
+  /// Create a data file cache in the directory path that is specified, using
+  /// the specified policy.
   ///
   /// Data will be cached in files created in this directory when clients call
   /// DataFileCache::SetCacheData.
-  DataFileCache(llvm::StringRef path);
+  DataFileCache(llvm::StringRef path,
+llvm::CachePruningPolicy policy =
+DataFileCache::GetLLDBIndexCachePolicy());
+
+  /// Gets the default LLDB index cache policy, which is controlled by the
+  /// "LLDBIndexCache" family of settings.
+  static llvm::CachePruningPolicy GetLLDBIndexCachePolicy();
 
   /// Get cached data from the cache directory for the specified key.
   ///


Index: lldb/source/Core/DataFileCache.cpp
===
--- lldb/source/Core/DataFileCache.cpp
+++ lldb/source/Core/DataFileCache.cpp
@@ -19,26 +19,34 @@
 
 using namespace lldb_private;
 
-DataFileCache::DataFileCache(llvm::StringRef path) {
-  m_cache_dir.SetPath(path);
 
-  // Prune the cache based off of the LLDB settings each time we create a cache
-  // object.
-  ModuleListProperties &properties =
-  ModuleList::GetGlobalModuleListProperties();
-  llvm::CachePruningPolicy policy;
-  // Only scan once an hour. If we have lots of debug sessions we don't want
-  // to scan this directory too often. A timestamp file is written to the
-  // director

[Lldb-commits] [PATCH] D131531: [lldb] Allow DataFileCache to be constructed with a different policy

2022-08-11 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc6c5944d05e8: [lldb] Allow DataFileCache to be constructed 
with a different policy (authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131531/new/

https://reviews.llvm.org/D131531

Files:
  lldb/include/lldb/Core/DataFileCache.h
  lldb/source/Core/DataFileCache.cpp


Index: lldb/source/Core/DataFileCache.cpp
===
--- lldb/source/Core/DataFileCache.cpp
+++ lldb/source/Core/DataFileCache.cpp
@@ -19,26 +19,34 @@
 
 using namespace lldb_private;
 
-DataFileCache::DataFileCache(llvm::StringRef path) {
-  m_cache_dir.SetPath(path);
 
-  // Prune the cache based off of the LLDB settings each time we create a cache
-  // object.
-  ModuleListProperties &properties =
-  ModuleList::GetGlobalModuleListProperties();
-  llvm::CachePruningPolicy policy;
-  // Only scan once an hour. If we have lots of debug sessions we don't want
-  // to scan this directory too often. A timestamp file is written to the
-  // directory to ensure different processes don't scan the directory too 
often.
-  // This setting doesn't mean that a thread will continually scan the cache
-  // directory within this process.
-  policy.Interval = std::chrono::hours(1);
-  // Get the user settings for pruning.
-  policy.MaxSizeBytes = properties.GetLLDBIndexCacheMaxByteSize();
-  policy.MaxSizePercentageOfAvailableSpace =
-  properties.GetLLDBIndexCacheMaxPercent();
-  policy.Expiration =
-  std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
+llvm::CachePruningPolicy DataFileCache::GetLLDBIndexCachePolicy() {
+  static llvm::CachePruningPolicy policy;
+  static llvm::once_flag once_flag;
+
+  llvm::call_once(once_flag, []() {
+// Prune the cache based off of the LLDB settings each time we create a
+// cache object.
+ModuleListProperties &properties =
+ModuleList::GetGlobalModuleListProperties();
+// Only scan once an hour. If we have lots of debug sessions we don't want
+// to scan this directory too often. A timestamp file is written to the
+// directory to ensure different processes don't scan the directory too
+// often. This setting doesn't mean that a thread will continually scan the
+// cache directory within this process.
+policy.Interval = std::chrono::hours(1);
+// Get the user settings for pruning.
+policy.MaxSizeBytes = properties.GetLLDBIndexCacheMaxByteSize();
+policy.MaxSizePercentageOfAvailableSpace =
+properties.GetLLDBIndexCacheMaxPercent();
+policy.Expiration =
+std::chrono::hours(properties.GetLLDBIndexCacheExpirationDays() * 24);
+  });
+  return policy;
+}
+
+DataFileCache::DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy 
policy) {
+  m_cache_dir.SetPath(path);
   pruneCache(path, policy);
 
   // This lambda will get called when the data is gotten from the cache and
@@ -311,3 +319,4 @@
 return llvm::StringRef();
   return llvm::StringRef(m_data.data() + offset);
 }
+
Index: lldb/include/lldb/Core/DataFileCache.h
===
--- lldb/include/lldb/Core/DataFileCache.h
+++ lldb/include/lldb/Core/DataFileCache.h
@@ -14,6 +14,7 @@
 #include "lldb/Utility/UUID.h"
 #include "lldb/lldb-forward.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/CachePruning.h"
 #include "llvm/Support/Caching.h"
 #include 
 
@@ -40,11 +41,18 @@
 
 class DataFileCache {
 public:
-  /// Create a data file cache in the directory path that is specified.
+  /// Create a data file cache in the directory path that is specified, using
+  /// the specified policy.
   ///
   /// Data will be cached in files created in this directory when clients call
   /// DataFileCache::SetCacheData.
-  DataFileCache(llvm::StringRef path);
+  DataFileCache(llvm::StringRef path,
+llvm::CachePruningPolicy policy =
+DataFileCache::GetLLDBIndexCachePolicy());
+
+  /// Gets the default LLDB index cache policy, which is controlled by the
+  /// "LLDBIndexCache" family of settings.
+  static llvm::CachePruningPolicy GetLLDBIndexCachePolicy();
 
   /// Get cached data from the cache directory for the specified key.
   ///


Index: lldb/source/Core/DataFileCache.cpp
===
--- lldb/source/Core/DataFileCache.cpp
+++ lldb/source/Core/DataFileCache.cpp
@@ -19,26 +19,34 @@
 
 using namespace lldb_private;
 
-DataFileCache::DataFileCache(llvm::StringRef path) {
-  m_cache_dir.SetPath(path);
 
-  // Prune the cache based off of the LLDB settings each time we create a cache
-  // object.
-  ModuleListProperties &properties =
-  ModuleList::GetGlobalModuleListProperties();
-  llvm::CachePruningPolicy policy;
-  // Only scan once an hour. If we have lots of debug sessions we don't want
- 

[Lldb-commits] [PATCH] D132382: [lldb] Remove prefer-dynamic-value test override

2022-08-22 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 accepted this revision.
augusto2112 added a comment.

I think this is a good change. One related thing that we could look into fixing 
is that currently both run-target and no-run-target do the **exact** same 
thing. Not sure if we could remove one of them since this could break user's 
settings, but we could at least document it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D132382/new/

https://reviews.llvm.org/D132382

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D122943: [LLDB][NativePDB] Fix a crash when S_DEFRANGE_SUBFIELD_REGISTER descirbes a simple type

2022-04-15 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

Hi @zequanwu, your patch's new test seems to be failing on CI 
(https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/). Could you fix it 
or revert the changes? Thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122943/new/

https://reviews.llvm.org/D122943

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D140051: [lldb] Add LTO dependency to lldb test suite

2022-12-14 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added a reviewer: aprantl.
Herald added a subscriber: inglorion.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Make the lldb test target depend on LTO, since TestFullLtoStepping
needs it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140051

Files:
  lldb/test/CMakeLists.txt


Index: lldb/test/CMakeLists.txt
===
--- lldb/test/CMakeLists.txt
+++ lldb/test/CMakeLists.txt
@@ -95,6 +95,9 @@
 if(TARGET clang)
   add_lldb_test_dependency(clang)
 
+  # TestFullLtoStepping depends on LTO, and only runs when the compiler is 
clang.
+  add_lldb_test_dependency(LTO)
+
   if (TARGET libcxx OR ("libcxx" IN_LIST LLVM_ENABLE_RUNTIMES))
 set(LLDB_HAS_LIBCXX ON)
 if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)


Index: lldb/test/CMakeLists.txt
===
--- lldb/test/CMakeLists.txt
+++ lldb/test/CMakeLists.txt
@@ -95,6 +95,9 @@
 if(TARGET clang)
   add_lldb_test_dependency(clang)
 
+  # TestFullLtoStepping depends on LTO, and only runs when the compiler is clang.
+  add_lldb_test_dependency(LTO)
+
   if (TARGET libcxx OR ("libcxx" IN_LIST LLVM_ENABLE_RUNTIMES))
 set(LLDB_HAS_LIBCXX ON)
 if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D140051: [lldb] Add LTO dependency to lldb test suite

2022-12-15 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

@DavidSpickett right now if you don't have LTO the test will run but fail.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140051/new/

https://reviews.llvm.org/D140051

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D140051: [lldb] Add LTO dependency to lldb test suite

2022-12-22 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

@DavidSpickett thanks for the review, I've updated the commit message to be 
clearer.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140051/new/

https://reviews.llvm.org/D140051

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D140051: [lldb] Add LTO dependency to lldb test suite

2022-12-22 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf85cc6009aa7: [lldb] Add LTO dependency to lldb test suite 
(authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140051/new/

https://reviews.llvm.org/D140051

Files:
  lldb/test/CMakeLists.txt


Index: lldb/test/CMakeLists.txt
===
--- lldb/test/CMakeLists.txt
+++ lldb/test/CMakeLists.txt
@@ -95,6 +95,9 @@
 if(TARGET clang)
   add_lldb_test_dependency(clang)
 
+  # TestFullLtoStepping depends on LTO, and only runs when the compiler is 
clang.
+  add_lldb_test_dependency(LTO)
+
   if (TARGET libcxx OR ("libcxx" IN_LIST LLVM_ENABLE_RUNTIMES))
 set(LLDB_HAS_LIBCXX ON)
 if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)


Index: lldb/test/CMakeLists.txt
===
--- lldb/test/CMakeLists.txt
+++ lldb/test/CMakeLists.txt
@@ -95,6 +95,9 @@
 if(TARGET clang)
   add_lldb_test_dependency(clang)
 
+  # TestFullLtoStepping depends on LTO, and only runs when the compiler is clang.
+  add_lldb_test_dependency(LTO)
+
   if (TARGET libcxx OR ("libcxx" IN_LIST LLVM_ENABLE_RUNTIMES))
 set(LLDB_HAS_LIBCXX ON)
 if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D141165: [lldb] Fix symbol table use after free

2023-01-06 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: labath, jingham, JDevlieghere.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

The symbol file stores a raw pointer to the main object file's symbol
table. This pointer, however, can be freed, if ObjectFile::ClearSymtab
is ever called. This patch makes sure the pointer to the symbol file
is valid before using it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141165

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/source/Symbol/SymbolFile.cpp


Index: lldb/source/Symbol/SymbolFile.cpp
===
--- lldb/source/Symbol/SymbolFile.cpp
+++ lldb/source/Symbol/SymbolFile.cpp
@@ -164,16 +164,15 @@
 
 Symtab *SymbolFileCommon::GetSymtab() {
   std::lock_guard guard(GetModuleMutex());
-  if (m_symtab)
-return m_symtab;
-
   // Fetch the symtab from the main object file.
-  m_symtab = GetMainObjectFile()->GetSymtab();
-
-  // Then add our symbols to it.
-  if (m_symtab)
-AddSymbols(*m_symtab);
+  auto *symtab = GetMainObjectFile()->GetSymtab();
+  if (m_symtab != symtab) {
+m_symtab = symtab;
 
+// Then add our symbols to it.
+if (m_symtab)
+  AddSymbols(*m_symtab);
+  }
   return m_symtab;
 }
 
@@ -186,8 +185,9 @@
   ObjectFile *symfile_objfile = GetObjectFile();
   if (symfile_objfile != module_objfile)
 symfile_objfile->SectionFileAddressesChanged();
-  if (m_symtab)
-m_symtab->SectionFileAddressesChanged();
+  auto *symtab = GetSymtab();
+  if (symtab)
+symtab->SectionFileAddressesChanged();
 }
 
 uint32_t SymbolFileCommon::GetNumCompileUnits() {
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -503,7 +503,6 @@
// file)
   llvm::Optional> m_compile_units;
   TypeList m_type_list;
-  Symtab *m_symtab = nullptr;
   uint32_t m_abilities = 0;
   bool m_calculated_abilities = false;
   bool m_index_was_loaded_from_cache = false;
@@ -516,6 +515,10 @@
 private:
   SymbolFileCommon(const SymbolFileCommon &) = delete;
   const SymbolFileCommon &operator=(const SymbolFileCommon &) = delete;
+
+  /// Do not use m_symtab directly, as it may be freed. Use GetSymtab()
+  /// to access it instead.
+  Symtab *m_symtab = nullptr;
 };
 
 } // namespace lldb_private


Index: lldb/source/Symbol/SymbolFile.cpp
===
--- lldb/source/Symbol/SymbolFile.cpp
+++ lldb/source/Symbol/SymbolFile.cpp
@@ -164,16 +164,15 @@
 
 Symtab *SymbolFileCommon::GetSymtab() {
   std::lock_guard guard(GetModuleMutex());
-  if (m_symtab)
-return m_symtab;
-
   // Fetch the symtab from the main object file.
-  m_symtab = GetMainObjectFile()->GetSymtab();
-
-  // Then add our symbols to it.
-  if (m_symtab)
-AddSymbols(*m_symtab);
+  auto *symtab = GetMainObjectFile()->GetSymtab();
+  if (m_symtab != symtab) {
+m_symtab = symtab;
 
+// Then add our symbols to it.
+if (m_symtab)
+  AddSymbols(*m_symtab);
+  }
   return m_symtab;
 }
 
@@ -186,8 +185,9 @@
   ObjectFile *symfile_objfile = GetObjectFile();
   if (symfile_objfile != module_objfile)
 symfile_objfile->SectionFileAddressesChanged();
-  if (m_symtab)
-m_symtab->SectionFileAddressesChanged();
+  auto *symtab = GetSymtab();
+  if (symtab)
+symtab->SectionFileAddressesChanged();
 }
 
 uint32_t SymbolFileCommon::GetNumCompileUnits() {
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -503,7 +503,6 @@
// file)
   llvm::Optional> m_compile_units;
   TypeList m_type_list;
-  Symtab *m_symtab = nullptr;
   uint32_t m_abilities = 0;
   bool m_calculated_abilities = false;
   bool m_index_was_loaded_from_cache = false;
@@ -516,6 +515,10 @@
 private:
   SymbolFileCommon(const SymbolFileCommon &) = delete;
   const SymbolFileCommon &operator=(const SymbolFileCommon &) = delete;
+
+  /// Do not use m_symtab directly, as it may be freed. Use GetSymtab()
+  /// to access it instead.
+  Symtab *m_symtab = nullptr;
 };
 
 } // namespace lldb_private
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D141318: [lldb] Store shared pointers in DieToTypePtr map instead of raw pointers

2023-01-09 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: labath, clayborg, aprantl.
Herald added a reviewer: shafik.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Storing raw pointers in DieToTypePtr may cause use-after-frees to occur,
since there are no guarantees that the shared pointers that owns the
underlying pointer to the type are kept around as long as the map.
Change the map to store a shared pointer instead.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141318

Files:
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -56,7 +56,6 @@
 class SymbolFileDWARFDwo;
 class SymbolFileDWARFDwp;
 
-#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1)
 
 class SymbolFileDWARF : public lldb_private::SymbolFileCommon,
 public lldb_private::UserID {
@@ -233,6 +232,10 @@
 
   static bool SupportedVersion(uint16_t version);
 
+  /// Returns a sentinel pointer that indicates that a DIE is being
+  /// parsed into a type.
+  static std::shared_ptr GetSentinelDieBeingParsed();
+
   DWARFDIE
   GetDeclContextDIEContainingDIE(const DWARFDIE &die);
 
@@ -348,7 +351,8 @@
   lldb_private::ConstString ConstructFunctionDemangledName(const DWARFDIE &die);
 
 protected:
-  typedef llvm::DenseMap
+  typedef llvm::DenseMap>
   DIEToTypePtr;
   typedef llvm::DenseMap
   DIEToVariableSP;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -517,6 +517,13 @@
   return version >= 2 && version <= 5;
 }
 
+std::shared_ptr
+SymbolFileDWARF::GetSentinelDieBeingParsed() {
+  static std::shared_ptr sentinel =
+  std::make_shared();
+  return sentinel;
+}
+
 uint32_t SymbolFileDWARF::CalculateAbilities() {
   uint32_t abilities = 0;
   if (m_objfile_sp != nullptr) {
@@ -1602,17 +1609,18 @@
 // to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done.
 GetForwardDeclClangTypeToDie().erase(die_it);
 
-Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
+auto type_sp = GetDIEToType().lookup(dwarf_die.GetDIE());
 
 Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion);
 if (log)
   GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
   log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
   dwarf_die.GetID(), dwarf_die.GetTagAsCString(),
-  type->GetName().AsCString());
+  type_sp->GetName().AsCString());
 assert(compiler_type);
 if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
-  return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
+  return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type_sp.get(),
+  compiler_type);
   }
   return false;
 }
@@ -1624,7 +1632,7 @@
 Type *type = GetTypeForDIE(die, resolve_function_context).get();
 
 if (assert_not_being_parsed) {
-  if (type != DIE_IS_BEING_PARSED)
+  if (type != SymbolFileDWARF::GetSentinelDieBeingParsed().get())
 return type;
 
   GetObjectFile()->GetModule()->ReportError(
@@ -2686,10 +2694,13 @@
 
 TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die,
   bool resolve_function_context) {
-  TypeSP type_sp;
   if (die) {
-Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
-if (type_ptr == nullptr) {
+if (auto type_sp = GetDIEToType().lookup(die.GetDIE())) {
+  if (type_sp.get() !=
+  SymbolFileDWARF::GetSentinelDieBeingParsed().get()) {
+return type_sp;
+  }
+} else {
   SymbolContextScope *scope;
   if (auto *dwarf_cu = llvm::dyn_cast(die.GetCU()))
 scope = GetCompUnitForDWARFCompUnit(*dwarf_cu);
@@ -2708,13 +2719,10 @@
   !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc))
 sc = sc_backup;
 
-  type_sp = ParseType(sc, die, nullptr);
-} else if (type_ptr != DIE_IS_BEING_PARSED) {
-  // Get the original shared pointer for this type
-  type_sp = type_ptr->shared_from_this();
+  return ParseType(sc, die, nullptr);
 }
   }
-  return type_sp;
+  return nullptr;
 }
 
 DWARFDIE
@@ -2850,7 +2858,9 @@
   return true;
 
 Type *resolved_type = ResolveType(type_die, false, true);
-if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED)
+if (!resolved_type ||
+   

[Lldb-commits] [PATCH] D141318: [lldb] Store shared pointers in DieToTypePtr map instead of raw pointers

2023-01-09 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.
Herald added a subscriber: JDevlieghere.

I changed the value of the map to a shared pointer, but could change it to a 
weak pointer instead, not sure which is more appropriate in this case.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141318/new/

https://reviews.llvm.org/D141318

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D141318: [lldb] Store shared pointers in DieToTypePtr map instead of raw pointers

2023-01-09 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D141318#4037557 , @JDevlieghere 
wrote:

> In D141318#4037541 , @augusto2112 
> wrote:
>
>> I changed the value of the map to a shared pointer, but could change it to a 
>> weak pointer instead, not sure which is more appropriate in this case.
>
> I was about to ask the same thing. What currently determines the lifetime of 
> the stored objects?

Currently, a bunch of functions in `DWARFASTParserClang` and `SymbolFileDWARF` 
will create a new `Type` SP, store the underlying pointer in the map, and 
return the SP. The lifetime of the stored objects varies by whatever the caller 
does with the returned SP. Looking at some of the callers, I don't see a very 
clear pattern, most seem to use it and immediately discard it  (use after free 
when we look up the same type again and the underlying pointer is still in the 
map), but at least one caller (`SymbolFileDWARF::ResolveType`) returns the 
underlying pointer to //its// callers, which would still be UB even if we 
changed the map to store weak pointers. Based on that I'm thinking we should 
store them as shared pointers instead of weak ones.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141318/new/

https://reviews.llvm.org/D141318

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D141318: [lldb] Store shared pointers in DieToTypePtr map instead of raw pointers

2023-01-09 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D141318#4037687 , @JDevlieghere 
wrote:

> In D141318#4037640 , @augusto2112 
> wrote:
>
>> In D141318#4037557 , @JDevlieghere 
>> wrote:
>>
>>> In D141318#4037541 , @augusto2112 
>>> wrote:
>>>
 I changed the value of the map to a shared pointer, but could change it to 
 a weak pointer instead, not sure which is more appropriate in this case.
>>>
>>> I was about to ask the same thing. What currently determines the lifetime 
>>> of the stored objects?
>>
>> Currently, a bunch of functions in `DWARFASTParserClang` and 
>> `SymbolFileDWARF` will create a new `Type` SP, store the underlying pointer 
>> in the map, and return the SP. The lifetime of the stored objects varies by 
>> whatever the caller does with the returned SP. Looking at some of the 
>> callers, I don't see a very clear pattern, most seem to use it and 
>> immediately discard it  (use after free when we look up the same type again 
>> and the underlying pointer is still in the map), but at least one caller 
>> (`SymbolFileDWARF::ResolveType`) returns the underlying pointer to //its// 
>> callers, which would still be UB even if we changed the map to store weak 
>> pointers. Based on that I'm thinking we should store them as shared pointers 
>> instead of weak ones.
>
> Then maybe the solution is to store the type as unique pointers in the map 
> and hand out raw pointers, relying on the map to keep the object alive? I 
> feel pretty uncomfortable with handing out shared pointers without clearly 
> understanding its lifetime cycle.

Yeah that seems like a better solution. I'm checking how hard implementing that 
would be. `TypeSP` is used in a bunch of places in LLDB.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141318/new/

https://reviews.llvm.org/D141318

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D141318: [lldb] Store shared pointers in DieToTypePtr map instead of raw pointers

2023-01-11 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D141318#4045372 , @clayborg wrote:

> Each SymbolFile has its own type list that keeps the shared pointers to all 
> types. So there should be no need for any of these changes here unless 
> someone isn't correctly storing a newly created type in the SymbolFile's type 
> list. You can see the types being stored in code like:
>
>   TypeSP type_sp(... /* create type here*/ ...);
>   dwarf->GetTypeList().Insert(type_sp); // Store the share reference in the 
> symbol file's type list 

What triggered the use after free for me was this snippet in 
`DWARFASTParserClang::ParseTypeModifier`:

...
TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
sc, function_type, &function_type_is_new_pointer);
  
if (lldb_function_type_sp) {
  clang_type = m_ast.CreateBlockPointerType(
  lldb_function_type_sp->GetForwardCompilerType());
  encoding_data_type = Type::eEncodingIsUID;
  attrs.type.Clear();
  resolve_state = Type::ResolveState::Full;
}
  }

`lldb_function_type_sp` is created, the underlying pointer is placed in the 
map, the SP is destroyed at the end of the scope, and any lookups for that type 
will get back the dangling pointer.

I could update this particular instance, but this just seems like a really easy 
mistake to make... There's nothing to suggest to callers that they must update 
the `m_type_list` when they ask for a new type. Wouldn't it be better we 
prevent this somehow, by updating the raw pointers of the map by being either 
unique, shared or weak pointers?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141318/new/

https://reviews.llvm.org/D141318

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D141318: [lldb] Store shared pointers in DieToTypePtr map instead of raw pointers

2023-01-13 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 489137.
augusto2112 added a comment.

Make Type constructor private


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141318/new/

https://reviews.llvm.org/D141318

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/include/lldb/Symbol/SymbolFileOnDemand.h
  lldb/include/lldb/Symbol/Type.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
  lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
  lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
  lldb/unittests/Symbol/TestTypeSystemClang.cpp

Index: lldb/unittests/Symbol/TestTypeSystemClang.cpp
===
--- lldb/unittests/Symbol/TestTypeSystemClang.cpp
+++ lldb/unittests/Symbol/TestTypeSystemClang.cpp
@@ -969,13 +969,10 @@
   ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts));
 }
 
-TEST_F(TestTypeSystemClang, GetExeModuleWhenMissingSymbolFile) {
-  CompilerType compiler_type = m_ast->GetBasicTypeFromAST(lldb::eBasicTypeInt);
-  lldb_private::Type t(0, nullptr, ConstString("MyType"), std::nullopt, nullptr,
-   0, {}, {}, compiler_type,
-   lldb_private::Type::ResolveState::Full);
-  // Test that getting the execution module when no type system is present
-  // is handled gracefully.
-  ModuleSP module = t.GetExeModule();
-  EXPECT_EQ(module.get(), nullptr);
+TEST_F(TestTypeSystemClang, GetDeclContextByNameWhenMissingSymbolFile) {
+  // Test that a type system without a symbol file is handled gracefully.
+  std::vector decls =
+  m_ast->DeclContextFindDeclByName(nullptr, ConstString("SomeName"), true);
+
+  EXPECT_TRUE(decls.empty());
 }
Index: lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
===
--- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -586,7 +586,6 @@
   lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
   if (result) {
 m_types.insert(std::make_pair(type_uid, result));
-GetTypeList().Insert(result);
   }
   return result.get();
 }
Index: lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
===
--- lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -465,10 +465,9 @@
   clang_type = clang_type.AddVolatileModifier();
 
 GetDeclarationForSymbol(type, decl);
-return std::make_shared(
-type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
-udt->getLength(), nullptr, LLDB_INVALID_UID,
-lldb_private::Type::eEncodingIsUID, decl, clang_type,
+return m_ast.GetSymbolFile()->MakeType(
+type.getSymIndexId(), ConstString(name), udt->getLength(), nullptr,
+LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type,
 type_resolve_state);
   } break;
   case PDB_SymType::Enum: {
@@ -535,10 +534,10 @@
   ast_enum = ast_enum.AddVolatileModifier();
 
 GetDeclarationForSymbol(type, decl);
-return std::make_shared(
-type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes,
-nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
-ast_enum, lldb_private::Type::ResolveState::Full);
+return m_ast.GetSymbolFile()->MakeType(
+type.getSymIndexId(), ConstString(name), bytes, nullptr,
+LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ast_enum,
+lldb_private::Type::ResolveState::Full);
   } break;
   case PDB_SymType::Typedef: {
 auto type_def = llvm::dyn_cast(&type);
@@ -584,11 +583,10 @@
 std::optional size;
 if (type_def->getLength())
   size = type_def->getLength();
-return std::make_shared(
-type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
-size, nullptr, target_type->GetID(),
-lldb_private::Type::eEncodingIsTypedefUID, decl, ast_typedef,
-lldb_private::Type::ResolveState::Full);
+return m_ast.GetSymbolFile()->MakeType(
+type_def->getSymIndexId(), ConstString(name), size, nullptr,
+target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID, decl,
+ast_typedef, lldb_private::Type::ResolveState::Full);
   } break;
   case PDB_SymType::Function:
   case PDB_SymType::FunctionSig: {
@@ -662,11 +660,10 @@
  arg_list.size(), is_variadic, type_quals, cc);
 
 GetDeclarationForSymbol(type, decl);
-return std::make_shared(
-type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
-std::nullopt, nullptr, LLDB_INVALID_UID,
-lldb_private::Type::eEncodingIsUID, decl, func_sig_ast_type,
-lldb_private

[Lldb-commits] [PATCH] D141318: [lldb] Store shared pointers in DieToTypePtr map instead of raw pointers

2023-01-13 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

@clayborg I went with your suggestion and made Type's constructor private, and 
any new Type created is automatically added to the TypeList. I think later on 
we should make TypeList keep a vector of unique pointers instead of shared ones.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141318/new/

https://reviews.llvm.org/D141318

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D142052: [lldb] Implement SymbolFile::CopyType

2023-01-18 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added a reviewer: clayborg.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

SymbolFiles should be the only point of creation of Types to ensure
that they aren't destroyed prematurely by keeping them in the
SymbolFile's TypeList. This patch hides the copy constructor of Types,
and adds a new CopyType function to SymbolFile, so Types can still be
copied safely.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142052

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/include/lldb/Symbol/SymbolFileOnDemand.h
  lldb/include/lldb/Symbol/Type.h


Index: lldb/include/lldb/Symbol/Type.h
===
--- lldb/include/lldb/Symbol/Type.h
+++ lldb/include/lldb/Symbol/Type.h
@@ -241,6 +241,14 @@
   // This makes an invalid type.  Used for functions that return a Type when
   // they get an error.
   Type();
+
+  Type(Type &t) = default;
+
+  Type(Type &&t) = default;
+
+  Type &operator=(const Type &t) = default;
+
+  Type &operator=(Type &&t) = default;
 };
 
 // the two classes here are used by the public API as a backend to the SBType
Index: lldb/include/lldb/Symbol/SymbolFileOnDemand.h
===
--- lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -241,6 +241,10 @@
 compiler_qual_type, compiler_type_resolve_state, opaque_payload);
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+return m_sym_file_impl->CopyType(other_type);
+  }
+
 private:
   Log *GetLog() const { return ::lldb_private::GetLog(LLDBLog::OnDemand); }
 
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -421,6 +421,8 @@
Type::ResolveState compiler_type_resolve_state,
uint32_t opaque_payload = 0) = 0;
 
+  virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
+
 protected:
   void AssertModuleLock();
 
@@ -521,6 +523,12 @@
  return type_sp;
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+ lldb::TypeSP type_sp (new Type(*other_type));
+ m_type_list.Insert(type_sp);
+ return type_sp;
+  }
+
 protected:
   virtual uint32_t CalculateNumCompileUnits() = 0;
   virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;


Index: lldb/include/lldb/Symbol/Type.h
===
--- lldb/include/lldb/Symbol/Type.h
+++ lldb/include/lldb/Symbol/Type.h
@@ -241,6 +241,14 @@
   // This makes an invalid type.  Used for functions that return a Type when
   // they get an error.
   Type();
+
+  Type(Type &t) = default;
+
+  Type(Type &&t) = default;
+
+  Type &operator=(const Type &t) = default;
+
+  Type &operator=(Type &&t) = default;
 };
 
 // the two classes here are used by the public API as a backend to the SBType
Index: lldb/include/lldb/Symbol/SymbolFileOnDemand.h
===
--- lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -241,6 +241,10 @@
 compiler_qual_type, compiler_type_resolve_state, opaque_payload);
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+return m_sym_file_impl->CopyType(other_type);
+  }
+
 private:
   Log *GetLog() const { return ::lldb_private::GetLog(LLDBLog::OnDemand); }
 
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -421,6 +421,8 @@
Type::ResolveState compiler_type_resolve_state,
uint32_t opaque_payload = 0) = 0;
 
+  virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
+
 protected:
   void AssertModuleLock();
 
@@ -521,6 +523,12 @@
  return type_sp;
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+ lldb::TypeSP type_sp (new Type(*other_type));
+ m_type_list.Insert(type_sp);
+ return type_sp;
+  }
+
 protected:
   virtual uint32_t CalculateNumCompileUnits() = 0;
   virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D142052: [lldb] Implement SymbolFile::CopyType

2023-01-19 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

@clayborg the intended usage here is to create a copy of the type in the same 
symbol file. I could add a sanity check that makes sure we're not creating a 
copy of something that isn't in the symbol file's type list in debug mode. 
Would that be enough?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142052/new/

https://reviews.llvm.org/D142052

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D142052: [lldb] Implement SymbolFile::CopyType

2023-01-19 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

@clayborg we have one instance downstream where we need to keep two types 
around. One for the original type and one for a slightly modified one (here 
).
 This patch is just a way to make sure any new type we copy is inserted in the 
type list as well.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142052/new/

https://reviews.llvm.org/D142052

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D142052: [lldb] Implement SymbolFile::CopyType

2023-01-20 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 490951.
augusto2112 added a comment.

Added check for same symbol file


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142052/new/

https://reviews.llvm.org/D142052

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/include/lldb/Symbol/SymbolFileOnDemand.h
  lldb/include/lldb/Symbol/Type.h


Index: lldb/include/lldb/Symbol/Type.h
===
--- lldb/include/lldb/Symbol/Type.h
+++ lldb/include/lldb/Symbol/Type.h
@@ -241,6 +241,14 @@
   // This makes an invalid type.  Used for functions that return a Type when
   // they get an error.
   Type();
+
+  Type(Type &t) = default;
+
+  Type(Type &&t) = default;
+
+  Type &operator=(const Type &t) = default;
+
+  Type &operator=(Type &&t) = default;
 };
 
 // the two classes here are used by the public API as a backend to the SBType
Index: lldb/include/lldb/Symbol/SymbolFileOnDemand.h
===
--- lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -241,6 +241,10 @@
 compiler_qual_type, compiler_type_resolve_state, opaque_payload);
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+return m_sym_file_impl->CopyType(other_type);
+  }
+
 private:
   Log *GetLog() const { return ::lldb_private::GetLog(LLDBLog::OnDemand); }
 
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -421,6 +421,8 @@
Type::ResolveState compiler_type_resolve_state,
uint32_t opaque_payload = 0) = 0;
 
+  virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
+
 protected:
   void AssertModuleLock();
 
@@ -521,6 +523,15 @@
  return type_sp;
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+ // Make sure the real symbol file matches when copying types.
+ if (GetBackingSymbolFile() != other_type->GetSymbolFile())
+  return lldb::TypeSP();
+ lldb::TypeSP type_sp(new Type(*other_type));
+ m_type_list.Insert(type_sp);
+ return type_sp;
+  }
+
 protected:
   virtual uint32_t CalculateNumCompileUnits() = 0;
   virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;


Index: lldb/include/lldb/Symbol/Type.h
===
--- lldb/include/lldb/Symbol/Type.h
+++ lldb/include/lldb/Symbol/Type.h
@@ -241,6 +241,14 @@
   // This makes an invalid type.  Used for functions that return a Type when
   // they get an error.
   Type();
+
+  Type(Type &t) = default;
+
+  Type(Type &&t) = default;
+
+  Type &operator=(const Type &t) = default;
+
+  Type &operator=(Type &&t) = default;
 };
 
 // the two classes here are used by the public API as a backend to the SBType
Index: lldb/include/lldb/Symbol/SymbolFileOnDemand.h
===
--- lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -241,6 +241,10 @@
 compiler_qual_type, compiler_type_resolve_state, opaque_payload);
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+return m_sym_file_impl->CopyType(other_type);
+  }
+
 private:
   Log *GetLog() const { return ::lldb_private::GetLog(LLDBLog::OnDemand); }
 
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -421,6 +421,8 @@
Type::ResolveState compiler_type_resolve_state,
uint32_t opaque_payload = 0) = 0;
 
+  virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
+
 protected:
   void AssertModuleLock();
 
@@ -521,6 +523,15 @@
  return type_sp;
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+ // Make sure the real symbol file matches when copying types.
+ if (GetBackingSymbolFile() != other_type->GetSymbolFile())
+  return lldb::TypeSP();
+ lldb::TypeSP type_sp(new Type(*other_type));
+ m_type_list.Insert(type_sp);
+ return type_sp;
+  }
+
 protected:
   virtual uint32_t CalculateNumCompileUnits() = 0;
   virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D142052: [lldb] Implement SymbolFile::CopyType

2023-01-20 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG901ba0fcae36: [lldb] Implement SymbolFile::CopyType 
(authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142052/new/

https://reviews.llvm.org/D142052

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/include/lldb/Symbol/SymbolFileOnDemand.h
  lldb/include/lldb/Symbol/Type.h


Index: lldb/include/lldb/Symbol/Type.h
===
--- lldb/include/lldb/Symbol/Type.h
+++ lldb/include/lldb/Symbol/Type.h
@@ -241,6 +241,14 @@
   // This makes an invalid type.  Used for functions that return a Type when
   // they get an error.
   Type();
+
+  Type(Type &t) = default;
+
+  Type(Type &&t) = default;
+
+  Type &operator=(const Type &t) = default;
+
+  Type &operator=(Type &&t) = default;
 };
 
 // the two classes here are used by the public API as a backend to the SBType
Index: lldb/include/lldb/Symbol/SymbolFileOnDemand.h
===
--- lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -241,6 +241,10 @@
 compiler_qual_type, compiler_type_resolve_state, opaque_payload);
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+return m_sym_file_impl->CopyType(other_type);
+  }
+
 private:
   Log *GetLog() const { return ::lldb_private::GetLog(LLDBLog::OnDemand); }
 
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -421,6 +421,8 @@
Type::ResolveState compiler_type_resolve_state,
uint32_t opaque_payload = 0) = 0;
 
+  virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
+
 protected:
   void AssertModuleLock();
 
@@ -521,6 +523,15 @@
  return type_sp;
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+ // Make sure the real symbol file matches when copying types.
+ if (GetBackingSymbolFile() != other_type->GetSymbolFile())
+  return lldb::TypeSP();
+ lldb::TypeSP type_sp(new Type(*other_type));
+ m_type_list.Insert(type_sp);
+ return type_sp;
+  }
+
 protected:
   virtual uint32_t CalculateNumCompileUnits() = 0;
   virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;


Index: lldb/include/lldb/Symbol/Type.h
===
--- lldb/include/lldb/Symbol/Type.h
+++ lldb/include/lldb/Symbol/Type.h
@@ -241,6 +241,14 @@
   // This makes an invalid type.  Used for functions that return a Type when
   // they get an error.
   Type();
+
+  Type(Type &t) = default;
+
+  Type(Type &&t) = default;
+
+  Type &operator=(const Type &t) = default;
+
+  Type &operator=(Type &&t) = default;
 };
 
 // the two classes here are used by the public API as a backend to the SBType
Index: lldb/include/lldb/Symbol/SymbolFileOnDemand.h
===
--- lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -241,6 +241,10 @@
 compiler_qual_type, compiler_type_resolve_state, opaque_payload);
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+return m_sym_file_impl->CopyType(other_type);
+  }
+
 private:
   Log *GetLog() const { return ::lldb_private::GetLog(LLDBLog::OnDemand); }
 
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -421,6 +421,8 @@
Type::ResolveState compiler_type_resolve_state,
uint32_t opaque_payload = 0) = 0;
 
+  virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
+
 protected:
   void AssertModuleLock();
 
@@ -521,6 +523,15 @@
  return type_sp;
   }
 
+  lldb::TypeSP CopyType(const lldb::TypeSP &other_type) override {
+ // Make sure the real symbol file matches when copying types.
+ if (GetBackingSymbolFile() != other_type->GetSymbolFile())
+  return lldb::TypeSP();
+ lldb::TypeSP type_sp(new Type(*other_type));
+ m_type_list.Insert(type_sp);
+ return type_sp;
+  }
+
 protected:
   virtual uint32_t CalculateNumCompileUnits() = 0;
   virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D143772: Adapt TestCustomShell and TestMultipleDebuggers to run under ASAN

2023-02-10 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: JDevlieghere, jingham, aprantl.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

In situations where only LLDB is ASANified, a false positive occurs
unless ASAN_OPTIONS=detect_container_overflow=0 is set in the
environment.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D143772

Files:
  lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
  lldb/test/Shell/Host/TestCustomShell.test


Index: lldb/test/Shell/Host/TestCustomShell.test
===
--- lldb/test/Shell/Host/TestCustomShell.test
+++ lldb/test/Shell/Host/TestCustomShell.test
@@ -7,7 +7,7 @@
 
 # RUN: %clang_host %S/Inputs/simple.c -g -o %t.out
 # RUN: SHELL=bogus not %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | 
FileCheck %s --check-prefix ERROR
-# RUN: env -i %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s
+# RUN: env -i ASAN_OPTIONS='detect_container_overflow=0' %lldb %t.out -b -o 
'process launch -X 1 --' 2>&1 | FileCheck %s
 
 # ERROR: error: shell expansion failed
 # CHECK-NOT: error: shell expansion failed
Index: lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
===
--- lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
+++ lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
@@ -15,7 +15,9 @@
 @skipIfNoSBHeaders
 @skipIfWindows
 def test_multiple_debuggers(self):
-env = {self.dylibPath: self.getLLDBLibraryEnvVal()}
+env = {self.dylibPath: self.getLLDBLibraryEnvVal(),
+  # We need this in order to run under ASAN, in case only LLDB is 
ASANified.
+  'ASAN_OPTIONS':'detect_container_overflow=0'}
 
 self.driver_exe = self.getBuildArtifact("multi-process-driver")
 self.buildDriver('multi-process-driver.cpp', self.driver_exe)


Index: lldb/test/Shell/Host/TestCustomShell.test
===
--- lldb/test/Shell/Host/TestCustomShell.test
+++ lldb/test/Shell/Host/TestCustomShell.test
@@ -7,7 +7,7 @@
 
 # RUN: %clang_host %S/Inputs/simple.c -g -o %t.out
 # RUN: SHELL=bogus not %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s --check-prefix ERROR
-# RUN: env -i %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s
+# RUN: env -i ASAN_OPTIONS='detect_container_overflow=0' %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s
 
 # ERROR: error: shell expansion failed
 # CHECK-NOT: error: shell expansion failed
Index: lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
===
--- lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
+++ lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
@@ -15,7 +15,9 @@
 @skipIfNoSBHeaders
 @skipIfWindows
 def test_multiple_debuggers(self):
-env = {self.dylibPath: self.getLLDBLibraryEnvVal()}
+env = {self.dylibPath: self.getLLDBLibraryEnvVal(),
+  # We need this in order to run under ASAN, in case only LLDB is ASANified.
+  'ASAN_OPTIONS':'detect_container_overflow=0'}
 
 self.driver_exe = self.getBuildArtifact("multi-process-driver")
 self.buildDriver('multi-process-driver.cpp', self.driver_exe)
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D143772: Adapt TestCustomShell and TestMultipleDebuggers to run under ASAN

2023-02-10 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D143772#4119213 , @JDevlieghere 
wrote:

> Why are only these two tests affected? Should this be something we set 
> globally for all the tests? The API tests already have support for forwarding 
> `ASAN_OPTIONS` and lit has a similar concept.

Because they both set their own environment in one way or the other, which 
doesn't happen in the usual cas.

> But I'm a little puzzled by the shell tests, especially since you only 
> updated a single RUN line.

"env -i " means only use the enviroments passed in that line (discard 
everything else).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D143772/new/

https://reviews.llvm.org/D143772

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D143772: Adapt TestCustomShell and TestMultipleDebuggers to run under ASAN

2023-02-10 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG294ca122956f: Adapt TestCustomShell and 
TestMultipleDebuggers to run under ASAN (authored by augusto2112).

Changed prior to commit:
  https://reviews.llvm.org/D143772?vs=496567&id=496643#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D143772/new/

https://reviews.llvm.org/D143772

Files:
  lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
  lldb/test/Shell/Host/TestCustomShell.test


Index: lldb/test/Shell/Host/TestCustomShell.test
===
--- lldb/test/Shell/Host/TestCustomShell.test
+++ lldb/test/Shell/Host/TestCustomShell.test
@@ -7,7 +7,7 @@
 
 # RUN: %clang_host %S/Inputs/simple.c -g -o %t.out
 # RUN: SHELL=bogus not %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | 
FileCheck %s --check-prefix ERROR
-# RUN: env -i %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s
+# RUN: env -i ASAN_OPTIONS='detect_container_overflow=0' %lldb %t.out -b -o 
'process launch -X 1 --' 2>&1 | FileCheck %s
 
 # ERROR: error: shell expansion failed
 # CHECK-NOT: error: shell expansion failed
Index: lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
===
--- lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
+++ lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
@@ -15,7 +15,9 @@
 @skipIfNoSBHeaders
 @skipIfWindows
 def test_multiple_debuggers(self):
-env = {self.dylibPath: self.getLLDBLibraryEnvVal()}
+env = {self.dylibPath: self.getLLDBLibraryEnvVal(),
+  # We need this in order to run under ASAN, in case only LLDB is 
ASANified.
+  'ASAN_OPTIONS': os.getenv('ASAN_OPTIONS', None)}
 
 self.driver_exe = self.getBuildArtifact("multi-process-driver")
 self.buildDriver('multi-process-driver.cpp', self.driver_exe)


Index: lldb/test/Shell/Host/TestCustomShell.test
===
--- lldb/test/Shell/Host/TestCustomShell.test
+++ lldb/test/Shell/Host/TestCustomShell.test
@@ -7,7 +7,7 @@
 
 # RUN: %clang_host %S/Inputs/simple.c -g -o %t.out
 # RUN: SHELL=bogus not %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s --check-prefix ERROR
-# RUN: env -i %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s
+# RUN: env -i ASAN_OPTIONS='detect_container_overflow=0' %lldb %t.out -b -o 'process launch -X 1 --' 2>&1 | FileCheck %s
 
 # ERROR: error: shell expansion failed
 # CHECK-NOT: error: shell expansion failed
Index: lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
===
--- lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
+++ lldb/test/API/api/multiple-debuggers/TestMultipleDebuggers.py
@@ -15,7 +15,9 @@
 @skipIfNoSBHeaders
 @skipIfWindows
 def test_multiple_debuggers(self):
-env = {self.dylibPath: self.getLLDBLibraryEnvVal()}
+env = {self.dylibPath: self.getLLDBLibraryEnvVal(),
+  # We need this in order to run under ASAN, in case only LLDB is ASANified.
+  'ASAN_OPTIONS': os.getenv('ASAN_OPTIONS', None)}
 
 self.driver_exe = self.getBuildArtifact("multi-process-driver")
 self.buildDriver('multi-process-driver.cpp', self.driver_exe)
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D145612: [lldb] Only replace valobj with persisted one if not null in DWIMPrint

2023-03-08 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added a reviewer: kastiglione.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145612

Files:
  lldb/source/Commands/CommandObjectDWIMPrint.cpp


Index: lldb/source/Commands/CommandObjectDWIMPrint.cpp
===
--- lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -88,8 +88,11 @@
   if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
 auto valobj_sp = frame->FindVariable(ConstString(expr));
 if (valobj_sp && valobj_sp->GetError().Success()) {
-  if (!eval_options.GetSuppressPersistentResult())
-valobj_sp = valobj_sp->Persist();
+  if (!eval_options.GetSuppressPersistentResult()) {
+auto persisted_valobj = valobj_sp->Persist();
+if (persisted_valobj)
+  valobj_sp = persisted_valobj;
+  }
 
   if (verbosity == eDWIMPrintVerbosityFull) {
 StringRef flags;


Index: lldb/source/Commands/CommandObjectDWIMPrint.cpp
===
--- lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -88,8 +88,11 @@
   if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
 auto valobj_sp = frame->FindVariable(ConstString(expr));
 if (valobj_sp && valobj_sp->GetError().Success()) {
-  if (!eval_options.GetSuppressPersistentResult())
-valobj_sp = valobj_sp->Persist();
+  if (!eval_options.GetSuppressPersistentResult()) {
+auto persisted_valobj = valobj_sp->Persist();
+if (persisted_valobj)
+  valobj_sp = persisted_valobj;
+  }
 
   if (verbosity == eDWIMPrintVerbosityFull) {
 StringRef flags;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D145612: [lldb] Only replace valobj with persisted one if not null in DWIMPrint

2023-03-08 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG581ac50d58b9: [lldb] Only replace valobj with persisted one 
if not null in DWIMPrint (authored by augusto2112).

Changed prior to commit:
  https://reviews.llvm.org/D145612?vs=503503&id=503518#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D145612/new/

https://reviews.llvm.org/D145612

Files:
  lldb/source/Commands/CommandObjectDWIMPrint.cpp


Index: lldb/source/Commands/CommandObjectDWIMPrint.cpp
===
--- lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -88,8 +88,10 @@
   if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
 auto valobj_sp = frame->FindVariable(ConstString(expr));
 if (valobj_sp && valobj_sp->GetError().Success()) {
-  if (!eval_options.GetSuppressPersistentResult())
-valobj_sp = valobj_sp->Persist();
+  if (!eval_options.GetSuppressPersistentResult()) {
+if (auto persisted_valobj = valobj_sp->Persist())
+  valobj_sp = persisted_valobj;
+  }
 
   if (verbosity == eDWIMPrintVerbosityFull) {
 StringRef flags;


Index: lldb/source/Commands/CommandObjectDWIMPrint.cpp
===
--- lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -88,8 +88,10 @@
   if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
 auto valobj_sp = frame->FindVariable(ConstString(expr));
 if (valobj_sp && valobj_sp->GetError().Success()) {
-  if (!eval_options.GetSuppressPersistentResult())
-valobj_sp = valobj_sp->Persist();
+  if (!eval_options.GetSuppressPersistentResult()) {
+if (auto persisted_valobj = valobj_sp->Persist())
+  valobj_sp = persisted_valobj;
+  }
 
   if (verbosity == eDWIMPrintVerbosityFull) {
 StringRef flags;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D146265: [lldb] Introduce SymbolFile::ParseAllLanguages

2023-03-16 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added a reviewer: aprantl.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: lldb-commits, jplehr, sstefan1.
Herald added a project: LLDB.

SymbolFile::ParseAllLanguages allows collecting the languages of the
extra compile units a SymbolFileDWARFDebugMap may have, which can't
be accessed otherwise. For every other symbol file type, it should
behave exactly the same as ParseLanguage.

rdar://97610458


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146265

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h


Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -62,6 +62,8 @@
   ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
   lldb_private::XcodeSDK
   ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
+  llvm::SmallSet
+  ParseAllLanguages(lldb_private::CompileUnit &comp_unit) override;
   size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
   bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
   bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -683,6 +683,17 @@
   return {};
 }
 
+llvm::SmallSet
+SymbolFileDWARFDebugMap::ParseAllLanguages(
+lldb_private::CompileUnit &comp_unit) {
+  llvm::SmallSet langs;
+  auto *info = GetCompUnitInfo(comp_unit);
+  for (auto &comp_unit : info->compile_units_sps) {
+langs.insert(comp_unit->GetLanguage());
+  }
+  return langs;
+}
+
 size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
   std::lock_guard guard(GetModuleMutex());
   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -25,6 +25,7 @@
 #include "lldb/Utility/XcodeSDK.h"
 #include "lldb/lldb-private.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/Support/Errc.h"
 
 #include 
@@ -146,6 +147,17 @@
   virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0;
   /// Return the Xcode SDK comp_unit was compiled against.
   virtual XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) { return {}; }
+
+  /// This function exists because SymbolFileDWARFDebugMap may extra compile
+  /// units which aren't exposed as "real" compile units. In every other
+  /// case this function should behave identically as ParseLanguage.
+  virtual llvm::SmallSet
+  ParseAllLanguages(CompileUnit &comp_unit) {
+llvm::SmallSet langs;
+langs.insert(ParseLanguage(comp_unit));
+return langs;
+  }
+
   virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0;
   virtual bool ParseLineTable(CompileUnit &comp_unit) = 0;
   virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0;


Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -62,6 +62,8 @@
   ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
   lldb_private::XcodeSDK
   ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
+  llvm::SmallSet
+  ParseAllLanguages(lldb_private::CompileUnit &comp_unit) override;
   size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
   bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
   bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -683,6 +683,17 @@
   return {};
 }
 
+llvm::SmallSet
+SymbolFileDWARFDebugMap::ParseAllLanguages(
+lldb_private::CompileUnit &comp_unit) {
+  llvm::SmallSet langs;
+  auto *info = GetCompUnitInfo(comp_unit);
+  for (auto &comp_unit : info->compile_units_sps) {
+langs.insert(comp_unit->GetLanguage());
+  }
+  return langs;
+}
+
 size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
   std::lock_guard 

[Lldb-commits] [PATCH] D146265: [lldb] Introduce SymbolFile::ParseAllLanguages

2023-03-18 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf03cd763384b: [lldb] Introduce SymbolFile::ParseAllLanguages 
(authored by augusto2112).

Changed prior to commit:
  https://reviews.llvm.org/D146265?vs=505952&id=506307#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146265/new/

https://reviews.llvm.org/D146265

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h


Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -62,6 +62,8 @@
   ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
   lldb_private::XcodeSDK
   ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
+  llvm::SmallSet
+  ParseAllLanguages(lldb_private::CompileUnit &comp_unit) override;
   size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
   bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
   bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -683,6 +683,17 @@
   return {};
 }
 
+llvm::SmallSet
+SymbolFileDWARFDebugMap::ParseAllLanguages(
+lldb_private::CompileUnit &comp_unit) {
+  llvm::SmallSet langs;
+  auto *info = GetCompUnitInfo(comp_unit);
+  for (auto &comp_unit : info->compile_units_sps) {
+langs.insert(comp_unit->GetLanguage());
+  }
+  return langs;
+}
+
 size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
   std::lock_guard guard(GetModuleMutex());
   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -25,6 +25,7 @@
 #include "lldb/Utility/XcodeSDK.h"
 #include "lldb/lldb-private.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/Support/Errc.h"
 
 #include 
@@ -146,6 +147,17 @@
   virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0;
   /// Return the Xcode SDK comp_unit was compiled against.
   virtual XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) { return {}; }
+
+  /// This function exists because SymbolFileDWARFDebugMap may extra compile
+  /// units which aren't exposed as "real" compile units. In every other
+  /// case this function should behave identically as ParseLanguage.
+  virtual llvm::SmallSet
+  ParseAllLanguages(CompileUnit &comp_unit) {
+llvm::SmallSet langs;
+langs.insert(ParseLanguage(comp_unit));
+return langs;
+  }
+
   virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0;
   virtual bool ParseLineTable(CompileUnit &comp_unit) = 0;
   virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0;


Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -62,6 +62,8 @@
   ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
   lldb_private::XcodeSDK
   ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
+  llvm::SmallSet
+  ParseAllLanguages(lldb_private::CompileUnit &comp_unit) override;
   size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
   bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
   bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -683,6 +683,17 @@
   return {};
 }
 
+llvm::SmallSet
+SymbolFileDWARFDebugMap::ParseAllLanguages(
+lldb_private::CompileUnit &comp_unit) {
+  llvm::SmallSet langs;
+  auto *info = GetCompUnitInfo(comp_unit);
+  for (auto &comp_unit : info->compile_units_sps) {
+langs.insert(comp_unit->GetLanguage());
+  }
+  return langs;
+}
+
 size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
   std::lock_guard guard(GetModuleMutex());
   SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/

[Lldb-commits] [PATCH] D146679: [lldb] Add support for the DW_AT_trampoline attribute with mangled names

2023-03-22 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: aprantl, jingham, dblaikie.
Herald added a reviewer: shafik.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

This patch adds support for the DW_AT_trampoline attribute whose values
are mangled names. This patch makes it so stepping into a trampoline 
will step through to the target subprogram instead, stepping out from the
target subprogram will also step out of the trampoline, and that setting 
breakpoints by name will (by default) ignore trampolines.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146679

Files:
  lldb/include/lldb/Symbol/Function.h
  lldb/include/lldb/Target/Target.h
  lldb/include/lldb/Target/ThreadPlanRunToAddress.h
  lldb/include/lldb/Target/ThreadPlanStepThrough.h
  lldb/source/Core/Module.cpp
  lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
  lldb/source/Symbol/Function.cpp
  lldb/source/Target/Target.cpp
  lldb/source/Target/TargetProperties.td
  lldb/source/Target/ThreadPlanRunToAddress.cpp
  lldb/source/Target/ThreadPlanShouldStopHere.cpp
  lldb/source/Target/ThreadPlanStepThrough.cpp
  lldb/test/API/lang/c/trampoline_stepping/Makefile
  lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
  lldb/test/API/lang/c/trampoline_stepping/main.c

Index: lldb/test/API/lang/c/trampoline_stepping/main.c
===
--- /dev/null
+++ lldb/test/API/lang/c/trampoline_stepping/main.c
@@ -0,0 +1,41 @@
+void bar(void) {}
+
+__attribute__((__trampoline__("bar")))
+void foo(void) {
+  bar();
+}
+
+__attribute__((__trampoline__("bar")))
+void baz(void) {
+  bar();
+}
+
+__attribute__((__trampoline__("bar")))
+void doesnt_call_trampoline(void) {
+  int a = 2;
+  int b = 3;
+  int c = a + b;
+}
+
+
+void direct_trampoline_call(void) {
+  foo(); // Break here for direct 
+  foo();
+}
+
+void chained_trampoline_call(void) {
+  baz(); // Break here for chained
+  baz();
+}
+
+void unused_target(void) {
+  doesnt_call_trampoline(); // Break here for unused
+}
+
+int main(void) {
+  direct_trampoline_call();
+  chained_trampoline_call();
+  unused_target();
+  return 0;
+}
+
Index: lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
===
--- /dev/null
+++ lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
@@ -0,0 +1,79 @@
+"""Test that stepping in/out of trampolines works as expected.
+"""
+
+
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestTrampoline(TestBase):
+def setup(self, bkpt_str):
+self.build()
+
+_, _, thread, _ = lldbutil.run_to_source_breakpoint(
+self, bkpt_str, lldb.SBFileSpec('main.c'))
+return thread
+
+def test_direct_call(self):
+thread = self.setup('Break here for direct')
+
+# Sanity check that we start out in the correct function.
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+# Check that stepping in will take us directly to the trampoline target.
+thread.StepInto()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('bar', name)
+
+# Check that stepping out takes us back to the trampoline caller.
+thread.StepOut()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+# Check that stepping over the end of the trampoline target 
+# takes us back to the trampoline caller.
+thread.StepInto()
+thread.StepOver()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+
+def test_chained_call(self):
+thread = self.setup('Break here for chained')
+
+# Sanity check that we start out in the correct function.
+name = thread.frames[0].GetFunctionName()
+self.assertIn('chained_trampoline_call', name)
+
+# Check that stepping in will take us directly to the trampoline target.
+thread.StepInto()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('bar', name)
+
+# Check that stepping out takes us back to the trampoline caller.
+thread.StepOut()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('chained_trampoline_call', name)
+
+# Check that stepping over the end of the trampoline target 
+# takes us back to the trampolin

[Lldb-commits] [PATCH] D146679: [lldb] Add support for the DW_AT_trampoline attribute with mangled names

2023-03-23 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 507841.
augusto2112 marked 14 inline comments as done.
augusto2112 added a comment.

Addressed comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146679/new/

https://reviews.llvm.org/D146679

Files:
  lldb/include/lldb/Symbol/Function.h
  lldb/include/lldb/Target/Target.h
  lldb/include/lldb/Target/ThreadPlanRunToAddress.h
  lldb/include/lldb/Target/ThreadPlanStepThrough.h
  lldb/source/Core/Module.cpp
  lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
  lldb/source/Symbol/Function.cpp
  lldb/source/Target/Target.cpp
  lldb/source/Target/TargetProperties.td
  lldb/source/Target/ThreadPlanRunToAddress.cpp
  lldb/source/Target/ThreadPlanShouldStopHere.cpp
  lldb/source/Target/ThreadPlanStepThrough.cpp
  lldb/test/API/lang/c/trampoline_stepping/Makefile
  lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
  lldb/test/API/lang/c/trampoline_stepping/main.c

Index: lldb/test/API/lang/c/trampoline_stepping/main.c
===
--- /dev/null
+++ lldb/test/API/lang/c/trampoline_stepping/main.c
@@ -0,0 +1,41 @@
+void foo(void) {}
+
+__attribute__((__trampoline__("foo")))
+void bar(void) {
+  foo();
+}
+
+__attribute__((__trampoline__("bar")))
+void baz(void) {
+  bar();
+}
+
+__attribute__((__trampoline__("bar")))
+void doesnt_call_trampoline(void) {
+  int a = 2;
+  int b = 3;
+  int c = a + b;
+}
+
+
+void direct_trampoline_call(void) {
+  bar(); // Break here for direct 
+  bar();
+}
+
+void chained_trampoline_call(void) {
+  baz(); // Break here for chained
+  baz();
+}
+
+void unused_target(void) {
+  doesnt_call_trampoline(); // Break here for unused
+}
+
+int main(void) {
+  direct_trampoline_call();
+  chained_trampoline_call();
+  unused_target();
+  return 0;
+}
+
Index: lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
===
--- /dev/null
+++ lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
@@ -0,0 +1,80 @@
+"""Test that stepping in/out of trampolines works as expected.
+"""
+
+
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestTrampoline(TestBase):
+def setup(self, bkpt_str):
+self.build()
+
+_, _, thread, _ = lldbutil.run_to_source_breakpoint(
+self, bkpt_str, lldb.SBFileSpec('main.c'))
+return thread
+
+def test_direct_call(self):
+thread = self.setup('Break here for direct')
+
+# Sanity check that we start out in the correct function.
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+# Check that stepping in will take us directly to the trampoline target.
+thread.StepInto()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('foo', name)
+
+# Check that stepping out takes us back to the trampoline caller.
+thread.StepOut()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+# Check that stepping over the end of the trampoline target 
+# takes us back to the trampoline caller.
+thread.StepInto()
+thread.StepOver()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+
+def test_chained_call(self):
+thread = self.setup('Break here for chained')
+
+# Sanity check that we start out in the correct function.
+name = thread.frames[0].GetFunctionName()
+self.assertIn('chained_trampoline_call', name)
+
+# Check that stepping in will take us directly to the trampoline target.
+thread.StepInto()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('foo', name)
+
+# Check that stepping out takes us back to the trampoline caller.
+thread.StepOut()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('chained_trampoline_call', name)
+
+# Check that stepping over the end of the trampoline target 
+# takes us back to the trampoline caller.
+thread.StepInto()
+thread.StepOver()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('chained_trampoline_call', name)
+
+def test_unused_target(self):
+thread = self.setup('Break here for unused')
+
+# Sanity check that we start out in the correct function.
+name = thread.frames[0].GetFunctionName()
+self.assertIn('un

[Lldb-commits] [PATCH] D146679: [lldb] Add support for the DW_AT_trampoline attribute with mangled names

2023-03-23 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added inline comments.



Comment at: lldb/include/lldb/Target/Target.h:253
 
+  bool GetEnableTrampolineSupport() const;
+

JDevlieghere wrote:
> What does trampoline "support" mean? Could this be named something more 
> descriptive? From the description of the patch it sounds like this guards 
> whether you step through trampolines, so maybe something like 
> `GetEnableStepThroughTrampolines` or something? 
Yeah I agree the name is pretty generic. This guards both stepping and setting 
breakpoints on trampolines (by name). We could potentially have two different 
settings (one for stepping on trampolines, one for breakpoints), but at the 
same time I don't think there are many users who would want to change only of 
or the other. I'll add a doxygen comment here with the explanation of what this 
does, but I'd be happy to change the setting name if anyone has a better 
suggestion.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146679/new/

https://reviews.llvm.org/D146679

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D147292: [lldb] Add support for the DW_AT_trampoline attribute with a boolean

2023-03-30 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: aprantl, jingham, dblaikie.
Herald added a reviewer: shafik.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

This patch adds support for the DW_AT_trampoline attribute whose value
is a boolean. Which is a "generic trampoline". Stepping into a generic
trampoline by default will step through the function, checking
at every branch, until we stop in a function which makes sense to stop
at (a function with debug info, which isn't a trampoline, for example).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147292

Files:
  lldb/include/lldb/Symbol/Function.h
  lldb/include/lldb/Target/Target.h
  lldb/include/lldb/Target/Thread.h
  lldb/include/lldb/Target/ThreadPlan.h
  lldb/include/lldb/Target/ThreadPlanStepOverRange.h
  lldb/include/lldb/Target/ThreadPlanStepRange.h
  lldb/include/lldb/Target/ThreadPlanStepThroughGenericTrampoline.h
  lldb/source/Core/Module.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
  lldb/source/Symbol/Function.cpp
  lldb/source/Target/CMakeLists.txt
  lldb/source/Target/Target.cpp
  lldb/source/Target/TargetProperties.td
  lldb/source/Target/Thread.cpp
  lldb/source/Target/ThreadPlanShouldStopHere.cpp
  lldb/source/Target/ThreadPlanStepInRange.cpp
  lldb/source/Target/ThreadPlanStepOverRange.cpp
  lldb/source/Target/ThreadPlanStepRange.cpp
  lldb/source/Target/ThreadPlanStepThrough.cpp
  lldb/source/Target/ThreadPlanStepThroughGenericTrampoline.cpp
  lldb/test/API/lang/c/trampoline_stepping/Makefile
  lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
  lldb/test/API/lang/c/trampoline_stepping/main.c

Index: lldb/test/API/lang/c/trampoline_stepping/main.c
===
--- /dev/null
+++ lldb/test/API/lang/c/trampoline_stepping/main.c
@@ -0,0 +1,52 @@
+void foo(void) {}
+
+__attribute__((transparent_stepping))
+void bar(void) {
+  foo();
+}
+
+__attribute__((transparent_stepping))
+void baz(void) {
+  bar();
+}
+
+__attribute__((nodebug))
+void nodebug(void) {}
+
+__attribute__((transparent_stepping))
+void nodebug_then_trampoline(void) {
+  nodebug();
+  baz();
+}
+
+__attribute__((transparent_stepping))
+void doesnt_call_trampoline(void) {}
+
+void direct_trampoline_call(void) {
+  bar(); // Break here for direct 
+  bar();
+}
+
+void chained_trampoline_call(void) {
+  baz(); // Break here for chained
+  baz();
+}
+
+void trampoline_after_nodebug(void) {
+  nodebug_then_trampoline(); // Break here for nodebug then trampoline
+  nodebug_then_trampoline();
+}
+
+void unused_target(void) {
+  doesnt_call_trampoline(); // Break here for unused
+}
+
+
+int main(void) {
+  direct_trampoline_call();
+  chained_trampoline_call();
+  trampoline_after_nodebug();
+  unused_target();
+  return 0;
+}
+
Index: lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
===
--- /dev/null
+++ lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
@@ -0,0 +1,104 @@
+"""Test that stepping in/out of trampolines works as expected.
+"""
+
+
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestTrampoline(TestBase):
+def setup(self, bkpt_str):
+self.build()
+
+_, _, thread, _ = lldbutil.run_to_source_breakpoint(
+self, bkpt_str, lldb.SBFileSpec('main.c'))
+return thread
+
+def test_direct_call(self):
+thread = self.setup('Break here for direct')
+
+# Sanity check that we start out in the correct function.
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+# Check that stepping in will take us directly to the trampoline target.
+thread.StepInto()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('foo', name)
+
+# Check that stepping out takes us back to the trampoline caller.
+thread.StepOut()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+# Check that stepping over the end of the trampoline target 
+# takes us back to the trampoline caller.
+thread.StepInto()
+thread.StepOver()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+
+def test_chained_call(self):
+thread = self.setup('Break here for chained')
+
+# Sanity check that we start out in the correct function.
+name = thread.frames[0].GetFunctionName

[Lldb-commits] [PATCH] D147292: [lldb] Add support for the DW_AT_trampoline attribute with a boolean

2023-04-01 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D147292#4238820 , @JDevlieghere 
wrote:

> There seems to be overlap in the code added in this patch and D146679 
> . Does one supersede the other or is there 
> a dependency? If it's the latter you should extract that into a separate 
> patch and make it a parent revision of this and D146679 
> .

Yes, sorry, I'm abandoning the other one in favor of this one.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147292/new/

https://reviews.llvm.org/D147292

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D146679: [lldb] Add support for the DW_AT_trampoline attribute with mangled names

2023-04-01 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 abandoned this revision.
augusto2112 added a comment.

Abandoning in favor of https://reviews.llvm.org/D147292/.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146679/new/

https://reviews.llvm.org/D146679

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D147292: [lldb] Add support for the DW_AT_trampoline attribute with a boolean

2023-04-06 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 511549.
augusto2112 marked 3 inline comments as done.
augusto2112 added a comment.

Addressed comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147292/new/

https://reviews.llvm.org/D147292

Files:
  lldb/include/lldb/Symbol/Function.h
  lldb/include/lldb/Target/Target.h
  lldb/include/lldb/Target/Thread.h
  lldb/include/lldb/Target/ThreadPlan.h
  lldb/include/lldb/Target/ThreadPlanStepOverRange.h
  lldb/include/lldb/Target/ThreadPlanStepRange.h
  lldb/include/lldb/Target/ThreadPlanStepThroughGenericTrampoline.h
  lldb/source/Core/Module.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
  lldb/source/Symbol/Function.cpp
  lldb/source/Target/CMakeLists.txt
  lldb/source/Target/Target.cpp
  lldb/source/Target/TargetProperties.td
  lldb/source/Target/Thread.cpp
  lldb/source/Target/ThreadPlanShouldStopHere.cpp
  lldb/source/Target/ThreadPlanStepInRange.cpp
  lldb/source/Target/ThreadPlanStepOverRange.cpp
  lldb/source/Target/ThreadPlanStepRange.cpp
  lldb/source/Target/ThreadPlanStepThrough.cpp
  lldb/source/Target/ThreadPlanStepThroughGenericTrampoline.cpp
  lldb/test/API/lang/c/trampoline_stepping/Makefile
  lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
  lldb/test/API/lang/c/trampoline_stepping/main.c

Index: lldb/test/API/lang/c/trampoline_stepping/main.c
===
--- /dev/null
+++ lldb/test/API/lang/c/trampoline_stepping/main.c
@@ -0,0 +1,52 @@
+void foo(void) {}
+
+__attribute__((debug_trampoline))
+void bar(void) {
+  foo();
+}
+
+__attribute__((debug_trampoline))
+void baz(void) {
+  bar();
+}
+
+__attribute__((nodebug))
+void nodebug(void) {}
+
+__attribute__((debug_trampoline))
+void nodebug_then_trampoline(void) {
+  nodebug();
+  baz();
+}
+
+__attribute__((debug_trampoline))
+void doesnt_call_trampoline(void) {}
+
+void direct_trampoline_call(void) {
+  bar(); // Break here for direct 
+  bar();
+}
+
+void chained_trampoline_call(void) {
+  baz(); // Break here for chained
+  baz();
+}
+
+void trampoline_after_nodebug(void) {
+  nodebug_then_trampoline(); // Break here for nodebug then trampoline
+  nodebug_then_trampoline();
+}
+
+void unused_target(void) {
+  doesnt_call_trampoline(); // Break here for unused
+}
+
+
+int main(void) {
+  direct_trampoline_call();
+  chained_trampoline_call();
+  trampoline_after_nodebug();
+  unused_target();
+  return 0;
+}
+
Index: lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
===
--- /dev/null
+++ lldb/test/API/lang/c/trampoline_stepping/TestTrampolineStepping.py
@@ -0,0 +1,104 @@
+"""Test that stepping in/out of trampolines works as expected.
+"""
+
+
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestTrampoline(TestBase):
+def setup(self, bkpt_str):
+self.build()
+
+_, _, thread, _ = lldbutil.run_to_source_breakpoint(
+self, bkpt_str, lldb.SBFileSpec('main.c'))
+return thread
+
+def test_direct_call(self):
+thread = self.setup('Break here for direct')
+
+# Sanity check that we start out in the correct function.
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+# Check that stepping in will take us directly to the trampoline target.
+thread.StepInto()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('foo', name)
+
+# Check that stepping out takes us back to the trampoline caller.
+thread.StepOut()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+# Check that stepping over the end of the trampoline target 
+# takes us back to the trampoline caller.
+thread.StepInto()
+thread.StepOver()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('direct_trampoline_call', name)
+
+
+def test_chained_call(self):
+thread = self.setup('Break here for chained')
+
+# Sanity check that we start out in the correct function.
+name = thread.frames[0].GetFunctionName()
+self.assertIn('chained_trampoline_call', name)
+
+# Check that stepping in will take us directly to the trampoline target.
+thread.StepInto()
+name = thread.frames[0].GetFunctionName()
+self.assertIn('foo', name)
+
+# Check that stepping out takes us back to the trampoline caller.
+thread.StepOut()
+name = thread.frames[0].GetFunctionName()
+self.

[Lldb-commits] [PATCH] D147748: [lldb] Implement SymbolFile::ContainsCompileOption

2023-04-06 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added a reviewer: aprantl.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Implement SymbolFile::ContainsCompileOption, which returns true if the
string option was used when compiling the binary.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147748

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h

Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -153,6 +153,8 @@
   // Statistics overrides.
   lldb_private::ModuleList GetDebugInfoModules() override;
 
+  bool ContainsCompileOption(const char *option) override;
+
 protected:
   enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
 
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -1549,3 +1549,12 @@
   }
   return Status();
 }
+
+bool SymbolFileDWARFDebugMap::ContainsCompileOption(const char *option) {
+  bool success = false;
+  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+success |= oso_dwarf->ContainsCompileOption(option);
+return success;
+  });
+  return success;
+}
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -340,6 +340,8 @@
 m_file_index = file_index;
   }
 
+  bool ContainsCompileOption(const char *option) override;
+
 protected:
   typedef llvm::DenseMap
   DIEToTypePtr;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4255,3 +4255,36 @@
   return Status("no variable information is available in debug info for this "
 "compile unit");
 }
+
+bool SymbolFileDWARF::ContainsCompileOption(const char *option) {
+  auto check_in_dwarf_cu = [&option](DWARFUnit *dwarf_cu) {
+const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
+if (!die)
+  return false;
+const char *flags = die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL);
+
+if (!flags)
+  return false;
+if (!strstr(flags, option))
+  return false;
+Args compiler_args(flags);
+for (auto &arg : compiler_args.GetArgumentArrayRef())
+  if (strcmp(arg, option) == 0)
+return true;
+
+return false;
+  };
+
+  DWARFDebugInfo &debug_info = DebugInfo();
+  const uint32_t num_compile_units = GetNumCompileUnits();
+
+  for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+DWARFUnit *dwarf_cu = debug_info.GetUnitAtIndex(cu_idx);
+if (dwarf_cu) {
+  if (check_in_dwarf_cu(dwarf_cu))
+return true;
+}
+  }
+
+  return false;
+}
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -435,6 +435,12 @@
 
   virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
 
+  /// Returns true if the option exists in the compile options encoded in 
+  /// the symbol file.
+  virtual bool ContainsCompileOption(const char *option) {
+return false;
+  }
+
 protected:
   void AssertModuleLock();
 
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D147748: [lldb] Implement SymbolFile::ContainsCompileOption

2023-04-07 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D147748#4251543 , @JDevlieghere 
wrote:

> At a higher level I wonder if this is really the best interface. If you ever 
> need all the compile options, you probably want something like `Args 
> SymbolFile::GetCompileOptions()`. Wouldn't that be a more generic way to do 
> the same thing here? Or do we expect that for `DW_AT_APPLE_flags` the only 
> possible use case is to check whether a particular flag is set?

I agree. I implemented it in such a a way to mirror the `GetCompileOption` 
function (which apparently doesn't exist upstream anymore). I'll update it to 
return the `Args` instead.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147748/new/

https://reviews.llvm.org/D147748

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D147748: [lldb] Implement SymbolFile::ContainsCompileOption

2023-04-07 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 511815.
augusto2112 marked an inline comment as done.
augusto2112 added a comment.
Herald added a reviewer: jdoerfert.
Herald added subscribers: jplehr, sstefan1.

Changed implementation to GetCompileOptions


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147748/new/

https://reviews.llvm.org/D147748

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h

Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -153,6 +153,9 @@
   // Statistics overrides.
   lldb_private::ModuleList GetDebugInfoModules() override;
 
+  void GetCompileOptions(
+  std::unordered_map &args) override;
+
 protected:
   enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
 
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -1549,3 +1549,12 @@
   }
   return Status();
 }
+
+void SymbolFileDWARFDebugMap::GetCompileOptions(
+std::unordered_map &args) {
+
+  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+oso_dwarf->GetCompileOptions(args);
+return false;
+  });
+}
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -523,6 +523,9 @@
 
   void InitializeFirstCodeAddress();
 
+  void GetCompileOptions(
+  std::unordered_map &args) override;
+
   lldb::ModuleWP m_debug_map_module_wp;
   SymbolFileDWARFDebugMap *m_debug_map_symfile;
 
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4255,3 +4255,30 @@
   return Status("no variable information is available in debug info for this "
 "compile unit");
 }
+
+void SymbolFileDWARF::GetCompileOptions(
+std::unordered_map &args) {
+
+  const uint32_t num_compile_units = GetNumCompileUnits();
+
+  for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+lldb::CompUnitSP comp_unit = GetCompileUnitAtIndex(cu_idx);
+if (!comp_unit)
+  continue;
+
+DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit.get());
+if (!dwarf_cu)
+  continue;
+
+const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
+if (!die)
+  continue;
+
+const char *flags = die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL);
+
+if (!flags)
+  continue;
+args.insert({comp_unit, Args(flags)});
+  }
+}
+
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -30,6 +30,7 @@
 
 #include 
 #include 
+#include 
 
 #if defined(LLDB_CONFIGURATION_DEBUG)
 #define ASSERT_MODULE_LOCK(expr) (expr->AssertModuleLock())
@@ -435,9 +436,20 @@
 
   virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
 
+  /// Returns a map of compilation unit to the compile option arguments
+  /// associated with that compilation unit.
+  std::unordered_map GetCompileOptions() {
+std::unordered_map args;
+GetCompileOptions(args);
+return args;
+  }
+
 protected:
   void AssertModuleLock();
 
+  virtual void GetCompileOptions(
+  std::unordered_map &args) {}
+
 private:
   SymbolFile(const SymbolFile &) = delete;
   const SymbolFile &operator=(const SymbolFile &) = delete;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D147748: [lldb] Implement SymbolFile::GetCompileOptions

2023-04-07 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added inline comments.



Comment at: lldb/include/lldb/Symbol/SymbolFile.h:441
+  /// associated with that compilation unit.
+  std::unordered_map GetCompileOptions() {
+std::unordered_map args;

JDevlieghere wrote:
> Any reason you picked `unordered_map`? Not that I expected this code to be 
> particularly hot, but I would've gone for an `llvm::DenseMap` which should 
> offer much better performance characteristics. 
Mainly because there's no implementation of shared pointer as keys for dense 
maps (`DenseMapInfo` where the `T` is a `shared_ptr`) at the moment, and I 
don't expect this to be super hot.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147748/new/

https://reviews.llvm.org/D147748

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D147748: [lldb] Implement SymbolFile::GetCompileOptions

2023-04-10 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG19d969e340c9: [lldb] Implement SymbolFile::GetCompileOptions 
(authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147748/new/

https://reviews.llvm.org/D147748

Files:
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h

Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -153,6 +153,9 @@
   // Statistics overrides.
   lldb_private::ModuleList GetDebugInfoModules() override;
 
+  void GetCompileOptions(
+  std::unordered_map &args) override;
+
 protected:
   enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
 
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -1549,3 +1549,12 @@
   }
   return Status();
 }
+
+void SymbolFileDWARFDebugMap::GetCompileOptions(
+std::unordered_map &args) {
+
+  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+oso_dwarf->GetCompileOptions(args);
+return false;
+  });
+}
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -523,6 +523,9 @@
 
   void InitializeFirstCodeAddress();
 
+  void GetCompileOptions(
+  std::unordered_map &args) override;
+
   lldb::ModuleWP m_debug_map_module_wp;
   SymbolFileDWARFDebugMap *m_debug_map_symfile;
 
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4255,3 +4255,30 @@
   return Status("no variable information is available in debug info for this "
 "compile unit");
 }
+
+void SymbolFileDWARF::GetCompileOptions(
+std::unordered_map &args) {
+
+  const uint32_t num_compile_units = GetNumCompileUnits();
+
+  for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+lldb::CompUnitSP comp_unit = GetCompileUnitAtIndex(cu_idx);
+if (!comp_unit)
+  continue;
+
+DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit.get());
+if (!dwarf_cu)
+  continue;
+
+const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
+if (!die)
+  continue;
+
+const char *flags = die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL);
+
+if (!flags)
+  continue;
+args.insert({comp_unit, Args(flags)});
+  }
+}
+
Index: lldb/include/lldb/Symbol/SymbolFile.h
===
--- lldb/include/lldb/Symbol/SymbolFile.h
+++ lldb/include/lldb/Symbol/SymbolFile.h
@@ -30,6 +30,7 @@
 
 #include 
 #include 
+#include 
 
 #if defined(LLDB_CONFIGURATION_DEBUG)
 #define ASSERT_MODULE_LOCK(expr) (expr->AssertModuleLock())
@@ -435,9 +436,20 @@
 
   virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
 
+  /// Returns a map of compilation unit to the compile option arguments
+  /// associated with that compilation unit.
+  std::unordered_map GetCompileOptions() {
+std::unordered_map args;
+GetCompileOptions(args);
+return args;
+  }
+
 protected:
   void AssertModuleLock();
 
+  virtual void GetCompileOptions(
+  std::unordered_map &args) {}
+
 private:
   SymbolFile(const SymbolFile &) = delete;
   const SymbolFile &operator=(const SymbolFile &) = delete;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D150826: [lldb] Implement GetValueTypeFromAddressType

2023-05-17 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added a reviewer: aprantl.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Value::ValueType is a superset of AddressType. Add a function to
convert an AddressType into a Value::ValueType.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150826

Files:
  lldb/include/lldb/Core/Value.h
  lldb/source/Core/Value.cpp


Index: lldb/source/Core/Value.cpp
===
--- lldb/source/Core/Value.cpp
+++ lldb/source/Core/Value.cpp
@@ -121,6 +121,19 @@
   return eAddressTypeInvalid;
 }
 
+Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) {
+  switch (address_type) {
+case eAddressTypeFile:
+  return Value::ValueType::FileAddress;
+case eAddressTypeLoad:
+  return Value::ValueType::LoadAddress;
+case eAddressTypeHost:
+  return Value::ValueType::HostAddress;
+case eAddressTypeInvalid:
+  return Value::ValueType::Invalid;
+  }
+}
+
 RegisterInfo *Value::GetRegisterInfo() const {
   if (m_context_type == ContextType::RegisterInfo)
 return static_cast(m_context);
Index: lldb/include/lldb/Core/Value.h
===
--- lldb/include/lldb/Core/Value.h
+++ lldb/include/lldb/Core/Value.h
@@ -145,6 +145,8 @@
 
   void Clear();
 
+  static ValueType GetValueTypeFromAddressType(AddressType address_type);
+
 protected:
   Scalar m_value;
   CompilerType m_compiler_type;


Index: lldb/source/Core/Value.cpp
===
--- lldb/source/Core/Value.cpp
+++ lldb/source/Core/Value.cpp
@@ -121,6 +121,19 @@
   return eAddressTypeInvalid;
 }
 
+Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) {
+  switch (address_type) {
+case eAddressTypeFile:
+  return Value::ValueType::FileAddress;
+case eAddressTypeLoad:
+  return Value::ValueType::LoadAddress;
+case eAddressTypeHost:
+  return Value::ValueType::HostAddress;
+case eAddressTypeInvalid:
+  return Value::ValueType::Invalid;
+  }
+}
+
 RegisterInfo *Value::GetRegisterInfo() const {
   if (m_context_type == ContextType::RegisterInfo)
 return static_cast(m_context);
Index: lldb/include/lldb/Core/Value.h
===
--- lldb/include/lldb/Core/Value.h
+++ lldb/include/lldb/Core/Value.h
@@ -145,6 +145,8 @@
 
   void Clear();
 
+  static ValueType GetValueTypeFromAddressType(AddressType address_type);
+
 protected:
   Scalar m_value;
   CompilerType m_compiler_type;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D150826: [lldb] Implement GetValueTypeFromAddressType

2023-05-17 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 added a comment.

In D150826#4351518 , @bulbazord wrote:

> Where do you plan on using this? Downstream I assume?

Yes, I need this downstream, but seemed general enough to add upstream.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150826/new/

https://reviews.llvm.org/D150826

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D150826: [lldb] Implement GetValueTypeFromAddressType

2023-05-17 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 523219.
augusto2112 added a comment.

Add llvm_unreachable


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150826/new/

https://reviews.llvm.org/D150826

Files:
  lldb/include/lldb/Core/Value.h
  lldb/source/Core/Value.cpp


Index: lldb/source/Core/Value.cpp
===
--- lldb/source/Core/Value.cpp
+++ lldb/source/Core/Value.cpp
@@ -121,6 +121,20 @@
   return eAddressTypeInvalid;
 }
 
+Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) {
+  switch (address_type) {
+case eAddressTypeFile:
+  return Value::ValueType::FileAddress;
+case eAddressTypeLoad:
+  return Value::ValueType::LoadAddress;
+case eAddressTypeHost:
+  return Value::ValueType::HostAddress;
+case eAddressTypeInvalid:
+  return Value::ValueType::Invalid;
+  }
+  llvm_unreachable("Unexpected address type!");
+}
+
 RegisterInfo *Value::GetRegisterInfo() const {
   if (m_context_type == ContextType::RegisterInfo)
 return static_cast(m_context);
Index: lldb/include/lldb/Core/Value.h
===
--- lldb/include/lldb/Core/Value.h
+++ lldb/include/lldb/Core/Value.h
@@ -145,6 +145,8 @@
 
   void Clear();
 
+  static ValueType GetValueTypeFromAddressType(AddressType address_type);
+
 protected:
   Scalar m_value;
   CompilerType m_compiler_type;


Index: lldb/source/Core/Value.cpp
===
--- lldb/source/Core/Value.cpp
+++ lldb/source/Core/Value.cpp
@@ -121,6 +121,20 @@
   return eAddressTypeInvalid;
 }
 
+Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) {
+  switch (address_type) {
+case eAddressTypeFile:
+  return Value::ValueType::FileAddress;
+case eAddressTypeLoad:
+  return Value::ValueType::LoadAddress;
+case eAddressTypeHost:
+  return Value::ValueType::HostAddress;
+case eAddressTypeInvalid:
+  return Value::ValueType::Invalid;
+  }
+  llvm_unreachable("Unexpected address type!");
+}
+
 RegisterInfo *Value::GetRegisterInfo() const {
   if (m_context_type == ContextType::RegisterInfo)
 return static_cast(m_context);
Index: lldb/include/lldb/Core/Value.h
===
--- lldb/include/lldb/Core/Value.h
+++ lldb/include/lldb/Core/Value.h
@@ -145,6 +145,8 @@
 
   void Clear();
 
+  static ValueType GetValueTypeFromAddressType(AddressType address_type);
+
 protected:
   Scalar m_value;
   CompilerType m_compiler_type;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D150826: [lldb] Implement GetValueTypeFromAddressType

2023-05-18 Thread Augusto Noronha via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8fe9718dd5f2: [lldb] Implement GetValueTypeFromAddressType 
(authored by augusto2112).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150826/new/

https://reviews.llvm.org/D150826

Files:
  lldb/include/lldb/Core/Value.h
  lldb/source/Core/Value.cpp


Index: lldb/source/Core/Value.cpp
===
--- lldb/source/Core/Value.cpp
+++ lldb/source/Core/Value.cpp
@@ -121,6 +121,20 @@
   return eAddressTypeInvalid;
 }
 
+Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) {
+  switch (address_type) {
+case eAddressTypeFile:
+  return Value::ValueType::FileAddress;
+case eAddressTypeLoad:
+  return Value::ValueType::LoadAddress;
+case eAddressTypeHost:
+  return Value::ValueType::HostAddress;
+case eAddressTypeInvalid:
+  return Value::ValueType::Invalid;
+  }
+  llvm_unreachable("Unexpected address type!");
+}
+
 RegisterInfo *Value::GetRegisterInfo() const {
   if (m_context_type == ContextType::RegisterInfo)
 return static_cast(m_context);
Index: lldb/include/lldb/Core/Value.h
===
--- lldb/include/lldb/Core/Value.h
+++ lldb/include/lldb/Core/Value.h
@@ -145,6 +145,8 @@
 
   void Clear();
 
+  static ValueType GetValueTypeFromAddressType(AddressType address_type);
+
 protected:
   Scalar m_value;
   CompilerType m_compiler_type;


Index: lldb/source/Core/Value.cpp
===
--- lldb/source/Core/Value.cpp
+++ lldb/source/Core/Value.cpp
@@ -121,6 +121,20 @@
   return eAddressTypeInvalid;
 }
 
+Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) {
+  switch (address_type) {
+case eAddressTypeFile:
+  return Value::ValueType::FileAddress;
+case eAddressTypeLoad:
+  return Value::ValueType::LoadAddress;
+case eAddressTypeHost:
+  return Value::ValueType::HostAddress;
+case eAddressTypeInvalid:
+  return Value::ValueType::Invalid;
+  }
+  llvm_unreachable("Unexpected address type!");
+}
+
 RegisterInfo *Value::GetRegisterInfo() const {
   if (m_context_type == ContextType::RegisterInfo)
 return static_cast(m_context);
Index: lldb/include/lldb/Core/Value.h
===
--- lldb/include/lldb/Core/Value.h
+++ lldb/include/lldb/Core/Value.h
@@ -145,6 +145,8 @@
 
   void Clear();
 
+  static ValueType GetValueTypeFromAddressType(AddressType address_type);
+
 protected:
   Scalar m_value;
   CompilerType m_compiler_type;
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D151950: [lldb] Unconditionally increment depth when printing children

2023-06-01 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 created this revision.
augusto2112 added reviewers: kastiglione, aprantl, DavidSpickett.
Herald added a project: All.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

The `target.max-children-depth` setting and `--depth` flag would be
ignored if treating pointer as arrays, fix that by always incrementing
the current depth when printing a new child.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151950

Files:
  lldb/source/DataFormatters/ValueObjectPrinter.cpp


Index: lldb/source/DataFormatters/ValueObjectPrinter.cpp
===
--- lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -590,7 +590,7 @@
 void ValueObjectPrinter::PrintChild(
 ValueObjectSP child_sp,
 const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) {
-  const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0;
+  const uint32_t consumed_depth = m_options.m_pointer_as_array ? 0 : 1;
   const bool does_consume_ptr_depth =
   ((IsPtr() && !m_options.m_pointer_as_array) || IsRef());
 
@@ -611,7 +611,7 @@
 ValueObjectPrinter child_printer(
 child_sp.get(), m_stream, child_options,
 does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
-m_curr_depth + consumed_depth, m_printed_instance_pointers);
+m_curr_depth + 1, m_printed_instance_pointers);
 child_printer.PrintValueObject();
   }
 }


Index: lldb/source/DataFormatters/ValueObjectPrinter.cpp
===
--- lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -590,7 +590,7 @@
 void ValueObjectPrinter::PrintChild(
 ValueObjectSP child_sp,
 const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) {
-  const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0;
+  const uint32_t consumed_depth = m_options.m_pointer_as_array ? 0 : 1;
   const bool does_consume_ptr_depth =
   ((IsPtr() && !m_options.m_pointer_as_array) || IsRef());
 
@@ -611,7 +611,7 @@
 ValueObjectPrinter child_printer(
 child_sp.get(), m_stream, child_options,
 does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
-m_curr_depth + consumed_depth, m_printed_instance_pointers);
+m_curr_depth + 1, m_printed_instance_pointers);
 child_printer.PrintValueObject();
   }
 }
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D151950: [lldb] Unconditionally increment depth when printing children

2023-06-01 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 527670.
augusto2112 added a comment.
Herald added a subscriber: JDevlieghere.

Add radar


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151950/new/

https://reviews.llvm.org/D151950

Files:
  lldb/source/DataFormatters/ValueObjectPrinter.cpp


Index: lldb/source/DataFormatters/ValueObjectPrinter.cpp
===
--- lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -590,7 +590,7 @@
 void ValueObjectPrinter::PrintChild(
 ValueObjectSP child_sp,
 const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) {
-  const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0;
+  const uint32_t consumed_depth = m_options.m_pointer_as_array ? 0 : 1;
   const bool does_consume_ptr_depth =
   ((IsPtr() && !m_options.m_pointer_as_array) || IsRef());
 
@@ -611,7 +611,7 @@
 ValueObjectPrinter child_printer(
 child_sp.get(), m_stream, child_options,
 does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
-m_curr_depth + consumed_depth, m_printed_instance_pointers);
+m_curr_depth + 1, m_printed_instance_pointers);
 child_printer.PrintValueObject();
   }
 }


Index: lldb/source/DataFormatters/ValueObjectPrinter.cpp
===
--- lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -590,7 +590,7 @@
 void ValueObjectPrinter::PrintChild(
 ValueObjectSP child_sp,
 const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) {
-  const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0;
+  const uint32_t consumed_depth = m_options.m_pointer_as_array ? 0 : 1;
   const bool does_consume_ptr_depth =
   ((IsPtr() && !m_options.m_pointer_as_array) || IsRef());
 
@@ -611,7 +611,7 @@
 ValueObjectPrinter child_printer(
 child_sp.get(), m_stream, child_options,
 does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
-m_curr_depth + consumed_depth, m_printed_instance_pointers);
+m_curr_depth + 1, m_printed_instance_pointers);
 child_printer.PrintValueObject();
   }
 }
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D151950: [lldb] Unconditionally increment depth when printing children

2023-06-07 Thread Augusto Noronha via Phabricator via lldb-commits
augusto2112 updated this revision to Diff 529463.
augusto2112 added a comment.

Add test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151950/new/

https://reviews.llvm.org/D151950

Files:
  lldb/source/DataFormatters/ValueObjectPrinter.cpp
  lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/Makefile
  
lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/TestFrameVarDepthAndElemCount.py
  lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/main.cpp


Index: lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/main.cpp
===
--- /dev/null
+++ lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/main.cpp
@@ -0,0 +1,16 @@
+struct A {
+  int i = 42;
+};
+
+struct B {
+  A a;
+};
+
+struct C {
+  B b;
+};
+
+int main() {
+  C *c = new C[5];
+  return 0; // break here
+}
Index: 
lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/TestFrameVarDepthAndElemCount.py
===
--- /dev/null
+++ 
lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/TestFrameVarDepthAndElemCount.py
@@ -0,0 +1,27 @@
+"""
+Tests that frame variable --depth and --element-count options work correctly
+together
+"""
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+
+class TestFrameVarDepthAndElemCount(TestBase):
+def test(self):
+"""Test that bool types work in the expression parser"""
+self.build()
+lldbutil.run_to_source_breakpoint(
+self, "// break here", lldb.SBFileSpec("main.cpp")
+)
+
+# Check that we print 5 elements but only 2 levels deep.
+self.expect('frame var --depth 2 --element-count 5 -- c', 
+substrs=[
+'[0] = {\nb ={...}\n  }',
+'[1] = {\nb ={...}\n  }',
+'[2] = {\nb ={...}\n  }',
+'[3] = {\nb ={...}\n  }',
+'[4] = {\nb ={...}\n  }',
+])
+
Index: lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/Makefile
===
--- /dev/null
+++ lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
Index: lldb/source/DataFormatters/ValueObjectPrinter.cpp
===
--- lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -590,7 +590,7 @@
 void ValueObjectPrinter::PrintChild(
 ValueObjectSP child_sp,
 const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) {
-  const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0;
+  const uint32_t consumed_summary_depth = m_options.m_pointer_as_array ? 0 : 1;
   const bool does_consume_ptr_depth =
   ((IsPtr() && !m_options.m_pointer_as_array) || IsRef());
 
@@ -603,7 +603,7 @@
   .SetHideValue(m_options.m_hide_value)
   .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1
? child_options.m_omit_summary_depth -
- consumed_depth
+ consumed_summary_depth
: 0)
   .SetElementCount(0);
 
@@ -611,7 +611,7 @@
 ValueObjectPrinter child_printer(
 child_sp.get(), m_stream, child_options,
 does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
-m_curr_depth + consumed_depth, m_printed_instance_pointers);
+m_curr_depth + 1, m_printed_instance_pointers);
 child_printer.PrintValueObject();
   }
 }


Index: lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/main.cpp
===
--- /dev/null
+++ lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/main.cpp
@@ -0,0 +1,16 @@
+struct A {
+  int i = 42;
+};
+
+struct B {
+  A a;
+};
+
+struct C {
+  B b;
+};
+
+int main() {
+  C *c = new C[5];
+  return 0; // break here
+}
Index: lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/TestFrameVarDepthAndElemCount.py
===
--- /dev/null
+++ lldb/test/API/lang/cpp/frame-var-depth-and-elem-count/TestFrameVarDepthAndElemCount.py
@@ -0,0 +1,27 @@
+"""
+Tests that frame variable --depth and --element-count options work correctly
+together
+"""
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+
+class TestFrameVarDepthAndElemCount(TestBase):
+def test(self):
+"""Test that bool types work in the expression parser"""
+self.build()
+lldbutil.run_to_source_breakpoint(
+self, "// break here", lldb.SBFileSpec("main.cpp")
+)
+
+# Check that we print 5 elements but only 2 levels deep.
+self.expect('frame var --depth 2 --element-count 5 -- c', 
+ 

  1   2   3   >