[Lldb-commits] [lldb] [lldb] Change Module to have a concrete UnwindTable, update (PR #101130)

2024-07-30 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Thanks for the suggestion @jimingham , I pushed an update to implement that 
idea.

https://github.com/llvm/llvm-project/pull/101130
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change Module to have a concrete UnwindTable, update (PR #101130)

2024-07-30 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/101130

>From 55b1ac1fbad89ebc50038738c1e09045e9884be8 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Mon, 29 Jul 2024 22:37:43 -0700
Subject: [PATCH 1/3] [lldb] Change Module to have a concrete UnwindTable,
 update

Currently a Module has a std::optional which is
created when the UnwindTable is requested from outside the
Module.  The idea is to delay its creation until the Module
has an ObjectFile initialized, which will have been done by
the time we're doing an unwind.

However, Module::GetUnwindTable wasn't doing any locking, so it was
possible for two threads to ask for the UnwindTable for the first
time, one would be created and returned while another thread would
create one, destroy the first in the process of emplacing it.
It was an uncommon crash, but it was possible.

Grabbing the Module's mutex would be one way to address it, but
when loading ELF binaries, we start creating the SymbolTable on one
thread (ObjectFileELF) grabbing the Module's mutex, and then spin
up worker threads to parse the individual DWARF compilation units,
which then try to also get the UnwindTable and deadlock if they try
to get the Module's mutex.

This changes Module to have a concrete UnwindTable as an ivar, and
when it adds an ObjectFile or SymbolFileVendor, it will call the
Update method on it, which will re-evaluate which sections exist
in the ObjectFile/SymbolFile. UnwindTable used to have an Initialize
method which set all the sections, and an Update method which would
set some of them if they weren't set.  I unified these with the
Initialize method taking a `force` option to re-initialize the
section pointers even if they had been done already before.

This is addressing a rare crash report we've received, and also a
failure Adrian spotted on the -fsanitize=address CI bot last week,
it's still uncommon with ASAN but it can happen with the standard
testsuite.

rdar://132514736
---
 lldb/include/lldb/Core/Module.h|  6 +--
 lldb/include/lldb/Symbol/UnwindTable.h |  2 +-
 lldb/source/Core/Module.cpp| 26 +++--
 lldb/source/Symbol/UnwindTable.cpp | 51 ++
 4 files changed, 23 insertions(+), 62 deletions(-)

diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index 0188057247a68..5589c1c9a350d 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -1021,9 +1021,9 @@ class Module : public 
std::enable_shared_from_this,
   lldb::ObjectFileSP m_objfile_sp; ///< A shared pointer to the object file
/// parser for this module as it may or may
/// not be shared with the SymbolFile
-  std::optional m_unwind_table; ///< Table of FuncUnwinders
- /// objects created for this
- /// Module's functions
+  UnwindTable m_unwind_table;  ///< Table of FuncUnwinders
+   /// objects created for this
+   /// Module's functions
   lldb::SymbolVendorUP
   m_symfile_up; ///< A pointer to the symbol vendor for this module.
   std::vector
diff --git a/lldb/include/lldb/Symbol/UnwindTable.h 
b/lldb/include/lldb/Symbol/UnwindTable.h
index 26826e5d1b497..0e7d76b1b896c 100644
--- a/lldb/include/lldb/Symbol/UnwindTable.h
+++ b/lldb/include/lldb/Symbol/UnwindTable.h
@@ -64,7 +64,7 @@ class UnwindTable {
 private:
   void Dump(Stream );
 
-  void Initialize();
+  void Initialize(bool force = false);
   std::optional GetAddressRange(const Address ,
   const SymbolContext );
 
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 9c105b3f0e57a..acc17ecad015b 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -131,7 +131,8 @@ Module *Module::GetAllocatedModuleAtIndex(size_t idx) {
 }
 
 Module::Module(const ModuleSpec _spec)
-: m_file_has_changed(false), m_first_file_changed_log(false) {
+: m_unwind_table(*this), m_file_has_changed(false),
+  m_first_file_changed_log(false) {
   // Scope for locker below...
   {
 std::lock_guard guard(
@@ -238,7 +239,8 @@ Module::Module(const FileSpec _spec, const ArchSpec 
,
 : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
   m_arch(arch), m_file(file_spec), m_object_name(object_name),
   m_object_offset(object_offset), m_object_mod_time(object_mod_time),
-  m_file_has_changed(false), m_first_file_changed_log(false) {
+  m_unwind_table(*this), m_file_has_changed(false),
+  m_first_file_changed_log(false) {
   // Scope for locker below...
   {
 std::lock_guard guard(
@@ -254,7 +256,9 @@ Module::Module(const FileSpec _spec, const ArchSpec 
,
   m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");
 }
 
-Module::Module() 

[Lldb-commits] [lldb] [lldb][test] Fix TestMultipleDebuggers test on non-x86, other small issues (PR #101169)

2024-07-30 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

Thanks for the good cleanup.

https://github.com/llvm/llvm-project/pull/101169
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change Module to have a concrete UnwindTable, update (PR #101130)

2024-07-30 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

> It is a little odd that the laziness of the UnwindTable itself gets defeated 
> by Update, which forces the Initialize even if the unwind table isn't 
> currently being requested.

I could add an ivar `m_module_has_updated` which is set when a new 
ObjectFile/SymbolFileVendor is added to the Module.  And all the getter methods 
in UnwindTable call `Initialize()` which currently checks that it has been 
initialized or not, and add that in.

> Not sure if that matters? If it does, Update could just tell the UnwindTable 
> that next time it gets asked a question it has to reread the unwind 
> information. Maybe it could even just set m_initialized back to `false` and 
> then let the lazy initialization redo the work when requested?

Hah, I didn't read your full comment.  Yes, same idea, and just as good.  I'll 
do that.


https://github.com/llvm/llvm-project/pull/101130
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change Module to have a concrete UnwindTable, update (PR #101130)

2024-07-30 Thread Jason Molenda via lldb-commits


@@ -64,7 +64,7 @@ class UnwindTable {
 private:
   void Dump(Stream );
 
-  void Initialize();
+  void Initialize(bool force = false);

jasonmolenda wrote:

Yeah I'm not thrilled with the terminology I used.  But I had `Initialize` 
which assumed no unwind sources had been discovered, and `Update` called after 
a SymbolFileVendor is added to the Module which looks for any un-set unwind 
sources and checks to see if they can now be found.  That duplication didn't 
thrill me.

https://github.com/llvm/llvm-project/pull/101130
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Optimized lldb-server memory usage (PR #100666)

2024-07-25 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Hm, I was worried that we might get the filepath of a unix socket in some use 
case, but we llvm::to_integer(port_cstr) shortly later, so that can't be the 
case.

https://github.com/llvm/llvm-project/pull/100666
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add constant value mode for RegisterLocation in UnwindPlans (PR #100624)

2024-07-25 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

This looks good to me.  One small nit on the Dump method.

As a bit of background, this would be very unusual for a normal UnwindPlan that 
is reused for a function in many different contexts (different places on the 
stack during the program runtime).  Felipe is dealing with the special case 
when the Swift LanguageRuntime creates an UnwindPlan that is used *once* in a 
given stack, and not saved in the UnwindTable for this Module.  Felipe could 
have constructed a DWARF expression, where the register value was stored in 
memory, or a DWARF expression with a constant value, but then we'd need to add 
a `DataBufferSP` to the `RegisterLocation` to have ownership of this 
heap-allocated dwarf expression, in addition to hand-creating the DWARF 
expression bytecodes.  It was a lot more straightforward to add this type of 
"this register is value x" for this one-shot UnwindPlan's that a 
LanguageRuntime can provide.



https://github.com/llvm/llvm-project/pull/100624
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add constant value mode for RegisterLocation in UnwindPlans (PR #100624)

2024-07-25 Thread Jason Molenda via lldb-commits


@@ -153,6 +155,9 @@ void UnwindPlan::Row::RegisterLocation::Dump(Stream ,
 if (m_type == atDWARFExpression)
   s.PutChar(']');
   } break;
+  case isConstant:
+s.Printf("=%x", m_location.offset);

jasonmolenda wrote:

Should the Printf be `("=0x%" PRIx64, m_location.constant_value)`?  If you do 
an unwind with one of these register locations in use, we should see this 
output when the unwind engine shows the unwind rules being used for this 
function.

https://github.com/llvm/llvm-project/pull/100624
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add constant value mode for RegisterLocation in UnwindPlans (PR #100624)

2024-07-25 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda edited 
https://github.com/llvm/llvm-project/pull/100624
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][SBSaveCore] Implement a selectable threadlist for Core Options. (PR #100443)

2024-07-24 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Stepping back a bit, do we gain anything in `SaveCoreOptions` by having 
`m_process_sp` be optional?  Is there a distinction between an empty ProcessSP 
and no ProcessSP object?

https://github.com/llvm/llvm-project/pull/100443
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][SBSaveCore] Implement a selectable threadlist for Core Options. (PR #100443)

2024-07-24 Thread Jason Molenda via lldb-commits


@@ -46,8 +48,79 @@ SaveCoreOptions::GetOutputFile() const {
   return m_file;
 }
 
+Status SaveCoreOptions::SetProcess(lldb::ProcessSP process_sp) {
+  Status error;
+  if (!process_sp) {
+ClearProcessSpecificData();
+m_process_sp = std::nullopt;
+return error;
+  }
+
+  if (!process_sp->IsValid()) {
+error.SetErrorString("Cannot assign an invalid process.");
+return error;
+  }
+
+  if (m_process_sp.has_value())

jasonmolenda wrote:

Just take this as one possible opinion: I find the naming of this 
`std::optional m_process_sp` a little confusing.  In this method we 
have a `ProcessSP process_sp` and `m_process_sp` which is an `optional`.  Above 
we see code doing `if (!process_sp)` - cool.  Then I come to `if 
(m_process_sp.has_value())` and I'm trying to figure out what that method does 
in a `std::shared_ptr` and why it's different than the above bool. 
I'm not sure `m_process_sp` is the best name, but we have no convention for 
this kind of thing today.

https://github.com/llvm/llvm-project/pull/100443
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][SBSaveCore] Implement a selectable threadlist for Core Options. (PR #100443)

2024-07-24 Thread Jason Molenda via lldb-commits


@@ -46,8 +48,79 @@ SaveCoreOptions::GetOutputFile() const {
   return m_file;
 }
 
+Status SaveCoreOptions::SetProcess(lldb::ProcessSP process_sp) {
+  Status error;
+  if (!process_sp) {
+ClearProcessSpecificData();
+m_process_sp = std::nullopt;
+return error;
+  }
+
+  if (!process_sp->IsValid()) {
+error.SetErrorString("Cannot assign an invalid process.");
+return error;
+  }
+
+  if (m_process_sp.has_value())
+ClearProcessSpecificData();
+
+  m_process_sp = process_sp;
+  return error;
+}
+
+Status SaveCoreOptions::AddThread(lldb_private::Thread *thread) {
+  Status error;
+  if (!thread) {
+error.SetErrorString("Thread is null");
+  }
+
+  if (!m_process_sp.has_value())
+m_process_sp = thread->GetProcess();
+
+  if (m_process_sp.value() != thread->GetProcess()) {
+error.SetErrorString("Cannot add thread from a different process.");
+return error;
+  }
+
+  std::pair tid_pair(thread->GetID(),
+  thread->GetBackingThread());
+  m_threads_to_save.insert(tid_pair);
+  return error;
+}
+
+bool SaveCoreOptions::RemoveThread(lldb_private::Thread *thread) {
+  return thread && m_threads_to_save.erase(thread->GetID()) > 0;
+}
+
+bool SaveCoreOptions::ShouldSaveThread(lldb::tid_t tid) const {

jasonmolenda wrote:

`ShouldSaveThread` makes this method sound like a caller can use this to 
request a thread is included. This is more like `ThreadWillBeSaved` maybe?

https://github.com/llvm/llvm-project/pull/100443
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][SBSaveCore] Implement a selectable threadlist for Core Options. (PR #100443)

2024-07-24 Thread Jason Molenda via lldb-commits


@@ -46,8 +48,79 @@ SaveCoreOptions::GetOutputFile() const {
   return m_file;
 }
 
+Status SaveCoreOptions::SetProcess(lldb::ProcessSP process_sp) {
+  Status error;
+  if (!process_sp) {
+ClearProcessSpecificData();
+m_process_sp = std::nullopt;
+return error;
+  }
+
+  if (!process_sp->IsValid()) {
+error.SetErrorString("Cannot assign an invalid process.");
+return error;
+  }
+
+  if (m_process_sp.has_value())
+ClearProcessSpecificData();
+
+  m_process_sp = process_sp;
+  return error;
+}
+
+Status SaveCoreOptions::AddThread(lldb_private::Thread *thread) {
+  Status error;
+  if (!thread) {
+error.SetErrorString("Thread is null");

jasonmolenda wrote:

Do you want to early-return here?  We might dereference the `thread` a few 
lines below.

https://github.com/llvm/llvm-project/pull/100443
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][SBSaveCore] Implement a selectable threadlist for Core Options. (PR #100443)

2024-07-24 Thread Jason Molenda via lldb-commits


@@ -46,8 +48,79 @@ SaveCoreOptions::GetOutputFile() const {
   return m_file;
 }
 
+Status SaveCoreOptions::SetProcess(lldb::ProcessSP process_sp) {
+  Status error;
+  if (!process_sp) {
+ClearProcessSpecificData();
+m_process_sp = std::nullopt;
+return error;
+  }
+
+  if (!process_sp->IsValid()) {
+error.SetErrorString("Cannot assign an invalid process.");
+return error;
+  }
+
+  if (m_process_sp.has_value())
+ClearProcessSpecificData();
+
+  m_process_sp = process_sp;
+  return error;
+}
+
+Status SaveCoreOptions::AddThread(lldb_private::Thread *thread) {
+  Status error;
+  if (!thread) {
+error.SetErrorString("Thread is null");
+  }
+
+  if (!m_process_sp.has_value())
+m_process_sp = thread->GetProcess();
+
+  if (m_process_sp.value() != thread->GetProcess()) {
+error.SetErrorString("Cannot add thread from a different process.");
+return error;
+  }
+
+  std::pair tid_pair(thread->GetID(),
+  thread->GetBackingThread());
+  m_threads_to_save.insert(tid_pair);

jasonmolenda wrote:

personal preference, but you could ` m_threads_to_save.insert({thread->GetID(), 
thread->GetBackingThread()})` here.  Fine this way too.

https://github.com/llvm/llvm-project/pull/100443
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][SBSaveCore] Implement a selectable threadlist for Core Options. (PR #100443)

2024-07-24 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda edited 
https://github.com/llvm/llvm-project/pull/100443
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB][SBSaveCore] Implement a selectable threadlist for Core Options. (PR #100443)

2024-07-24 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda commented:

The MachO changes look fine to me.  I had a few other small pieces of feedback, 
I think they're mostly matters of opinion so just take them as such, not 
something that must be changed.

https://github.com/llvm/llvm-project/pull/100443
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)

2024-07-24 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I've merged https://github.com/llvm/llvm-project/pull/100288 I think we should 
close this PR.

https://github.com/llvm/llvm-project/pull/99045
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Don't use a vm addr range starting at 0 for local memory (PR #100288)

2024-07-24 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda closed 
https://github.com/llvm/llvm-project/pull/100288
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Don't use a vm addr range starting at 0 for local memory (PR #100288)

2024-07-24 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/100288

>From 28439443b9e44a242e59bf1cdd114486380d54fc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Tue, 23 Jul 2024 18:54:31 -0700
Subject: [PATCH 1/2] [lldb] Don't use a vm addr range starting at 0 for local
 memory

When an inferior stub cannot allocate memory for lldb, and lldb
needs to store the result of expressions, it will do it in lldb's
own memory range ("host memory").  But it needs to find a virtual
address range that is not used in the inferior process.  It tries
to use the qMemoryRegionInfo gdb remote serial protocol packet to
find a range that is inaccessible, starting at address 0 and moving
up the size of each region.

If the first region found at address 0 is inaccessible, lldb will
use the address range starting at 0 to mean "read lldb's host memory,
not the process memory", and programs that crash with a null
dereference will have poor behavior.

This patch skips consideration of a memory region that starts at
address 0.

I also clarified the documentation of qMemoryRegionInfo to make it
clear that the stub is required to provide permissions for a memory
range that is accessable, it is not an optional key in this response.
This issue was originally found by a stub that did not list
permissions, and lldb treated the first region returned as the one
it would use.
---
 lldb/docs/resources/lldbgdbremote.md   |  8 +++-
 lldb/source/Expression/IRMemoryMap.cpp | 17 -
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/lldb/docs/resources/lldbgdbremote.md 
b/lldb/docs/resources/lldbgdbremote.md
index 7076a75032dae..5cac3736337a8 100644
--- a/lldb/docs/resources/lldbgdbremote.md
+++ b/lldb/docs/resources/lldbgdbremote.md
@@ -1403,6 +1403,12 @@ For instance, with a macOS process which has nothing 
mapped in the first
 The lack of `permissions:` indicates that none of read/write/execute are valid
 for this region.
 
+The stub must include `permissions:` key-value on all memory ranges
+that are valid to access in the inferior process -- the lack of
+`permissions:` means that this is an inaccessible (no page table
+entries exist, in a system using VM) memory range.  If a stub cannot
+determine actual permissions, return `rwx`.
+
 **Priority To Implement:** Medium
 
 This is nice to have, but it isn't necessary. It helps LLDB
@@ -2434,4 +2440,4 @@ The `0x` prefixes are optional - like most of the 
gdb-remote packets,
 omitting them will work fine; these numbers are always base 16.
 
 The length of the payload is not provided.  A reliable, 8-bit clean,
-transport layer is assumed.
\ No newline at end of file
+transport layer is assumed.
diff --git a/lldb/source/Expression/IRMemoryMap.cpp 
b/lldb/source/Expression/IRMemoryMap.cpp
index de631370bb048..bb3e4e0a9a9fc 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -84,7 +84,7 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) {
   // any allocations.  Otherwise start at the beginning of memory.
 
   if (m_allocations.empty()) {
-ret = 0x0;
+ret = 0;
   } else {
 auto back = m_allocations.rbegin();
 lldb::addr_t addr = back->first;
@@ -116,10 +116,17 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) {
 Status err = process_sp->GetMemoryRegionInfo(ret, region_info);
 if (err.Success()) {
   while (true) {
-if (region_info.GetReadable() != MemoryRegionInfo::OptionalBool::eNo ||
-region_info.GetWritable() != MemoryRegionInfo::OptionalBool::eNo ||
-region_info.GetExecutable() !=
-MemoryRegionInfo::OptionalBool::eNo) {
+if (region_info.GetRange().GetRangeBase() == 0 &&
+region_info.GetRange().GetRangeEnd() - 1 < end_of_memory) {
+  // Don't use a region that starts at address 0,
+  // that can mask null dereferences in the inferior.
+  ret = region_info.GetRange().GetRangeEnd();
+} else if (region_info.GetReadable() !=
+   MemoryRegionInfo::OptionalBool::eNo ||
+   region_info.GetWritable() !=
+   MemoryRegionInfo::OptionalBool::eNo ||
+   region_info.GetExecutable() !=
+   MemoryRegionInfo::OptionalBool::eNo) {
   if (region_info.GetRange().GetRangeEnd() - 1 >= end_of_memory) {
 ret = LLDB_INVALID_ADDRESS;
 break;

>From 6fbe7592b2baccdb7656b20198088a350ab887f1 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Wed, 24 Jul 2024 16:01:21 -0700
Subject: [PATCH 2/2] fix minor nit.

---
 lldb/source/Expression/IRMemoryMap.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Expression/IRMemoryMap.cpp 
b/lldb/source/Expression/IRMemoryMap.cpp
index bb3e4e0a9a9fc..0c1d9016616cb 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -117,9 +117,10 @@ lldb::addr_t 

[Lldb-commits] [lldb] [lldb] Prevent passing a nullptr to std::string in ObjectFileMachO (PR #100421)

2024-07-24 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

LGTM.


https://github.com/llvm/llvm-project/pull/100421
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)

2024-07-23 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I put up a PR that avoids a memory region starting at address 0, and also 
clarifies the documentation of the qMemoryRegionInfo packet to state that 
permissions: are required for all memory regions that are accessible by the 
inferior process.  A memory region with no `permissions:` key means that it is 
not an accessible region of memory.  I put this PR up at 
https://github.com/llvm/llvm-project/pull/100288  
@dlav-sc what do you think?  I know you've moved past this issue by 
implementing memory-allocation and fixing your qMemoryRegionInfo packet 
response, but I wanted to get a final fix before we all walk away from this PR.

https://github.com/llvm/llvm-project/pull/99045
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Don't use a vm addr range starting at 0 for local memory (PR #100288)

2024-07-23 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I created this PR as an alternative approach to the issue reported in 
https://github.com/llvm/llvm-project/pull/99045

https://github.com/llvm/llvm-project/pull/100288
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Don't use a vm addr range starting at 0 for local memory (PR #100288)

2024-07-23 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/100288

When an inferior stub cannot allocate memory for lldb, and lldb needs to store 
the result of expressions, it will do it in lldb's own memory range ("host 
memory").  But it needs to find a virtual address range that is not used in the 
inferior process.  It tries to use the qMemoryRegionInfo gdb remote serial 
protocol packet to find a range that is inaccessible, starting at address 0 and 
moving up the size of each region.

If the first region found at address 0 is inaccessible, lldb will use the 
address range starting at 0 to mean "read lldb's host memory, not the process 
memory", and programs that crash with a null dereference will have poor 
behavior.

This patch skips consideration of a memory region that starts at address 0.

I also clarified the documentation of qMemoryRegionInfo to make it clear that 
the stub is required to provide permissions for a memory range that is 
accessable, it is not an optional key in this response. This issue was 
originally found by a stub that did not list permissions in its response, and 
lldb treated the first region returned as the one it would use.  (the stub also 
didn't support the memory-allocate packet)

>From 28439443b9e44a242e59bf1cdd114486380d54fc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Tue, 23 Jul 2024 18:54:31 -0700
Subject: [PATCH] [lldb] Don't use a vm addr range starting at 0 for local
 memory

When an inferior stub cannot allocate memory for lldb, and lldb
needs to store the result of expressions, it will do it in lldb's
own memory range ("host memory").  But it needs to find a virtual
address range that is not used in the inferior process.  It tries
to use the qMemoryRegionInfo gdb remote serial protocol packet to
find a range that is inaccessible, starting at address 0 and moving
up the size of each region.

If the first region found at address 0 is inaccessible, lldb will
use the address range starting at 0 to mean "read lldb's host memory,
not the process memory", and programs that crash with a null
dereference will have poor behavior.

This patch skips consideration of a memory region that starts at
address 0.

I also clarified the documentation of qMemoryRegionInfo to make it
clear that the stub is required to provide permissions for a memory
range that is accessable, it is not an optional key in this response.
This issue was originally found by a stub that did not list
permissions, and lldb treated the first region returned as the one
it would use.
---
 lldb/docs/resources/lldbgdbremote.md   |  8 +++-
 lldb/source/Expression/IRMemoryMap.cpp | 17 -
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/lldb/docs/resources/lldbgdbremote.md 
b/lldb/docs/resources/lldbgdbremote.md
index 7076a75032dae..5cac3736337a8 100644
--- a/lldb/docs/resources/lldbgdbremote.md
+++ b/lldb/docs/resources/lldbgdbremote.md
@@ -1403,6 +1403,12 @@ For instance, with a macOS process which has nothing 
mapped in the first
 The lack of `permissions:` indicates that none of read/write/execute are valid
 for this region.
 
+The stub must include `permissions:` key-value on all memory ranges
+that are valid to access in the inferior process -- the lack of
+`permissions:` means that this is an inaccessible (no page table
+entries exist, in a system using VM) memory range.  If a stub cannot
+determine actual permissions, return `rwx`.
+
 **Priority To Implement:** Medium
 
 This is nice to have, but it isn't necessary. It helps LLDB
@@ -2434,4 +2440,4 @@ The `0x` prefixes are optional - like most of the 
gdb-remote packets,
 omitting them will work fine; these numbers are always base 16.
 
 The length of the payload is not provided.  A reliable, 8-bit clean,
-transport layer is assumed.
\ No newline at end of file
+transport layer is assumed.
diff --git a/lldb/source/Expression/IRMemoryMap.cpp 
b/lldb/source/Expression/IRMemoryMap.cpp
index de631370bb048..bb3e4e0a9a9fc 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -84,7 +84,7 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) {
   // any allocations.  Otherwise start at the beginning of memory.
 
   if (m_allocations.empty()) {
-ret = 0x0;
+ret = 0;
   } else {
 auto back = m_allocations.rbegin();
 lldb::addr_t addr = back->first;
@@ -116,10 +116,17 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) {
 Status err = process_sp->GetMemoryRegionInfo(ret, region_info);
 if (err.Success()) {
   while (true) {
-if (region_info.GetReadable() != MemoryRegionInfo::OptionalBool::eNo ||
-region_info.GetWritable() != MemoryRegionInfo::OptionalBool::eNo ||
-region_info.GetExecutable() !=
-MemoryRegionInfo::OptionalBool::eNo) {
+if (region_info.GetRange().GetRangeBase() == 0 &&
+region_info.GetRange().GetRangeEnd() - 1 < end_of_memory) {
+  // 

[Lldb-commits] [lldb] [lldb] Don't crash when attaching to pid and no binaries found (PR #100287)

2024-07-23 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda closed 
https://github.com/llvm/llvm-project/pull/100287
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Don't crash when attaching to pid and no binaries found (PR #100287)

2024-07-23 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/100287

There is a narrow window during process launch on macOS where lldb can attach 
and no binaries will be seen as loaded in the process (none reported by libdyld 
SPI).  A year ago I made changes to set the new-binary-loaded breakpoint 
correctly despite this.  But we've seen a crash when this combination is seen, 
where CommandObjectProcessAttach::DoExecute assumed there was at least one 
binary registered in the Target.  Fix that.

Also fix two FileSpec API uses from when we didn't have a GetPath() method that 
returned a std::string, and was copying the filepaths into fixed length 
buffers.  All of this code was from ~14 years ago when we didn't have that API.

rdar://131631627

>From 4cec9c8e71229cb47ab0d0536f7e654caf05d2f1 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Tue, 23 Jul 2024 17:33:24 -0700
Subject: [PATCH] [lldb] Don't crash when attaching to pid and no binaries
 found

There is a narrow window during process launch on macOS where
lldb can attach and no binaries will be seen as loaded in the
process (none reported by libdyld SPI).  A year ago I made
changes to set the new-binary-loaded breakpoint correctly despite
this.  But we've seen a crash when this combination is seen, where
CommandObjectProcessAttach::DoExecute assumed there was at least
one binary registered in the Target.  Fix that.

Also fix two FileSpec API uses from when we didn't have a GetPath()
method that returned a std::string, and was copying the filepaths
into fixed length buffers.  All of this code was from ~14 years ago
when we didn't have that API.

rdar://131631627
---
 lldb/source/Commands/CommandObjectProcess.cpp | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectProcess.cpp 
b/lldb/source/Commands/CommandObjectProcess.cpp
index 50695af556939..e605abdb3c771 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -369,25 +369,23 @@ class CommandObjectProcessAttach : public 
CommandObjectProcessLaunchOrAttach {
 
 // Okay, we're done.  Last step is to warn if the executable module has
 // changed:
-char new_path[PATH_MAX];
 ModuleSP new_exec_module_sp(target->GetExecutableModule());
 if (!old_exec_module_sp) {
   // We might not have a module if we attached to a raw pid...
   if (new_exec_module_sp) {
-new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
-result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
-   new_path);
+result.AppendMessageWithFormat(
+"Executable binary set to \"%s\".\n",
+new_exec_module_sp->GetFileSpec().GetPath().c_str());
   }
+} else if (!new_exec_module_sp) {
+  result.AppendWarningWithFormat("No executable binary.");
 } else if (old_exec_module_sp->GetFileSpec() !=
new_exec_module_sp->GetFileSpec()) {
-  char old_path[PATH_MAX];
-
-  old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
-  new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
 
   result.AppendWarningWithFormat(
-  "Executable module changed from \"%s\" to \"%s\".\n", old_path,
-  new_path);
+  "Executable binary changed from \"%s\" to \"%s\".\n",
+  old_exec_module_sp->GetFileSpec().GetPath().c_str(),
+  new_exec_module_sp->GetFileSpec().GetPath().c_str());
 }
 
 if (!old_arch_spec.IsValid()) {

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


[Lldb-commits] [lldb] [lldb][debugserver] Retry sleep(0.25s) when interrupted (PR #99962)

2024-07-22 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda closed 
https://github.com/llvm/llvm-project/pull/99962
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][debugserver] Retry sleep(0.25s) when interrupted (PR #99962)

2024-07-22 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Ah, Jonas points out that I've fixed the wrong sleep.  He has a patch he'll put 
up for the real problem.  This does not fix a known problem.

https://github.com/llvm/llvm-project/pull/99962
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][debugserver] Retry sleep(0.25s) when interrupted (PR #99962)

2024-07-22 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda edited 
https://github.com/llvm/llvm-project/pull/99962
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][debugserver] Retry sleep(0.25s) when interrupted (PR #99962)

2024-07-22 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/99962

After lldb has ptrace()'ed the process, it sleeps for 0.25 seconds before 
trying to pause the process.  We see logging that in some rare cases, this 
sleep is interrupted and the pause fails, the attach fails.  usleep(3) says 
that the only errno it will return is EINTR if interrupted, so retry on that 
case.  I capped it at four retries so the process can't hang infinitely if it's 
being spammed with asynchronous signals.

I don't know what environment setup results in this behavior, it's only rarely 
seen by end users and we see evidence, after the fact of it, in logging.

rdar://131602093

>From 01255f7c906c9b5995b0f33c420c7c7eb707bddf Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Mon, 22 Jul 2024 14:55:04 -0700
Subject: [PATCH] [lldb][debugserver] Retry sleep(0.25s) when interrupted

After lldb has ptrace()'ed the process, it sleeps for 0.25 seconds
before trying to pause the process.  We see logging that in some
rare cases, this sleep is interrupted and the pause fails.  usleep(3)
says that the only errno it will return is EINTR if interrupted,
so retry on that case.  I capped it at four retries so the process
can't hang infinitely if it's being spammed with asynchronous
signals.

I don't know what environment setup results in this behavior,
it's only rarely seen by end users and we see evidence, after
the factof it, in logging.

rdar://131602093
---
 lldb/tools/debugserver/source/MacOSX/MachProcess.mm | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm 
b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
index cbe3c5459e91f..89c031fdc75d6 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -2846,9 +2846,12 @@ static uint64_t bits(uint64_t value, uint32_t msbit, 
uint32_t lsbit) {
 if (err.Success()) {
   m_flags |= eMachProcessFlagsAttached;
   // Sleep a bit to let the exception get received and set our process
-  // status
-  // to stopped.
-  ::usleep(25);
+  // status to stopped.
+  int max_retry = 4;
+  do {
+errno = 0;
+usleep(25); // If our 0.25 second sleep is interrupted, redo
+  } while (errno == EINTR && --max_retry > 0);
   DNBLog("[LaunchAttach] (%d) Done napping after ptrace(PT_ATTACHEXC)'ing",
  getpid());
   DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", pid);

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


[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)

2024-07-20 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Ah, but I see my misunderstanding as I look at what debugserver returns.  It 
uses "no permissions" to indicate a memory range that is unmapped -- 

```
 <  23> send packet: $qMemoryRegionInfo:0#44
 <  27> read packet: $start:0;size:1;#00
 <  31> send packet: $qMemoryRegionInfo:1#c5
 <  67> read packet: 
$start:1;size:4000;permissions:rx;dirty-pages:1;#00
 <  31> send packet: $qMemoryRegionInfo:14000#c9
 <  57> read packet: $start:14000;size:4000;permissions:r;dirty-pages:;#00
 <  31> send packet: $qMemoryRegionInfo:18000#cd
 <  32> read packet: $start:18000;size:404000;#00
 <  31> send packet: $qMemoryRegionInfo:10040c000#fc
 < 198> read packet: 
$start:10040c000;size:4;permissions:rw;dirty-pages:10040c000,10041,100414000,100418000,10041c000,10042,100424000,100428000,10042c000,10043,100434000,100438000,10043c000,10044;#00
```

0x18000-0x00010040c000 is a free address range in this example, and 
what this loop should choose if it had to find an unused memory range.  That 
conflicts with the behavior that this PR started with originally, where no 
permissions were returned for any memory regions --- which looks like the way 
debugserver reports a free memory region.

(The low 4 GB segment at the start of my output above is the PAGEZERO empty 
segment of virtual address space on 64-bit darwin processes)

https://github.com/llvm/llvm-project/pull/99045
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)

2024-07-20 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I haven't tested it (or even tried to compile it, lol) but I think this loop 
might be expressable as simply
```
MemoryRegionInfo region_info;
while (process_sp->GetMemoryRegionInfo(ret, region_info) == err.Success() &&
region_info.GetRange().GetRangeEnd() - 1 < end_of_memory) {
  
  // Don't ever choose a memory region starting at address 0,
  // it will conflict with programs that deference null pointers.
  if (ret == 0) {
ret = region_info.GetRange().GetRangeEnd();
continue;
  }

  // A memory region that is inaccessible, and large enough, is a good
  // choice.
  if (region_info.GetReadable() != MemoryRegionInfo::OptionalBool::eNo && 
  region_info.GetWritable() != MemoryRegionInfo::OptionalBool::eNo && 
  region_info.GetExecutable() != MemoryRegionInfo::OptionalBool::eNo) {
 if (ret + size < region_info.GetRange().GetRangeEnd()) {
  return ret;
 }
  }
  
  // Get the next region.
  ret = region_info.GetRange().GetRangeEnd();
}
```

I dropped two behaviors here - one is that it would emit a unique assert if 
qMemoryRegionInfo worked once, but failed for a different address.  The second 
is that I think the old code would try to combine consecutive memory regions to 
make one block large enough to satisfy the size requirement (not sure it was 
doing this correctly).

https://github.com/llvm/llvm-project/pull/99045
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-20 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

> FYI, I also ran into failures due to this change, when debugging on Windows 
> (with DWARF). See the run in 
> https://github.com/mstorsjo/actions-test/actions/runs/10020326811 vs 
> https://github.com/mstorsjo/actions-test/actions/runs/10020393197. Thanks for 
> reverting; hopefully it’s the same root cause as on other platforms.

oooh that 10020393197 is surprising.  It looks like we hit a breakpoint, did 
`finish` up until a recursive function and it resumed execution without 
stopping.  I haven't seen that one before, and not sure how I could have 
introduced it.  I'll def need to look at my ProcessWindows changes and again 
see if I can't figure out what might be going on.  Aleksandr ran a slightly 
earlier version of the windows changes against the lldb testsuite and didn't 
uncover any problems, but it didn't include this test file.

@mstorsjo is this test source file on-line somewhere, or can you paste it into 
a comment?  I'll try to repo on linux or macos too, maybe it is a unique corner 
case unrelated to Windows that is a problem.  (unlikely, but you never know if 
we might get lucky).  Thanks for the heads-up.

https://github.com/llvm/llvm-project/pull/96260
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-19 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I've reverted this change until I can debug the failures found on the CI bots.  

Two debuginfo dexter tests failed, likely because the way stepping and 
breakpoints works is now different.  If you're sitting at a BreakpointSite 
which has not yet executed, previously lldb would overwrite the stop reason 
with "breakpoint hit" even though it had not been hit.  Now, you'll have your 
actual stop reason -- and when you resume, you'll hit the breakpoint and stop 
again.  If you 'continue', it stops again.  If you 'next/step', it stops again 
and your next/step is still on the thread plan stack, so if you 'continue', 
you're going to first do the next/step that was on the thread stack, and then 
you can do your other command.

I've spent a lot of time thinking about any other approach to this, and they 
all have bad outcomes that we don't want to add.

In short, I expect the debuginfo tests are continuing from a breakpoint and not 
expecting the breakpoint to be hit.

The ubuntu-arm bot failed TestConsecutiveBreakpoints.py and 
TestConsecutiveBreakpoints.py, but it seems like the only failure text was like 
"process exited -9" or something.  I may need to re-land the patch with a lot 
more logging enabled on these two, to narrow down what this bot is seeing.  I 
let it run an extra cycle and it failed in the same spot again, so it wasn't a 
oneoff error.

https://github.com/llvm/llvm-project/pull/96260
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] 52c08d7 - Revert "[lldb] Change lldb's breakpoint handling behavior (#96260)"

2024-07-19 Thread Jason Molenda via lldb-commits

Author: Jason Molenda
Date: 2024-07-19T18:43:53-07:00
New Revision: 52c08d7ffd380f4abd819c20bec76252272f6337

URL: 
https://github.com/llvm/llvm-project/commit/52c08d7ffd380f4abd819c20bec76252272f6337
DIFF: 
https://github.com/llvm/llvm-project/commit/52c08d7ffd380f4abd819c20bec76252272f6337.diff

LOG: Revert "[lldb] Change lldb's breakpoint handling behavior (#96260)"

This reverts commit 05f0e86cc895181b3d2210458c78938f83353002.

The debuginfo dexter tests are failing, probably because the way
stepping over breakpoints has changed with my patches.  And there
are two API tests fails on the ubuntu-arm (32-bit) bot. I'll need
to investigate both of these, neither has an obvious failure reason.

Added: 


Modified: 
lldb/include/lldb/Target/Thread.h
lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
lldb/source/Target/StopInfo.cpp
lldb/source/Target/Thread.cpp

lldb/test/API/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py

lldb/test/API/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py

Removed: 




diff  --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index d3e429e9256df..2ff1f50d497e2 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -129,7 +129,6 @@ class Thread : public std::enable_shared_from_this,
 register_backup_sp; // You need to restore the registers, of course...
 uint32_t current_inlined_depth;
 lldb::addr_t current_inlined_pc;
-lldb::addr_t stopped_at_unexecuted_bp;
   };
 
   /// Constructor
@@ -379,26 +378,6 @@ class Thread : public std::enable_shared_from_this,
 
   virtual void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) 
{}
 
-  /// When a thread stops at an enabled BreakpointSite that has not executed,
-  /// the Process plugin should call SetThreadStoppedAtUnexecutedBP(pc).
-  /// If that BreakpointSite was actually triggered (the instruction was
-  /// executed, for a software breakpoint), regardless of whether the
-  /// breakpoint is valid for this thread, SetThreadHitBreakpointSite()
-  /// should be called to record that fact.
-  ///
-  /// Depending on the structure of the Process plugin, it may be easiest
-  /// to call SetThreadStoppedAtUnexecutedBP(pc) unconditionally when at
-  /// a BreakpointSite, and later when it is known that it was triggered,
-  /// SetThreadHitBreakpointSite() can be called.  These two methods
-  /// overwrite the same piece of state in the Thread, the last one
-  /// called on a Thread wins.
-  void SetThreadStoppedAtUnexecutedBP(lldb::addr_t pc) {
-m_stopped_at_unexecuted_bp = pc;
-  }
-  void SetThreadHitBreakpointSite() {
-m_stopped_at_unexecuted_bp = LLDB_INVALID_ADDRESS;
-  }
-
   /// Whether this Thread already has all the Queue information cached or not
   ///
   /// A Thread may be associated with a libdispatch work Queue at a given
@@ -1333,9 +1312,6 @@ class Thread : public 
std::enable_shared_from_this,
   bool m_should_run_before_public_stop;  // If this thread has "stop others" 
  // private work to do, then it will
  // set this.
-  lldb::addr_t m_stopped_at_unexecuted_bp; // Set to the address of a 
breakpoint
-   // instruction that we have not yet
-   // hit, but will hit when we resume.
   const uint32_t m_index_id; ///< A unique 1 based index assigned to each 
thread
  /// for easy UI/command line access.
   lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this

diff  --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp 
b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
index f1853be12638e..25cee369d7ee3 100644
--- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -488,6 +488,38 @@ const char *StopInfoMachException::GetDescription() {
   return m_description.c_str();
 }
 
+static StopInfoSP GetStopInfoForHardwareBP(Thread , Target *target,
+   uint32_t exc_data_count,
+   uint64_t exc_sub_code,
+   uint64_t exc_sub_sub_code) {
+  // Try hardware watchpoint.
+  if (target) {
+// The exc_sub_code indicates the data break address.
+WatchpointResourceSP wp_rsrc_sp =
+target->GetProcessSP()->GetWatchpointResourceList().FindByAddress(
+(addr_t)exc_sub_code);
+if (wp_rsrc_sp && 

[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-19 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda closed 
https://github.com/llvm/llvm-project/pull/96260
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-19 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

The pre-merge linux-x86 test builds both failed in TestConcurrentVFork.py after 
I updated the branch to current main.  I don't know if there's a bot issue or a 
main issue.  I tried repoing on aarch64 ubuntu; that test is skipped on aarch64 
but I removed the skips and it runs without fails in my VM.  I'm going to try 
landing this and see what happens; will revert if bots blow up.  I've tried to 
test all the combinations I have access to here, and Aleksandr's testing on 
windows has been invaluable, but it's still possible it'll need a little 
reworking.

https://github.com/llvm/llvm-project/pull/96260
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-19 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/96260

>From 9b541e6a035635e26c6a24eca022de8552fa4c17 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 20 Jun 2024 17:53:17 -0700
Subject: [PATCH 1/8] [lldb] Change lldb's breakpoint handling behavior

lldb today has two rules:  When a thread stops at a BreakpointSite,
we set the thread's StopReason to be "breakpoint hit" (regardless
if we've actually hit the breakpoint, or if we've merely stopped
*at* the breakpoint instruction/point and haven't tripped it yet).
And second, when resuming a process, any thread sitting at a
BreakpointSite is silently stepped over the BreakpointSite -- because
we've already flagged the breakpoint hit when we stopped there
originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint.  When we resume, we only silently step past a
BreakpointSite that we've registered as hit.  We preserve this state
across inferior function calls that the user may do while stopped,
etc.

Also, when a user adds a new breakpoint at $pc while stopped, or
changes $pc to be the address of a BreakpointSite, we will silently
step past that breakpoint when the process resumes.  This is purely
a UX call, I don't think there's any person who wants to set a
breakpoint at $pc and then hit it immediately on resuming.

One non-intuitive UX from this change, but I'm convinced it is
necessary:  If you're stopped at a BreakpointSite that has not yet
executed, you `stepi`, you will hit the breakpoint and the pc will
not yet advance.  This thread has not completed its stepi, and the
thread plan is still on the stack.  If you then `continue` the
thread, lldb will now stop and say, "instruction step completed",
one instruction past the BreakpointSite.  You can continue a second
time to resume execution.  I discussed this with Jim, and trying
to paper over this behavior will lead to more complicated scenarios
behaving non-intuitively.  And mostly it's the testsuite that was
trying to instruction step past a breakpoint and getting thrown off
-- and I changed those tests to expect the new behavior.

The bugs driving this change are all from lldb dropping the real
stop reason for a thread and setting it to breakpoint-hit when that
was not the case.  Jim hit one where we have an aarch64 watchpoint
that triggers one instruction before a BreakpointSite.  On this
arch we are notified of the watchpoint hit after the instruction
has been unrolled -- we disable the watchpoint, instruction step,
re-enable the watchpoint and collect the new value.  But now we're
on a BreakpointSite so the watchpoint-hit stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282
we attach to/launch a process with the pc at a BreakpointSite and
misbehave.  Caroline Tice mentioned it is also a problem they've
had with putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control
is that

1. If we've stopped at a BreakpointSite (whether we hit it or not),
we call Thread::SetThreadStoppedAtBreakpointSite(pc) to record the
state at the point when the thread stopped.  (so we can detect
newly-added breakpoints, or when the pc is changed to an instruction
that is a BreakpointSite)

2. When we have actually hit a breakpoint, and it is enabled for
this thread, we call Thread::SetThreadHitBreakpointAtAddr(pc) so
we know that it should be silently stepped past when we resume
execution.

When resuming, we silently step over a breakpoint if we've hit it,
or if it is newly added (or the pc was changed to an existing
BreakpointSite).

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason.  The Mach exception
codes differ in a few places depending on the target (unambiguously),
and I didn't want to duplicate the new code for each target so I've
tested what mach exceptions we get for each action on each target,
and reorganized StopInfoMachException::CreateStopReasonWithMachException
to document these possible values, and handle them without specializing
based on the target arch.

rdar://123942164
---
 lldb/include/lldb/Target/Thread.h |  29 ++
 .../Process/Utility/StopInfoMachException.cpp | 296 +++---
 .../Process/Windows/Common/ProcessWindows.cpp |  16 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   | 118 +++
 .../Process/scripted/ScriptedThread.cpp   |   9 +
 lldb/source/Target/Thread.cpp |  17 +-
 .../TestConsecutiveBreakpoints.py |  26 +-
 .../TestStepOverBreakpoint.py |   6 +-
 8 files changed, 235 insertions(+), 282 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index c17bddf4d98b8..1e1aead896018 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ 

[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-19 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/96260

>From 9b541e6a035635e26c6a24eca022de8552fa4c17 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 20 Jun 2024 17:53:17 -0700
Subject: [PATCH 1/8] [lldb] Change lldb's breakpoint handling behavior

lldb today has two rules:  When a thread stops at a BreakpointSite,
we set the thread's StopReason to be "breakpoint hit" (regardless
if we've actually hit the breakpoint, or if we've merely stopped
*at* the breakpoint instruction/point and haven't tripped it yet).
And second, when resuming a process, any thread sitting at a
BreakpointSite is silently stepped over the BreakpointSite -- because
we've already flagged the breakpoint hit when we stopped there
originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint.  When we resume, we only silently step past a
BreakpointSite that we've registered as hit.  We preserve this state
across inferior function calls that the user may do while stopped,
etc.

Also, when a user adds a new breakpoint at $pc while stopped, or
changes $pc to be the address of a BreakpointSite, we will silently
step past that breakpoint when the process resumes.  This is purely
a UX call, I don't think there's any person who wants to set a
breakpoint at $pc and then hit it immediately on resuming.

One non-intuitive UX from this change, but I'm convinced it is
necessary:  If you're stopped at a BreakpointSite that has not yet
executed, you `stepi`, you will hit the breakpoint and the pc will
not yet advance.  This thread has not completed its stepi, and the
thread plan is still on the stack.  If you then `continue` the
thread, lldb will now stop and say, "instruction step completed",
one instruction past the BreakpointSite.  You can continue a second
time to resume execution.  I discussed this with Jim, and trying
to paper over this behavior will lead to more complicated scenarios
behaving non-intuitively.  And mostly it's the testsuite that was
trying to instruction step past a breakpoint and getting thrown off
-- and I changed those tests to expect the new behavior.

The bugs driving this change are all from lldb dropping the real
stop reason for a thread and setting it to breakpoint-hit when that
was not the case.  Jim hit one where we have an aarch64 watchpoint
that triggers one instruction before a BreakpointSite.  On this
arch we are notified of the watchpoint hit after the instruction
has been unrolled -- we disable the watchpoint, instruction step,
re-enable the watchpoint and collect the new value.  But now we're
on a BreakpointSite so the watchpoint-hit stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282
we attach to/launch a process with the pc at a BreakpointSite and
misbehave.  Caroline Tice mentioned it is also a problem they've
had with putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control
is that

1. If we've stopped at a BreakpointSite (whether we hit it or not),
we call Thread::SetThreadStoppedAtBreakpointSite(pc) to record the
state at the point when the thread stopped.  (so we can detect
newly-added breakpoints, or when the pc is changed to an instruction
that is a BreakpointSite)

2. When we have actually hit a breakpoint, and it is enabled for
this thread, we call Thread::SetThreadHitBreakpointAtAddr(pc) so
we know that it should be silently stepped past when we resume
execution.

When resuming, we silently step over a breakpoint if we've hit it,
or if it is newly added (or the pc was changed to an existing
BreakpointSite).

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason.  The Mach exception
codes differ in a few places depending on the target (unambiguously),
and I didn't want to duplicate the new code for each target so I've
tested what mach exceptions we get for each action on each target,
and reorganized StopInfoMachException::CreateStopReasonWithMachException
to document these possible values, and handle them without specializing
based on the target arch.

rdar://123942164
---
 lldb/include/lldb/Target/Thread.h |  29 ++
 .../Process/Utility/StopInfoMachException.cpp | 296 +++---
 .../Process/Windows/Common/ProcessWindows.cpp |  16 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   | 118 +++
 .../Process/scripted/ScriptedThread.cpp   |   9 +
 lldb/source/Target/Thread.cpp |  17 +-
 .../TestConsecutiveBreakpoints.py |  26 +-
 .../TestStepOverBreakpoint.py |   6 +-
 8 files changed, 235 insertions(+), 282 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index c17bddf4d98b8..1e1aead896018 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ 

[Lldb-commits] [lldb] [lldb/Target] Add GetStartSymbol method to DynamicLoader plugins (PR #99673)

2024-07-19 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

LGTM.

https://github.com/llvm/llvm-project/pull/99673
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb/Target] Add GetStartSymbol method to DynamicLoader plugins (PR #99673)

2024-07-19 Thread Jason Molenda via lldb-commits


@@ -10,9 +10,11 @@
 #define LLDB_TARGET_DYNAMICLOADER_H
 
 #include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/Symbol.h"
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/UUID.h"
+#include "lldb/Utility/UnimplementedError.h"

jasonmolenda wrote:

We can remove this header file include now.

https://github.com/llvm/llvm-project/pull/99673
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb/Target] Add GetStartSymbol method to DynamicLoader plugins (PR #99673)

2024-07-19 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda edited 
https://github.com/llvm/llvm-project/pull/99673
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb/Target] Add GetStartSymbol method to DynamicLoader plugins (PR #99673)

2024-07-19 Thread Jason Molenda via lldb-commits


@@ -329,6 +330,11 @@ class DynamicLoader : public PluginInterface {
   /// safe to call certain APIs or SPIs.
   virtual bool IsFullyInitialized() { return true; }
 
+  /// Return the `start` function \b symbol in the dynamic loader module.
+  virtual llvm::Expected GetStartSymbol() {

jasonmolenda wrote:

I would DEFINITELY not bank on this assumption.  The world of environments a 
debugger needs to support is vast.

https://github.com/llvm/llvm-project/pull/99673
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb/Target] Add GetStartSymbol method to DynamicLoader plugins (PR #99673)

2024-07-19 Thread Jason Molenda via lldb-commits


@@ -329,6 +330,11 @@ class DynamicLoader : public PluginInterface {
   /// safe to call certain APIs or SPIs.
   virtual bool IsFullyInitialized() { return true; }
 
+  /// Return the `start` function \b symbol in the dynamic loader module.
+  virtual llvm::Expected GetStartSymbol() {

jasonmolenda wrote:

Should this be an llvm::Expected?  It's only going to be defined for 
DynamicLoaderDarwin today.  If some generic code wanted to use this, where it 
may not be applicable or defined for another DynamicLoader plugin, it'll need 
to consume the UnimplementedError.  Given the optionality of it, a 
std::optional seems more natural to me maybe?

https://github.com/llvm/llvm-project/pull/99673
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb/Target] Add GetStartSymbol method to DynamicLoader plugins (PR #99673)

2024-07-19 Thread Jason Molenda via lldb-commits


@@ -329,6 +330,11 @@ class DynamicLoader : public PluginInterface {
   /// safe to call certain APIs or SPIs.
   virtual bool IsFullyInitialized() { return true; }
 
+  /// Return the `start` function \b symbol in the dynamic loader module.

jasonmolenda wrote:

The meaning of this is clear in a Darwin environment, but I wonder if we should 
explain it a little more, like "This is the symbol the process will begin 
executing with `process launch --stop-at-entry`".  I don't feel strongly about 
this.

https://github.com/llvm/llvm-project/pull/99673
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][RISCV] function calls support in lldb expressions (PR #99336)

2024-07-19 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,58 @@
+//===--- DirectToIndirectFCR.h - RISC-V specific pass 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#pragma once
+
+#include "lldb/lldb-types.h"
+
+#include "llvm/IR/Instructions.h"
+#include "llvm/Pass.h"
+
+namespace lldb_private {
+
+class ExecutionContext;
+
+// During the lldb expression execution lldb wraps a user expression, jittes
+// fabricated code and then puts it into the stack memory. Thus, if user tried
+// to make a function call there will be a jump from a stack address to a code
+// sections's address. RISC-V Architecture doesn't have a large code model yet
+// and can make only a +-2GiB jumps, but in 64-bit architecture a distance
+// between stack addresses and code sections's addresses is longer. Therefore,
+// relocations resolver obtains an invalid address. To avoid such problem, this
+// pass should be used. It replaces function calls with appropriate function's
+// addresses explicitly. By doing so it removes relocations related to function
+// calls. This pass should be cosidered as temprorary solution until a large
+// code model will be approved.
+class DirectToIndirectFCR : public llvm::FunctionPass {

jasonmolenda wrote:

It's a minor detail, and I never work on the llvm side of the codebase so this 
is probably just my own ignorance, but: I have no idea what DirectToIndirectFCR 
means, beyond the explanation above.  I'm sure to people more familiar with 
llvm/clang this is clear.

https://github.com/llvm/llvm-project/pull/99336
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][RISCV] function calls support in lldb expressions (PR #99336)

2024-07-19 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,58 @@
+//===--- DirectToIndirectFCR.h - RISC-V specific pass 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#pragma once
+
+#include "lldb/lldb-types.h"
+
+#include "llvm/IR/Instructions.h"
+#include "llvm/Pass.h"
+
+namespace lldb_private {
+
+class ExecutionContext;
+
+// During the lldb expression execution lldb wraps a user expression, jittes
+// fabricated code and then puts it into the stack memory. Thus, if user tried

jasonmolenda wrote:

I don't think this is quite true.  lldb asks the remote stub to allocate memory 
with read+write permissions for storing the arguments, and read+execute 
permissions for the jitted code, e.g. 
```
(lldb) p (int)isdigit('1')
 <  13> send packet: $_M1000,rx#83
 <  13> read packet: $18000#00
 <  13> send packet: $_M1000,rw#82
 <  13> read packet: $1c000#00
```

It would be surprising (to me) if the stub returned memory regions on the 
stack, because lldb is allowed to reuse these regions throughout the debug 
session, and we can't have the inferior process overwriting them.

You are correct that the allocated regions may be too far from the function(s) 
they'll need to call, and the same problem you describe below could exist.  I 
don't mean to focus on the "stack memory" part of this, but I think it will 
confuse people when they read it.

https://github.com/llvm/llvm-project/pull/99336
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)

2024-07-19 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I think we should change these checks to look for an explicitly inaccessible 
memory region, like 

```
   if (region_info.GetReadable() != MemoryRegionInfo::OptionalBool::eNo &&
region_info.GetWritable() != MemoryRegionInfo::OptionalBool::eNo &&
region_info.GetExecutable() !=
MemoryRegionInfo::OptionalBool::eNo) {
   // This region is inaccessible, if it is large enough, use this 
address.
   if (ret + size < region_info.GetRange().GetRangeEnd())
return ret;
   else 
 ret = region_info.GetRange().GetRangeEnd();
 // keep searching
```

and I also do think there is value in adding a special case for address 0.  
Even if we have an inaddressable memory block at address 0 which should be 
eligible for shadowing with lldb's host memory, using that is a poor choice 
because people crash at address 0 all the time and we don't want references to 
that address finding the IRMemoryMap host side memory values.

```
} else if (ret == 0) {
   // Don't put our host-side memory block at virtual address 0 even if 
it
   // seems eligible, we don't want to confuse things when a program 
   // crashes accessing that address, a common way of crashing.
   ret = region_info.GetRange().GetRangeEnd();
```



https://github.com/llvm/llvm-project/pull/99045
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][RISCV] function calls support in lldb expressions (PR #99336)

2024-07-19 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

As for getting to the jitted code, of course lldb sets the pc directly so that 
initial switch from user code to jitted code region is fine.  But getting from 
the jitted wrapper function to the user functions we need to call would require 
JALR instructions?

https://github.com/llvm/llvm-project/pull/99336
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][RISCV] function calls support in lldb expressions (PR #99336)

2024-07-19 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

A quick look at the RISCV ISA and it says that the JAL instruction is pc 
relative and can jump +/- 1MB.  JALR is also pc-relative but it gets the upper 
20 bits from a general purpose register and it includes 12 low bits in its 
instruction encoding.  I know almost nothing about rv32, but is this what you 
mean by a Large Memory Model, the use of the JALR instruction? I didn't find 
the part that talks about how JALR works in rv64, but it seems likely it can 
specify an arbitrary 64-bit address?

https://github.com/llvm/llvm-project/pull/99336
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)

2024-07-19 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I'd describe this patch as handling the case where a remote stub cannot jit 
memory and has a qMemoryRegion info packet which does not specify permissions.  
The patch you reference makes jitted code expressions work, but I think 
IRMemoryMap::FindSpec only needs to find space in the inferior virtual address 
space -- allocate memory -- and that was already working, wasn't it?  Also, 
your before & after packets show that you've got permissions returned for your 
qMemoryRegionInfo responses now, which you don't before -- you won't hit this 
failure because of that change.

One thing I'd say is that this patch is looking for "is this a region with 
read, write, or execute permissions", so it can skip that.  It does this with, 

```
if (region_info.GetReadable() != MemoryRegionInfo::OptionalBool::eNo ||
region_info.GetWritable() != MemoryRegionInfo::OptionalBool::eNo ||
region_info.GetExecutable() !=
MemoryRegionInfo::OptionalBool::eNo) {
ret = region_info.GetRange().GetRangeEnd();
 /// keep iterating
```

but `MemoryRegionInfo::OptionalBool` can be `eDontKnow` which it is here.  I 
think this conditional would be more clearly expressed as

```
   bool all_permissions_unknown = region_info.GetReadable() == 
MemoryRegionInfo::OptionalBool::eDontKnow &&

region_info.GetWritable() == MemoryRegionInfo::OptionalBool::eDontKnow &&
 
region_info.GetExecutable() == MemoryRegionInfo::OptionalBool::eDontKnow;
   bool any_permissions_yes = region_info.GetReadable() == 
MemoryRegionInfo::OptionalBool::eYes

region_info.GetWritable() == MemoryRegionInfo::OptionalBool::eYes
 
region_info.GetExecutable() ==  MemoryRegionInfo::OptionalBool::eYes;
if (all_permissions_unknown || any_permissions_yes)
ret = region_info.GetRange().GetRangeEnd();
 /// keep iterating
```

or more simply, change the while (true) loop to first check if all permissions 
are No in a region,

```
if (region_info.GetReadable() != MemoryRegionInfo::OptionalBool::eNo &&
region_info.GetWritable() != MemoryRegionInfo::OptionalBool::eNo &&
region_info.GetExecutable() !=
MemoryRegionInfo::OptionalBool::eNo) {
   if (ret + size < region_info.GetRange().GetRangeEnd())
return ret;
   else 
 ret = region_info.GetRange().GetRangeEnd();
 // keep searching
```



https://github.com/llvm/llvm-project/pull/99045
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [lldb][RISCV] function calls support in lldb expressions (PR #99336)

2024-07-18 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,58 @@
+//===--- DirectToIndirectFCR.h - RISC-V specific pass 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#pragma once
+
+#include "lldb/lldb-types.h"
+
+#include "llvm/IR/Instructions.h"
+#include "llvm/Pass.h"
+
+namespace lldb_private {
+
+class ExecutionContext;
+
+// During the lldb expression execution lldb wraps a user expression, jittes
+// fabricated code and then puts it into the stack memory. Thus, if user tried
+// to make a function call there will be a jump from a stack address to a code
+// sections's address. RISC-V Architecture doesn't have a large code model yet
+// and can make only a +-2GiB jumps, but in 64-bit architecture a distance
+// between stack addresses and code sections's addresses is longer. Therefore,
+// relocations resolver obtains an invalid address. To avoid such problem, this
+// pass should be used. It replaces function calls with appropriate function's
+// addresses explicitly. By doing so it removes relocations related to function
+// calls. This pass should be cosidered as temprorary solution until a large

jasonmolenda wrote:

tiny nit: "cosidered", "temprorary".  I do this all the time myself, just 
happened to see them.

https://github.com/llvm/llvm-project/pull/99336
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-17 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda edited 
https://github.com/llvm/llvm-project/pull/96260
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-17 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/96260

>From 9b541e6a035635e26c6a24eca022de8552fa4c17 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 20 Jun 2024 17:53:17 -0700
Subject: [PATCH 1/7] [lldb] Change lldb's breakpoint handling behavior

lldb today has two rules:  When a thread stops at a BreakpointSite,
we set the thread's StopReason to be "breakpoint hit" (regardless
if we've actually hit the breakpoint, or if we've merely stopped
*at* the breakpoint instruction/point and haven't tripped it yet).
And second, when resuming a process, any thread sitting at a
BreakpointSite is silently stepped over the BreakpointSite -- because
we've already flagged the breakpoint hit when we stopped there
originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint.  When we resume, we only silently step past a
BreakpointSite that we've registered as hit.  We preserve this state
across inferior function calls that the user may do while stopped,
etc.

Also, when a user adds a new breakpoint at $pc while stopped, or
changes $pc to be the address of a BreakpointSite, we will silently
step past that breakpoint when the process resumes.  This is purely
a UX call, I don't think there's any person who wants to set a
breakpoint at $pc and then hit it immediately on resuming.

One non-intuitive UX from this change, but I'm convinced it is
necessary:  If you're stopped at a BreakpointSite that has not yet
executed, you `stepi`, you will hit the breakpoint and the pc will
not yet advance.  This thread has not completed its stepi, and the
thread plan is still on the stack.  If you then `continue` the
thread, lldb will now stop and say, "instruction step completed",
one instruction past the BreakpointSite.  You can continue a second
time to resume execution.  I discussed this with Jim, and trying
to paper over this behavior will lead to more complicated scenarios
behaving non-intuitively.  And mostly it's the testsuite that was
trying to instruction step past a breakpoint and getting thrown off
-- and I changed those tests to expect the new behavior.

The bugs driving this change are all from lldb dropping the real
stop reason for a thread and setting it to breakpoint-hit when that
was not the case.  Jim hit one where we have an aarch64 watchpoint
that triggers one instruction before a BreakpointSite.  On this
arch we are notified of the watchpoint hit after the instruction
has been unrolled -- we disable the watchpoint, instruction step,
re-enable the watchpoint and collect the new value.  But now we're
on a BreakpointSite so the watchpoint-hit stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282
we attach to/launch a process with the pc at a BreakpointSite and
misbehave.  Caroline Tice mentioned it is also a problem they've
had with putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control
is that

1. If we've stopped at a BreakpointSite (whether we hit it or not),
we call Thread::SetThreadStoppedAtBreakpointSite(pc) to record the
state at the point when the thread stopped.  (so we can detect
newly-added breakpoints, or when the pc is changed to an instruction
that is a BreakpointSite)

2. When we have actually hit a breakpoint, and it is enabled for
this thread, we call Thread::SetThreadHitBreakpointAtAddr(pc) so
we know that it should be silently stepped past when we resume
execution.

When resuming, we silently step over a breakpoint if we've hit it,
or if it is newly added (or the pc was changed to an existing
BreakpointSite).

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason.  The Mach exception
codes differ in a few places depending on the target (unambiguously),
and I didn't want to duplicate the new code for each target so I've
tested what mach exceptions we get for each action on each target,
and reorganized StopInfoMachException::CreateStopReasonWithMachException
to document these possible values, and handle them without specializing
based on the target arch.

rdar://123942164
---
 lldb/include/lldb/Target/Thread.h |  29 ++
 .../Process/Utility/StopInfoMachException.cpp | 296 +++---
 .../Process/Windows/Common/ProcessWindows.cpp |  16 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   | 118 +++
 .../Process/scripted/ScriptedThread.cpp   |   9 +
 lldb/source/Target/Thread.cpp |  17 +-
 .../TestConsecutiveBreakpoints.py |  26 +-
 .../TestStepOverBreakpoint.py |   6 +-
 8 files changed, 235 insertions(+), 282 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index c17bddf4d98b8..1e1aead896018 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ 

[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-17 Thread Jason Molenda via lldb-commits


@@ -229,6 +229,17 @@ bool ScriptedThread::CalculateStopInfo() {
 LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", 
error,
 LLDBLog::Thread);
 
+  // If we're at a BreakpointSite, mark that we stopped there and

jasonmolenda wrote:

This comment was meant to be on ProcessGDBRemote.cpp where I removed a section 
of code for a thread that had no stop signal/reason, but is sitting at a 
BreakpointSite.  The old comment on this:
```
// If a thread is stopped at a breakpoint site, set that as the stop
// reason even if it hasn't executed the breakpoint instruction yet.
// We will silently step over the breakpoint when we resume execution
// and miss the fact that this thread hit the breakpoint.
```

That's the old stepping behavior.  The new stepping behavior is if a thread 
stops at a BreakpointSite but has no signal/breakpoint hit reason, we call 
`Thread::SetThreadStoppedAtUnexecutedBP(pc)`.  This is done at the top of 
`ProcessGDBRemote::SetThreadStopInfo` already if the thread stops at a 
BreakpointSite but hasn't hit it, so there's no need for this block to still be 
around.

https://github.com/llvm/llvm-project/pull/96260
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)

2024-07-17 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

To make sure I'm clear: I don't have a problem with the basic idea of the 
change, although we could comment what is going on more clearly, and I'm 
curious about that qMemoryRegionInfo packet.  But it looks like you're 
connecting to a device which can't allocate memory through gdb remote serial 
protocol (common for jtag/vm type stubs), but can report memory region info 
(much less common, it's an lldb extension I believe), and the memory region at 
address 0 is reported as being inaccessible (reasonable).  So the IRMemoryMap 
is trying to use address 0 and that overlaps with actual addresses seen in the 
process, leading to confusion.  

Most similar environments, that can't allocate memory, don't support 
qMemoryRegionInfo so we pick one of our bogus addresses ranges (in higher 
memory) to get a better chance of avoiding actual program addresses.

https://github.com/llvm/llvm-project/pull/99045
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-17 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda closed 
https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-17 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/98845

>From cead9ae6de627ee64fb58a829fa3485f526a0afc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Sun, 14 Jul 2024 16:59:51 -0700
Subject: [PATCH 1/8] [lldb] progressive progress reporting for darwin
 kernel/firmware

When doing firmware/kernel debugging, it is frequent that
binaries and debug info need to be retrieved / downloaded,
and the lack of progress reports made for a poor experience,
with lldb seemingly hung while downloading things over the
network. This PR adds progress reports to the critical sites
for these use cases.
---
 lldb/source/Core/DynamicLoader.cpp| 27 +++--
 .../DynamicLoaderDarwinKernel.cpp | 39 ---
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/lldb/source/Core/DynamicLoader.cpp 
b/lldb/source/Core/DynamicLoader.cpp
index 7871be6fc451d..a59136381c23b 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",
+  prog_str.GetString().str());
 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
 
-if (memory_module_sp)
+if (memory_module_sp) {
   uuid = memory_module_sp->GetUUID();
+  if (uuid.IsValid()) {
+prog_str << " ";
+prog_str << uuid.GetAsString();
+  }
+}
   }
   ModuleSpec module_spec;
   module_spec.GetUUID() = uuid;
   FileSpec name_filespec(name);
-  if (FileSystem::Instance().Exists(name_filespec))
-module_spec.GetFileSpec() = name_filespec;
 
   if (uuid.IsValid()) {
+Progress progress("Locating external symbol file",
+  prog_str.GetString().str());
+
 // Has lldb already seen a module with this UUID?
+// Or have external lookup enabled in DebugSymbols on macOS.
 if (!module_sp)
   error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
   nullptr, nullptr);
diff --git 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 8d83937aab668..93eb1e7b9dea9 100644
--- 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -757,6 +758,23 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+std::unique_ptr progress_up;
+if (IsKernel()) {
+  StreamString prog_str;
+  // 'mach_kernel' is a fake name we make up to find kernels
+  // that were located by the local filesystem scan.
+  if (GetName() != "mach_kernel")
+prog_str << GetName() << " ";
+  if (GetUUID().IsValid())
+prog_str << GetUUID().GetAsString() << " ";
+  if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(GetLoadAddress());
+  }
+  progress_up = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+}
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
@@ -1058,12 +1076,9 @@ void 
DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
 }
   }
 }
-
-if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
-  if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
+if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
+  if (!m_kernel.LoadImageUsingMemoryModule(m_process))
 m_kernel.LoadImageAtFileAddress(m_process);
-  }
-}
 
 // The operating system plugin gets loaded and initialized in
 // LoadImageUsingMemoryModule when we discover the 

[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-16 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/98845

>From cead9ae6de627ee64fb58a829fa3485f526a0afc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Sun, 14 Jul 2024 16:59:51 -0700
Subject: [PATCH 1/7] [lldb] progressive progress reporting for darwin
 kernel/firmware

When doing firmware/kernel debugging, it is frequent that
binaries and debug info need to be retrieved / downloaded,
and the lack of progress reports made for a poor experience,
with lldb seemingly hung while downloading things over the
network. This PR adds progress reports to the critical sites
for these use cases.
---
 lldb/source/Core/DynamicLoader.cpp| 27 +++--
 .../DynamicLoaderDarwinKernel.cpp | 39 ---
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/lldb/source/Core/DynamicLoader.cpp 
b/lldb/source/Core/DynamicLoader.cpp
index 7871be6fc451d..a59136381c23b 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",
+  prog_str.GetString().str());
 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
 
-if (memory_module_sp)
+if (memory_module_sp) {
   uuid = memory_module_sp->GetUUID();
+  if (uuid.IsValid()) {
+prog_str << " ";
+prog_str << uuid.GetAsString();
+  }
+}
   }
   ModuleSpec module_spec;
   module_spec.GetUUID() = uuid;
   FileSpec name_filespec(name);
-  if (FileSystem::Instance().Exists(name_filespec))
-module_spec.GetFileSpec() = name_filespec;
 
   if (uuid.IsValid()) {
+Progress progress("Locating external symbol file",
+  prog_str.GetString().str());
+
 // Has lldb already seen a module with this UUID?
+// Or have external lookup enabled in DebugSymbols on macOS.
 if (!module_sp)
   error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
   nullptr, nullptr);
diff --git 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 8d83937aab668..93eb1e7b9dea9 100644
--- 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -757,6 +758,23 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+std::unique_ptr progress_up;
+if (IsKernel()) {
+  StreamString prog_str;
+  // 'mach_kernel' is a fake name we make up to find kernels
+  // that were located by the local filesystem scan.
+  if (GetName() != "mach_kernel")
+prog_str << GetName() << " ";
+  if (GetUUID().IsValid())
+prog_str << GetUUID().GetAsString() << " ";
+  if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(GetLoadAddress());
+  }
+  progress_up = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+}
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
@@ -1058,12 +1076,9 @@ void 
DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
 }
   }
 }
-
-if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
-  if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
+if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
+  if (!m_kernel.LoadImageUsingMemoryModule(m_process))
 m_kernel.LoadImageAtFileAddress(m_process);
-  }
-}
 
 // The operating system plugin gets loaded and initialized in
 // LoadImageUsingMemoryModule when we discover the 

[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-16 Thread Jason Molenda via lldb-commits


@@ -633,171 +613,142 @@ StopInfoSP 
StopInfoMachException::CreateStopReasonWithMachException(
 }
 break;
 
+  // [exc_type, exc_code, exc_sub_code, exc_sub_sub_code]
+  //
+  // Instruction step:
+  //   [6, 1, 0]
+  //   Intel KDP [6, 3, ??]
+  //   armv7 [6, 0x102, ]  Same as software breakpoint!
+  //
+  // Software breakpoint:
+  //   x86 [6, 2, 0]
+  //   Intel KDP [6, 2, ]
+  //   arm64 [6, 1, ]
+  //   armv7 [6, 0x102, ]  Same as instruction step!
+  //
+  // Hardware breakpoint:
+  //   x86 [6, 1, , 0]
+  //   x86/Rosetta not implemented, see software breakpoint
+  //   arm64 [6, 1, ]
+  //   armv7 not implemented, see software breakpoint
+  //
+  // Hardware watchpoint:
+  //   x86 [6, 1, , 0] (both Intel hw and Rosetta)
+  //   arm64 [6, 0x102, , 0]
+  //   armv7 [6, 0x102, , 0]
+  //
+  // arm64 BRK instruction (imm arg not reflected in the ME)
+  //   [ 6, 1, ]
+  //
+  // In order of codes mach exceptions:
+  //   [6, 1, 0] - instruction step
+  //   [6, 1, ] - hardware breakpoint or watchpoint
+  //
+  //   [6, 2, 0] - software breakpoint
+  //   [6, 2, ] - software breakpoint
+  //
+  //   [6, 3] - instruction step
+  //
+  //   [6, 0x102, ] armv7 instruction step
+  //   [6, 0x102, ] armv7 software breakpoint
+  //   [6, 0x102, , 0] arm64/armv7 watchpoint
   case 6: // EXC_BREAKPOINT
   {
-bool is_actual_breakpoint = false;
-bool is_trace_if_actual_breakpoint_missing = false;
-switch (cpu) {
-case llvm::Triple::x86:
-case llvm::Triple::x86_64:
-  if (exc_code == 1) // EXC_I386_SGL
-  {
-if (!exc_sub_code) {
-  // This looks like a plain trap.
-  // Have to check if there is a breakpoint here as well.  When you
-  // single-step onto a trap, the single step stops you not to trap.
-  // Since we also do that check below, let's just use that logic.
-  is_actual_breakpoint = true;
-  is_trace_if_actual_breakpoint_missing = true;
-} else {
-  if (StopInfoSP stop_info =
-  GetStopInfoForHardwareBP(thread, target, exc_data_count,
-   exc_sub_code, exc_sub_sub_code))
-return stop_info;
-}
-  } else if (exc_code == 2 || // EXC_I386_BPT
- exc_code == 3)   // EXC_I386_BPTFLT
-  {
-// KDP returns EXC_I386_BPTFLT for trace breakpoints
-if (exc_code == 3)
-  is_trace_if_actual_breakpoint_missing = true;
-
-is_actual_breakpoint = true;
-if (!pc_already_adjusted)
-  pc_decrement = 1;
-  }
-  break;
-
-case llvm::Triple::arm:
-case llvm::Triple::thumb:
-  if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
-  {
-// LWP_TODO: We need to find the WatchpointResource that matches
-// the address, and evaluate its Watchpoints.
-
-// It's a watchpoint, then, if the exc_sub_code indicates a
-// known/enabled data break address from our watchpoint list.
-lldb::WatchpointSP wp_sp;
-if (target)
-  wp_sp = target->GetWatchpointList().FindByAddress(
-  (lldb::addr_t)exc_sub_code);
-if (wp_sp && wp_sp->IsEnabled()) {
-  return StopInfo::CreateStopReasonWithWatchpointID(thread,
-wp_sp->GetID());
-} else {
-  is_actual_breakpoint = true;
-  is_trace_if_actual_breakpoint_missing = true;
-}
-  } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
-  {
-is_actual_breakpoint = true;
-is_trace_if_actual_breakpoint_missing = true;
-  } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
-// is currently returning this so accept it
-// as indicating a breakpoint until the
-// kernel is fixed
-  {
-is_actual_breakpoint = true;
-is_trace_if_actual_breakpoint_missing = true;
-  }
-  break;
+bool stopped_by_hitting_breakpoint = false;
+bool stopped_by_completing_stepi = false;
+bool stopped_watchpoint = false;
+std::optional value;
+
+// exc_code 1
+if (exc_code == 1 && exc_sub_code == 0)
+  stopped_by_completing_stepi = true;
+if (exc_code == 1 && exc_sub_code != 0) {
+  stopped_by_hitting_breakpoint = true;
+  stopped_watchpoint = true;
+  value = exc_sub_code;
+}
 
-case llvm::Triple::aarch64_32:
-case llvm::Triple::aarch64: {
-  // xnu describes three things with type EXC_BREAKPOINT:
-  //
-  //   exc_code 0x102 [EXC_ARM_DA_DEBUG], exc_sub_code addr-of-insn
-  //  Watchpoint access.  exc_sub_code is the address of the
-  //  instruction which trigged the watchpoint trap.
-  //  debugserver may add the watchpoint number that was triggered
-  //  in exc_sub_sub_code.
-  //
-  //   exc_code 1 

[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-16 Thread Jason Molenda via lldb-commits


@@ -633,171 +613,142 @@ StopInfoSP 
StopInfoMachException::CreateStopReasonWithMachException(
 }
 break;
 
+  // [exc_type, exc_code, exc_sub_code, exc_sub_sub_code]
+  //
+  // Instruction step:
+  //   [6, 1, 0]
+  //   Intel KDP [6, 3, ??]
+  //   armv7 [6, 0x102, ]  Same as software breakpoint!
+  //
+  // Software breakpoint:
+  //   x86 [6, 2, 0]
+  //   Intel KDP [6, 2, ]
+  //   arm64 [6, 1, ]
+  //   armv7 [6, 0x102, ]  Same as instruction step!
+  //
+  // Hardware breakpoint:
+  //   x86 [6, 1, , 0]
+  //   x86/Rosetta not implemented, see software breakpoint
+  //   arm64 [6, 1, ]
+  //   armv7 not implemented, see software breakpoint
+  //
+  // Hardware watchpoint:
+  //   x86 [6, 1, , 0] (both Intel hw and Rosetta)
+  //   arm64 [6, 0x102, , 0]
+  //   armv7 [6, 0x102, , 0]
+  //
+  // arm64 BRK instruction (imm arg not reflected in the ME)
+  //   [ 6, 1, ]
+  //
+  // In order of codes mach exceptions:
+  //   [6, 1, 0] - instruction step
+  //   [6, 1, ] - hardware breakpoint or watchpoint
+  //
+  //   [6, 2, 0] - software breakpoint
+  //   [6, 2, ] - software breakpoint
+  //
+  //   [6, 3] - instruction step
+  //
+  //   [6, 0x102, ] armv7 instruction step
+  //   [6, 0x102, ] armv7 software breakpoint
+  //   [6, 0x102, , 0] arm64/armv7 watchpoint
   case 6: // EXC_BREAKPOINT
   {
-bool is_actual_breakpoint = false;
-bool is_trace_if_actual_breakpoint_missing = false;
-switch (cpu) {
-case llvm::Triple::x86:
-case llvm::Triple::x86_64:
-  if (exc_code == 1) // EXC_I386_SGL
-  {
-if (!exc_sub_code) {
-  // This looks like a plain trap.
-  // Have to check if there is a breakpoint here as well.  When you
-  // single-step onto a trap, the single step stops you not to trap.
-  // Since we also do that check below, let's just use that logic.
-  is_actual_breakpoint = true;
-  is_trace_if_actual_breakpoint_missing = true;
-} else {
-  if (StopInfoSP stop_info =
-  GetStopInfoForHardwareBP(thread, target, exc_data_count,
-   exc_sub_code, exc_sub_sub_code))
-return stop_info;
-}
-  } else if (exc_code == 2 || // EXC_I386_BPT
- exc_code == 3)   // EXC_I386_BPTFLT
-  {
-// KDP returns EXC_I386_BPTFLT for trace breakpoints
-if (exc_code == 3)
-  is_trace_if_actual_breakpoint_missing = true;
-
-is_actual_breakpoint = true;
-if (!pc_already_adjusted)
-  pc_decrement = 1;
-  }
-  break;
-
-case llvm::Triple::arm:
-case llvm::Triple::thumb:
-  if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
-  {
-// LWP_TODO: We need to find the WatchpointResource that matches
-// the address, and evaluate its Watchpoints.
-
-// It's a watchpoint, then, if the exc_sub_code indicates a
-// known/enabled data break address from our watchpoint list.
-lldb::WatchpointSP wp_sp;
-if (target)
-  wp_sp = target->GetWatchpointList().FindByAddress(
-  (lldb::addr_t)exc_sub_code);
-if (wp_sp && wp_sp->IsEnabled()) {
-  return StopInfo::CreateStopReasonWithWatchpointID(thread,
-wp_sp->GetID());
-} else {
-  is_actual_breakpoint = true;
-  is_trace_if_actual_breakpoint_missing = true;
-}
-  } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
-  {
-is_actual_breakpoint = true;
-is_trace_if_actual_breakpoint_missing = true;
-  } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
-// is currently returning this so accept it
-// as indicating a breakpoint until the
-// kernel is fixed
-  {
-is_actual_breakpoint = true;
-is_trace_if_actual_breakpoint_missing = true;
-  }
-  break;
+bool stopped_by_hitting_breakpoint = false;
+bool stopped_by_completing_stepi = false;
+bool stopped_watchpoint = false;
+std::optional value;
+
+// exc_code 1
+if (exc_code == 1 && exc_sub_code == 0)
+  stopped_by_completing_stepi = true;
+if (exc_code == 1 && exc_sub_code != 0) {
+  stopped_by_hitting_breakpoint = true;
+  stopped_watchpoint = true;
+  value = exc_sub_code;
+}
 
-case llvm::Triple::aarch64_32:
-case llvm::Triple::aarch64: {
-  // xnu describes three things with type EXC_BREAKPOINT:
-  //
-  //   exc_code 0x102 [EXC_ARM_DA_DEBUG], exc_sub_code addr-of-insn
-  //  Watchpoint access.  exc_sub_code is the address of the
-  //  instruction which trigged the watchpoint trap.
-  //  debugserver may add the watchpoint number that was triggered
-  //  in exc_sub_sub_code.
-  //
-  //   exc_code 1 

[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-16 Thread Jason Molenda via lldb-commits


@@ -2545,6 +2546,11 @@ ModuleSP Process::ReadModuleFromMemory(const FileSpec 
_spec,
   ModuleSP module_sp(new Module(file_spec, ArchSpec()));
   if (module_sp) {
 Status error;
+std::unique_ptr progress_up;
+if (!GetCoreFile())

jasonmolenda wrote:

Oh whoops, my bad on that one, thanks.  I'll change to use this instead, it's 
clearer.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-16 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/98845

>From cead9ae6de627ee64fb58a829fa3485f526a0afc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Sun, 14 Jul 2024 16:59:51 -0700
Subject: [PATCH 1/6] [lldb] progressive progress reporting for darwin
 kernel/firmware

When doing firmware/kernel debugging, it is frequent that
binaries and debug info need to be retrieved / downloaded,
and the lack of progress reports made for a poor experience,
with lldb seemingly hung while downloading things over the
network. This PR adds progress reports to the critical sites
for these use cases.
---
 lldb/source/Core/DynamicLoader.cpp| 27 +++--
 .../DynamicLoaderDarwinKernel.cpp | 39 ---
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/lldb/source/Core/DynamicLoader.cpp 
b/lldb/source/Core/DynamicLoader.cpp
index 7871be6fc451d..a59136381c23b 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",
+  prog_str.GetString().str());
 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
 
-if (memory_module_sp)
+if (memory_module_sp) {
   uuid = memory_module_sp->GetUUID();
+  if (uuid.IsValid()) {
+prog_str << " ";
+prog_str << uuid.GetAsString();
+  }
+}
   }
   ModuleSpec module_spec;
   module_spec.GetUUID() = uuid;
   FileSpec name_filespec(name);
-  if (FileSystem::Instance().Exists(name_filespec))
-module_spec.GetFileSpec() = name_filespec;
 
   if (uuid.IsValid()) {
+Progress progress("Locating external symbol file",
+  prog_str.GetString().str());
+
 // Has lldb already seen a module with this UUID?
+// Or have external lookup enabled in DebugSymbols on macOS.
 if (!module_sp)
   error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
   nullptr, nullptr);
diff --git 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 8d83937aab668..93eb1e7b9dea9 100644
--- 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -757,6 +758,23 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+std::unique_ptr progress_up;
+if (IsKernel()) {
+  StreamString prog_str;
+  // 'mach_kernel' is a fake name we make up to find kernels
+  // that were located by the local filesystem scan.
+  if (GetName() != "mach_kernel")
+prog_str << GetName() << " ";
+  if (GetUUID().IsValid())
+prog_str << GetUUID().GetAsString() << " ";
+  if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(GetLoadAddress());
+  }
+  progress_up = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+}
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
@@ -1058,12 +1076,9 @@ void 
DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
 }
   }
 }
-
-if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
-  if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
+if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
+  if (!m_kernel.LoadImageUsingMemoryModule(m_process))
 m_kernel.LoadImageAtFileAddress(m_process);
-  }
-}
 
 // The operating system plugin gets loaded and initialized in
 // LoadImageUsingMemoryModule when we discover the 

[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-16 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/98845

>From cead9ae6de627ee64fb58a829fa3485f526a0afc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Sun, 14 Jul 2024 16:59:51 -0700
Subject: [PATCH 1/5] [lldb] progressive progress reporting for darwin
 kernel/firmware

When doing firmware/kernel debugging, it is frequent that
binaries and debug info need to be retrieved / downloaded,
and the lack of progress reports made for a poor experience,
with lldb seemingly hung while downloading things over the
network. This PR adds progress reports to the critical sites
for these use cases.
---
 lldb/source/Core/DynamicLoader.cpp| 27 +++--
 .../DynamicLoaderDarwinKernel.cpp | 39 ---
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/lldb/source/Core/DynamicLoader.cpp 
b/lldb/source/Core/DynamicLoader.cpp
index 7871be6fc451d..a59136381c23b 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",
+  prog_str.GetString().str());
 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
 
-if (memory_module_sp)
+if (memory_module_sp) {
   uuid = memory_module_sp->GetUUID();
+  if (uuid.IsValid()) {
+prog_str << " ";
+prog_str << uuid.GetAsString();
+  }
+}
   }
   ModuleSpec module_spec;
   module_spec.GetUUID() = uuid;
   FileSpec name_filespec(name);
-  if (FileSystem::Instance().Exists(name_filespec))
-module_spec.GetFileSpec() = name_filespec;
 
   if (uuid.IsValid()) {
+Progress progress("Locating external symbol file",
+  prog_str.GetString().str());
+
 // Has lldb already seen a module with this UUID?
+// Or have external lookup enabled in DebugSymbols on macOS.
 if (!module_sp)
   error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
   nullptr, nullptr);
diff --git 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 8d83937aab668..93eb1e7b9dea9 100644
--- 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -757,6 +758,23 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+std::unique_ptr progress_up;
+if (IsKernel()) {
+  StreamString prog_str;
+  // 'mach_kernel' is a fake name we make up to find kernels
+  // that were located by the local filesystem scan.
+  if (GetName() != "mach_kernel")
+prog_str << GetName() << " ";
+  if (GetUUID().IsValid())
+prog_str << GetUUID().GetAsString() << " ";
+  if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(GetLoadAddress());
+  }
+  progress_up = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+}
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
@@ -1058,12 +1076,9 @@ void 
DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
 }
   }
 }
-
-if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
-  if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
+if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
+  if (!m_kernel.LoadImageUsingMemoryModule(m_process))
 m_kernel.LoadImageAtFileAddress(m_process);
-  }
-}
 
 // The operating system plugin gets loaded and initialized in
 // LoadImageUsingMemoryModule when we discover the 

[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-16 Thread Jason Molenda via lldb-commits


@@ -2545,6 +2546,11 @@ ModuleSP Process::ReadModuleFromMemory(const FileSpec 
_spec,
   ModuleSP module_sp(new Module(file_spec, ArchSpec()));
   if (module_sp) {
 Status error;
+std::unique_ptr progress_up;
+if (!GetCoreFile())

jasonmolenda wrote:

The name is a little misleading, `IsLiveDebugSession` is only false for 
`PostMortemProcess`.  Maybe we should have a `Process::IsCorefileProcess` or 
something, or I could put a comment there about what I'm doing.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] IRMemoryMap zero address mapping fix (PR #99045)

2024-07-16 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I don't think this change is correct, or I don't understand what it is trying 
to do.

When we're connected to a stub that can allocate memory in the target, none of 
this code is executed.  So lldb-server/debugserver will not hit this.

We send `qMemoryRegionInfo` packets to look for a block of memory that is 
unallocated, or has permissions no-read+no-write+no-execute.  The memory region 
scan starts at address 0 and moves up by the size of each memory region, 
looking for `size` bytes between allocated memory regions, and returns that 
address if it is found.

So I'm guessing we have (1) a target that cannot allocate memory, (2) a target 
that supported `qMemoryRegionInfo`, a non-accessible block of memory at address 
0? (did I read this right?) and in that case, we end up picking address 0 as 
our host-side virtual address+memory buffer for expression data storage.

Can you show what your `qMemoryRegionInfo` results are for address 0 on this 
target, so I can confirm I didn't misread/misunderstand the situation here?

https://github.com/llvm/llvm-project/pull/99045
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][RISCV] function prologue backtrace fix (PR #99043)

2024-07-16 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

Agreed, this fix is correct, thanks for the PR.  The register numbering in the 
UnwindPlan can be any eRegisterKind, but it does need to be self consistent, 
and this was not.  Do you have permissions to merge this PR?  I can do that for 
you if not.

https://github.com/llvm/llvm-project/pull/99043
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-16 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/98845

>From cead9ae6de627ee64fb58a829fa3485f526a0afc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Sun, 14 Jul 2024 16:59:51 -0700
Subject: [PATCH 1/4] [lldb] progressive progress reporting for darwin
 kernel/firmware

When doing firmware/kernel debugging, it is frequent that
binaries and debug info need to be retrieved / downloaded,
and the lack of progress reports made for a poor experience,
with lldb seemingly hung while downloading things over the
network. This PR adds progress reports to the critical sites
for these use cases.
---
 lldb/source/Core/DynamicLoader.cpp| 27 +++--
 .../DynamicLoaderDarwinKernel.cpp | 39 ---
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/lldb/source/Core/DynamicLoader.cpp 
b/lldb/source/Core/DynamicLoader.cpp
index 7871be6fc451d..a59136381c23b 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",
+  prog_str.GetString().str());
 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
 
-if (memory_module_sp)
+if (memory_module_sp) {
   uuid = memory_module_sp->GetUUID();
+  if (uuid.IsValid()) {
+prog_str << " ";
+prog_str << uuid.GetAsString();
+  }
+}
   }
   ModuleSpec module_spec;
   module_spec.GetUUID() = uuid;
   FileSpec name_filespec(name);
-  if (FileSystem::Instance().Exists(name_filespec))
-module_spec.GetFileSpec() = name_filespec;
 
   if (uuid.IsValid()) {
+Progress progress("Locating external symbol file",
+  prog_str.GetString().str());
+
 // Has lldb already seen a module with this UUID?
+// Or have external lookup enabled in DebugSymbols on macOS.
 if (!module_sp)
   error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
   nullptr, nullptr);
diff --git 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 8d83937aab668..93eb1e7b9dea9 100644
--- 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -757,6 +758,23 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+std::unique_ptr progress_up;
+if (IsKernel()) {
+  StreamString prog_str;
+  // 'mach_kernel' is a fake name we make up to find kernels
+  // that were located by the local filesystem scan.
+  if (GetName() != "mach_kernel")
+prog_str << GetName() << " ";
+  if (GetUUID().IsValid())
+prog_str << GetUUID().GetAsString() << " ";
+  if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(GetLoadAddress());
+  }
+  progress_up = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+}
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
@@ -1058,12 +1076,9 @@ void 
DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
 }
   }
 }
-
-if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
-  if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
+if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
+  if (!m_kernel.LoadImageUsingMemoryModule(m_process))
 m_kernel.LoadImageAtFileAddress(m_process);
-  }
-}
 
 // The operating system plugin gets loaded and initialized in
 // LoadImageUsingMemoryModule when we discover the 

[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-15 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Thanks for the helpful feedback @clayborg pushed an update.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-15 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/98845

>From cead9ae6de627ee64fb58a829fa3485f526a0afc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Sun, 14 Jul 2024 16:59:51 -0700
Subject: [PATCH 1/3] [lldb] progressive progress reporting for darwin
 kernel/firmware

When doing firmware/kernel debugging, it is frequent that
binaries and debug info need to be retrieved / downloaded,
and the lack of progress reports made for a poor experience,
with lldb seemingly hung while downloading things over the
network. This PR adds progress reports to the critical sites
for these use cases.
---
 lldb/source/Core/DynamicLoader.cpp| 27 +++--
 .../DynamicLoaderDarwinKernel.cpp | 39 ---
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/lldb/source/Core/DynamicLoader.cpp 
b/lldb/source/Core/DynamicLoader.cpp
index 7871be6fc451d..a59136381c23b 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",
+  prog_str.GetString().str());
 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
 
-if (memory_module_sp)
+if (memory_module_sp) {
   uuid = memory_module_sp->GetUUID();
+  if (uuid.IsValid()) {
+prog_str << " ";
+prog_str << uuid.GetAsString();
+  }
+}
   }
   ModuleSpec module_spec;
   module_spec.GetUUID() = uuid;
   FileSpec name_filespec(name);
-  if (FileSystem::Instance().Exists(name_filespec))
-module_spec.GetFileSpec() = name_filespec;
 
   if (uuid.IsValid()) {
+Progress progress("Locating external symbol file",
+  prog_str.GetString().str());
+
 // Has lldb already seen a module with this UUID?
+// Or have external lookup enabled in DebugSymbols on macOS.
 if (!module_sp)
   error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
   nullptr, nullptr);
diff --git 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 8d83937aab668..93eb1e7b9dea9 100644
--- 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -757,6 +758,23 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+std::unique_ptr progress_up;
+if (IsKernel()) {
+  StreamString prog_str;
+  // 'mach_kernel' is a fake name we make up to find kernels
+  // that were located by the local filesystem scan.
+  if (GetName() != "mach_kernel")
+prog_str << GetName() << " ";
+  if (GetUUID().IsValid())
+prog_str << GetUUID().GetAsString() << " ";
+  if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(GetLoadAddress());
+  }
+  progress_up = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+}
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
@@ -1058,12 +1076,9 @@ void 
DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
 }
   }
 }
-
-if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
-  if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
+if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
+  if (!m_kernel.LoadImageUsingMemoryModule(m_process))
 m_kernel.LoadImageAtFileAddress(m_process);
-  }
-}
 
 // The operating system plugin gets loaded and initialized in
 // LoadImageUsingMemoryModule when we discover the 

[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-15 Thread Jason Molenda via lldb-commits


@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at 0x";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",
+  prog_str.GetString().str());
 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
 
-if (memory_module_sp)
+if (memory_module_sp) {
   uuid = memory_module_sp->GetUUID();
+  if (uuid.IsValid()) {
+prog_str << " ";
+prog_str << uuid.GetAsString();
+  }
+}
   }
   ModuleSpec module_spec;
   module_spec.GetUUID() = uuid;
   FileSpec name_filespec(name);
-  if (FileSystem::Instance().Exists(name_filespec))
-module_spec.GetFileSpec() = name_filespec;
 
   if (uuid.IsValid()) {
+Progress progress("Locating external symbol file",
+  prog_str.GetString().str());
+
 // Has lldb already seen a module with this UUID?
+// Or have external lookup enabled in DebugSymbols on macOS.

jasonmolenda wrote:

It's a little tricky because we do call ModuleList::GetSharedModule which will 
return a module if it's already in the global module cache, and it will call 
into the DebugSymbols framework on macOS, where it might call an external 
program to do a slow copy of a binary to the local computer.   But after that, 
it then goes on to call `LocateExecutableSymbolFile` 
`LocateExecutableObjectFile` looking in known local filesystem locations.  If 
that fails, then it calls `DownloadObjectAndSymbolFile 
(force_symbol_search=true)` which can call out to an external program to do a 
slow copy of a binary to the local computer.

I wanted to log one message to cover possibly all of these being run.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-15 Thread Jason Molenda via lldb-commits


@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at 0x";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",

jasonmolenda wrote:

Good suggestion.  I think I'll conditionalize this progress with a `if 
(!process->GetCoreFile())` -- reading a binary out of a local corefile will be 
very fast.  Over a live gdb-remote connection, not so much.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-15 Thread Jason Molenda via lldb-commits


@@ -757,11 +758,32 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+StreamString prog_str;
+// 'mach_kernel' is a fake name we make up to find kernels
+// that were located by the local filesystem scan.
+if (GetName() != "mach_kernel")
+  prog_str << GetName() << " ";
+if (GetUUID().IsValid())
+  prog_str << GetUUID().GetAsString() << " ";
+if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+  prog_str << "at 0x";
+  prog_str.PutHex64(GetLoadAddress());
+}
+std::unique_ptr progress_wp;
+if (IsKernel())
+  progress_wp = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+else
+  progress_wp = std::make_unique("Loading kext",
+   prog_str.GetString().str());
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
   module_spec.GetUUID() = m_uuid;
-  module_spec.GetArchitecture() = target.GetArchitecture();
+  if (!m_uuid.IsValid())
+module_spec.GetArchitecture() = target.GetArchitecture();

jasonmolenda wrote:

just to be clear, it's almost always the "environment" or "os" part of the 
triple, which is nearly an entire fiction with firmware style debugging, that 
is the problem.  One binary will say "hey I'm iOS" and another binary that 
needs to be loaded also is like "I'm something else" and lldb will reject the 
module load even though the UUIDs match.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-15 Thread Jason Molenda via lldb-commits


@@ -757,11 +758,32 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+StreamString prog_str;
+// 'mach_kernel' is a fake name we make up to find kernels
+// that were located by the local filesystem scan.
+if (GetName() != "mach_kernel")
+  prog_str << GetName() << " ";
+if (GetUUID().IsValid())
+  prog_str << GetUUID().GetAsString() << " ";
+if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+  prog_str << "at 0x";
+  prog_str.PutHex64(GetLoadAddress());
+}
+std::unique_ptr progress_wp;
+if (IsKernel())
+  progress_wp = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+else
+  progress_wp = std::make_unique("Loading kext",
+   prog_str.GetString().str());
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
   module_spec.GetUUID() = m_uuid;
-  module_spec.GetArchitecture() = target.GetArchitecture();
+  if (!m_uuid.IsValid())
+module_spec.GetArchitecture() = target.GetArchitecture();

jasonmolenda wrote:

I know I shouldn't be making changes like this at the same time as adding 
progress status logging, but it irked me when I saw it.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-15 Thread Jason Molenda via lldb-commits


@@ -757,11 +758,32 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+StreamString prog_str;
+// 'mach_kernel' is a fake name we make up to find kernels
+// that were located by the local filesystem scan.
+if (GetName() != "mach_kernel")
+  prog_str << GetName() << " ";
+if (GetUUID().IsValid())
+  prog_str << GetUUID().GetAsString() << " ";
+if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+  prog_str << "at 0x";
+  prog_str.PutHex64(GetLoadAddress());
+}
+std::unique_ptr progress_wp;
+if (IsKernel())
+  progress_wp = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+else
+  progress_wp = std::make_unique("Loading kext",
+   prog_str.GetString().str());
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
   module_spec.GetUUID() = m_uuid;
-  module_spec.GetArchitecture() = target.GetArchitecture();
+  if (!m_uuid.IsValid())
+module_spec.GetArchitecture() = target.GetArchitecture();

jasonmolenda wrote:

If I have a UUID, it's authoritative, whereas the ArchSpec might be 
heuristically determined.  I don't like setting both in a ModuleSpec if the 
UUID is valid, it it noramlly fine but it's a little footgun waiting for some 
unusual combination where the heuristically determined ArchSpec is not quite 
the same ("compatible") with the arch of the UUID specified.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-15 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Ah no, I misunderstood.  The Increment method of Progress is intended for use 
where you have one progress status display that takes multiple steps to 
complete.  It's a separate mechanism from "finding dSYM for file x" etc.  I 
can't use an Increment style progress reporting in this PR.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-14 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/98845

>From cead9ae6de627ee64fb58a829fa3485f526a0afc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Sun, 14 Jul 2024 16:59:51 -0700
Subject: [PATCH 1/2] [lldb] progressive progress reporting for darwin
 kernel/firmware

When doing firmware/kernel debugging, it is frequent that
binaries and debug info need to be retrieved / downloaded,
and the lack of progress reports made for a poor experience,
with lldb seemingly hung while downloading things over the
network. This PR adds progress reports to the critical sites
for these use cases.
---
 lldb/source/Core/DynamicLoader.cpp| 27 +++--
 .../DynamicLoaderDarwinKernel.cpp | 39 ---
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/lldb/source/Core/DynamicLoader.cpp 
b/lldb/source/Core/DynamicLoader.cpp
index 7871be6fc451d..a59136381c23b 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",
+  prog_str.GetString().str());
 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
 
-if (memory_module_sp)
+if (memory_module_sp) {
   uuid = memory_module_sp->GetUUID();
+  if (uuid.IsValid()) {
+prog_str << " ";
+prog_str << uuid.GetAsString();
+  }
+}
   }
   ModuleSpec module_spec;
   module_spec.GetUUID() = uuid;
   FileSpec name_filespec(name);
-  if (FileSystem::Instance().Exists(name_filespec))
-module_spec.GetFileSpec() = name_filespec;
 
   if (uuid.IsValid()) {
+Progress progress("Locating external symbol file",
+  prog_str.GetString().str());
+
 // Has lldb already seen a module with this UUID?
+// Or have external lookup enabled in DebugSymbols on macOS.
 if (!module_sp)
   error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
   nullptr, nullptr);
diff --git 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 8d83937aab668..93eb1e7b9dea9 100644
--- 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -757,6 +758,23 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+std::unique_ptr progress_up;
+if (IsKernel()) {
+  StreamString prog_str;
+  // 'mach_kernel' is a fake name we make up to find kernels
+  // that were located by the local filesystem scan.
+  if (GetName() != "mach_kernel")
+prog_str << GetName() << " ";
+  if (GetUUID().IsValid())
+prog_str << GetUUID().GetAsString() << " ";
+  if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(GetLoadAddress());
+  }
+  progress_up = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+}
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
@@ -1058,12 +1076,9 @@ void 
DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
 }
   }
 }
-
-if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
-  if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
+if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
+  if (!m_kernel.LoadImageUsingMemoryModule(m_process))
 m_kernel.LoadImageAtFileAddress(m_process);
-  }
-}
 
 // The operating system plugin gets loaded and initialized in
 // LoadImageUsingMemoryModule when we discover the 

[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-14 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

The one thing I was uncertain of is when I load kexts -- I have a known number 
of kexts that I will be attempting to load -- and I wasn't sure if I should log 
them individually as they happen (what I did), or if I should initialize a 
progress category with the number of kexts that lldb will be attempting to 
load, so the progress of the job overall can be visualized.

https://github.com/llvm/llvm-project/pull/98845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] progressive progress reporting for darwin kernel/firmware (PR #98845)

2024-07-14 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/98845

When doing firmware/kernel debugging, it is frequent that binaries and debug 
info need to be retrieved / downloaded, and the lack of progress reports made 
for a poor experience, with lldb seemingly hung while downloading things over 
the network. This PR adds progress reports to the critical sites for these use 
cases.

>From cead9ae6de627ee64fb58a829fa3485f526a0afc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Sun, 14 Jul 2024 16:59:51 -0700
Subject: [PATCH] [lldb] progressive progress reporting for darwin
 kernel/firmware

When doing firmware/kernel debugging, it is frequent that
binaries and debug info need to be retrieved / downloaded,
and the lack of progress reports made for a poor experience,
with lldb seemingly hung while downloading things over the
network. This PR adds progress reports to the critical sites
for these use cases.
---
 lldb/source/Core/DynamicLoader.cpp| 27 +++--
 .../DynamicLoaderDarwinKernel.cpp | 39 ---
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/lldb/source/Core/DynamicLoader.cpp 
b/lldb/source/Core/DynamicLoader.cpp
index 7871be6fc451d..a59136381c23b 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -195,20 +196,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
   Target  = process->GetTarget();
   Status error;
 
+  StreamString prog_str;
+  if (!name.empty()) {
+prog_str << name.str() << " ";
+  }
+  if (uuid.IsValid())
+prog_str << uuid.GetAsString();
+  if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(value);
+  }
+
   if (!uuid.IsValid() && !value_is_offset) {
+Progress progress_memread("Reading load commands from memory",
+  prog_str.GetString().str());
 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
 
-if (memory_module_sp)
+if (memory_module_sp) {
   uuid = memory_module_sp->GetUUID();
+  if (uuid.IsValid()) {
+prog_str << " ";
+prog_str << uuid.GetAsString();
+  }
+}
   }
   ModuleSpec module_spec;
   module_spec.GetUUID() = uuid;
   FileSpec name_filespec(name);
-  if (FileSystem::Instance().Exists(name_filespec))
-module_spec.GetFileSpec() = name_filespec;
 
   if (uuid.IsValid()) {
+Progress progress("Locating external symbol file",
+  prog_str.GetString().str());
+
 // Has lldb already seen a module with this UUID?
+// Or have external lookup enabled in DebugSymbols on macOS.
 if (!module_sp)
   error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
   nullptr, nullptr);
diff --git 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 8d83937aab668..93eb1e7b9dea9 100644
--- 
a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ 
b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -757,6 +758,23 @@ bool 
DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
 const ModuleList _images = target.GetImages();
 m_module_sp = target_images.FindModule(m_uuid);
 
+std::unique_ptr progress_up;
+if (IsKernel()) {
+  StreamString prog_str;
+  // 'mach_kernel' is a fake name we make up to find kernels
+  // that were located by the local filesystem scan.
+  if (GetName() != "mach_kernel")
+prog_str << GetName() << " ";
+  if (GetUUID().IsValid())
+prog_str << GetUUID().GetAsString() << " ";
+  if (GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+prog_str << "at ";
+prog_str.PutHex64(GetLoadAddress());
+  }
+  progress_up = std::make_unique("Loading kernel",
+   prog_str.GetString().str());
+}
+
 // Search for the kext on the local filesystem via the UUID
 if (!m_module_sp && m_uuid.IsValid()) {
   ModuleSpec module_spec;
@@ -1058,12 +1076,9 @@ void 
DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
 }
   }
 }
-
-if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
-  if 

[Lldb-commits] [lldb] 3478573 - [lldb] [NFC] a couple comment typeo and markup fixes.

2024-07-14 Thread Jason Molenda via lldb-commits

Author: Jason Molenda
Date: 2024-07-14T10:59:46-07:00
New Revision: 3478573773d02e574524fd45c14631de5b7d10a9

URL: 
https://github.com/llvm/llvm-project/commit/3478573773d02e574524fd45c14631de5b7d10a9
DIFF: 
https://github.com/llvm/llvm-project/commit/3478573773d02e574524fd45c14631de5b7d10a9.diff

LOG: [lldb] [NFC] a couple comment typeo and markup fixes.

Added: 


Modified: 
lldb/include/lldb/Core/Progress.h

Removed: 




diff  --git a/lldb/include/lldb/Core/Progress.h 
b/lldb/include/lldb/Core/Progress.h
index cd87be79c4f0e..421e435a9e685 100644
--- a/lldb/include/lldb/Core/Progress.h
+++ b/lldb/include/lldb/Core/Progress.h
@@ -42,8 +42,8 @@ namespace lldb_private {
 ///uint64_t total,
 ///void *baton);
 ///
-/// This callback will always initially be called with "completed" set to zero
-/// and "total" set to the total amount specified in the contructor. This is
+/// This callback will always initially be called with \a completed set to zero
+/// and \a total set to the total amount specified in the constructor. This is
 /// considered the progress start event. As Progress::Increment() is called,
 /// the callback will be called as long as the Progress::m_completed has not
 /// yet exceeded the Progress::m_total. When the callback is called with
@@ -52,7 +52,7 @@ namespace lldb_private {
 /// Progress::m_total, then this is considered a progress update event.
 ///
 /// This callback will be called in the destructor if Progress::m_completed is
-/// not equal to Progress::m_total with the "completed" set to
+/// not equal to Progress::m_total with the \a completed set to
 /// Progress::m_total. This ensures we always send a progress completed update
 /// even if the user does not.
 
@@ -62,7 +62,7 @@ class Progress {
   ///
   /// The constructor will create a unique progress reporting object and
   /// immediately send out a progress update by calling the installed callback
-  /// with completed set to zero out of the specified total.
+  /// with \a completed set to zero out of the specified total.
   ///
   /// @param [in] title The title of this progress activity.
   ///
@@ -86,11 +86,11 @@ class Progress {
   /// Destroy the progress object.
   ///
   /// If the progress has not yet sent a completion update, the destructor
-  /// will send out a notification where the completed == m_total. This ensures
-  /// that we always send out a progress complete notification.
+  /// will send out a notification where the \a completed == m_total. This
+  /// ensures that we always send out a progress complete notification.
   ~Progress();
 
-  /// Increment the progress and send a notification to the intalled callback.
+  /// Increment the progress and send a notification to the installed callback.
   ///
   /// If incrementing ends up exceeding m_total, m_completed will be updated
   /// to match m_total and no subsequent progress notifications will be sent.



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


[Lldb-commits] [lldb] [lldb] Allow fetching of RA register when above fault handler (PR #98566)

2024-07-12 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda closed 
https://github.com/llvm/llvm-project/pull/98566
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Allow fetching of RA register when above fault handler (PR #98566)

2024-07-12 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:


> Testing this is in theory possible, tricky bit is guaranteeing a frameless 
> function. There is the naked attribute but it's not portable 
> https://godbolt.org/z/s9117Gr7a. Or you could write the function in an 
> assembly file, or define and call it inside an inline assembly block, inside 
> a normal C function. That function would branch to self waiting for SIGALRM 
> for example.
> 
> Maybe that has its own problems, I haven't tried it. Maybe it wouldn't 
> generate enough debug info for us to know that the assembly function was 
> there?

There's (I'd argue) three parts to the unwind system.  First is converting the 
different unwind info formats (eh_frame, debug_frame, compact unwind, arm idx, 
assembly instruciton scanning) into the intermediate representation of 
UnwindPlans.  Second is the unwind engine itself, which encodes rules about 
which type of unwind plan to use for a given stack frame, which registers can 
be passed up the stack, and rules about behavior on the 0th frame or above a 
fault handler/sigtramp.  And third are correctly fetching the register value 
for a row in an UnwindPlan (often, dereferencing memory offset from the 
Canonical Frame Address which is set in terms of another register most often) 
-- these often end up being dwarf expressions.

That middle bit, the unwind engine logic, is hard to test today without making 
hand-written assembly programs that set up specific unwind scenarios with 
metadata (.cfi directives) about what they've done.  Source level tests are at 
the mercy of compiler codegen and not stable, or requires capturing a corefile 
and object binary when the necessary conditions are achieved.

But here's the idea I had the other day.  With a scripted process, an 
ObjectFileJSON to create a fake binary with function start addresses, and a way 
to specify UnwindPlans for those functions, where all of the register rules 
would be "and the value of fp is " instead of "read stack memory to get the 
value of fp", I bet there's a way we could write unwind engine tests entirely 
in these terms.   And honest, the unwind engine method has a lot of very tricky 
corner cases and because it's not directly tested, it's easy to make mistakes - 
I am genuinely not thrilled about the state of it.  And without strong test 
infrastructure, it's going to be very intimidating to try to rewrite if anyone 
wanted to do that some day.

This is only "shower thoughts" level detail, but it's the first time I can see 
a testing strategy that I actually think could work well.

https://github.com/llvm/llvm-project/pull/98566
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add support for displaying `__float128` variables (PR #98369)

2024-07-11 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda edited 
https://github.com/llvm/llvm-project/pull/98369
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add support for displaying `__float128` variables (PR #98369)

2024-07-11 Thread Jason Molenda via lldb-commits


@@ -46,6 +46,7 @@ static constexpr FormatInfo g_format_infos[] = {
 {eFormatHex, 'x', "hex"},
 {eFormatHexUppercase, 'X', "uppercase hex"},
 {eFormatFloat, 'f', "float"},
+{eFormatFloat128, '\0', "float128"},

jasonmolenda wrote:

I'm not familiar with this part of lldb, but do we need an entry with a 
character code that can't be entered?  I don't think there are commands which 
take the "long name" of these entries, do they?  Vaguely relatedly, I wondered 
about `OptionGroupFormat::ParserGDBFormatLetter` which recognizes the gdb 
formatters (v. 
https://sourceware.org/gdb/current/onlinedocs/gdb.html/Output-Formats.html ) 
but I think just "f" for "float of undetermined size" is correct as-is?  This 
is seen in commands like `x/2gx $fp` etc, which command aliases rewrite to a 
longer `memory read`.

https://github.com/llvm/llvm-project/pull/98369
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Allow fetching of RA register when above fault handler (PR #98566)

2024-07-11 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/98566

In RegisterContextUnwind::SavedLocationForRegister we have special logic for 
retrieving the Return Address register when it has the caller's return address 
in it. An example would be the lr register on AArch64.

This register is never retrieved from a newer stack frame because it is 
necessarly overwritten by a normal ABI function call.  We allow frame 0 to 
provide its lr value to get the caller's return address, if it has not been 
overwritten/saved to stack yet.

When a function is interrupted asynchronously by a POSIX signal (sigtramp), or 
a fault handler more generally, the sigtramp/fault handler has the entire 
register context available. In this situation, if the fault handler is frame 0, 
the function that was async interrupted is frame 1 and frame 2's return address 
may still be stored in lr.  We need to get the lr value for frame 1 from the 
fault handler in frame 0, to get the return address for frame 2.

Without this fix, a frameless function that faults in a firmware environment 
(that's where we've seen this issue most commonly) hasn't spilled lr to stack, 
so we need to retrieve it from the fault handler's full-register-context to 
find the caller of the frameless function that faulted.

It's an unsurprising fix, all of the work was finding exactly where in 
RegisterContextUnwind we were only allowing RA register use for frame 0, when 
it should have been frame 0 or above a fault handler function.

rdar://127518945

>From 48a06a9d85d2ca07e50bfda9002350d3ab157ed9 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 11 Jul 2024 17:03:13 -0700
Subject: [PATCH] [lldb] Allow fetching of RA register when above fault handler

In RegisterContextUnwind::SavedLocationForRegister we have special
logic for retrieving the Return Address register when it has
the caller's return address in it. An example would be the lr
register on AArch64.

This register is never retrieved from a newer stack frame because
it is necessarly overwritten by a normal ABI function call.  We
allow frame 0 to provide its lr value to get the caller's return
address, if it has not been overwritten/saved to stack yet.

When a function is interrupted asynchronously by a POSIX signal
(sigtramp), or a fault handler more generally, the sigtramp/fault
handler has the entire register context available. In this situation,
if the fault handler is frame 0, the function that was async
interrupted is frame 1 and frame 2's return address may still be
stored in lr.  We need to get the lr value for frame 1 from the
fault handler in frame 0, to get the return address for frame 2.

Without this fix, a frameless function that faults in a firmware
environment (that's where we've seen this issue most commonly)
hasn't spilled lr to stack, so we need to retrieve it from the
fault handler's full-register-context to find the caller of the
frameless function that faulted.

It's an unsurprising fix, all of the work was finding exactly where
in RegisterContextUnwind we were only allowing RA register use for
frame 0, when it should have been frame 0 or above a fault handler
function.

rdar://127518945
---
 lldb/source/Target/RegisterContextUnwind.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Target/RegisterContextUnwind.cpp 
b/lldb/source/Target/RegisterContextUnwind.cpp
index 95e8abd763d53..bc8081f4e3b31 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -1401,7 +1401,7 @@ RegisterContextUnwind::SavedLocationForRegister(
   // it's still live in the actual register. Handle this specially.
 
   if (!have_unwindplan_regloc && return_address_reg.IsValid() &&
-  IsFrameZero()) {
+  BehavesLikeZerothFrame()) {
 if (return_address_reg.GetAsKind(eRegisterKindLLDB) !=
 LLDB_INVALID_REGNUM) {
   lldb_private::UnwindLLDB::RegisterLocation new_regloc;

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


[Lldb-commits] [lldb] 1988c27 - [lldb] [NFC] Update TestEarlyProcessLaunch to work on macOS 15

2024-07-11 Thread Jason Molenda via lldb-commits

Author: Jason Molenda
Date: 2024-07-11T16:51:28-07:00
New Revision: 1988c27e5f4dbcf42c9a80f44bdee7ccd208a0ac

URL: 
https://github.com/llvm/llvm-project/commit/1988c27e5f4dbcf42c9a80f44bdee7ccd208a0ac
DIFF: 
https://github.com/llvm/llvm-project/commit/1988c27e5f4dbcf42c9a80f44bdee7ccd208a0ac.diff

LOG: [lldb] [NFC] Update TestEarlyProcessLaunch to work on macOS 15

This test sets a breakpoint on malloc, as a way to stop early in
dyld's setting up code, before the system libraries are initialized
so we can confirm that we don't fetch the Objective-C class table
before it's initialized.

In macOS 15 (macOS Sonoma), dyld doesn't call malloc any longer,
so this heuristic/trick isn't working.  It does call other things
called *alloc though, so I'm changing this to use a regex breakpoint
on that, to keep the test working.

Added: 


Modified: 
lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py

Removed: 




diff  --git 
a/lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py 
b/lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py
index c15abbabc2374..ff704104f7892 100644
--- a/lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py
+++ b/lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py
@@ -1,6 +1,5 @@
 """Test that we don't read objc class tables early in process startup."""
 
-
 import time
 import lldb
 from lldbsuite.test.decorators import *
@@ -30,7 +29,14 @@ def test_early_process_launch(self):
 ###
 ### Use the types logging to detect the 
diff erence.
 
-target, process, _, bkpt = lldbutil.run_to_name_breakpoint(self, 
"malloc")
+exe = self.getBuildArtifact("a.out")
+target = self.dbg.CreateTarget(exe)
+self.assertTrue(target.IsValid())
+bkpt = target.BreakpointCreateByRegex("alloc", None)
+self.assertTrue(bkpt.IsValid())
+(target, process, thread, bkpt) = lldbutil.run_to_breakpoint_do_run(
+self, target, bkpt
+)
 
 target.DisableAllBreakpoints()
 target.BreakpointCreateByName("main")



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


[Lldb-commits] [lldb] [lldb] Don't crash on malformed filesets (PR #98388)

2024-07-10 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

LGTM.  We'll skip any fileset entries that we can't read the filename of.

https://github.com/llvm/llvm-project/pull/98388
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-08 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Thanks again for all the help @AlexK0 I pushed an update that should compile 
correctly with my update.  It's great to hear that the testsuite looks clean -- 
that's the part that worried me the most about these changes.

I finished an aarch64 Ubuntu testsuite run and it is clean.  I think this patch 
is about ready for review by @jimingham when he has time.

https://github.com/llvm/llvm-project/pull/96260
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-08 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/96260

>From 9b541e6a035635e26c6a24eca022de8552fa4c17 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 20 Jun 2024 17:53:17 -0700
Subject: [PATCH 1/6] [lldb] Change lldb's breakpoint handling behavior

lldb today has two rules:  When a thread stops at a BreakpointSite,
we set the thread's StopReason to be "breakpoint hit" (regardless
if we've actually hit the breakpoint, or if we've merely stopped
*at* the breakpoint instruction/point and haven't tripped it yet).
And second, when resuming a process, any thread sitting at a
BreakpointSite is silently stepped over the BreakpointSite -- because
we've already flagged the breakpoint hit when we stopped there
originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint.  When we resume, we only silently step past a
BreakpointSite that we've registered as hit.  We preserve this state
across inferior function calls that the user may do while stopped,
etc.

Also, when a user adds a new breakpoint at $pc while stopped, or
changes $pc to be the address of a BreakpointSite, we will silently
step past that breakpoint when the process resumes.  This is purely
a UX call, I don't think there's any person who wants to set a
breakpoint at $pc and then hit it immediately on resuming.

One non-intuitive UX from this change, but I'm convinced it is
necessary:  If you're stopped at a BreakpointSite that has not yet
executed, you `stepi`, you will hit the breakpoint and the pc will
not yet advance.  This thread has not completed its stepi, and the
thread plan is still on the stack.  If you then `continue` the
thread, lldb will now stop and say, "instruction step completed",
one instruction past the BreakpointSite.  You can continue a second
time to resume execution.  I discussed this with Jim, and trying
to paper over this behavior will lead to more complicated scenarios
behaving non-intuitively.  And mostly it's the testsuite that was
trying to instruction step past a breakpoint and getting thrown off
-- and I changed those tests to expect the new behavior.

The bugs driving this change are all from lldb dropping the real
stop reason for a thread and setting it to breakpoint-hit when that
was not the case.  Jim hit one where we have an aarch64 watchpoint
that triggers one instruction before a BreakpointSite.  On this
arch we are notified of the watchpoint hit after the instruction
has been unrolled -- we disable the watchpoint, instruction step,
re-enable the watchpoint and collect the new value.  But now we're
on a BreakpointSite so the watchpoint-hit stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282
we attach to/launch a process with the pc at a BreakpointSite and
misbehave.  Caroline Tice mentioned it is also a problem they've
had with putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control
is that

1. If we've stopped at a BreakpointSite (whether we hit it or not),
we call Thread::SetThreadStoppedAtBreakpointSite(pc) to record the
state at the point when the thread stopped.  (so we can detect
newly-added breakpoints, or when the pc is changed to an instruction
that is a BreakpointSite)

2. When we have actually hit a breakpoint, and it is enabled for
this thread, we call Thread::SetThreadHitBreakpointAtAddr(pc) so
we know that it should be silently stepped past when we resume
execution.

When resuming, we silently step over a breakpoint if we've hit it,
or if it is newly added (or the pc was changed to an existing
BreakpointSite).

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason.  The Mach exception
codes differ in a few places depending on the target (unambiguously),
and I didn't want to duplicate the new code for each target so I've
tested what mach exceptions we get for each action on each target,
and reorganized StopInfoMachException::CreateStopReasonWithMachException
to document these possible values, and handle them without specializing
based on the target arch.

rdar://123942164
---
 lldb/include/lldb/Target/Thread.h |  29 ++
 .../Process/Utility/StopInfoMachException.cpp | 296 +++---
 .../Process/Windows/Common/ProcessWindows.cpp |  16 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   | 118 +++
 .../Process/scripted/ScriptedThread.cpp   |   9 +
 lldb/source/Target/Thread.cpp |  17 +-
 .../TestConsecutiveBreakpoints.py |  26 +-
 .../TestStepOverBreakpoint.py |   6 +-
 8 files changed, 235 insertions(+), 282 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index c17bddf4d98b8..1e1aead896018 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ 

[Lldb-commits] [lldb] [lldb][NFC] Add maybe_unused to err used in asserts (PR #98055)

2024-07-08 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

LGTM.

https://github.com/llvm/llvm-project/pull/98055
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Move std::map iterator formatter into LibCxxMap.cpp (PR #97687)

2024-07-04 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

LGTM.

https://github.com/llvm/llvm-project/pull/97687
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Improve error message for unrecognized executables (PR #97490)

2024-07-02 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

This look good.  I like distinguishing between "is not a known binary type" and 
"does not contain an architecture supported on this platform (but is a binary 
file that we recognize)".

https://github.com/llvm/llvm-project/pull/97490
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][AArch64] Add register field enum information (PR #96887)

2024-07-02 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda approved this pull request.

LGTM.

https://github.com/llvm/llvm-project/pull/96887
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [ObjectFileMachO] BSS segments are loadable segments (PR #96983)

2024-07-01 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda closed 
https://github.com/llvm/llvm-project/pull/96983
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-01 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/96260

>From 9b541e6a035635e26c6a24eca022de8552fa4c17 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 20 Jun 2024 17:53:17 -0700
Subject: [PATCH 1/5] [lldb] Change lldb's breakpoint handling behavior

lldb today has two rules:  When a thread stops at a BreakpointSite,
we set the thread's StopReason to be "breakpoint hit" (regardless
if we've actually hit the breakpoint, or if we've merely stopped
*at* the breakpoint instruction/point and haven't tripped it yet).
And second, when resuming a process, any thread sitting at a
BreakpointSite is silently stepped over the BreakpointSite -- because
we've already flagged the breakpoint hit when we stopped there
originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint.  When we resume, we only silently step past a
BreakpointSite that we've registered as hit.  We preserve this state
across inferior function calls that the user may do while stopped,
etc.

Also, when a user adds a new breakpoint at $pc while stopped, or
changes $pc to be the address of a BreakpointSite, we will silently
step past that breakpoint when the process resumes.  This is purely
a UX call, I don't think there's any person who wants to set a
breakpoint at $pc and then hit it immediately on resuming.

One non-intuitive UX from this change, but I'm convinced it is
necessary:  If you're stopped at a BreakpointSite that has not yet
executed, you `stepi`, you will hit the breakpoint and the pc will
not yet advance.  This thread has not completed its stepi, and the
thread plan is still on the stack.  If you then `continue` the
thread, lldb will now stop and say, "instruction step completed",
one instruction past the BreakpointSite.  You can continue a second
time to resume execution.  I discussed this with Jim, and trying
to paper over this behavior will lead to more complicated scenarios
behaving non-intuitively.  And mostly it's the testsuite that was
trying to instruction step past a breakpoint and getting thrown off
-- and I changed those tests to expect the new behavior.

The bugs driving this change are all from lldb dropping the real
stop reason for a thread and setting it to breakpoint-hit when that
was not the case.  Jim hit one where we have an aarch64 watchpoint
that triggers one instruction before a BreakpointSite.  On this
arch we are notified of the watchpoint hit after the instruction
has been unrolled -- we disable the watchpoint, instruction step,
re-enable the watchpoint and collect the new value.  But now we're
on a BreakpointSite so the watchpoint-hit stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282
we attach to/launch a process with the pc at a BreakpointSite and
misbehave.  Caroline Tice mentioned it is also a problem they've
had with putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control
is that

1. If we've stopped at a BreakpointSite (whether we hit it or not),
we call Thread::SetThreadStoppedAtBreakpointSite(pc) to record the
state at the point when the thread stopped.  (so we can detect
newly-added breakpoints, or when the pc is changed to an instruction
that is a BreakpointSite)

2. When we have actually hit a breakpoint, and it is enabled for
this thread, we call Thread::SetThreadHitBreakpointAtAddr(pc) so
we know that it should be silently stepped past when we resume
execution.

When resuming, we silently step over a breakpoint if we've hit it,
or if it is newly added (or the pc was changed to an existing
BreakpointSite).

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason.  The Mach exception
codes differ in a few places depending on the target (unambiguously),
and I didn't want to duplicate the new code for each target so I've
tested what mach exceptions we get for each action on each target,
and reorganized StopInfoMachException::CreateStopReasonWithMachException
to document these possible values, and handle them without specializing
based on the target arch.

rdar://123942164
---
 lldb/include/lldb/Target/Thread.h |  29 ++
 .../Process/Utility/StopInfoMachException.cpp | 296 +++---
 .../Process/Windows/Common/ProcessWindows.cpp |  16 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   | 118 +++
 .../Process/scripted/ScriptedThread.cpp   |   9 +
 lldb/source/Target/Thread.cpp |  17 +-
 .../TestConsecutiveBreakpoints.py |  26 +-
 .../TestStepOverBreakpoint.py |   6 +-
 8 files changed, 235 insertions(+), 282 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index c17bddf4d98b8..1e1aead896018 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ 

[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-01 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Hi @AlexK0 I restructured this PR to track everything with a single piece of 
state in the Thread object, and redid all three Process plugins.  I'm feeling a 
lot better about my changes to ProcessWindows now.  I haven't tested the 
aarch64 ubuntu yet, I will do that tomorrow and if that looks good, I'm going 
to ask for more careful reviews of the PR.  No rush at all, but if you have a 
chance to try this version on Windows I would really appreciate it.  Thanks!

https://github.com/llvm/llvm-project/pull/96260
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-07-01 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/96260

>From 9b541e6a035635e26c6a24eca022de8552fa4c17 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 20 Jun 2024 17:53:17 -0700
Subject: [PATCH 1/4] [lldb] Change lldb's breakpoint handling behavior

lldb today has two rules:  When a thread stops at a BreakpointSite,
we set the thread's StopReason to be "breakpoint hit" (regardless
if we've actually hit the breakpoint, or if we've merely stopped
*at* the breakpoint instruction/point and haven't tripped it yet).
And second, when resuming a process, any thread sitting at a
BreakpointSite is silently stepped over the BreakpointSite -- because
we've already flagged the breakpoint hit when we stopped there
originally.

In this patch, I change lldb to only set a thread's stop reason to
breakpoint-hit when we've actually executed the instruction/triggered
the breakpoint.  When we resume, we only silently step past a
BreakpointSite that we've registered as hit.  We preserve this state
across inferior function calls that the user may do while stopped,
etc.

Also, when a user adds a new breakpoint at $pc while stopped, or
changes $pc to be the address of a BreakpointSite, we will silently
step past that breakpoint when the process resumes.  This is purely
a UX call, I don't think there's any person who wants to set a
breakpoint at $pc and then hit it immediately on resuming.

One non-intuitive UX from this change, but I'm convinced it is
necessary:  If you're stopped at a BreakpointSite that has not yet
executed, you `stepi`, you will hit the breakpoint and the pc will
not yet advance.  This thread has not completed its stepi, and the
thread plan is still on the stack.  If you then `continue` the
thread, lldb will now stop and say, "instruction step completed",
one instruction past the BreakpointSite.  You can continue a second
time to resume execution.  I discussed this with Jim, and trying
to paper over this behavior will lead to more complicated scenarios
behaving non-intuitively.  And mostly it's the testsuite that was
trying to instruction step past a breakpoint and getting thrown off
-- and I changed those tests to expect the new behavior.

The bugs driving this change are all from lldb dropping the real
stop reason for a thread and setting it to breakpoint-hit when that
was not the case.  Jim hit one where we have an aarch64 watchpoint
that triggers one instruction before a BreakpointSite.  On this
arch we are notified of the watchpoint hit after the instruction
has been unrolled -- we disable the watchpoint, instruction step,
re-enable the watchpoint and collect the new value.  But now we're
on a BreakpointSite so the watchpoint-hit stop reason is lost.

Another was reported by ZequanWu in
https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282
we attach to/launch a process with the pc at a BreakpointSite and
misbehave.  Caroline Tice mentioned it is also a problem they've
had with putting a breakpoint on _dl_debug_state.

The change to each Process plugin that does execution control
is that

1. If we've stopped at a BreakpointSite (whether we hit it or not),
we call Thread::SetThreadStoppedAtBreakpointSite(pc) to record the
state at the point when the thread stopped.  (so we can detect
newly-added breakpoints, or when the pc is changed to an instruction
that is a BreakpointSite)

2. When we have actually hit a breakpoint, and it is enabled for
this thread, we call Thread::SetThreadHitBreakpointAtAddr(pc) so
we know that it should be silently stepped past when we resume
execution.

When resuming, we silently step over a breakpoint if we've hit it,
or if it is newly added (or the pc was changed to an existing
BreakpointSite).

The biggest set of changes is to StopInfoMachException where we
translate a Mach Exception into a stop reason.  The Mach exception
codes differ in a few places depending on the target (unambiguously),
and I didn't want to duplicate the new code for each target so I've
tested what mach exceptions we get for each action on each target,
and reorganized StopInfoMachException::CreateStopReasonWithMachException
to document these possible values, and handle them without specializing
based on the target arch.

rdar://123942164
---
 lldb/include/lldb/Target/Thread.h |  29 ++
 .../Process/Utility/StopInfoMachException.cpp | 296 +++---
 .../Process/Windows/Common/ProcessWindows.cpp |  16 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   | 118 +++
 .../Process/scripted/ScriptedThread.cpp   |   9 +
 lldb/source/Target/Thread.cpp |  17 +-
 .../TestConsecutiveBreakpoints.py |  26 +-
 .../TestStepOverBreakpoint.py |   6 +-
 8 files changed, 235 insertions(+), 282 deletions(-)

diff --git a/lldb/include/lldb/Target/Thread.h 
b/lldb/include/lldb/Target/Thread.h
index c17bddf4d98b8..1e1aead896018 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ 

[Lldb-commits] [lldb] [lldb] [ObjectFileMachO] BSS segments are loadable segments (PR #96983)

2024-07-01 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/96983

>From 6bd566504355e8d50b9c922df9ebce18e07a726f Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 27 Jun 2024 15:34:48 -0700
Subject: [PATCH 1/2] [lldb] [ObjectFileMachO] BSS segments are loadable
 segments

ObjectFileMachO::SetLoadAddress sets the address of each segment
in a binary in a Target, but it ignores segments that are not loaded
in the virtual address space.  It was marking segments that were
purely BSS -- having no content in the file, but in zero-initialized
memory when running in the virtual address space -- as not-loadable,
unless they were named "DATA".  This works pretty well for typical
userland binaries, but in less Darwin environments, there may be
BSS segments with other names, that ARE loadable.

I looked at the origin of SectionIsLoadable's check for this, and
it was a cleanup by Greg in 2018 where we had three different
implementations of the idea in ObjectFileMachO and one of them
skipped zero-file-size segments (BSS), which made it into the
centralized SectionIsLoadable method.

Also add some logging to the DynamicLoader log channel when loading
a binary - it's the first place I look when debugging segment address
setting bugs, and it wasn't emitting anything.

rdar://129870649
---
 .../ObjectFile/Mach-O/ObjectFileMachO.cpp | 31 ---
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 
b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 2979bf69bf762..164c4409747e0 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -6159,10 +6159,6 @@ Section *ObjectFileMachO::GetMachHeaderSection() {
 bool ObjectFileMachO::SectionIsLoadable(const Section *section) {
   if (!section)
 return false;
-  const bool is_dsym = (m_header.filetype == MH_DSYM);
-  if (section->GetFileSize() == 0 && !is_dsym &&
-  section->GetName() != GetSegmentNameDATA())
-return false;
   if (section->IsThreadSpecific())
 return false;
   if (GetModule().get() != section->GetModule().get())
@@ -6202,6 +6198,7 @@ lldb::addr_t 
ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
 
 bool ObjectFileMachO::SetLoadAddress(Target , lldb::addr_t value,
  bool value_is_offset) {
+  Log *log(GetLog(LLDBLog::DynamicLoader));
   ModuleSP module_sp = GetModule();
   if (!module_sp)
 return false;
@@ -6217,17 +6214,37 @@ bool ObjectFileMachO::SetLoadAddress(Target , 
lldb::addr_t value,
   // malformed.
   const bool warn_multiple = true;
 
+  if (log) {
+std::string binary_description;
+if (GetFileSpec()) {
+  binary_description += "path='";
+  binary_description += GetFileSpec().GetPath();
+  binary_description += "' ";
+}
+if (GetUUID()) {
+  binary_description += "uuid=";
+  binary_description += GetUUID().GetAsString();
+}
+LLDB_LOGF(log, "ObjectFileMachO::SetLoadAddress %s",
+  binary_description.c_str());
+  }
   if (value_is_offset) {
 // "value" is an offset to apply to each top level segment
 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
   // Iterate through the object file sections to find all of the
   // sections that size on disk (to avoid __PAGEZERO) and load them
   SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
-  if (SectionIsLoadable(section_sp.get()))
+  if (SectionIsLoadable(section_sp.get())) {
+LLDB_LOGF(log,
+  "ObjectFileMachO::SetLoadAddress segment '%s' load addr is "
+  "0x%" PRIx64,
+  section_sp->GetName().AsCString(),
+  section_sp->GetFileAddress() + value);
 if (target.GetSectionLoadList().SetSectionLoadAddress(
 section_sp, section_sp->GetFileAddress() + value,
 warn_multiple))
   ++num_loaded_sections;
+  }
 }
   } else {
 // "value" is the new base address of the mach_header, adjust each
@@ -6242,6 +6259,10 @@ bool ObjectFileMachO::SetLoadAddress(Target , 
lldb::addr_t value,
 CalculateSectionLoadAddressForMemoryImage(
 value, mach_header_section, section_sp.get());
 if (section_load_addr != LLDB_INVALID_ADDRESS) {
+  LLDB_LOGF(log,
+"ObjectFileMachO::SetLoadAddress segment '%s' load addr is 
"
+"0x%" PRIx64,
+section_sp->GetName().AsCString(), section_load_addr);
   if (target.GetSectionLoadList().SetSectionLoadAddress(
   section_sp, section_load_addr, warn_multiple))
 ++num_loaded_sections;

>From 2a7b154cbdffb75d763d3f8587266c9a7c0a0eb0 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Mon, 1 Jul 2024 17:29:41 -0700
Subject: [PATCH 2/2] Build up the log message 

[Lldb-commits] [lldb] [lldb] [ObjectFileMachO] BSS segments are loadable segments (PR #96983)

2024-06-28 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I was about to add a macosx/ API test to compile a program with only BSS data 
in the DATA segment, and I noticed I'd written 
`TestBSSOnlyDataSectionSliding.py` last year when I opted sections named "DATA" 
out of this "don't set a load address for BSS-only segments" behavior in 
ObjectFileMachO.  This existing test is already covering the change I'm making 
in this PR.

https://github.com/llvm/llvm-project/pull/96983
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [ObjectFileMachO] BSS segments are loadable segments (PR #96983)

2024-06-27 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/96983

ObjectFileMachO::SetLoadAddress sets the address of each segment in a binary in 
a Target, but it ignores segments that are not loaded in the virtual address 
space.  It was marking segments that were purely BSS -- having no content in 
the file, but in zero-initialized memory when running in the virtual address 
space -- as not-loadable, unless they were named "DATA".  This works pretty 
well for typical userland binaries, but in less Darwin environments, there may 
be BSS segments with other names, that ARE loadable.

I looked at the origin of SectionIsLoadable's check for this, and it was a 
cleanup by Greg in 2018 where we had three different implementations of the 
idea in ObjectFileMachO and one of them skipped zero-file-size segments (BSS), 
which made it into the centralized SectionIsLoadable method.

Also add some logging to the DynamicLoader log channel when loading a binary - 
it's the first place I look when debugging segment address setting bugs, and it 
wasn't emitting anything.

rdar://129870649

>From 6bd566504355e8d50b9c922df9ebce18e07a726f Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 27 Jun 2024 15:34:48 -0700
Subject: [PATCH] [lldb] [ObjectFileMachO] BSS segments are loadable segments

ObjectFileMachO::SetLoadAddress sets the address of each segment
in a binary in a Target, but it ignores segments that are not loaded
in the virtual address space.  It was marking segments that were
purely BSS -- having no content in the file, but in zero-initialized
memory when running in the virtual address space -- as not-loadable,
unless they were named "DATA".  This works pretty well for typical
userland binaries, but in less Darwin environments, there may be
BSS segments with other names, that ARE loadable.

I looked at the origin of SectionIsLoadable's check for this, and
it was a cleanup by Greg in 2018 where we had three different
implementations of the idea in ObjectFileMachO and one of them
skipped zero-file-size segments (BSS), which made it into the
centralized SectionIsLoadable method.

Also add some logging to the DynamicLoader log channel when loading
a binary - it's the first place I look when debugging segment address
setting bugs, and it wasn't emitting anything.

rdar://129870649
---
 .../ObjectFile/Mach-O/ObjectFileMachO.cpp | 31 ---
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 
b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 2979bf69bf762..164c4409747e0 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -6159,10 +6159,6 @@ Section *ObjectFileMachO::GetMachHeaderSection() {
 bool ObjectFileMachO::SectionIsLoadable(const Section *section) {
   if (!section)
 return false;
-  const bool is_dsym = (m_header.filetype == MH_DSYM);
-  if (section->GetFileSize() == 0 && !is_dsym &&
-  section->GetName() != GetSegmentNameDATA())
-return false;
   if (section->IsThreadSpecific())
 return false;
   if (GetModule().get() != section->GetModule().get())
@@ -6202,6 +6198,7 @@ lldb::addr_t 
ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
 
 bool ObjectFileMachO::SetLoadAddress(Target , lldb::addr_t value,
  bool value_is_offset) {
+  Log *log(GetLog(LLDBLog::DynamicLoader));
   ModuleSP module_sp = GetModule();
   if (!module_sp)
 return false;
@@ -6217,17 +6214,37 @@ bool ObjectFileMachO::SetLoadAddress(Target , 
lldb::addr_t value,
   // malformed.
   const bool warn_multiple = true;
 
+  if (log) {
+std::string binary_description;
+if (GetFileSpec()) {
+  binary_description += "path='";
+  binary_description += GetFileSpec().GetPath();
+  binary_description += "' ";
+}
+if (GetUUID()) {
+  binary_description += "uuid=";
+  binary_description += GetUUID().GetAsString();
+}
+LLDB_LOGF(log, "ObjectFileMachO::SetLoadAddress %s",
+  binary_description.c_str());
+  }
   if (value_is_offset) {
 // "value" is an offset to apply to each top level segment
 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
   // Iterate through the object file sections to find all of the
   // sections that size on disk (to avoid __PAGEZERO) and load them
   SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
-  if (SectionIsLoadable(section_sp.get()))
+  if (SectionIsLoadable(section_sp.get())) {
+LLDB_LOGF(log,
+  "ObjectFileMachO::SetLoadAddress segment '%s' load addr is "
+  "0x%" PRIx64,
+  section_sp->GetName().AsCString(),
+  section_sp->GetFileAddress() + value);
 if (target.GetSectionLoadList().SetSectionLoadAddress(
 section_sp, 

[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)

2024-06-24 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

Thanks @AlexK0 !  After Pavel's suggestion, I need to do a minor bit of changes 
to the patch soon I think, for all platforms, so I'll see if this is easier to 
express in ProcessWindows that way.

I've was thinking about @labath 's suggestion over the weekend and I agree that 
the way the patch is written today isn't ideal about tracking state at 
stop-time and resume-time, as I developed the change I had to change its 
behavior and I didn't rethink what I was doing.

The original goal was:  If we hit a breakpoint (whether it is enabled for this 
thread or not), when we Resume the thread, we silently instruction step past 
that breakpoint instruction before resuming.  Then I realized the problem of 
"user sets a breakpoint at $pc, or changes $pc to a BreakpointSite" and I want 
to also silently step past the breakpoint in that case, so I added a separate 
variable to track that.

Looking at the total requirements, the rule can be condensed to:  If this 
thread stopped at a BreakpointSite which it did not execute, we should execute 
the breakpoint on Resume.  In any other case, a thread sitting at a 
BreakpointSite should silently step past it and resume execution.

So when a thread stops at a BreakpointSite that has executed (whether it is 
valid for this thread or not), we record nothing.  When a thread stops at a 
BreakpointSite that has not executed, we need to record the address of that 
BreakpointSite.  And on Resume, if the thread is still at this same address, we 
want to hit the breakpoint.

I don't think we can store this information in the StopInfo easily, because a 
thread with no stop reason (e.g. a multi-threaded program that hits a 
breakpoint on one thread, but the others were executing normally) wouldn't have 
a way to record that they were sitting at a BreakpointSite that needed to be 
hit still.

I outlined the idea of storing this data in the StopInfo to @jimingham earlier 
today briefly, and he agreed that we should have StopInfos around until we 
Resume, but I hadn't thought this through enough to account for threads with no 
stop reason.  I'll check in with him about the details on this before I make 
the change, but I think I need to keep tracking this in the Thread object.

https://github.com/llvm/llvm-project/pull/96260
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


  1   2   3   4   5   6   7   8   9   10   >