# \[RFC\] Debug info for coroutine suspension locations

**URL:** <https://discourse.llvm.org/t/rfc-debug-info-for-coroutine-suspension-locations/64721>\
**Category:** LLVM Project\
**Tags:** debuginfo, clang\
**Created:** [August 19, 2022, 5:00pm UTC](https://discourse.llvm.org/t/rfc-debug-info-for-coroutine-suspension-locations/64721 "2022-08-19T17:00:14Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![avogelsgesang](https://sea1.discourse-cdn.com/flex021/user_avatar/discourse.llvm.org/avogelsgesang/32/2282_2.png) [@avogelsgesang](https://discourse.llvm.org/u/avogelsgesang)\
**Post date:** [August 19, 2022, 5:00pm UTC](https://discourse.llvm.org/t/rfc-debug-info-for-coroutine-suspension-locations/64721/1 "2022-08-19T17:00:14Z")

</div>

Hi,

I am trying to improve the debugging experience for C++20 coroutines. In particular, I want to get the exact location where a coroutine is suspended by inspecting a `std::coroutine_handle` in the debugger. Currently, I can already get the id of the current suspension point id by printing the coroutine frame (see [the example in our docs](https://clang.llvm.org/docs/DebuggingCoroutines.html#examples-to-print-coroutine-frames)). However, the suspension point id `__coro_index` is only displayed as an integer.

There is currently no good way to map this compiler-internal id back to a source location. One previously proposed approach is [to keep track of the suspension point explicitly](https://clang.llvm.org/docs/DebuggingCoroutines.html#get-the-suspended-points) by using `std::source_location`. However, this approach requires changes to the coroutine types and will be cumbersome for library-defined coroutine types like `std::generator`.

**My proposal**

In my mental model, the suspension point id is not a plain integer but rather an enum: Only a subset of the integer values are valid, and each of those integer values has an associated meaning, representing a certain point at which the coroutine was suspended.

If I follow this line of thought and represent the suspension point id as the enum

```auto
enum suspension_point {
      line_32_col_4,
      line_45_col_8,
      line_50_col_4,
      final_suspend
};

```

lldb and gdb print the coroutine frame as

```auto
$1 = {
  __resume_fn = 0x555555555940 <test(int&)>,
  __destroy_fn = 0x555555555f10 <test(int&)>,
  __promise = {<No data fields>},
  __suspension_point =__ suspension_point::line_45_col_8,
  ...

```

instead of

```auto
$1 = {
  __resume_fn = 0x555555555940 <test(int&)>,
  __destroy_fn = 0x555555555f10 <test(int&)>,
  __promise = {<No data fields>},
  __suspension_point = 1 '001',
  ...

```

Note how the value of `__suspension_point` directly tells me where my coroutine was suspended.

A draft implementation can be found at [⚙ D132240 [Coroutine][Debug] Add line and column number to suspension point id](https://reviews.llvm.org/D132240)

One downside of this approach (already brought up by @ChuanqiXu in the review): Encoding the source code location as enum values will store them as strings in the debug info, and thereby lead to a larger debug size compared to an normal, integer encoding of line/column numbers.

What do you think about this approach? Is there a better way to associate the suspension point ids with source code locations? Are we fine with the size increase which the additional strings will cause?

---

_[View the full topic](https://discourse.llvm.org/t/rfc-debug-info-for-coroutine-suspension-locations/64721)._
