@@ -8,7 +8,7 @@ Debugging C++ Coroutines
8
8
Introduction
9
9
============
10
10
11
- Coroutines in C++ were introduced in C++20, and their user experience for
11
+ Coroutines in C++ were introduced in C++20, and the user experience for
12
12
debugging them can still be challenging. This document guides you how to most
13
13
efficiently debug coroutines and how to navigate existing shortcomings in
14
14
debuggers and compilers.
@@ -20,7 +20,7 @@ generators section, as it will introduce foundational debugging techniques also
20
20
applicable to the debugging of asynchronous programming.
21
21
22
22
Both compilers (clang, gcc, ...) and debuggers (lldb, gdb, ...) are
23
- still improving their support for coroutines. As such, we recommend to use the
23
+ still improving their support for coroutines. As such, we recommend using the
24
24
latest available version of your toolchain.
25
25
26
26
This document focuses on clang and lldb. The screenshots show
@@ -35,20 +35,20 @@ This guide will first showcase the more polished, bleeding-edge experience, but
35
35
will also show you how to debug coroutines with older toolchains. In general,
36
36
the older your toolchain, the deeper you will have to dive into the
37
37
implementation details of coroutines (such as their ABI). The further down in
38
- this document, the more low-level, technical the content will become. If you
38
+ this document you go , the more low-level, technical the content will become. If you
39
39
are on an up-to-date toolchain, you will hopefully be able to stop reading
40
40
earlier.
41
41
42
42
Debugging generators
43
43
====================
44
44
45
- The first major use case for coroutines in C++ are generators, i.e. functions
45
+ The first major use case for coroutines in C++ are generators, i.e., functions
46
46
which can produce values via ``co_yield ``. Values are produced lazily,
47
47
on-demand. For that purpose, every time a new value is requested the coroutine
48
48
gets resumed. As soon as it reaches a ``co_yield `` and thereby returns the
49
49
requested value, the coroutine is suspended again.
50
50
51
- This logic is encapsulated in a ``generator `` type similar to
51
+ This logic is encapsulated in a ``generator `` type similar to this one:
52
52
53
53
.. code-block :: c++
54
54
@@ -77,8 +77,8 @@ This logic is encapsulated in a ``generator`` type similar to
77
77
generator(std::coroutine_handle<promise_type> h) : hdl(h) { hdl.resume(); }
78
78
~generator() { hdl.destroy(); }
79
79
80
- generator<int >& operator++() { hdl.resume(); return *this; } // resume the coroutine
81
- int operator*() const { return hdl.promise().current_value; }
80
+ generator<T >& operator++() { hdl.resume(); return *this; } // resume the coroutine
81
+ T operator*() const { return hdl.promise().current_value; }
82
82
83
83
private:
84
84
std::coroutine_handle<promise_type> hdl;
@@ -159,7 +159,7 @@ If you stop at ``++fib`` and try to step into the generator, you will first
159
159
find yourself inside ``operator++ ``. Stepping into the ``handle.resume() `` will
160
160
not work by default.
161
161
162
- This is because lldb does not step int functions from the standard library by
162
+ This is because lldb does not step into functions from the standard library by
163
163
default. To make this work, you first need to run ``settings set
164
164
target.process.thread.step-avoid-regexp "" ``. You can do so from the "Debug
165
165
Console" towards the bottom of the screen. With that setting change, you can
@@ -267,7 +267,7 @@ Async stack traces
267
267
268
268
Besides generators, the second common use case for coroutines in C++ is
269
269
asynchronous programming, usually involving libraries such as stdexec, folly,
270
- cppcoro, boost::asio or similar libraries. Some of those libraries already
270
+ cppcoro, boost::asio, or similar libraries. Some of those libraries already
271
271
provide custom debugging support, so in addition to this guide, you might want
272
272
to check out their documentation.
273
273
@@ -625,7 +625,7 @@ In practice, one would use the ``show-coro-frame`` command provided by the
625
625
626
626
LLDB comes with devirtualization support out of the box, as part of the
627
627
pretty-printer for ``std::coroutine_handle ``. Internally, this pretty-printer
628
- uses the second approach. We lookup the types in the destroy function and not
628
+ uses the second approach. We look up the types in the destroy function and not
629
629
the resume function because the resume function pointer will be set to a
630
630
nullptr as soon as a coroutine reaches its final suspension point. If we used
631
631
the resume function, devirtualization would hence fail for all coroutines that
0 commit comments