[Lldb-commits] [lldb] [LLDB] Don't ignore artificial variables and members for coroutines (PR #70779)

2023-10-31 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/70779
___
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 ignore artificial variables and members for coroutines (PR #70779)

2023-10-31 Thread Adrian Vogelsgesang via lldb-commits


@@ -41,7 +41,10 @@ CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
 : LanguageRuntime(process) {}
 
 bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
-  return name == g_this;
+  // FIXME: use a list when the list grows more.
+  return name == g_this ||
+ name == ConstString("__promise") ||
+ name == ConstString("__coro_frame");

vogelsgesang wrote:

I am not sure if I would expose the `__coro_frame` variable. Maybe I would only 
expose the `__promise` variable by default. The `__coro_frame` is usually 
out-of-sync and does not hold the up-to-date coroutine state while the 
coroutine is in flight

https://github.com/llvm/llvm-project/pull/70779
___
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 ignore artificial variables and members for coroutines (PR #70779)

2023-10-31 Thread Adrian Vogelsgesang via lldb-commits

https://github.com/vogelsgesang commented:

I can't provide feedback on the lldb integration aspects, as I don't know the 
lldb code base well enough

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


[Lldb-commits] [lldb] 54d4a25 - [LLDB] Fix assertion failure by removing `CopyType` in `std::coroutine_handle` pretty printer

2023-02-08 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2023-02-08T10:22:50-08:00
New Revision: 54d4a2550d3167d51a9d386d9823a06aca459531

URL: 
https://github.com/llvm/llvm-project/commit/54d4a2550d3167d51a9d386d9823a06aca459531
DIFF: 
https://github.com/llvm/llvm-project/commit/54d4a2550d3167d51a9d386d9823a06aca459531.diff

LOG: [LLDB] Fix assertion failure by removing `CopyType` in 
`std::coroutine_handle` pretty printer

The pretty printer for `std::coroutine_handle` was running into
> Assertion failed: (target_ctx != source_ctx && "Can't import into itself")
from ClangASTImporter.h, line 270.

This commit fixes the issue by removing the `CopyType` call from the
pretty printer. While this call was necessary in the past, it seems to
be no longer required, at least all test cases are still passing. Maybe
something changed in the meantime around the handling of `TypesystemClang`
instances. I don't quite understand why `CopyType` was necessary earlier.

I am not sure how to add a regression test for this, though. It seems
the issue is already triggered by the exising `TestCoroutineHandle.py`,
but API tests seem to ignore all violations of `lldbassert` and still
report the test as "passed", even if assertions were triggered

Differential Revision: https://reviews.llvm.org/D143127

Added: 


Modified: 
lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
lldb/source/Plugins/Language/CPlusPlus/Coroutines.h

Removed: 




diff  --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index bd428a812531a..c5170757496f1 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -8,7 +8,6 @@
 
 #include "Coroutines.h"
 
-#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/VariableList.h"
@@ -97,8 +96,7 @@ bool 
lldb_private::formatters::StdlibCoroutineHandleSummaryProvider(
 
 lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
 StdlibCoroutineHandleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-: SyntheticChildrenFrontEnd(*valobj_sp),
-  m_ast_importer(std::make_unique()) {
+: SyntheticChildrenFrontEnd(*valobj_sp) {
   if (valobj_sp)
 Update();
 }
@@ -174,8 +172,7 @@ bool 
lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
 if (Function *destroy_func =
 ExtractDestroyFunction(target_sp, frame_ptr_addr)) {
   if (CompilerType inferred_type = InferPromiseType(*destroy_func)) {
-// Copy the type over to the correct `TypeSystemClang` instance
-promise_type = m_ast_importer->CopyType(*ast_ctx, inferred_type);
+promise_type = inferred_type;
   }
 }
   }

diff  --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.h 
b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.h
index e2e640ab48430..b26cc9ed6132d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.h
@@ -16,8 +16,6 @@
 
 namespace lldb_private {
 
-class ClangASTImporter;
-
 namespace formatters {
 
 /// Summary provider for `std::coroutine_handle` from  libc++, libstdc++ and
@@ -50,7 +48,6 @@ class StdlibCoroutineHandleSyntheticFrontEnd
   lldb::ValueObjectSP m_resume_ptr_sp;
   lldb::ValueObjectSP m_destroy_ptr_sp;
   lldb::ValueObjectSP m_promise_ptr_sp;
-  std::unique_ptr m_ast_importer;
 };
 
 SyntheticChildrenFrontEnd *



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


[Lldb-commits] [lldb] 8aa3137 - [LLDB] Do not dereference promise pointer in `coroutine_handle` pretty printer

2023-01-31 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2023-01-31T07:40:31-08:00
New Revision: 8aa313755118bf43c6042fb316b6c243b2c59be2

URL: 
https://github.com/llvm/llvm-project/commit/8aa313755118bf43c6042fb316b6c243b2c59be2
DIFF: 
https://github.com/llvm/llvm-project/commit/8aa313755118bf43c6042fb316b6c243b2c59be2.diff

LOG: [LLDB] Do not dereference promise pointer in `coroutine_handle` pretty 
printer

So far, the pretty printer for `std::coroutine_handle` internally
dereferenced the contained frame pointer displayed the `promise`
as a sub-value. As noticed in https://reviews.llvm.org/D132624
by @labath, this can lead to an endless loop in lldb during printing
if the coroutine frame pointers form a cycle.

This commit breaks the cycle by exposing the `promise` as a pointer
type instead of a value type. The depth to which the `frame variable`
and the `expression` commands dereference those pointers can be
controlled using the `--ptr-depth` argument.

Differential Revision: https://reviews.llvm.org/D132815

Added: 


Modified: 
lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
lldb/source/Plugins/Language/CPlusPlus/Coroutines.h

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

Removed: 




diff  --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py 
b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 97fe14e769cdd..e2c076132fc63 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -247,7 +247,7 @@ def which(program):
 
 class ValueCheck:
 def __init__(self, name=None, value=None, type=None, summary=None,
- children=None):
+ children=None, dereference=None):
 """
 :param name: The name that the SBValue should have. None if the summary
  should not be checked.
@@ -262,12 +262,15 @@ def __init__(self, name=None, value=None, type=None, 
summary=None,
  The order of checks is the order of the checks in the
  list. The number of checks has to match the number of
  children.
+:param dereference: A ValueCheck for the SBValue returned by the
+`Dereference` function.
 """
 self.expect_name = name
 self.expect_value = value
 self.expect_type = type
 self.expect_summary = summary
 self.children = children
+self.dereference = dereference
 
 def check_value(self, test_base, val, error_msg=None):
 """
@@ -309,6 +312,9 @@ def check_value(self, test_base, val, error_msg=None):
 if self.children is not None:
 self.check_value_children(test_base, val, error_msg)
 
+if self.dereference is not None:
+self.dereference.check_value(test_base, val.Dereference(), 
error_msg)
+
 def check_value_children(self, test_base, val, error_msg=None):
 """
 Checks that the children of a SBValue match a certain structure and

diff  --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index bd9ff99db67b8..bd428a812531a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -17,38 +17,37 @@ using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-static ValueObjectSP GetCoroFramePtrFromHandle(ValueObject ) {
-  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+static lldb::addr_t GetCoroFramePtrFromHandle(ValueObjectSP valobj_sp) {
   if (!valobj_sp)
-return nullptr;
+return LLDB_INVALID_ADDRESS;
 
   // We expect a single pointer in the `coroutine_handle` class.
   // We don't care about its name.
   if (valobj_sp->GetNumChildren() != 1)
-return nullptr;
+return LLDB_INVALID_ADDRESS;
   ValueObjectSP ptr_sp(valobj_sp->GetChildAtIndex(0, true));
   if (!ptr_sp)
-return nullptr;
+return LLDB_INVALID_ADDRESS;
   if (!ptr_sp->GetCompilerType().IsPointerType())
-return nullptr;
-
-  return ptr_sp;
-}
-
-static Function *ExtractDestroyFunction(ValueObjectSP _ptr_sp) {
-  lldb::TargetSP target_sp = frame_ptr_sp->GetTargetSP();
-  lldb::ProcessSP process_sp = frame_ptr_sp->GetProcessSP();
-  auto ptr_size = process_sp->GetAddressByteSize();
+return LLDB_INVALID_ADDRESS;
 
   AddressType addr_type;
-  lldb::addr_t frame_ptr_addr = frame_ptr_sp->GetPointerValue(_type);
+  lldb::addr_t frame_ptr_addr = ptr_sp->GetPointerValue(_type);
   if (!frame_ptr_addr || frame_ptr_addr == LLDB_INVALID_ADDRESS)
-return nullptr;
+return LLDB_INVALID_ADDRESS;
   lldbassert(addr_type == AddressType::eAddressTypeLoad);
+  if (addr_type != AddressType::eAddressTypeLoad)
+   

Re: [Lldb-commits] green dragon testsuite crash on TestCoroutineHandle.py from coroutines formatter changes, temporarily revert?

2022-12-07 Thread Adrian Vogelsgesang via lldb-commits
> I don't know what tools are installed on the builder but I'll ask around
the office on Monday, I know there are people who are more familiar with
how these bots are set up.

Sounds good. Thank you!

> FWIW I could repo promise_type failure on my macOS desktop which has the
current Xcode 14 tools installed

You mean you were able to reproduce the crash? Or were you able to
reproduce the test failure described in
https://github.com/llvm/llvm-project/commit/2b2f2f66141d52dc0d3082ddd12805d36872a189
also on your macOS desktop?

My current hypothesis is:

   1.
   
https://github.com/llvm/llvm-project/commit/4346318f5c700f4e85f866610fb8328fc429319b
   failed because
   - green dragon is using an outdated pre-release version of clang
  - as commented in the test case "clang version < 16 did not yet write
  debug info for the noop coroutines."
  - the test case hence uses the condition "if not (is_clang and
  self.expectedCompilerVersion(["<", "16"])):"" to only expect check this
  test expectation on recent enough compilers
  - my understanding is that "clang-16 development builds" would pass
  this version check, even if they did not yet include
  https://reviews.llvm.org/D132580 and then fail the test expectation
  - If it turns out to be true that green dragon uses an older
  clang-version, I would propose the following course of action:
 - Somebody should upgrades the version of clang used in green
 dragon
 - I resubmit this change unchanged
  2.
   
https://github.com/llvm/llvm-project/commit/cd3091a88f7c55c90d9b5fff372ce1cdfc71948d
   - was indeed buggy. This commit turned a "missing debug information"
  situation into a crash
  - I am pretty sure that Apple clang version 14.0.0 did not contain
  https://reviews.llvm.org/D132580, and is hence missing the debug
  information. This would explain the crash on your mac Desktop.
  - I would first wait after we resolved the issues around the first
  commit, though, because rebasing this commit so it can be applied before
  4346318f5c700f4e85f866610fb8328fc429319b would be cumbersome
  - I will then add the additional `if (!promise_type.isVoid())` check,
  so we no longer crash on missing debug info, and then re-apply the patch

Do you agree with that plan? Do you know somebody who can update clang on
green dragon?

Cheers,
Adrian

On Sat, Nov 26, 2022 at 3:24 AM Jason Molenda  wrote:

> FWIW I could repo promise_type failure on my macOS desktop which has the
> current Xcode 14 tools installed, but I can't tell you exactly what this
> corresponds to in github hash terms (it's "Apple clang version 14.0.0
> (clang-1400.0.29.100)"), I think it was originally branched 2021-10-26,
> although there have been a lot of cherrypicks pulled in too, so it's not an
> exact snapshot of October 26 sources.
>
> J
>
> > On Nov 25, 2022, at 2:22 PM, Adrian Vogelsgesang <
> avogelsges...@salesforce.com> wrote:
> >
> > Hm... wait a second...
> >
> > Which clang-version is
> https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/ using? Is it
> using an older version of clang? Does that version already contain the
> patch https://reviews.llvm.org/D132580?
> >
> > If not, that might explain things...
> >
> > On Fri, Nov 25, 2022 at 11:18 PM Adrian Vogelsgesang <
> avogelsges...@salesforce.com> wrote:
> > Hi Jason,
> >
> > Sorry for the late reply - your mail got caught in my spam filter, and I
> just realized about the build breakage now after you reverted the commits.
> Just to confirm:
> >
> > I looked at the original change again, and I think I know what's going
> wrong here: Devirtualization fails, and `promise_type` stays `void`.
> Obviously, `CreateValueObjectFromAddress` cannot create an object of type
> `void` and fails. The previous version was robust against that scenario,
> but https://reviews.llvm.org/D132815 accidentally regressed this.
> >
> > If a program has all the expected debug info, devirtualization should
> never fail and `promise_type` never stays `void`. It seems something is
> wrong/unexpected with the debug info on Darwin. Devirtualization relies on
> being able to identify the function pointer of the `destroy` function and
> inspects that function. So the root cause seems to be the same as for the
> revert
> https://github.com/llvm/llvm-project/commit/2b2f2f66141d52dc0d3082ddd12805d36872a189:
> For some reason, the debugger cannot find debug info for the function
> pointed to by the `destroy` function.
> >
> > However, I still don't quite understand what's wrong with the debug info
> on Mac.
> >
> > Either way, the pretty printer should of course be robust against such
> unexpected debug info. I think a simple additional check should be enough
> to make this robust so we no longer crash:
> > if (!promise_type.isVoid()) { // < additional check
> >   lldb::ValueObjectSP promise = CreateValueObjectFromAddress(
> >   "promise", frame_ptr_addr + 2 * 

Re: [Lldb-commits] green dragon testsuite crash on TestCoroutineHandle.py from coroutines formatter changes, temporarily revert?

2022-12-07 Thread Adrian Vogelsgesang via lldb-commits
Hm... wait a second...

Which clang-version is
https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/ using? Is it
using an older version of clang? Does that version already contain the
patch https://reviews.llvm.org/D132580?

If not, that might explain things...

On Fri, Nov 25, 2022 at 11:18 PM Adrian Vogelsgesang <
avogelsges...@salesforce.com> wrote:

> Hi Jason,
>
> Sorry for the late reply - your mail got caught in my spam filter, and I
> just realized about the build breakage now after you reverted the commits.
> Just to confirm:
>
> I looked at the original change again, and I think I know what's going
> wrong here: Devirtualization fails, and `promise_type` stays `void`.
> Obviously, `CreateValueObjectFromAddress` cannot create an object of type
> `void` and fails. The previous version was robust against that scenario,
> but https://reviews.llvm.org/D132815 accidentally regressed this.
>
> If a program has all the expected debug info, devirtualization should
> never fail and `promise_type` never stays `void`. It seems something is
> wrong/unexpected with the debug info on Darwin. Devirtualization relies on
> being able to identify the function pointer of the `destroy` function and
> inspects that function. So the root cause seems to be the same as for the
> revert
> https://github.com/llvm/llvm-project/commit/2b2f2f66141d52dc0d3082ddd12805d36872a189:
> For some reason, the debugger cannot find debug info for the function
> pointed to by the `destroy` function.
>
> However, I still don't quite understand what's wrong with the debug info
> on Mac.
>
> Either way, the pretty printer should of course be robust against such
> unexpected debug info. I think a simple additional check should be enough
> to make this robust so we no longer crash:
> if (!promise_type.isVoid()) { // < additional check
>   lldb::ValueObjectSP promise = CreateValueObjectFromAddress(
>   "promise", frame_ptr_addr + 2 * ptr_size, exe_ctx, promise_type);
>   Status error;
>   lldb::ValueObjectSP promisePtr = promise->AddressOf(error);
>   if (error.Success())
> m_promise_ptr_sp = promisePtr->Clone(ConstString("promise"));
> }
>
> Meta question: I am a bit confused about
> https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/. I thought
> LLVM's buildbots were set up to send an email in case somebody breaks the
> build. Also, I made sure that all builds in
> https://lab.llvm.org/buildbot/#/builders stayed green after my commit. So
> what are the expectations around which CIs need to stay green after a
> commit? Do I need to setup anything such that green.lab.llvm.org also
> sends me an email if I break it?
>
> Cheers,
> Adrian
>
> On Thu, Nov 24, 2022 at 10:50 PM Jason Molenda  wrote:
>
>> Ah, little misstatement below.  My first thought was that promise_type
>> was null, but when I stepped through here with a debugger, it was not.  I
>> didn't know how to dig in to a CompilerType object but there was some
>> reason why this CreateValueObjectFromAddress failed to return an actual
>> ValueObject, and I assumed it's something to do with that CompilerType.
>> But I didn't dig in far enough to understand what the issue in the type was.
>>
>> > On Nov 24, 2022, at 1:20 PM, Jason Molenda  wrote:
>> >
>> > Hi Adrian, the green dragon Incremental CI bot has been failing the
>> past couple of days after the changes for the coroutines formatter, most
>> directly   https://reviews.llvm.org/D132815 landed -
>> TestCoroutineHandle.py results in a segfault on Darwin systems (both on the
>> CI and on my mac desktop) consistently.
>> https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/
>> >
>> > It's crashing in formatters::StdlibCoroutineHandleSyntheticFrontEnd
>> where you're doing
>> >
>> > ```
>> >  // Add the `promise` member. We intentionally add `promise` as a
>> pointer type
>> >  // instead of a value type, and don't automatically dereference this
>> pointer.
>> >  // We do so to avoid potential very deep recursion in case there is a
>> cycle in
>> >  // formed between `std::coroutine_handle`s and their promises.
>> >  lldb::ValueObjectSP promise = CreateValueObjectFromAddress(
>> >  "promise", frame_ptr_addr + 2 * ptr_size, exe_ctx, promise_type);
>> >  Status error;
>> >  lldb::ValueObjectSP promisePtr = promise->AddressOf(error);
>> > ```
>> >
>> > and the promise_type dose not have a CompilerType so promisePtr is
>> nullptr and we crash on the method call to AddressOf. I looked briefly, but
>> this isn't a part of lldb I know well and I'm not sure the nature of the
>> problem.
>> >
>> > It's a long weekend in the US, so if you have a suggestion for
>> addressing this that'd be great, or I can roll back the changes necessary
>> to get the bot clean later today and we can look at this next week.
>> >
>> > Thanks!
>>
>>
>>
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


Re: [Lldb-commits] green dragon testsuite crash on TestCoroutineHandle.py from coroutines formatter changes, temporarily revert?

2022-12-07 Thread Adrian Vogelsgesang via lldb-commits
Hi Jason,

Sorry for the late reply - your mail got caught in my spam filter, and I
just realized about the build breakage now after you reverted the commits.
Just to confirm:

I looked at the original change again, and I think I know what's going
wrong here: Devirtualization fails, and `promise_type` stays `void`.
Obviously, `CreateValueObjectFromAddress` cannot create an object of type
`void` and fails. The previous version was robust against that scenario,
but https://reviews.llvm.org/D132815 accidentally regressed this.

If a program has all the expected debug info, devirtualization should never
fail and `promise_type` never stays `void`. It seems something is
wrong/unexpected with the debug info on Darwin. Devirtualization relies on
being able to identify the function pointer of the `destroy` function and
inspects that function. So the root cause seems to be the same as for the
revert
https://github.com/llvm/llvm-project/commit/2b2f2f66141d52dc0d3082ddd12805d36872a189:
For some reason, the debugger cannot find debug info for the function
pointed to by the `destroy` function.

However, I still don't quite understand what's wrong with the debug info on
Mac.

Either way, the pretty printer should of course be robust against such
unexpected debug info. I think a simple additional check should be enough
to make this robust so we no longer crash:
if (!promise_type.isVoid()) { // < additional check
  lldb::ValueObjectSP promise = CreateValueObjectFromAddress(
  "promise", frame_ptr_addr + 2 * ptr_size, exe_ctx, promise_type);
  Status error;
  lldb::ValueObjectSP promisePtr = promise->AddressOf(error);
  if (error.Success())
m_promise_ptr_sp = promisePtr->Clone(ConstString("promise"));
}

Meta question: I am a bit confused about
https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/. I thought
LLVM's buildbots were set up to send an email in case somebody breaks the
build. Also, I made sure that all builds in
https://lab.llvm.org/buildbot/#/builders stayed green after my commit. So
what are the expectations around which CIs need to stay green after a
commit? Do I need to setup anything such that green.lab.llvm.org also sends
me an email if I break it?

Cheers,
Adrian

On Thu, Nov 24, 2022 at 10:50 PM Jason Molenda  wrote:

> Ah, little misstatement below.  My first thought was that promise_type was
> null, but when I stepped through here with a debugger, it was not.  I
> didn't know how to dig in to a CompilerType object but there was some
> reason why this CreateValueObjectFromAddress failed to return an actual
> ValueObject, and I assumed it's something to do with that CompilerType.
> But I didn't dig in far enough to understand what the issue in the type was.
>
> > On Nov 24, 2022, at 1:20 PM, Jason Molenda  wrote:
> >
> > Hi Adrian, the green dragon Incremental CI bot has been failing the past
> couple of days after the changes for the coroutines formatter, most
> directly   https://reviews.llvm.org/D132815 landed -
> TestCoroutineHandle.py results in a segfault on Darwin systems (both on the
> CI and on my mac desktop) consistently.
> https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/
> >
> > It's crashing in formatters::StdlibCoroutineHandleSyntheticFrontEnd
> where you're doing
> >
> > ```
> >  // Add the `promise` member. We intentionally add `promise` as a
> pointer type
> >  // instead of a value type, and don't automatically dereference this
> pointer.
> >  // We do so to avoid potential very deep recursion in case there is a
> cycle in
> >  // formed between `std::coroutine_handle`s and their promises.
> >  lldb::ValueObjectSP promise = CreateValueObjectFromAddress(
> >  "promise", frame_ptr_addr + 2 * ptr_size, exe_ctx, promise_type);
> >  Status error;
> >  lldb::ValueObjectSP promisePtr = promise->AddressOf(error);
> > ```
> >
> > and the promise_type dose not have a CompilerType so promisePtr is
> nullptr and we crash on the method call to AddressOf. I looked briefly, but
> this isn't a part of lldb I know well and I'm not sure the nature of the
> problem.
> >
> > It's a long weekend in the US, so if you have a suggestion for
> addressing this that'd be great, or I can roll back the changes necessary
> to get the bot clean later today and we can look at this next week.
> >
> > Thanks!
>
>
>
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


Re: [Lldb-commits] [PATCH] D132624: [LLDB] Devirtualize coroutine promise types for `std::coroutine_handle`

2022-12-07 Thread Adrian Vogelsgesang via lldb-commits
Thank you for that hint, Jim! This infrastructure indeed looks very
interesting for my use case.
I will most likely use the HistoryThread class to represent the backtrace
of the logical coroutine threads.

Is my understanding correct, that `GetExtendedBacktraceThreads` only allows
me to append additional stack trace frames to existing, physical
threads, though? I want to expose completely new threads instead. In a
sense, I want to display each pending request inside my asynchronous
multiplexer as its own thread, such that I can see not only the requests
which an OS-level thread is currently working on, but also the onse which
are currently queued/not yet processed/blocked on IO

On Fri, Aug 26, 2022 at 6:38 PM Jim Ingham  wrote:

>
>
> > On Aug 26, 2022, at 7:05 AM, Adrian Vogelsgesang via Phabricator via
> lldb-commits  wrote:
> >
> > avogelsgesang added a comment.
> >
> >> I don't know much about coroutines, but it seems like your goal is to
> format them like a linked list
> >
> > actually, my preferred goal would be to show them as a logical,
> user-level thread. Such that you can type
> >
> >  thread backtrace cxxcoro:0xb2a0
> >
> > to get the backtrace of the logical coroutine thread routed at the
> coroutine at address `0xb2a0`, or maybe even
> >
> >  thread backtrace cxxcoro:hdl
> >
> > where `hdl` is evaluated as an expression to identify the coroutine
> handle from where to dump the backtrace.
> >
> > Also, it would be neat if those logical threads show up in `thread
> list`...
> >
> > But it seems there is currently no infrastructure yet in LLDB for
> logical threads provided by `LanguageRuntime` plugins.
> >
> > I guess at some point, I will write an RFC about that on discourse. But
> before that, I will first do some more exploration on how LLDB works and I
> will first grab the low-hanging fruits (like a data formatter for
> `std::coroutine_handle` and patching LLVM to emit the necessary debug info)
>
> lldb has the notion of "extended backtrace threads" - backed by lldb's
> "History" threads - that it uses in a similar circumstance handling Darwin
> dispatch queues.  If you have a thread that is serving a Darwin "dispatch
> queue" SBThread.GetExtendedBacktraceThreads will return the backtrace of
> the thread that enqueued the work, at the point where the enqueuing is
> done.  I bet you could make the same setup work for these coroutines.
>
> Jim
>
>
> >
> >
> > Repository:
> >  rG LLVM Github Monorepo
> >
> > CHANGES SINCE LAST ACTION
> >  https://reviews.llvm.org/D132624/new/
> >
> > https://reviews.llvm.org/D132624
> >
> > ___
> > lldb-commits mailing list
> > lldb-commits@lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
>
>
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] cd3091a - [LLDB] Do not dereference promise pointer in `coroutine_handle` pretty printer

2022-11-20 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2022-11-20T14:26:36-08:00
New Revision: cd3091a88f7c55c90d9b5fff372ce1cdfc71948d

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

LOG: [LLDB] Do not dereference promise pointer in `coroutine_handle` pretty 
printer

So far, the pretty printer for `std::coroutine_handle` internally
dereferenced the contained frame pointer displayed the `promise`
as a sub-value. As noticed in https://reviews.llvm.org/D132624
by @labath, this can lead to an endless loop in lldb during printing
if the coroutine frame pointers form a cycle.

This commit breaks the cycle by exposing the `promise` as a pointer
type instead of a value type. The depth to which the `frame variable`
and the `expression` commands dereference those pointers can be
controlled using the `--ptr-depth` argument.

Differential Revision: https://reviews.llvm.org/D132815

Added: 


Modified: 
lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
lldb/source/Plugins/Language/CPlusPlus/Coroutines.h

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

Removed: 




diff  --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py 
b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 63bad9d0241de..f579a0160b2b7 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -246,7 +246,7 @@ def which(program):
 
 class ValueCheck:
 def __init__(self, name=None, value=None, type=None, summary=None,
- children=None):
+ children=None, dereference=None):
 """
 :param name: The name that the SBValue should have. None if the summary
  should not be checked.
@@ -261,12 +261,15 @@ def __init__(self, name=None, value=None, type=None, 
summary=None,
  The order of checks is the order of the checks in the
  list. The number of checks has to match the number of
  children.
+:param dereference: A ValueCheck for the SBValue returned by the
+`Dereference` function.
 """
 self.expect_name = name
 self.expect_value = value
 self.expect_type = type
 self.expect_summary = summary
 self.children = children
+self.dereference = dereference
 
 def check_value(self, test_base, val, error_msg=None):
 """
@@ -308,6 +311,9 @@ def check_value(self, test_base, val, error_msg=None):
 if self.children is not None:
 self.check_value_children(test_base, val, error_msg)
 
+if self.dereference is not None:
+self.dereference.check_value(test_base, val.Dereference(), 
error_msg)
+
 def check_value_children(self, test_base, val, error_msg=None):
 """
 Checks that the children of a SBValue match a certain structure and

diff  --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index aa6a6ef7e56ae..7e1302c7eb785 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -17,34 +17,35 @@ using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
-static ValueObjectSP GetCoroFramePtrFromHandle(ValueObject ) {
-  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+static lldb::addr_t GetCoroFramePtrFromHandle(ValueObjectSP valobj_sp) {
   if (!valobj_sp)
-return nullptr;
+return LLDB_INVALID_ADDRESS;
 
   // We expect a single pointer in the `coroutine_handle` class.
   // We don't care about its name.
   if (valobj_sp->GetNumChildren() != 1)
-return nullptr;
+return LLDB_INVALID_ADDRESS;
   ValueObjectSP ptr_sp(valobj_sp->GetChildAtIndex(0, true));
   if (!ptr_sp)
-return nullptr;
+return LLDB_INVALID_ADDRESS;
   if (!ptr_sp->GetCompilerType().IsPointerType())
-return nullptr;
-
-  return ptr_sp;
-}
-
-static Function *ExtractFunction(ValueObjectSP _ptr_sp, int offset) {
-  lldb::TargetSP target_sp = frame_ptr_sp->GetTargetSP();
-  lldb::ProcessSP process_sp = frame_ptr_sp->GetProcessSP();
-  auto ptr_size = process_sp->GetAddressByteSize();
+return LLDB_INVALID_ADDRESS;
 
   AddressType addr_type;
-  lldb::addr_t frame_ptr_addr = frame_ptr_sp->GetPointerValue(_type);
+  lldb::addr_t frame_ptr_addr = ptr_sp->GetPointerValue(_type);
   if (!frame_ptr_addr || frame_ptr_addr == LLDB_INVALID_ADDRESS)
-return nullptr;
+return LLDB_INVALID_ADDRESS;
   lldbassert(addr_type == AddressType::eAddressTypeLoad);
+  if (addr_type != 

[Lldb-commits] [lldb] 4346318 - [LLDB] Recognize `std::noop_coroutine()` in `std::coroutine_handle` pretty printer

2022-11-20 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2022-11-20T11:18:52-08:00
New Revision: 4346318f5c700f4e85f866610fb8328fc429319b

URL: 
https://github.com/llvm/llvm-project/commit/4346318f5c700f4e85f866610fb8328fc429319b
DIFF: 
https://github.com/llvm/llvm-project/commit/4346318f5c700f4e85f866610fb8328fc429319b.diff

LOG: [LLDB] Recognize `std::noop_coroutine()` in `std::coroutine_handle` pretty 
printer

With this commit, the `std::coroutine_handle` pretty printer now
recognizes `std::noop_coroutine()` handles. For noop coroutine handles,
we identify use the summary string `noop_coroutine` and we don't print
children

Instead of
```
(std::coroutine_handle) $3 = coro frame = 0x9058 {
  resume = 0x64f0 
(a.out`std::__1::coroutine_handle::__noop_coroutine_frame_ty_::__dummy_resume_destroy_func()
 at noop_coroutine_handle.h:79)
  destroy = 0x64f0 
(a.out`std::__1::coroutine_handle::__noop_coroutine_frame_ty_::__dummy_resume_destroy_func()
 at noop_coroutine_handle.h:79)
}
```

we now print

```
(std::coroutine_handle) $3 = noop_coroutine
```

Differential Revision: https://reviews.llvm.org/D132735

Added: 


Modified: 
lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp

Removed: 




diff  --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index bd9ff99db67b8..aa6a6ef7e56ae 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -35,7 +35,7 @@ static ValueObjectSP GetCoroFramePtrFromHandle(ValueObject 
) {
   return ptr_sp;
 }
 
-static Function *ExtractDestroyFunction(ValueObjectSP _ptr_sp) {
+static Function *ExtractFunction(ValueObjectSP _ptr_sp, int offset) {
   lldb::TargetSP target_sp = frame_ptr_sp->GetTargetSP();
   lldb::ProcessSP process_sp = frame_ptr_sp->GetProcessSP();
   auto ptr_size = process_sp->GetAddressByteSize();
@@ -47,24 +47,64 @@ static Function *ExtractDestroyFunction(ValueObjectSP 
_ptr_sp) {
   lldbassert(addr_type == AddressType::eAddressTypeLoad);
 
   Status error;
-  // The destroy pointer is the 2nd pointer inside the compiler-generated
-  // `pair`.
-  auto destroy_func_ptr_addr = frame_ptr_addr + ptr_size;
-  lldb::addr_t destroy_func_addr =
-  process_sp->ReadPointerFromMemory(destroy_func_ptr_addr, error);
+  auto func_ptr_addr = frame_ptr_addr + offset * ptr_size;
+  lldb::addr_t func_addr =
+  process_sp->ReadPointerFromMemory(func_ptr_addr, error);
   if (error.Fail())
 return nullptr;
 
-  Address destroy_func_address;
-  if (!target_sp->ResolveLoadAddress(destroy_func_addr, destroy_func_address))
+  Address func_address;
+  if (!target_sp->ResolveLoadAddress(func_addr, func_address))
 return nullptr;
 
-  Function *destroy_func =
-  destroy_func_address.CalculateSymbolContextFunction();
-  if (!destroy_func)
-return nullptr;
+  return func_address.CalculateSymbolContextFunction();
+}
+
+static Function *ExtractResumeFunction(ValueObjectSP _ptr_sp) {
+  return ExtractFunction(frame_ptr_sp, 0);
+}
+
+static Function *ExtractDestroyFunction(ValueObjectSP _ptr_sp) {
+  return ExtractFunction(frame_ptr_sp, 1);
+}
+
+static bool IsNoopCoroFunction(Function *f) {
+  if (!f)
+return false;
 
-  return destroy_func;
+  // clang's `__builtin_coro_noop` gets lowered to
+  // `_NoopCoro_ResumeDestroy`. This is used by libc++
+  // on clang.
+  auto mangledName = f->GetMangled().GetMangledName();
+  if (mangledName == "__NoopCoro_ResumeDestroy")
+return true;
+
+  // libc++ uses the following name as a fallback on
+  // compilers without `__builtin_coro_noop`.
+  auto name = f->GetNameNoArguments();
+  static RegularExpression libcxxRegex(
+  "^std::coroutine_handle::"
+  "__noop_coroutine_frame_ty_::__dummy_resume_destroy_func$");
+  lldbassert(libcxxRegex.IsValid());
+  if (libcxxRegex.Execute(name.GetStringRef()))
+return true;
+  static RegularExpression libcxxRegexAbiNS(
+  "^std::__[[:alnum:]]+::coroutine_handle::__noop_coroutine_frame_ty_::"
+  "__dummy_resume_destroy_func$");
+  lldbassert(libcxxRegexAbiNS.IsValid());
+  if (libcxxRegexAbiNS.Execute(name.GetStringRef()))
+return true;
+
+  // libstdc++ uses the following name on both gcc and clang.
+  static RegularExpression libstdcppRegex(
+  "^std::__[[:alnum:]]+::coroutine_handle::__frame::__dummy_resume_destroy$");
+  lldbassert(libstdcppRegex.IsValid());
+  if (libstdcppRegex.Execute(name.GetStringRef()))
+return true;
+
+  return false;
 }
 
 static CompilerType InferPromiseType(Function _func) {
@@ -113,9 +153,15 @@ bool 
lldb_private::formatters::StdlibCoroutineHandleSummaryProvider(
 

[Lldb-commits] [lldb] fb61dce - [lldb] Fix test expectation in `TestCoroutineHandle.py` for 32-bit systems

2022-11-20 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2022-11-20T10:30:29-08:00
New Revision: fb61dce1adc4572e794e836861915d8ae372749d

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

LOG: [lldb] Fix test expectation in `TestCoroutineHandle.py` for 32-bit systems

Added: 


Modified: 

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

Removed: 




diff  --git 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py
 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py
index ed03fd0961cce..44e5e6451c10d 100644
--- 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py
+++ 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py
@@ -97,7 +97,7 @@ def do_test(self, stdlib_type):
 self.expect_expr("type_erased_hdl",
 result_summary=re.compile("^coro frame = 0x[0-9a-f]*$"),
 result_children=[
-ValueCheck(name="resume", value = "0x"),
+ValueCheck(name="resume", value = re.compile("^0x0+$")),
 ValueCheck(name="destroy", summary = 
test_generator_func_ptr_re),
 ValueCheck(name="promise", children=[
 ValueCheck(name="current_value", value = "42"),



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


[Lldb-commits] [lldb] 01f4c30 - Reapply "[LLDB] Devirtualize coroutine promise types for `std::coroutine_handle`"

2022-11-20 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2022-11-20T06:35:16-08:00
New Revision: 01f4c305fae9ff2f165ce0f635a90f8e2292308c

URL: 
https://github.com/llvm/llvm-project/commit/01f4c305fae9ff2f165ce0f635a90f8e2292308c
DIFF: 
https://github.com/llvm/llvm-project/commit/01f4c305fae9ff2f165ce0f635a90f8e2292308c.diff

LOG: Reapply "[LLDB] Devirtualize coroutine promise types for 
`std::coroutine_handle`"

The original commit was missing a `ClangASTImporter::CopyType` call.
Original commit message:

This commit teaches the `std::coroutine_handle` pretty-printer to
devirtualize type-erased promise types. This is particularly useful to
resonstruct call stacks, either of asynchronous control flow or of
recursive invocations of `std::generator`. For the example recently
introduced by https://reviews.llvm.org/D132451, printing the `__promise`
variable now shows

```
(std::__coroutine_traits_sfinae::promise_type) __promise = {
  continuation = coro frame = 0x55562430 {
resume = 0x6310 (a.out`task detail::chain_fn<1>() at 
llvm-nested-example.cpp:66)
destroy = 0x6700 (a.out`task detail::chain_fn<1>() at 
llvm-nested-example.cpp:66)
promise = {
  continuation = coro frame = 0x555623e0 {
resume = 0x7070 (a.out`task detail::chain_fn<2>() at 
llvm-nested-example.cpp:66)
destroy = 0x7460 (a.out`task detail::chain_fn<2>() at 
llvm-nested-example.cpp:66)
promise = {
  ...
}
  }
  result = 0
}
  }
  result = 0
}
```

(shortened to keep the commit message readable) instead of

```
(std::__coroutine_traits_sfinae::promise_type) __promise = {
  continuation = coro frame = 0x55562430 {
resume = 0x6310 (a.out`task detail::chain_fn<1>() at 
llvm-nested-example.cpp:66)
destroy = 0x6700 (a.out`task detail::chain_fn<1>() at 
llvm-nested-example.cpp:66)
  }
  result = 0
}
```

Note how the new debug output reveals the complete asynchronous call
stack: our own function resumes `chain_fn<1>` which in turn will resume
`chain_fn<2>` and so on. Thereby this change allows users of lldb to
inspect the logical coroutine call stack without using any custom debug
scripts (although the display is still a bit clumsy. It would be nicer
to also integrate this into lldb's backtrace feature, but I don't know
how to do so)

The devirtualization currently works by introspecting the function
pointed to by the `destroy` pointer. (The `resume` pointer is not worth
much, given that for the final suspend point `resume` is set to a
nullptr. We have to use the `destroy` pointer instead.) We then look
for a `__promise` variable inside the `destroy` function. This
`__promise` variable is synthetically generated by LLVM, and looking at
its type reveals the type-erased promise_type.

This approach only works for clang-generated code, though. While gcc
also adds a `_Coro_promise` variable to the `resume` function, it does
not do so for the `destroy` function. However, we can't use the `resume`
function, as it will be reset to a nullptr at the final suspension
point. For the time being, I am happy with de-virtualization only working
for clang. A follow-up commit will further improve devirtualization and
also expose the variables spilled to the coroutine frame. As part of
this, I will also revisit gcc support.

Differential Revision: https://reviews.llvm.org/D132624

Added: 


Modified: 
lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
lldb/source/Plugins/Language/CPlusPlus/Coroutines.h

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp

Removed: 




diff  --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index de5d1831c01ef..bd9ff99db67b8 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -8,7 +8,10 @@
 
 #include "Coroutines.h"
 
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/VariableList.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -32,6 +35,56 @@ static ValueObjectSP GetCoroFramePtrFromHandle(ValueObject 
) {
   return ptr_sp;
 }
 
+static Function *ExtractDestroyFunction(ValueObjectSP _ptr_sp) {
+  lldb::TargetSP target_sp = frame_ptr_sp->GetTargetSP();
+  lldb::ProcessSP process_sp = frame_ptr_sp->GetProcessSP();
+  auto ptr_size = process_sp->GetAddressByteSize();
+
+  AddressType addr_type;
+  lldb::addr_t frame_ptr_addr = frame_ptr_sp->GetPointerValue(_type);
+  if (!frame_ptr_addr || frame_ptr_addr == LLDB_INVALID_ADDRESS)
+return nullptr;
+  

[Lldb-commits] [lldb] d7e1c27 - Revert "[LLDB] Devirtualize coroutine promise types for `std::coroutine_handle`"

2022-11-11 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2022-11-11T10:00:58-08:00
New Revision: d7e1c2770fa57fb8df2f09f74d433ac9cf80a595

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

LOG: Revert "[LLDB] Devirtualize coroutine promise types for 
`std::coroutine_handle`"

This reverts commit 558db7787005348e2efaabb628ec36f1c461a741 due to
buildbot failures on ARM
* https://lab.llvm.org/buildbot/#/builders/96/builds/31416
* https://lab.llvm.org/buildbot/#/builders/17/builds/30086

Added: 


Modified: 
lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp

Removed: 




diff  --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index 89ee4bb67f931..5427a7a2b7850 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -9,8 +9,6 @@
 #include "Coroutines.h"
 
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/VariableList.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -34,57 +32,6 @@ static ValueObjectSP GetCoroFramePtrFromHandle(ValueObject 
) {
   return ptr_sp;
 }
 
-static Function *ExtractDestroyFunction(ValueObjectSP _ptr_sp) {
-  lldb::TargetSP target_sp = frame_ptr_sp->GetTargetSP();
-  lldb::ProcessSP process_sp = frame_ptr_sp->GetProcessSP();
-  auto ptr_size = process_sp->GetAddressByteSize();
-
-  AddressType addr_type;
-  lldb::addr_t frame_ptr_addr = frame_ptr_sp->GetPointerValue(_type);
-  if (!frame_ptr_addr || frame_ptr_addr == LLDB_INVALID_ADDRESS)
-return nullptr;
-  lldbassert(addr_type == AddressType::eAddressTypeLoad);
-
-  Status error;
-  // The destroy pointer is the 2nd pointer inside the compiler-generated
-  // `pair`.
-  auto destroy_func_ptr_addr = frame_ptr_addr + ptr_size;
-  lldb::addr_t destroy_func_addr =
-  process_sp->ReadPointerFromMemory(destroy_func_ptr_addr, error);
-  if (error.Fail())
-return nullptr;
-
-  Address destroy_func_address;
-  if (!target_sp->ResolveLoadAddress(destroy_func_addr, destroy_func_address))
-return nullptr;
-
-  Function *destroy_func =
-  destroy_func_address.CalculateSymbolContextFunction();
-  if (!destroy_func)
-return nullptr;
-
-  return destroy_func;
-}
-
-static CompilerType InferPromiseType(Function _func) {
-  SymbolContext sc;
-  Block  = destroy_func.GetBlock(true);
-  auto variable_list = block.GetBlockVariableList(true);
-
-  // clang generates an artificial `__promise` variable inside the
-  // `destroy` function. Look for it.
-  auto promise_var = variable_list->FindVariable(ConstString("__promise"));
-  if (!promise_var)
-return {};
-  if (!promise_var->IsArtificial())
-return {};
-
-  Type *promise_type = promise_var->GetType();
-  if (!promise_type)
-return {};
-  return promise_type->GetForwardCompilerType();
-}
-
 static CompilerType GetCoroutineFrameType(TypeSystemClang _ctx,
   CompilerType promise_type) {
   CompilerType void_type = ast_ctx.GetBasicType(lldb::eBasicTypeVoid);
@@ -111,11 +58,7 @@ bool 
lldb_private::formatters::StdlibCoroutineHandleSummaryProvider(
   if (!ptr_sp)
 return false;
 
-  if (!ptr_sp->GetValueAsUnsigned(0)) {
-stream << "nullptr";
-  } else {
-stream.Printf("coro frame = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
-  }
+  stream.Printf("coro frame = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
   return true;
 }
 
@@ -157,26 +100,15 @@ bool 
lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
   if (!ptr_sp)
 return false;
 
-  // Get the `promise_type` from the template argument
+  TypeSystemClang *ast_ctx = llvm::dyn_cast_or_null(
+  valobj_sp->GetCompilerType().GetTypeSystem());
+  if (!ast_ctx)
+return false;
+
   CompilerType promise_type(
   valobj_sp->GetCompilerType().GetTypeTemplateArgument(0));
   if (!promise_type)
 return false;
-
-  // Try to infer the promise_type if it was type-erased
-  if (promise_type.IsVoidType()) {
-if (Function *destroy_func = ExtractDestroyFunction(ptr_sp)) {
-  if (CompilerType inferred_type = InferPromiseType(*destroy_func)) {
-promise_type = inferred_type;
-  }
-}
-  }
-
-  // Build the coroutine frame type
-  TypeSystemClang *ast_ctx = llvm::dyn_cast_or_null(
-  ptr_sp->GetCompilerType().GetTypeSystem());
-  if (!ast_ctx)
-return {};
   CompilerType coro_frame_type = GetCoroutineFrameType(*ast_ctx, promise_type);
 
   m_frame_ptr_sp = 

[Lldb-commits] [lldb] 558db77 - [LLDB] Devirtualize coroutine promise types for `std::coroutine_handle`

2022-11-11 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2022-11-11T09:37:08-08:00
New Revision: 558db7787005348e2efaabb628ec36f1c461a741

URL: 
https://github.com/llvm/llvm-project/commit/558db7787005348e2efaabb628ec36f1c461a741
DIFF: 
https://github.com/llvm/llvm-project/commit/558db7787005348e2efaabb628ec36f1c461a741.diff

LOG: [LLDB] Devirtualize coroutine promise types for `std::coroutine_handle`

This commit teaches the `std::coroutine_handle` pretty-printer to
devirtualize type-erased promise types. This is particularly useful to
resonstruct call stacks, either of asynchronous control flow or of
recursive invocations of `std::generator`. For the example recently
introduced by https://reviews.llvm.org/D132451, printing the `__promise`
variable now shows

```
(std::__coroutine_traits_sfinae::promise_type) __promise = {
  continuation = coro frame = 0x55562430 {
resume = 0x6310 (a.out`task detail::chain_fn<1>() at 
llvm-nested-example.cpp:66)
destroy = 0x6700 (a.out`task detail::chain_fn<1>() at 
llvm-nested-example.cpp:66)
promise = {
  continuation = coro frame = 0x555623e0 {
resume = 0x7070 (a.out`task detail::chain_fn<2>() at 
llvm-nested-example.cpp:66)
destroy = 0x7460 (a.out`task detail::chain_fn<2>() at 
llvm-nested-example.cpp:66)
promise = {
  ...
}
  }
  result = 0
}
  }
  result = 0
}
```

(shortened to keep the commit message readable) instead of

```
(std::__coroutine_traits_sfinae::promise_type) __promise = {
  continuation = coro frame = 0x55562430 {
resume = 0x6310 (a.out`task detail::chain_fn<1>() at 
llvm-nested-example.cpp:66)
destroy = 0x6700 (a.out`task detail::chain_fn<1>() at 
llvm-nested-example.cpp:66)
  }
  result = 0
}
```

Note how the new debug output reveals the complete asynchronous call
stack: our own function resumes `chain_fn<1>` which in turn will resume
`chain_fn<2>` and so on. Thereby this change allows users of lldb to
inspect the logical coroutine call stack without using any custom debug
scripts (although the display is still a bit clumsy. It would be nicer
to also integrate this into lldb's backtrace feature, but I don't know
how to do so)

The devirtualization currently works by introspecting the function
pointed to by the `destroy` pointer. (The `resume` pointer is not worth
much, given that for the final suspend point `resume` is set to a
nullptr. We have to use the `destroy` pointer instead.) We then look
for a `__promise` variable inside the `destroy` function. This
`__promise` variable is synthetically generated by LLVM, and looking at
its type reveals the type-erased promise_type.

This approach only works for clang-generated code, though. While gcc
also adds a `_Coro_promise` variable to the `resume` function, it does
not do so for the `destroy` function. However, we can't use the `resume`
function, as it will be reset to a nullptr at the final suspension
point. For the time being, I am happy with de-virtualization only working
for clang. A follow-up commit will further improve devirtualization and
also expose the variables spilled to the coroutine frame. As part of
this, I will also revisit gcc support.

Differential Revision: https://reviews.llvm.org/D132624

Added: 


Modified: 
lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp

Removed: 




diff  --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index 5427a7a2b7850..89ee4bb67f931 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -9,6 +9,8 @@
 #include "Coroutines.h"
 
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/VariableList.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -32,6 +34,57 @@ static ValueObjectSP GetCoroFramePtrFromHandle(ValueObject 
) {
   return ptr_sp;
 }
 
+static Function *ExtractDestroyFunction(ValueObjectSP _ptr_sp) {
+  lldb::TargetSP target_sp = frame_ptr_sp->GetTargetSP();
+  lldb::ProcessSP process_sp = frame_ptr_sp->GetProcessSP();
+  auto ptr_size = process_sp->GetAddressByteSize();
+
+  AddressType addr_type;
+  lldb::addr_t frame_ptr_addr = frame_ptr_sp->GetPointerValue(_type);
+  if (!frame_ptr_addr || frame_ptr_addr == LLDB_INVALID_ADDRESS)
+return nullptr;
+  lldbassert(addr_type == AddressType::eAddressTypeLoad);
+
+  Status error;
+  // The destroy pointer is the 2nd pointer inside the compiler-generated
+  // `pair`.
+  auto destroy_func_ptr_addr = frame_ptr_addr + ptr_size;
+  

[Lldb-commits] [lldb] 6f88388 - [lldb][test] Fix nullptr test expctation for 32-bit system

2022-08-25 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2022-08-25T17:11:57-07:00
New Revision: 6f88388f61327b375112e76ff4b80741a1b349cb

URL: 
https://github.com/llvm/llvm-project/commit/6f88388f61327b375112e76ff4b80741a1b349cb
DIFF: 
https://github.com/llvm/llvm-project/commit/6f88388f61327b375112e76ff4b80741a1b349cb.diff

LOG: [lldb][test] Fix nullptr test expctation for 32-bit system

Follow-up to https://reviews.llvm.org/D132415

Fixes https://lab.llvm.org/buildbot/#/builders/17/builds/26630

Added: 


Modified: 
lldb/packages/Python/lldbsuite/test/lldbtest.py

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

Removed: 




diff  --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py 
b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 1c090395e6c4c..0d449737cfd0b 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -286,8 +286,12 @@ def check_value(self, test_base, val, error_msg=None):
 test_base.assertEqual(self.expect_name, val.GetName(),
   this_error_msg)
 if self.expect_value:
-test_base.assertEqual(self.expect_value, val.GetValue(),
-  this_error_msg)
+if isinstance(self.expect_value, re.Pattern):
+test_base.assertRegex(val.GetValue(), self.expect_value,
+  this_error_msg)
+else:
+test_base.assertEqual(self.expect_value, val.GetValue(),
+  this_error_msg)
 if self.expect_type:
 test_base.assertEqual(self.expect_type, val.GetDisplayTypeName(),
   this_error_msg)

diff  --git 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py
 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py
index 33d580d98df61..50cac6ebff7fd 100644
--- 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py
+++ 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py
@@ -63,7 +63,7 @@ def do_test(self, stdlib_type):
 # Check that we still show the remaining data correctly.
 self.expect_expr("gen.hdl",
 result_children=[
-ValueCheck(name="resume", value = "0x"),
+ValueCheck(name="resume", value = re.compile("^0x0+$")),
 ValueCheck(name="destroy", summary = 
test_generator_func_ptr_re),
 ValueCheck(name="promise", children=[
 ValueCheck(name="current_value", value = "42"),



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


[Lldb-commits] [lldb] 9138900 - [LLDB] Add data formatter for std::coroutine_handle

2022-08-24 Thread Adrian Vogelsgesang via lldb-commits

Author: Adrian Vogelsgesang
Date: 2022-08-24T14:40:53-07:00
New Revision: 91389000abe8ef5d06d98cbbefd3fa03ac7e4480

URL: 
https://github.com/llvm/llvm-project/commit/91389000abe8ef5d06d98cbbefd3fa03ac7e4480
DIFF: 
https://github.com/llvm/llvm-project/commit/91389000abe8ef5d06d98cbbefd3fa03ac7e4480.diff

LOG: [LLDB] Add data formatter for std::coroutine_handle

This patch adds a formatter for `std::coroutine_handle`, both for libc++
and libstdc++. For the type-erased `coroutine_handle<>`, it shows the
`resume` and `destroy` function pointers. For a non-type-erased
`coroutine_handle` it also shows the `promise` value.

With this change, executing the `v t` command on the example from
https://clang.llvm.org/docs/DebuggingCoroutines.html now outputs

```
(task) t = {
  handle = coro frame = 0xb2a0 {
resume = 0x5a10 (a.out`coro_task(int, int) at 
llvm-example.cpp:36)
destroy = 0x6090 (a.out`coro_task(int, int) at 
llvm-example.cpp:36)
  }
}
```

instead of just

```
(task) t = {
  handle = {
__handle_ = 0xb2a0
  }
}
```

Note, how the symbols for the `resume` and `destroy` function pointer
reveal which coroutine is stored inside the `std::coroutine_handle`.
A follow-up commit will use this fact to infer the coroutine's promise
type and the representation of its internal coroutine state based on
the `resume` and `destroy` pointers.

The same formatter is used for both libc++ and libstdc++. It would
also work for MSVC's standard library, however it is not registered
for MSVC, given that lldb does not provide pretty printers for other
MSVC types, either.

The formatter is in a newly added  `Coroutines.{h,cpp}` file because there
does not seem to be an already existing place where we could share
formatters across libc++ and libstdc++. Also, I expect this code to grow
as we improve debugging experience for coroutines further.

**Testing**

* Added API test

Differential Revision: https://reviews.llvm.org/D132415

Added: 
lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
lldb/source/Plugins/Language/CPlusPlus/Coroutines.h

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/Makefile

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp

Modified: 
clang/docs/tools/clang-formatted-files.txt
lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/packages/Python/lldbsuite/test/lldbutil.py
lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Removed: 




diff  --git a/clang/docs/tools/clang-formatted-files.txt 
b/clang/docs/tools/clang-formatted-files.txt
index f89e19ca7cd3a..c49acfaec58aa 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -4180,6 +4180,8 @@ 
lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
 lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h
 lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
 lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h
+lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+lldb/source/Plugins/Language/CPlusPlus/Coroutines.h
 lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
 lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
 lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h

diff  --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py 
b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 69bb5ac5629e4..1c090395e6c4c 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -292,8 +292,12 @@ def check_value(self, test_base, val, error_msg=None):
 test_base.assertEqual(self.expect_type, val.GetDisplayTypeName(),
   this_error_msg)
 if self.expect_summary:
-test_base.assertEqual(self.expect_summary, val.GetSummary(),
-  this_error_msg)
+if isinstance(self.expect_summary, re.Pattern):
+test_base.assertRegex(val.GetSummary(), self.expect_summary,
+  this_error_msg)
+else:
+test_base.assertEqual(self.expect_summary, val.GetSummary(),
+  this_error_msg)
 if self.children is not None:
 self.check_value_children(test_base, val, error_msg)
 

diff  --git a/lldb/packages/Python/lldbsuite/test/lldbutil.py 
b/lldb/packages/Python/lldbsuite/test/lldbutil.py
index 8bd49c742cb04..7e64afb3639cd 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbutil.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbutil.py
@@ -988,6 +988,21 @@ def