[AMDGPU][AsmParser][NFC] Get rid of custom default operand handlers.
[llvm-project.git] / clang / docs / DebuggingCoroutines.rst
blob591d2eadabe531d464fbef80db5e3064ffca1aec
1 ========================
2 Debugging C++ Coroutines
3 ========================
5 .. contents::
6    :local:
8 Introduction
9 ============
11 For performance and other architectural reasons, the C++ Coroutines feature in
12 the Clang compiler is implemented in two parts of the compiler.  Semantic
13 analysis is performed in Clang, and Coroutine construction and optimization
14 takes place in the LLVM middle-end.
16 However, this design forces us to generate insufficient debugging information.
17 Typically, the compiler generates debug information in the Clang frontend, as
18 debug information is highly language specific. However, this is not possible
19 for Coroutine frames because the frames are constructed in the LLVM middle-end.
21 To mitigate this problem, the LLVM middle end attempts to generate some debug
22 information, which is unfortunately incomplete, since much of the language
23 specific information is missing in the middle end.
25 This document describes how to use this debug information to better debug
26 coroutines.
28 Terminology
29 ===========
31 Due to the recent nature of C++20 Coroutines, the terminology used to describe
32 the concepts of Coroutines is not settled.  This section defines a common,
33 understandable terminology to be used consistently throughout this document.
35 coroutine type
36 --------------
38 A `coroutine function` is any function that contains any of the Coroutine
39 Keywords `co_await`, `co_yield`, or `co_return`.  A `coroutine type` is a
40 possible return type of one of these `coroutine functions`.  `Task` and
41 `Generator` are commonly referred to coroutine types.
43 coroutine
44 ---------
46 By technical definition, a `coroutine` is a suspendable function. However,
47 programmers typically use `coroutine` to refer to an individual instance.
48 For example:
50 .. code-block:: c++
52   std::vector<Task> Coros; // Task is a coroutine type.
53   for (int i = 0; i < 3; i++)
54     Coros.push_back(CoroTask()); // CoroTask is a coroutine function, which
55                                  // would return a coroutine type 'Task'.
57 In practice, we typically say "`Coros` contains 3 coroutines" in the above
58 example, though this is not strictly correct.  More technically, this should
59 say "`Coros` contains 3 coroutine instances" or "Coros contains 3 coroutine
60 objects."
62 In this document, we follow the common practice of using `coroutine` to refer
63 to an individual `coroutine instance`, since the terms `coroutine instance` and
64 `coroutine object` aren't sufficiently defined in this case.
66 coroutine frame
67 ---------------
69 The C++ Standard uses `coroutine state` to describe the allocated storage. In
70 the compiler, we use `coroutine frame` to describe the generated data structure
71 that contains the necessary information.
73 The structure of coroutine frames
74 =================================
76 The structure of coroutine frames is defined as:
78 .. code-block:: c++
80   struct {
81     void (*__r)(); // function pointer to the `resume` function
82     void (*__d)(); // function pointer to the `destroy` function
83     promise_type; // the corresponding `promise_type`
84     ... // Any other needed information
85   }
87 In the debugger, the function's name is obtainable from the address of the
88 function. And the name of `resume` function is equal to the name of the
89 coroutine function. So the name of the coroutine is obtainable once the
90 address of the coroutine is known.
92 Print promise_type
93 ==================
95 Every coroutine has a `promise_type`, which defines the behavior
96 for the corresponding coroutine. In other words, if two coroutines have the
97 same `promise_type`, they should behave in the same way.
98 To print a `promise_type` in a debugger when stopped at a breakpoint inside a
99 coroutine, printing the `promise_type` can be done by:
101 .. parsed-literal::
103   print __promise
105 It is also possible to print the `promise_type` of a coroutine from the address
106 of the coroutine frame. For example, if the address of a coroutine frame is
107 0x416eb0, and the type of the `promise_type` is `task::promise_type`, printing
108 the `promise_type` can be done by:
110 .. parsed-literal::
112   print (task::promise_type)*(0x416eb0+0x10)
114 This is possible because the `promise_type` is guaranteed by the ABI to be at a
115 16 bit offset from the coroutine frame.
117 Note that there is also an ABI independent method:
119 .. parsed-literal::
121   print std::coroutine_handle<task::promise_type>::from_address((void*)0x416eb0).promise()
123 The functions `from_address(void*)` and `promise()` are often small enough to
124 be removed during optimization, so this method may not be possible.
126 Print coroutine frames
127 ======================
129 LLVM generates the debug information for the coroutine frame in the LLVM middle
130 end, which permits printing of the coroutine frame in the debugger. Much like
131 the `promise_type`, when stopped at a breakpoint inside a coroutine we can
132 print the coroutine frame by:
134 .. parsed-literal::
136   print __coro_frame
139 Just as printing the `promise_type` is possible from the coroutine address,
140 printing the details of the coroutine frame from an address is also possible:
144   (gdb) # Get the address of coroutine frame
145   (gdb) print/x *0x418eb0
146   $1 = 0x4019e0
147   (gdb) # Get the linkage name for the coroutine
148   (gdb) x 0x4019e0
149   0x4019e0 <_ZL9coro_taski>:  0xe5894855
150   (gdb) # Turn off the demangler temporarily to avoid the debugger misunderstanding the name.
151   (gdb) set demangle-style none
152   (gdb) # The coroutine frame type is 'linkage_name.coro_frame_ty'
153   (gdb) print  ('_ZL9coro_taski.coro_frame_ty')*(0x418eb0)
154   $2 = {__resume_fn = 0x4019e0 <coro_task(int)>, __destroy_fn = 0x402000 <coro_task(int)>, __promise = {...}, ...}
156 The above is possible because:
158 (1) The name of the debug type of the coroutine frame is the `linkage_name`,
159 plus the `.coro_frame_ty` suffix because each coroutine function shares the
160 same coroutine type.
162 (2) The coroutine function name is accessible from the address of the coroutine
163 frame.
165 The above commands can be simplified by placing them in debug scripts.
167 Examples to print coroutine frames
168 ----------------------------------
170 The print examples below use the following definition:
172 .. code-block:: c++
174   #include <coroutine>
175   #include <iostream>
177   struct task{
178     struct promise_type {
179       task get_return_object() { return std::coroutine_handle<promise_type>::from_promise(*this); }
180       std::suspend_always initial_suspend() { return {}; }
181       std::suspend_always final_suspend() noexcept { return {}; }
182       void return_void() noexcept {}
183       void unhandled_exception() noexcept {}
185       int count = 0;
186     };
188     void resume() noexcept {
189       handle.resume();
190     }
192     task(std::coroutine_handle<promise_type> hdl) : handle(hdl) {}
193     ~task() {
194       if (handle)
195         handle.destroy();
196     }
198     std::coroutine_handle<> handle;
199   };
201   class await_counter : public std::suspend_always {
202     public:
203       template<class PromiseType>
204       void await_suspend(std::coroutine_handle<PromiseType> handle) noexcept {
205           handle.promise().count++;
206       }
207   };
209   static task coro_task(int v) {
210     int a = v;
211     co_await await_counter{};
212     a++;
213     std::cout << a << "\n";
214     a++;
215     std::cout << a << "\n";
216     a++;
217     std::cout << a << "\n";
218     co_await await_counter{};
219     a++;
220     std::cout << a << "\n";
221     a++;
222     std::cout << a << "\n";
223   }
225   int main() {
226     task t = coro_task(43);
227     t.resume();
228     t.resume();
229     t.resume();
230     return 0;
231   }
233 In debug mode (`O0` + `g`), the printing result would be:
235 .. parsed-literal::
237   {__resume_fn = 0x4019e0 <coro_task(int)>, __destroy_fn = 0x402000 <coro_task(int)>, __promise = {count = 1}, v = 43, a = 45, __coro_index = 1 '\001', struct_std__suspend_always_0 = {__int_8 = 0 '\000'},
238     class_await_counter_1 = {__int_8 = 0 '\000'}, class_await_counter_2 = {__int_8 = 0 '\000'}, struct_std__suspend_always_3 = {__int_8 = 0 '\000'}}
240 In the above, the values of `v` and `a` are clearly expressed, as are the
241 temporary values for `await_counter` (`class_await_counter_1` and
242 `class_await_counter_2`) and `std::suspend_always` (
243 `struct_std__suspend_always_0` and `struct_std__suspend_always_3`). The index
244 of the current suspension point of the coroutine is emitted as `__coro_index`.
245 In the above example, the `__coro_index` value of `1` means the coroutine
246 stopped at the second suspend point (Note that `__coro_index` is zero indexed)
247 which is the first `co_await await_counter{};` in `coro_task`. Note that the
248 first initial suspend point is the compiler generated
249 `co_await promise_type::initial_suspend()`.
251 However, when optimizations are enabled, the printed result changes drastically:
253 .. parsed-literal::
255   {__resume_fn = 0x401280 <coro_task(int)>, __destroy_fn = 0x401390 <coro_task(int)>, __promise = {count = 1}, __int_32_0 = 43, __coro_index = 1 '\001'}
257 Unused values are optimized out, as well as the name of the local variable `a`.
258 The only information remained is the value of a 32 bit integer. In this simple
259 case, it seems to be pretty clear that `__int_32_0` represents `a`. However, it
260 is not true.
262 An important note with optimization is that the value of a variable may not
263 properly express the intended value in the source code.  For example:
265 .. code-block:: c++
267   static task coro_task(int v) {
268     int a = v;
269     co_await await_counter{};
270     a++; // __int_32_0 is 43 here
271     std::cout << a << "\n";
272     a++; // __int_32_0 is still 43 here
273     std::cout << a << "\n";
274     a++; // __int_32_0 is still 43 here!
275     std::cout << a << "\n";
276     co_await await_counter{};
277     a++; // __int_32_0 is still 43 here!!
278     std::cout << a << "\n";
279     a++; // Why is __int_32_0 still 43 here?
280     std::cout << a << "\n";
281   }
283 When debugging step-by-step, the value of `__int_32_0` seemingly does not
284 change, despite being frequently incremented, and instead is always `43`.
285 While this might be surprising, this is a result of the optimizer recognizing
286 that it can eliminate most of the load/store operations. The above code gets
287 optimized to the equivalent of:
289 .. code-block:: c++
291   static task coro_task(int v) {
292     store v to __int_32_0 in the frame
293     co_await await_counter{};
294     a = load __int_32_0
295     std::cout << a+1 << "\n";
296     std::cout << a+2 << "\n";
297     std::cout << a+3 << "\n";
298     co_await await_counter{};
299     a = load __int_32_0
300     std::cout << a+4 << "\n";
301     std::cout << a+5 << "\n";
302   }
304 It should now be obvious why the value of `__int_32_0` remains unchanged
305 throughout the function. It is important to recognize that `__int_32_0`
306 does not directly correspond to `a`, but is instead a variable generated
307 to assist the compiler in code generation. The variables in an optimized
308 coroutine frame should not be thought of as directly representing the
309 variables in the C++ source.
311 Get the suspended points
312 ========================
314 An important requirement for debugging coroutines is to understand suspended
315 points, which are where the coroutine is currently suspended and awaiting.
317 For simple cases like the above, inspecting the value of the `__coro_index`
318 variable in the coroutine frame works well.
320 However, it is not quite so simple in really complex situations. In these
321 cases, it is necessary to use the coroutine libraries to insert the
322 line-number.
324 For example:
326 .. code-block:: c++
328   // For all the promise_type we want:
329   class promise_type {
330     ...
331   +  unsigned line_number = 0xffffffff;
332   };
334   #include <source_location>
336   // For all the awaiter types we need:
337   class awaiter {
338     ...
339     template <typename Promise>
340     void await_suspend(std::coroutine_handle<Promise> handle,
341                        std::source_location sl = std::source_location::current()) {
342           ...
343           handle.promise().line_number = sl.line();
344     }
345   };
347 In this case, we use `std::source_location` to store the line number of the
348 await inside the `promise_type`.  Since we can locate the coroutine function
349 from the address of the coroutine, we can identify suspended points this way
350 as well.
352 The downside here is that this comes at the price of additional runtime cost.
353 This is consistent with the C++ philosophy of "Pay for what you use".
355 Get the asynchronous stack
356 ==========================
358 Another important requirement to debug a coroutine is to print the asynchronous
359 stack to identify the asynchronous caller of the coroutine.  As many
360 implementations of coroutine types store `std::coroutine_handle<> continuation`
361 in the promise type, identifying the caller should be trivial.  The
362 `continuation` is typically the awaiting coroutine for the current coroutine.
363 That is, the asynchronous parent.
365 Since the `promise_type` is obtainable from the address of a coroutine and
366 contains the corresponding continuation (which itself is a coroutine with a
367 `promise_type`), it should be trivial to print the entire asynchronous stack.
369 This logic should be quite easily captured in a debugger script.
371 Examples to print asynchronous stack
372 ------------------------------------
374 Here is an example to print the asynchronous stack for the normal task implementation.
376 .. code-block:: c++
378   // debugging-example.cpp
379   #include <coroutine>
380   #include <iostream>
381   #include <utility>
383   struct task {
384     struct promise_type {
385       task get_return_object();
386       std::suspend_always initial_suspend() { return {}; }
387       
388       void unhandled_exception() noexcept {}
390       struct FinalSuspend {
391         std::coroutine_handle<> continuation;
392         auto await_ready() noexcept { return false; }
393         auto await_suspend(std::coroutine_handle<> handle) noexcept {
394           return continuation;
395         }
396         void await_resume() noexcept {}
397       };
398       FinalSuspend final_suspend() noexcept { return {continuation}; }
400       void return_value(int res) { result = res; }
402       std::coroutine_handle<> continuation = std::noop_coroutine();
403       int result = 0;
404     };
406     task(std::coroutine_handle<promise_type> handle) : handle(handle) {}
407     ~task() {
408       if (handle)
409         handle.destroy();
410     }
412     auto operator co_await() {
413       struct Awaiter {
414         std::coroutine_handle<promise_type> handle;
415         auto await_ready() { return false; }
416         auto await_suspend(std::coroutine_handle<> continuation) {
417           handle.promise().continuation = continuation;
418           return handle;
419         }
420         int await_resume() {
421           int ret = handle.promise().result;
422           handle.destroy();
423           return ret;
424         }
425       };
426       return Awaiter{std::exchange(handle, nullptr)};
427     }
429     int syncStart() {
430       handle.resume();
431       return handle.promise().result;
432     }
434   private:
435     std::coroutine_handle<promise_type> handle;
436   };
438   task task::promise_type::get_return_object() {
439     return std::coroutine_handle<promise_type>::from_promise(*this);
440   }
442   namespace detail {
443   template <int N>
444   task chain_fn() {
445     co_return N + co_await chain_fn<N - 1>();
446   }
448   template <>
449   task chain_fn<0>() {
450     // This is the default breakpoint.
451     __builtin_debugtrap();
452     co_return 0;
453   }
454   }  // namespace detail
456   task chain() {
457     co_return co_await detail::chain_fn<30>();
458   }
460   int main() {
461     std::cout << chain().syncStart() << "\n";
462     return 0;
463   }
465 In the example, the ``task`` coroutine holds a ``continuation`` field,
466 which would be resumed once the ``task`` completes.
467 In another word, the ``continuation`` is the asynchronous caller for the ``task``.
468 Just like the normal function returns to its caller when the function completes.
470 So we can use the ``continuation`` field to construct the asynchronous stack:
472 .. code-block:: python
474   # debugging-helper.py
475   import gdb
476   from gdb.FrameDecorator import FrameDecorator
478   class SymValueWrapper():
479       def __init__(self, symbol, value):
480           self.sym = symbol
481           self.val = value
483       def __str__(self):
484           return str(self.sym) + " = " + str(self.val)
486   def get_long_pointer_size():
487       return gdb.lookup_type('long').pointer().sizeof
489   def cast_addr2long_pointer(addr):
490       return gdb.Value(addr).cast(gdb.lookup_type('long').pointer())
492   def dereference(addr):
493       return long(cast_addr2long_pointer(addr).dereference())
495   class CoroutineFrame(object):
496       def __init__(self, task_addr):
497           self.frame_addr = task_addr
498           self.resume_addr = task_addr
499           self.destroy_addr = task_addr + get_long_pointer_size()
500           self.promise_addr = task_addr + get_long_pointer_size() * 2
501           # In the example, the continuation is the first field member of the promise_type.
502           # So they have the same addresses.
503           # If we want to generalize the scripts to other coroutine types, we need to be sure
504           # the continuation field is the first memeber of promise_type.
505           self.continuation_addr = self.promise_addr
507       def next_task_addr(self):
508           return dereference(self.continuation_addr)
510   class CoroutineFrameDecorator(FrameDecorator):
511       def __init__(self, coro_frame):
512           super(CoroutineFrameDecorator, self).__init__(None)
513           self.coro_frame = coro_frame
514           self.resume_func = dereference(self.coro_frame.resume_addr)
515           self.resume_func_block = gdb.block_for_pc(self.resume_func)
516           if self.resume_func_block == None:
517               raise Exception('Not stackless coroutine.')
518           self.line_info = gdb.find_pc_line(self.resume_func)
520       def address(self):
521           return self.resume_func
523       def filename(self):
524           return self.line_info.symtab.filename
526       def frame_args(self):
527           return [SymValueWrapper("frame_addr", cast_addr2long_pointer(self.coro_frame.frame_addr)),
528                   SymValueWrapper("promise_addr", cast_addr2long_pointer(self.coro_frame.promise_addr)),
529                   SymValueWrapper("continuation_addr", cast_addr2long_pointer(self.coro_frame.continuation_addr))
530                   ]
532       def function(self):
533           return self.resume_func_block.function.print_name
535       def line(self):
536           return self.line_info.line
538   class StripDecorator(FrameDecorator):
539       def __init__(self, frame):
540           super(StripDecorator, self).__init__(frame)
541           self.frame = frame
542           f = frame.function()
543           self.function_name = f
545       def __str__(self, shift = 2):
546           addr = "" if self.address() == None else '%#x' % self.address() + " in "
547           location = "" if self.filename() == None else " at " + self.filename() + ":" + str(self.line())
548           return addr + self.function() + " " + str([str(args) for args in self.frame_args()]) + location
550   class CoroutineFilter:
551       def create_coroutine_frames(self, task_addr):
552           frames = []
553           while task_addr != 0:
554               coro_frame = CoroutineFrame(task_addr)
555               frames.append(CoroutineFrameDecorator(coro_frame))
556               task_addr = coro_frame.next_task_addr()
557           return frames
559   class AsyncStack(gdb.Command):
560       def __init__(self):
561           super(AsyncStack, self).__init__("async-bt", gdb.COMMAND_USER)
563       def invoke(self, arg, from_tty):
564           coroutine_filter = CoroutineFilter()
565           argv = gdb.string_to_argv(arg)
566           if len(argv) == 0:
567               try:
568                   task = gdb.parse_and_eval('__coro_frame')
569                   task = int(str(task.address), 16)
570               except Exception:
571                   print ("Can't find __coro_frame in current context.\n" +
572                         "Please use `async-bt` in stackless coroutine context.")
573                   return
574           elif len(argv) != 1:
575               print("usage: async-bt <pointer to task>")
576               return
577           else:
578               task = int(argv[0], 16)
580           frames = coroutine_filter.create_coroutine_frames(task)
581           i = 0
582           for f in frames:
583               print '#'+ str(i), str(StripDecorator(f))
584               i += 1
585           return
587   AsyncStack()
589   class ShowCoroFrame(gdb.Command):
590       def __init__(self):
591           super(ShowCoroFrame, self).__init__("show-coro-frame", gdb.COMMAND_USER)
593       def invoke(self, arg, from_tty):
594           argv = gdb.string_to_argv(arg)
595           if len(argv) != 1:
596               print("usage: show-coro-frame <address of coroutine frame>")
597               return
599           addr = int(argv[0], 16)
600           block = gdb.block_for_pc(long(cast_addr2long_pointer(addr).dereference()))
601           if block == None:
602               print "block " + str(addr) + "  is none."
603               return
605           # Disable demangling since gdb will treat names starting with `_Z`(The marker for Itanium ABI) specially.
606           gdb.execute("set demangle-style none")
608           coro_frame_type = gdb.lookup_type(block.function.linkage_name + ".coro_frame_ty")
609           coro_frame_ptr_type = coro_frame_type.pointer()
610           coro_frame = gdb.Value(addr).cast(coro_frame_ptr_type).dereference()
612           gdb.execute("set demangle-style auto")
613           gdb.write(coro_frame.format_string(pretty_structs = True))
615   ShowCoroFrame()
617 Then let's run:
619 .. code-block:: text
621   $ clang++ -std=c++20 -g debugging-example.cpp -o debugging-example
622   $ gdb ./debugging-example
623   (gdb) # We've already set the breakpoint.
624   (gdb) r
625   Program received signal SIGTRAP, Trace/breakpoint trap.
626   detail::chain_fn<0> () at debugging-example2.cpp:73
627   73      co_return 0;
628   (gdb) # Executes the debugging scripts
629   (gdb) source debugging-helper.py
630   (gdb) # Print the asynchronous stack
631   (gdb) async-bt
632   #0 0x401c40 in detail::chain_fn<0>() ['frame_addr = 0x441860', 'promise_addr = 0x441870', 'continuation_addr = 0x441870'] at debugging-example.cpp:71
633   #1 0x4022d0 in detail::chain_fn<1>() ['frame_addr = 0x441810', 'promise_addr = 0x441820', 'continuation_addr = 0x441820'] at debugging-example.cpp:66
634   #2 0x403060 in detail::chain_fn<2>() ['frame_addr = 0x4417c0', 'promise_addr = 0x4417d0', 'continuation_addr = 0x4417d0'] at debugging-example.cpp:66
635   #3 0x403df0 in detail::chain_fn<3>() ['frame_addr = 0x441770', 'promise_addr = 0x441780', 'continuation_addr = 0x441780'] at debugging-example.cpp:66
636   #4 0x404b80 in detail::chain_fn<4>() ['frame_addr = 0x441720', 'promise_addr = 0x441730', 'continuation_addr = 0x441730'] at debugging-example.cpp:66
637   #5 0x405910 in detail::chain_fn<5>() ['frame_addr = 0x4416d0', 'promise_addr = 0x4416e0', 'continuation_addr = 0x4416e0'] at debugging-example.cpp:66
638   #6 0x4066a0 in detail::chain_fn<6>() ['frame_addr = 0x441680', 'promise_addr = 0x441690', 'continuation_addr = 0x441690'] at debugging-example.cpp:66
639   #7 0x407430 in detail::chain_fn<7>() ['frame_addr = 0x441630', 'promise_addr = 0x441640', 'continuation_addr = 0x441640'] at debugging-example.cpp:66
640   #8 0x4081c0 in detail::chain_fn<8>() ['frame_addr = 0x4415e0', 'promise_addr = 0x4415f0', 'continuation_addr = 0x4415f0'] at debugging-example.cpp:66
641   #9 0x408f50 in detail::chain_fn<9>() ['frame_addr = 0x441590', 'promise_addr = 0x4415a0', 'continuation_addr = 0x4415a0'] at debugging-example.cpp:66
642   #10 0x409ce0 in detail::chain_fn<10>() ['frame_addr = 0x441540', 'promise_addr = 0x441550', 'continuation_addr = 0x441550'] at debugging-example.cpp:66
643   #11 0x40aa70 in detail::chain_fn<11>() ['frame_addr = 0x4414f0', 'promise_addr = 0x441500', 'continuation_addr = 0x441500'] at debugging-example.cpp:66
644   #12 0x40b800 in detail::chain_fn<12>() ['frame_addr = 0x4414a0', 'promise_addr = 0x4414b0', 'continuation_addr = 0x4414b0'] at debugging-example.cpp:66
645   #13 0x40c590 in detail::chain_fn<13>() ['frame_addr = 0x441450', 'promise_addr = 0x441460', 'continuation_addr = 0x441460'] at debugging-example.cpp:66
646   #14 0x40d320 in detail::chain_fn<14>() ['frame_addr = 0x441400', 'promise_addr = 0x441410', 'continuation_addr = 0x441410'] at debugging-example.cpp:66
647   #15 0x40e0b0 in detail::chain_fn<15>() ['frame_addr = 0x4413b0', 'promise_addr = 0x4413c0', 'continuation_addr = 0x4413c0'] at debugging-example.cpp:66
648   #16 0x40ee40 in detail::chain_fn<16>() ['frame_addr = 0x441360', 'promise_addr = 0x441370', 'continuation_addr = 0x441370'] at debugging-example.cpp:66
649   #17 0x40fbd0 in detail::chain_fn<17>() ['frame_addr = 0x441310', 'promise_addr = 0x441320', 'continuation_addr = 0x441320'] at debugging-example.cpp:66
650   #18 0x410960 in detail::chain_fn<18>() ['frame_addr = 0x4412c0', 'promise_addr = 0x4412d0', 'continuation_addr = 0x4412d0'] at debugging-example.cpp:66
651   #19 0x4116f0 in detail::chain_fn<19>() ['frame_addr = 0x441270', 'promise_addr = 0x441280', 'continuation_addr = 0x441280'] at debugging-example.cpp:66
652   #20 0x412480 in detail::chain_fn<20>() ['frame_addr = 0x441220', 'promise_addr = 0x441230', 'continuation_addr = 0x441230'] at debugging-example.cpp:66
653   #21 0x413210 in detail::chain_fn<21>() ['frame_addr = 0x4411d0', 'promise_addr = 0x4411e0', 'continuation_addr = 0x4411e0'] at debugging-example.cpp:66
654   #22 0x413fa0 in detail::chain_fn<22>() ['frame_addr = 0x441180', 'promise_addr = 0x441190', 'continuation_addr = 0x441190'] at debugging-example.cpp:66
655   #23 0x414d30 in detail::chain_fn<23>() ['frame_addr = 0x441130', 'promise_addr = 0x441140', 'continuation_addr = 0x441140'] at debugging-example.cpp:66
656   #24 0x415ac0 in detail::chain_fn<24>() ['frame_addr = 0x4410e0', 'promise_addr = 0x4410f0', 'continuation_addr = 0x4410f0'] at debugging-example.cpp:66
657   #25 0x416850 in detail::chain_fn<25>() ['frame_addr = 0x441090', 'promise_addr = 0x4410a0', 'continuation_addr = 0x4410a0'] at debugging-example.cpp:66
658   #26 0x4175e0 in detail::chain_fn<26>() ['frame_addr = 0x441040', 'promise_addr = 0x441050', 'continuation_addr = 0x441050'] at debugging-example.cpp:66
659   #27 0x418370 in detail::chain_fn<27>() ['frame_addr = 0x440ff0', 'promise_addr = 0x441000', 'continuation_addr = 0x441000'] at debugging-example.cpp:66
660   #28 0x419100 in detail::chain_fn<28>() ['frame_addr = 0x440fa0', 'promise_addr = 0x440fb0', 'continuation_addr = 0x440fb0'] at debugging-example.cpp:66
661   #29 0x419e90 in detail::chain_fn<29>() ['frame_addr = 0x440f50', 'promise_addr = 0x440f60', 'continuation_addr = 0x440f60'] at debugging-example.cpp:66
662   #30 0x41ac20 in detail::chain_fn<30>() ['frame_addr = 0x440f00', 'promise_addr = 0x440f10', 'continuation_addr = 0x440f10'] at debugging-example.cpp:66
663   #31 0x41b9b0 in chain() ['frame_addr = 0x440eb0', 'promise_addr = 0x440ec0', 'continuation_addr = 0x440ec0'] at debugging-example.cpp:77
665 Now we get the complete asynchronous stack!
666 It is also possible to print other asynchronous stack which doesn't live in the top of the stack.
667 We can make it by passing the address of the corresponding coroutine frame to ``async-bt`` command.
669 By the debugging scripts, we can print any coroutine frame too as long as we know the address.
670 For example, we can print the coroutine frame for ``detail::chain_fn<18>()`` in the above example.
671 From the log record, we know the address of the coroutine frame is ``0x4412c0`` in the run. Then we can:
673 .. code-block:: text
675   (gdb) show-coro-frame 0x4412c0
676   {
677     __resume_fn = 0x410960 <detail::chain_fn<18>()>,
678     __destroy_fn = 0x410d60 <detail::chain_fn<18>()>,
679     __promise = {
680       continuation = {
681         _M_fr_ptr = 0x441270
682       },
683       result = 0
684     },
685     struct_Awaiter_0 = {
686       struct_std____n4861__coroutine_handle_0 = {
687         struct_std____n4861__coroutine_handle = {
688           PointerType = 0x441310
689         }
690       }
691     },
692     struct_task_1 = {
693       struct_std____n4861__coroutine_handle_0 = {
694         struct_std____n4861__coroutine_handle = {
695           PointerType = 0x0
696         }
697       }
698     },
699     struct_task__promise_type__FinalSuspend_2 = {
700       struct_std____n4861__coroutine_handle = {
701         PointerType = 0x0
702       }
703     },
704     __coro_index = 1 '\001',
705     struct_std____n4861__suspend_always_3 = {
706       __int_8 = 0 '\000'
707     }
710 Get the living coroutines
711 =========================
713 Another useful task when debugging coroutines is to enumerate the list of
714 living coroutines, which is often done with threads.  While technically
715 possible, this task is not recommended in production code as it is costly at
716 runtime. One such solution is to store the list of currently running coroutines
717 in a collection:
719 .. code-block:: c++
721   inline std::unordered_set<void*> lived_coroutines;
722   // For all promise_type we want to record
723   class promise_type {
724   public:
725       promise_type() {
726           // Note to avoid data races
727           lived_coroutines.insert(std::coroutine_handle<promise_type>::from_promise(*this).address());
728       }
729       ~promise_type() {
730           // Note to avoid data races
731           lived_coroutines.erase(std::coroutine_handle<promise_type>::from_promise(*this).address());
732       }
733   };
735 In the above code snippet, we save the address of every lived coroutine in the
736 `lived_coroutines` `unordered_set`. As before, once we know the address of the
737 coroutine we can derive the function, `promise_type`, and other members of the
738 frame. Thus, we could print the list of lived coroutines from that collection.
740 Please note that the above is expensive from a storage perspective, and requires
741 some level of locking (not pictured) on the collection to prevent data races.