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). 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 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
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
$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
$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
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?