Commit Graph

105 Commits

Author SHA1 Message Date
Haojian Wu
b837361b80 [LLDB] Display artificial __promise and __coro_frame variables. (#71928)
See the discussion in #69309.
2023-11-14 09:06:40 +01:00
Haojian Wu
0515ccc0c4 [lldb] Fix a typo in the comment, NFC 2023-11-13 10:12:55 +01:00
Michael Buch
c3f7ca7810 [lldb][Test] TestDataFormatterLibcxxChrono.py: skip test on older clang versions (#70544)
These tests were failing on the LLDB public matrix build-bots for older
clang versions:
```
clang-7: warning: argument unused during compilation: '-nostdlib++' [-Wunused-command-line-argument]
error: invalid value 'c++20' in '-std=c++20'
note: use 'c++98' or 'c++03' for 'ISO C++ 1998 with amendments' standard
note: use 'gnu++98' or 'gnu++03' for 'ISO C++ 1998 with amendments and GNU extensions' standard
note: use 'c++11' for 'ISO C++ 2011 with amendments' standard
note: use 'gnu++11' for 'ISO C++ 2011 with amendments and GNU extensions' standard
note: use 'c++14' for 'ISO C++ 2014 with amendments' standard
note: use 'gnu++14' for 'ISO C++ 2014 with amendments and GNU extensions' standard
note: use 'c++17' for 'ISO C++ 2017 with amendments' standard
note: use 'gnu++17' for 'ISO C++ 2017 with amendments and GNU extensions' standard
note: use 'c++2a' for 'Working draft for ISO C++ 2020' standard
note: use 'gnu++2a' for 'Working draft for ISO C++ 2020 with GNU extensions' standard
make: *** [main.o] Error 1
```

The test fails because we try to compile it with `-std=c++20` (which is
required for std::chrono::{days,weeks,months,years}) on clang versions
that don't support the `-std=c++20` flag.

We could change the test to conditionally compile the C++20 parts of the
test based on the `-std=` flag and have two versions of the python
tests, one for the C++11 chrono features and one for the C++20 features.

This patch instead just disables the test on older clang versions
(because it's simpler and we don't really lose important coverage).
2023-10-30 17:08:25 +00:00
Mark de Wever
0e4264ab1e [lldb][libc++] Adds chrono data formatters.
This adds the data formatters for chrono duration typedefs.

Reviewed By: Michael137

Differential Revision: https://reviews.llvm.org/D159127
2023-10-25 19:36:47 +02:00
jeffreytan81
00d3ed6dea [Reland] Detect against invalid variant index for LibStdC++ std::variant data formatters (#69614)
This is relanding of https://github.com/llvm/llvm-project/pull/69253.
`TestTemplatePackArgs.py` is passing now.

https://github.com/llvm/llvm-project/pull/68012/files added new data
formatters for LibStdC++ std::variant.

However, this formatter can crash if std::variant's index field has
invalid value (exceeds the number of template arguments).
This can happen if the current IP stops at a place std::variant is not
initialized yet.

This patch fixes the crash by ensuring the index is a valid value and
fix GetNthTemplateArgument() to make sure it is not crashing.

Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
2023-10-24 08:44:34 -07:00
David Spickett
0dca56603b Revert "Detect against invalid variant index for LibStdC++ std::variant data formatters (#69253)"
This reverts commit 659a48f25a.

This caused another test to fail on Windows AArch64 and x86_64, and AArch64 Linux.
2023-10-18 10:25:41 +00:00
jeffreytan81
659a48f25a Detect against invalid variant index for LibStdC++ std::variant data formatters (#69253)
https://github.com/llvm/llvm-project/pull/68012/files added new data
formatters for LibStdC++ std::variant.

However, this formatter can crash if std::variant's index field has
invalid value (exceeds the number of template arguments).
This can happen if the current IP stops at a place std::variant is not
initialized yet.

This patch fixes the crash by ensuring the index is a valid value.

---------

Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
2023-10-17 17:26:05 -07:00
jeffreytan81
40c1f5b2fb Fix std::variant test failure on certain buildbot (#68139)
https://github.com/llvm/llvm-project/pull/68012 works on my CentOS Linux
and Macbook but seems to fail for certain build bots. The error log
complains "No Value" check failure for `std::variant` but not very
actionable without a reproduce.

To unblock the build bots, I am commenting out the "No Value" checks.

Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
2023-10-03 15:37:41 -07:00
jeffreytan81
1ec4330f7e Implement data formatters for LibStdC++ std::variant (#68012)
This patch implements the data formatters for LibStdC++ `std::variant`.

---------

Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
2023-10-02 17:46:41 -07:00
Michael Buch
487ab39a50 [lldb][test] Remove tests relying on deprecated std::char_traits specializations
(motivated by test failures after D157058)

With D157058 the base template for `std::char_traits` was removed from
libc++. Quoting the release notes:

```
The base template for ``std::char_traits`` has been removed. If you are using
``std::char_traits`` with types other than ``char``, ``wchar_t``, ``char8_t``,
``char16_t``, ``char32_t`` or a custom character type for which you
specialized ``std::char_traits``, your code will no longer work.
```

This patch simply removes all such instantiations to make sure the
tests that run against the latest libc++ version pass.

One could try testing the existence of this base template from within
the test source files but this doesn't seem like something we want
support.

Differential Revision: https://reviews.llvm.org/D157636
2023-08-10 19:48:44 +01:00
Jonas Devlieghere
2238dcc393 [NFC][Py Reformat] Reformat python files in lldb
This is an ongoing series of commits that are reformatting our Python
code. Reformatting is done with `black` (23.1.0).

If you end up having problems merging this commit because you have made
changes to a python file, the best way to handle that is to run `git
checkout --ours <yourfile>` and then reformat it with black.

RFC: https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style

Differential revision: https://reviews.llvm.org/D151460
2023-05-25 12:54:09 -07:00
Michael Buch
44bb442fd5 [lldb][DataFormatter] Add dereference support to libstdcpp std::shared_ptr formatter
This mimicks the implementation of the libstdcpp std::unique_ptr
formatter.

This has been attempted several years ago in
`0789722d85cf1f1fdbe2ffb2245ea0ba034a9f94` but was reverted in
`e7dd3972094c2f2fb42dc9d4d5344e54a431e2ce`.

The difference to the original patch is that we now maintain
a `$$dereference$$` member and we only store weak pointers
to the other children inside the synthetic frontend. This is
what the libc++ formatters do to prevent the recursion mentioned
in the revert commit.
2023-05-24 13:01:11 +01:00
Jeffrey Tan
25159ee3af Fix libstdc++ data formatter for reference/pointer to std::string
This patch fixes libstdc++ data formatter for reference/pointer to std::string.
The failure testcases are added which succeed with the patch.

Differential Revision: https://reviews.llvm.org/D150313
2023-05-12 10:09:58 -07:00
Jorge Gorbe Moya
d69518b4e5 Re-land "[lldb] Make the libcxx unique_ptr prettyprinter support custom deleters."
This reverts commit 4535112010.
2023-05-01 16:19:01 -07:00
Jorge Gorbe Moya
4535112010 Revert "[lldb] Make the libcxx unique_ptr prettyprinter support custom deleters."
This reverts commit d366da97bd.
2023-05-01 14:14:09 -07:00
Jorge Gorbe Moya
d366da97bd [lldb] Make the libcxx unique_ptr prettyprinter support custom deleters.
The unique_ptr prettyprinter calls `GetValueOfLibCXXCompressedPair`,
which looks for a `__value_` child. However, when the second value in
the compressed pair is not an empty class, there are two `__value_`
children because `__compressed_pair` derives twice from
`__compressed_pair_elem`, one for each member of the pair. And then the
lookup fails because it's ambiguous.

This patch makes the following changes:

- Rename `GetValueOfLibCXXCompressedPair` to
  `GetFirstValueOfLibCXXCompressedPair`, and add a similar function to
  get the second value. Put both functions in
  Plugin/Language/CPlusPlus/LibCxx.cpp because it seems inappropriate to
  have libcxx-specific helpers separate from all the libcxx-dependent
  code.

- Read the second value of the `__ptr_` pair and display a "deleter"
  child in the unique_ptr synthetic child provider, when available.

- Add a test case for the non-empty deleter case.

Differential Revision: https://reviews.llvm.org/D148662
2023-05-01 13:08:04 -07:00
Jorge Gorbe Moya
3c91d01634 [lldb] Build libcxx unique_ptr and shared_ptr test programs with -glldb.
The functionality added by https://reviews.llvm.org/D145803 is gated by
lldb tuning, so we need to build the test programs with `-glldb` to make
these tests print the expected preferred name.

Differential Revision: https://reviews.llvm.org/D148582
2023-04-17 17:03:29 -07:00
Michael Buch
1414a5bdfe [lldb][DataFormatter] Fix libcxx std::deque formatter for references and pointers
(Addresses GH#62153)

The `SBType` APIs to retrieve details about template arguments,
such as `GetTemplateArgumentType` or `GetTemplateArgumentKind`
don't "desugar" LValueReferences/RValueReferences or pointers.
So when we try to format a `std::deque&`, the python call to
`GetTemplateArgumentType` fails to get a type, leading to
an `element_size` of `0` and a division-by-zero python exception
(which gets caught by the summary provider silently). This leads
to the contents of such `std::deque&` to be printed incorrectly.

This patch dereferences the reference/pointer before calling
into the above SBAPIs.

**Testing**

* Add API test

Differential Revision: https://reviews.llvm.org/D148531
2023-04-17 21:31:30 +01:00
Michael Buch
711a644127 [clang][DebugInfo] Emit DW_AT_type of preferred name if available
With this patch, whenever we emit a `DW_AT_type` for some declaration
and the type is a template class with a `clang::PreferredNameAttr`, we
will emit the typedef that the attribute refers to instead. I.e.,

```
0x123 DW_TAG_variable
        DW_AT_name "var"
        DW_AT_type (0x123 "basic_string<char>")

0x124 DW_TAG_structure_type
        DW_AT_name "basic_string<char>"
```
...becomes
```
0x123 DW_TAG_variable
        DW_AT_name "var"
        DW_AT_type (0x124 "std::string")

0x124 DW_TAG_structure_type
        DW_AT_name "basic_string<char>"

0x125 DW_TAG_typedef
        DW_AT_name "std::string"
        DW_AT_type (0x124 "basic_string<char>")
```

We do this by returning the preferred name typedef `DIType` when
we create a structure definition. In some cases, e.g., with `-gmodules`,
we don't complete the structure definition immediately but do so later
via `completeClassData`, which overwrites the `TypeCache`. In such cases
we don't actually want to rewrite the cache with the preferred name. We
handle this by returning both the definition and the preferred typedef
from `CreateTypeDefinition` and let the callee decide what to do with
it.

Essentially we set up the types as:
```
TypeCache[Record] => DICompositeType
ReplaceMap[Record] => DIDerivedType(baseType: DICompositeType)
```

For now we keep this behind LLDB tuning.

**Testing**

- Added clang unit-test
- `check-llvm`, `check-clang` pass
- Confirmed that this change correctly repoints
  `basic_string` references in some of my test programs.
- Will add follow-up LLDB API tests

Differential Revision: https://reviews.llvm.org/D145803
2023-04-07 01:37:36 +01:00
Michael Buch
ad81d019a6 [lldb][Test] Check compiler in data forammter compiler version checks
**Summary**

The compiler version check wouldn't make sense for non-GCC
compilers, so check for the compiler too.

Differential Revision: https://reviews.llvm.org/D143656
2023-02-10 01:37:26 +00:00
Michael Buch
3c66729887 [lldb][Test] Fix import-std-module and data-formatter tests on older compilers
Fixes API tests for older compilers.
Since https://reviews.llvm.org/D141828 defaulted
arguments will be omitted, but older Clang's won't.

Differential Revision: https://reviews.llvm.org/D143022
2023-02-02 11:34:07 +00:00
Adrian Vogelsgesang
8aa3137551 [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
2023-01-31 07:40:31 -08:00
Michael Buch
ce6a56e667 Reland "[lldb] Add support for DW_AT_default_value in template params"
**Summary**

This patch makes LLDB understand the `DW_AT_default_value` on
template argument DIEs. As a result, type summaries will no
longer contain the defaulted template arguments, reducing
noise substantially. E.g.,

Before:
```
(lldb) v nested
(std::vector<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator <char> > > > > >) nested = size=0 {}
```

After:
```
(lldb) v nested
(std::vector<std::vector<std::basic_string<char> > >) nested = size=0 {}
```

See discussion in https://reviews.llvm.org/D140423

**Testing**

* Adjust API tests
* Added unit-test

Differential Revision: https://reviews.llvm.org/D141828
2023-01-27 22:49:46 +00:00
Dave Lee
47f0384bb9 [lldb][test] Set minimum compiler_versions
Set compiler_versions on these tests, as they fail if tested on lower compiler
versions versions.

Differential Revision: https://reviews.llvm.org/D142513
2023-01-27 14:29:45 -08:00
David Spickett
1efde67d99 Revert "[lldb] Add support for DW_AT_default_value in template params"
This reverts commit 1cf52e540242f968e0cf789587bcf76c01332aeb.

Due to test failures on Arm and AArch64 bots:
https://lab.llvm.org/buildbot/#/builders/96/builds/34718

(which were obscured by an earlier build failure)
2023-01-27 11:36:42 +00:00
Michael Buch
1aee040c65 [lldb] Add support for DW_AT_default_value in template params
**Summary**

This patch makes LLDB understand the `DW_AT_default_value` on
template argument DIEs. As a result, type summaries will no
longer contain the defaulted template arguments, reducing
noise substantially. E.g.,

Before:
```
(lldb) v nested
(std::vector<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator <char> > > > > >) nested = size=0 {}
```

After:
```
(lldb) v nested
(std::vector<std::vector<std::basic_string<char> > >) nested = size=0 {}
```

See discussion in https://reviews.llvm.org/D140423

**Testing**

* Adjust API tests
* Added unit-test

Differential Revision: https://reviews.llvm.org/D141828
2023-01-27 02:24:36 +00:00
Dave Lee
4076664228 [lldb][test] Replace use of p with expression (NFC)
In API tests, replace use of the `p` alias with the `expression` command.

To avoid conflating tests of the alias with tests of the expression command,
this patch canonicalizes to the use `expression`.

Differential Revision: https://reviews.llvm.org/D141539
2023-01-25 11:03:58 -08:00
Michael Buch
9bfc8ba7a7 [lldb][Test] TestDataFormatterLibcxxRangesRefView.py: skip on old compiler versions
`std::ranges` are only available in libcxx shipped with Clang > 15.0
2023-01-03 13:12:31 +00:00
Jordan Rupprecht
3c51ea3619 [DataFormatter] Fix variant npos with _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION enabled.
This data formatter should print "No Value" if a variant is unset. It does so by checking if `__index` has a value of `-1`, however it does so by interpreting it as a signed int.

By default, `__index` has type `unsigned int`. When `_LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION` is enabled, the type of `__index` is either `unsigned char`, `unsigned short`, or `unsigned int`, depending on how many fields there are -- as small as possible. For example, when `std::variant` has only a few types, the index type is `unsigned char`, and the npos value will be interpreted by LLDB as `255` when it should be `-1`.

This change does not special case the variant optimization; it just reads the type instead of assuming it's `unsigned int`.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D138892
2022-11-30 13:20:13 -08:00
Michael Buch
77b2205245 [lldb][DataFormatter] Add std::ranges::ref_view formatter
This patch adds a formatter for `std::ranges::ref_view<T>`.
It simply holds a `T*`, so all this formatter does is dereference
this pointer and format it as `T` would be.

**Testing**

* Added API tests

Differential Revision: https://reviews.llvm.org/D138558
2022-11-30 14:39:39 +00:00
Jordan Rupprecht
7d26f9e132 [test] Allow libc++ namespaces besides __1
The libc++ data formatter for `std::shared_ptr` allows any namespace, but the test asserts that it must be the default `__1` namespace. Relax the regex to allow anything that looks like `__.*` (although we use `__[^:]*` so we don't match arbitrarily long text).

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D129898
2022-11-29 04:34:40 -08:00
Jordan Rupprecht
3c10e9c773 [test] Implement layout for unstable std::string garbage formatter tests.
The layout is essentially just reversed from the stable std::string layout.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D138850
2022-11-29 04:22:30 -08:00
Jason Molenda
2b2f2f6614 Revert "[LLDB] Recognize std::noop_coroutine() in std::coroutine_handle pretty printer"
This reverts commit 4346318f5c.

This test case is failing on macOS, reverting until it can be
looked at more closely to unblock the macOS CI bots.

```
  File "/Volumes/work/llvm/llvm-project/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py", line 121, in test_libcpp
    self.do_test(USE_LIBCPP)
  File "/Volumes/work/llvm/llvm-project/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py", line 45, in do_test
    self.expect_expr("noop_hdl",
  File "/Volumes/work/llvm/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 2441, in expect_expr
    value_check.check_value(self, eval_result, str(eval_result))
  File "/Volumes/work/llvm/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 306, in check_value
    test_base.assertEqual(self.expect_summary, val.GetSummary(),
AssertionError: 'noop_coroutine' != 'coro frame = 0x100004058'
- noop_coroutine+ coro frame = 0x100004058 : (std::coroutine_handle<void>) $1 = coro frame = 0x100004058 {
  resume = 0x0000000100003344 (a.out`___lldb_unnamed_symbol223)
  destroy = 0x0000000100003344 (a.out`___lldb_unnamed_symbol223)
}
Checking SBValue: (std::coroutine_handle<void>) $1 = coro frame = 0x100004058 {
  resume = 0x0000000100003344 (a.out`___lldb_unnamed_symbol223)
  destroy = 0x0000000100003344 (a.out`___lldb_unnamed_symbol223)
}
```

Those lldb_unnamed_symbols are synthetic names that ObjectFileMachO
adds to the symbol table, most often seen with stripped binaries,
based off of the function start addresses for all the functions -
if a function has no symbol name, lldb adds one of these names.
This change was originally landed via https://reviews.llvm.org/D132624
2022-11-25 12:32:33 -08:00
Jason Molenda
f6d4e68717 Revert "[LLDB] Do not dereference promise pointer in coroutine_handle pretty printer"
This reverts commit cd3091a88f.

This change crashes on macOS systems in
formatters::StdlibCoroutineHandleSyntheticFrontEnd when
it fails to create the `ValueObjectSP promise` and calls
a method on it.  The failure causes a segfault while running
TestCoroutineHandle.py on the "LLDB Incremental" CI bot,
https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/

This change originally landed via https://reviews.llvm.org/D132815
2022-11-25 12:22:58 -08:00
Adrian Vogelsgesang
cd3091a88f [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
2022-11-20 14:26:36 -08:00
Adrian Vogelsgesang
4346318f5c [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<void>) $3 = coro frame = 0x555555559058 {
  resume = 0x00005555555564f0 (a.out`std::__1::coroutine_handle<std::__1::noop_coroutine_promise>::__noop_coroutine_frame_ty_::__dummy_resume_destroy_func() at noop_coroutine_handle.h:79)
  destroy = 0x00005555555564f0 (a.out`std::__1::coroutine_handle<std::__1::noop_coroutine_promise>::__noop_coroutine_frame_ty_::__dummy_resume_destroy_func() at noop_coroutine_handle.h:79)
}
```

we now print

```
(std::coroutine_handle<void>) $3 = noop_coroutine
```

Differential Revision: https://reviews.llvm.org/D132735
2022-11-20 11:18:52 -08:00
Adrian Vogelsgesang
fb61dce1ad [lldb] Fix test expectation in TestCoroutineHandle.py for 32-bit systems 2022-11-20 10:30:29 -08:00
Adrian Vogelsgesang
01f4c305fa 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<task, void>::promise_type) __promise = {
  continuation = coro frame = 0x555555562430 {
    resume = 0x0000555555556310 (a.out`task detail::chain_fn<1>() at llvm-nested-example.cpp:66)
    destroy = 0x0000555555556700 (a.out`task detail::chain_fn<1>() at llvm-nested-example.cpp:66)
    promise = {
      continuation = coro frame = 0x5555555623e0 {
        resume = 0x0000555555557070 (a.out`task detail::chain_fn<2>() at llvm-nested-example.cpp:66)
        destroy = 0x0000555555557460 (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<task, void>::promise_type) __promise = {
  continuation = coro frame = 0x555555562430 {
    resume = 0x0000555555556310 (a.out`task detail::chain_fn<1>() at llvm-nested-example.cpp:66)
    destroy = 0x0000555555556700 (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
2022-11-20 06:35:16 -08:00
Dave Lee
8f121a3f18 [lldb] Update regex to be less fragile in TestDataFormatterGenericUnordered
Follow up to D129386 where libc++ naming conventions were made consistent.

This changes the pattern to not rely on the internal name (`__cc` or `__cc_`),
and instead uses a pattern to check that the child has the form:

```
[0] = {
  first = ...
```

Thanks to @rupprecht for pointing out this issue: https://reviews.llvm.org/D133259#3773120

Reviewed By: rupprecht

Differential Revision: https://reviews.llvm.org/D133395
2022-11-11 11:42:56 -08:00
Adrian Vogelsgesang
d7e1c2770f Revert "[LLDB] Devirtualize coroutine promise types for std::coroutine_handle"
This reverts commit 558db77870 due to
buildbot failures on ARM
* https://lab.llvm.org/buildbot/#/builders/96/builds/31416
* https://lab.llvm.org/buildbot/#/builders/17/builds/30086
2022-11-11 10:00:58 -08:00
Adrian Vogelsgesang
558db77870 [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<task, void>::promise_type) __promise = {
  continuation = coro frame = 0x555555562430 {
    resume = 0x0000555555556310 (a.out`task detail::chain_fn<1>() at llvm-nested-example.cpp:66)
    destroy = 0x0000555555556700 (a.out`task detail::chain_fn<1>() at llvm-nested-example.cpp:66)
    promise = {
      continuation = coro frame = 0x5555555623e0 {
        resume = 0x0000555555557070 (a.out`task detail::chain_fn<2>() at llvm-nested-example.cpp:66)
        destroy = 0x0000555555557460 (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<task, void>::promise_type) __promise = {
  continuation = coro frame = 0x555555562430 {
    resume = 0x0000555555556310 (a.out`task detail::chain_fn<1>() at llvm-nested-example.cpp:66)
    destroy = 0x0000555555556700 (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
2022-11-11 09:37:08 -08:00
Adrian Prantl
79e522fb44 Revert "Skip crashing test"
This reverts commit c1ce19021da0cf1c88722024e6ff9cee7aabc7b6.
2022-09-26 17:17:47 -07:00
Felipe de Azevedo Piovezan
10a35632d5 [lldb] Skip tests incompatible with older versions of Clang
The coroutine tests require a standard library implementation of
coroutines, which was only made available some time _after_ Clang 13.
The first such Clang tested by the LLDB matrix bot is 15.0.1

The TestObjCExceptions test forces the use of the system's libcxx. For
the lldb matrix bot, the first Clang version compatible with the bot's
libraries is 13.0.

Differential Revision: https://reviews.llvm.org/D134645
2022-09-26 13:27:51 -04:00
Adrian Prantl
8599cb002b Skip crashing test 2022-09-12 09:48:42 -07:00
Adrian Prantl
2f4a66eed6 Adapt LLDB dataformatters for libcxx change D129386
Differential Revision: https://reviews.llvm.org/D133618
2022-09-09 15:58:55 -07:00
Adrian Prantl
c988965efb Temporarily XFAIL libcxx tests.
These tests started failing on green dragon after a configuration change that compiles tests using the just-built libcxx. We may need to force the system libcxx here, or change LLDB to import the std module from the just-built libcxx, too.
2022-09-09 10:43:03 -07:00
Dave Lee
a2ec18ee04 [lldb] From unordered_map synthetic provider, return std::pair children
Change the behavior of the libc++ `unordered_map` synthetic provider to present
children as `std::pair` values, just like `std::map` does.

The synthetic provider for libc++ `std::unordered_map` has returned children
that expose a level of internal structure (over top of the key/value pair). For
example, given an unordered map initialized with `{{1,2}, {3, 4}}`, the output
is:

```
(std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<const int, int> > >) map = size=2 {
  [0] = {
    __cc = (first = 3, second = 4)
  }
  [1] = {
    __cc = (first = 1, second = 2)
  }
}
```

It's not ideal/necessary to have the numbered children embdedded in the `__cc`
field.

Note: the numbered children have type
`std::__hash_node<std::__hash_value_type<Key, T>, void *>::__node_value_type`,
and the `__cc` fields have type `std::__hash_value_type<Key, T>::value_type`.

Compare this output to `std::map`:

```
(std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >) map = size=2 {
  [0] = (first = 1, second = 2)
  [1] = (first = 3, second = 4)
```

Where the numbered children have type `std::pair<const Key, T>`.

This changes the behavior of the synthetic provider for `unordered_map` to also
present children as `pairs`, just like `std::map`.

It appears the synthetic provider implementation for `unordered_map` was meant
to provide this behavior, but was maybe incomplete (see
d22a94377f). It has both an `m_node_type` and an
`m_element_type`, but uses only the former. The latter is exactly the type
needed for the children pairs. With this existing code, it's not much of a
change to make this work.

Differential Revision: https://reviews.llvm.org/D117383
2022-09-02 08:53:46 -07:00
Pavel Labath
afdfb3ae6b [lldb] Skip TestCoroutineHandle.py on libstdc++<11 2022-08-26 14:04:04 +02:00
Adrian Vogelsgesang
6f88388f61 [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
2022-08-25 17:11:57 -07:00
Adrian Vogelsgesang
91389000ab [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<promise_type>` 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 = 0x55555555b2a0 {
    resume = 0x0000555555555a10 (a.out`coro_task(int, int) at llvm-example.cpp:36)
    destroy = 0x0000555555556090 (a.out`coro_task(int, int) at llvm-example.cpp:36)
  }
}
```

instead of just

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

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
2022-08-24 14:40:53 -07:00