xref: /aosp_15_r20/external/grpc-grpc/src/ruby/nativedebug/README.md (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard WorkerThis package contains debug symbols that can be useful for debugging
2*cc02d7e2SAndroid Build Coastguard Workerapplications that use grpc pre-compiled binary gems.
3*cc02d7e2SAndroid Build Coastguard Worker
4*cc02d7e2SAndroid Build Coastguard WorkerAn example of a pre-compiled binary gem is `grpc-1.58.0-x86_64-linux.gem`
5*cc02d7e2SAndroid Build Coastguard Worker(as opposed to a source-built gem like `grpc-1.58.0.gem`).
6*cc02d7e2SAndroid Build Coastguard Worker
7*cc02d7e2SAndroid Build Coastguard Worker`grpc-native-debug` gems contain debug symbols which complement the
8*cc02d7e2SAndroid Build Coastguard Workernative libraries in these grpc binary gems. After fetching and unpacking a
9*cc02d7e2SAndroid Build Coastguard Workerproper `grpc-native-debug` gem, one can load the correct `.dbg` symbol file to
10*cc02d7e2SAndroid Build Coastguard Workerdebug their grpc application.
11*cc02d7e2SAndroid Build Coastguard Worker
12*cc02d7e2SAndroid Build Coastguard Worker# Background
13*cc02d7e2SAndroid Build Coastguard Worker
14*cc02d7e2SAndroid Build Coastguard Workergrpc-ruby pre-compiled binary gems are *released with debug symbols stripped*.
15*cc02d7e2SAndroid Build Coastguard WorkerAs a consequence, if you are to examine a grpc stack trace in a debugger
16*cc02d7e2SAndroid Build Coastguard Workerfor example, a lot of information will initially be missing.
17*cc02d7e2SAndroid Build Coastguard Worker
18*cc02d7e2SAndroid Build Coastguard Worker# Using grpc-native-debug
19*cc02d7e2SAndroid Build Coastguard Worker
20*cc02d7e2SAndroid Build Coastguard Worker## Finding the correct grpc-native-debug gem
21*cc02d7e2SAndroid Build Coastguard Worker
22*cc02d7e2SAndroid Build Coastguard WorkerEach `grpc-native-debug` gem is *one-to-one* with a `grpc` gem. Specifically:
23*cc02d7e2SAndroid Build Coastguard Worker
24*cc02d7e2SAndroid Build Coastguard Worker- The version of a `grpc-native-debug` gem **must match the version** of the `grpc`
25*cc02d7e2SAndroid Build Coastguard Worker  gem.
26*cc02d7e2SAndroid Build Coastguard Worker
27*cc02d7e2SAndroid Build Coastguard Worker- The ruby platform of a `grpc-native-debug` gem **must match the ruby platform** of
28*cc02d7e2SAndroid Build Coastguard Worker  the `grpc` gem.
29*cc02d7e2SAndroid Build Coastguard Worker
30*cc02d7e2SAndroid Build Coastguard WorkerSo for example, if you are debugging `grpc-1.60.1-x86_64-linux.gem`, then you
31*cc02d7e2SAndroid Build Coastguard Workerneed to fetch `grpc-native-debug-1.60.1-x86_64-linux.gem`.
32*cc02d7e2SAndroid Build Coastguard Worker
33*cc02d7e2SAndroid Build Coastguard Worker## Finding the correct .dbg symbol file
34*cc02d7e2SAndroid Build Coastguard Worker
35*cc02d7e2SAndroid Build Coastguard WorkerEach `grpc-native-debug` gem has a top-level `symbols` directory containing
36*cc02d7e2SAndroid Build Coastguard Workersymbol files ending in `.dbg`.
37*cc02d7e2SAndroid Build Coastguard Worker
38*cc02d7e2SAndroid Build Coastguard Worker`grpc` binary gems are shipped with multiple native libraries. There is one
39*cc02d7e2SAndroid Build Coastguard Workernative library for each supported *minor version* of ruby. As such,
40*cc02d7e2SAndroid Build Coastguard Worker`grpc-native-debug` gems have exactly one `.dbg` file for each native library
41*cc02d7e2SAndroid Build Coastguard Workerin the corresponding `grpc` gem.
42*cc02d7e2SAndroid Build Coastguard Worker
43*cc02d7e2SAndroid Build Coastguard WorkerIf you unpack a `grpc-native-debug` gem and look at the `symbols`
44*cc02d7e2SAndroid Build Coastguard Workerdirectory, you might see something like this:
45*cc02d7e2SAndroid Build Coastguard Worker
46*cc02d7e2SAndroid Build Coastguard Worker```
47*cc02d7e2SAndroid Build Coastguard Workergrpc-native-debug-1.60.1-x86_64-linux/symbols/grpc-1.60.1-x86_64-linux-ruby-3.0.dbg
48*cc02d7e2SAndroid Build Coastguard Workergrpc-native-debug-1.60.1-x86_64-linux/symbols/grpc-1.60.1-x86_64-linux-ruby-2.7.dbg
49*cc02d7e2SAndroid Build Coastguard Workergrpc-native-debug-1.60.1-x86_64-linux/symbols/grpc-1.60.1-x86_64-linux-ruby-3.2.dbg
50*cc02d7e2SAndroid Build Coastguard Workergrpc-native-debug-1.60.1-x86_64-linux/symbols/grpc-1.60.1-x86_64-linux-ruby-3.1.dbg
51*cc02d7e2SAndroid Build Coastguard Worker```
52*cc02d7e2SAndroid Build Coastguard Worker
53*cc02d7e2SAndroid Build Coastguard WorkerIn each of these `.dbg` files, the `ruby-<major>-<minor>` portion of the string
54*cc02d7e2SAndroid Build Coastguard Workerindicates which ruby version it's supposed to be used with.
55*cc02d7e2SAndroid Build Coastguard Worker
56*cc02d7e2SAndroid Build Coastguard WorkerSo for example, if you are debugging `grpc-1.60.1-x86_64-linux.gem` on ruby-3.0, then you
57*cc02d7e2SAndroid Build Coastguard Workerneed to use symbol file
58*cc02d7e2SAndroid Build Coastguard Worker`grpc-native-debug-1.60.1-x86_64-linux/symbols/grpc-1.60.1-x86_64-linux-ruby-3.0.dbg`.
59*cc02d7e2SAndroid Build Coastguard Worker
60*cc02d7e2SAndroid Build Coastguard Worker## Putting symbols into action (example gdb workflow)
61*cc02d7e2SAndroid Build Coastguard Worker
62*cc02d7e2SAndroid Build Coastguard WorkerThere are a variety of ways to use these symbols.
63*cc02d7e2SAndroid Build Coastguard Worker
64*cc02d7e2SAndroid Build Coastguard WorkerAs a toy example, suppose we are running an application under gdb using:
65*cc02d7e2SAndroid Build Coastguard Worker
66*cc02d7e2SAndroid Build Coastguard Worker- ruby-3.0
67*cc02d7e2SAndroid Build Coastguard Worker
68*cc02d7e2SAndroid Build Coastguard Worker- grpc-1.60.1.x86_64-linux.gem
69*cc02d7e2SAndroid Build Coastguard Worker
70*cc02d7e2SAndroid Build Coastguard WorkerAt first, in gdb we might dump a grpc-ruby stack trace looking
71*cc02d7e2SAndroid Build Coastguard Workersomething like this:
72*cc02d7e2SAndroid Build Coastguard Worker
73*cc02d7e2SAndroid Build Coastguard Worker```
74*cc02d7e2SAndroid Build Coastguard Worker(gdb) bt
75*cc02d7e2SAndroid Build Coastguard Worker#0  0x00007ffff7926e56 in epoll_wait (epfd=5, events=0x7ffff3cb4144, maxevents=100, timeout=-1) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
76*cc02d7e2SAndroid Build Coastguard Worker#1  0x00007ffff383eb9e in ?? () from /home/.rvm/gems/ruby-3.0.0/gems/grpc-1.60.1-x86_64-linux/src/ruby/lib/grpc/3.0/grpc_c.so
77*cc02d7e2SAndroid Build Coastguard Worker#2  0x00007ffff355e002 in ?? () from /home/.rvm/gems/ruby-3.0.0/gems/grpc-1.60.1-x86_64-linux/src/ruby/lib/grpc/3.0/grpc_c.so
78*cc02d7e2SAndroid Build Coastguard Worker#3  0x00007ffff38466e2 in ?? () from /home/.rvm/gems/ruby-3.0.0/gems/grpc-1.60.1-x86_64-linux/src/ruby/lib/grpc/3.0/grpc_c.so
79*cc02d7e2SAndroid Build Coastguard Worker#4  0x00007ffff35ba2ea in ?? () from /home/.rvm/gems/ruby-3.0.0/gems/grpc-1.60.1-x86_64-linux/src/ruby/lib/grpc/3.0/grpc_c.so
80*cc02d7e2SAndroid Build Coastguard Worker#5  0x00007ffff34abf6b in ?? () from /home/.rvm/gems/ruby-3.0.0/gems/grpc-1.60.1-x86_64-linux/src/ruby/lib/grpc/3.0/grpc_c.so
81*cc02d7e2SAndroid Build Coastguard Worker#6  0x00007ffff7c67ca7 in rb_nogvl (func=0x7ffff34abed3, data1=0x0, ubf=<optimized out>, data2=<optimized out>, flags=<optimized out>) at thread.c:1669
82*cc02d7e2SAndroid Build Coastguard Worker#7  0x00007ffff34ab110 in ?? () from /home/.rvm/gems/ruby-3.0.0/gems/grpc-1.60.1-x86_64-linux/src/ruby/lib/grpc/3.0/grpc_c.so
83*cc02d7e2SAndroid Build Coastguard Worker#8  0x00007ffff7c6780c in thread_do_start (th=0x555555ad16e0) at thread.c:769
84*cc02d7e2SAndroid Build Coastguard Worker#9  thread_start_func_2 (th=th@entry=0x555555ad16e0, stack_start=<optimized out>) at thread.c:822
85*cc02d7e2SAndroid Build Coastguard Worker#10 0x00007ffff7c679a6 in thread_start_func_1 (th_ptr=<optimized out>) at /home/.rvm/src/ruby-3.0.0/thread_pthread.c:994
86*cc02d7e2SAndroid Build Coastguard Worker#11 0x00007ffff78a63ec in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444
87*cc02d7e2SAndroid Build Coastguard Worker#12 0x00007ffff7926a4c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
88*cc02d7e2SAndroid Build Coastguard Worker```
89*cc02d7e2SAndroid Build Coastguard Worker
90*cc02d7e2SAndroid Build Coastguard WorkerWe could take the following steps to get more debug info:
91*cc02d7e2SAndroid Build Coastguard Worker
92*cc02d7e2SAndroid Build Coastguard Worker<h3>1) Fetch the correct grpc-native-debug gem</h3>
93*cc02d7e2SAndroid Build Coastguard Worker
94*cc02d7e2SAndroid Build Coastguard Worker```
95*cc02d7e2SAndroid Build Coastguard Workercd /home
96*cc02d7e2SAndroid Build Coastguard Workergem fetch grpc-native-debug-1.60.1.x86_64-linux.gem
97*cc02d7e2SAndroid Build Coastguard Workergem unpack grpc-native-debug-1.60.1.x86_64-linux.gem
98*cc02d7e2SAndroid Build Coastguard Worker```
99*cc02d7e2SAndroid Build Coastguard Worker
100*cc02d7e2SAndroid Build Coastguard Worker(note again the version and platform of `grpc-native-debug` must match the `grpc` gem)
101*cc02d7e2SAndroid Build Coastguard Worker
102*cc02d7e2SAndroid Build Coastguard Worker<h3>2) Load debug symbols (for ruby-3.0)</h3>
103*cc02d7e2SAndroid Build Coastguard Worker
104*cc02d7e2SAndroid Build Coastguard Worker```
105*cc02d7e2SAndroid Build Coastguard Worker(gdb) info sharedlibrary
106*cc02d7e2SAndroid Build Coastguard WorkerFrom                To                  Syms Read   Shared Object Library
107*cc02d7e2SAndroid Build Coastguard Worker...
108*cc02d7e2SAndroid Build Coastguard Worker0x00007ffff3497450  0x00007ffff3a61912  Yes (*)     /home/.rvm/gems/ruby-3.0.0/gems/grpc-1.60.1-x86_64-linux/src/ruby/lib/grpc/3.0/grpc_c.so
109*cc02d7e2SAndroid Build Coastguard Worker0x00007ffff3e78730  0x00007ffff3ea60df  Yes (*)     /home/.rvm/gems/ruby-3.0.0/gems/google-protobuf-3.24.4-x86_64-linux/lib/google/3.0/protobuf_c.so
110*cc02d7e2SAndroid Build Coastguard Worker(*): Shared library is missing debugging information.
111*cc02d7e2SAndroid Build Coastguard Worker(gdb) add-symbol-file /home/grpc-native-debug-1.60.1-x86_64-linux/symbols/grpc-1.60.1-x86_64-linux-ruby-3.0.dbg 0x00007ffff3497450
112*cc02d7e2SAndroid Build Coastguard Workeradd symbol table from file "/home/grpc-native-debug-1.60.1-x86_64-linux/symbols/grpc-1.60.1-x86_64-linux-ruby-3.0.dbg" at
113*cc02d7e2SAndroid Build Coastguard Worker	.text_addr = 0x7ffff3497450
114*cc02d7e2SAndroid Build Coastguard Worker(y or n) y
115*cc02d7e2SAndroid Build Coastguard WorkerReading symbols from /home/grpc-native-debug-1.60.1-x86_64-linux/symbols/grpc-1.60.1-x86_64-linux-ruby-3.0.dbg...
116*cc02d7e2SAndroid Build Coastguard Worker(gdb)
117*cc02d7e2SAndroid Build Coastguard Worker```
118*cc02d7e2SAndroid Build Coastguard Worker
119*cc02d7e2SAndroid Build Coastguard WorkerOur stack trace might look more like this now:
120*cc02d7e2SAndroid Build Coastguard Worker
121*cc02d7e2SAndroid Build Coastguard Worker```
122*cc02d7e2SAndroid Build Coastguard Worker(gdb) bt
123*cc02d7e2SAndroid Build Coastguard Worker#0  0x00007ffff7926e56 in epoll_wait (epfd=5, events=0x7ffff3cb4144, maxevents=100, timeout=-1) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
124*cc02d7e2SAndroid Build Coastguard Worker#1  0x00007ffff383eb9e in do_epoll_wait (ps=0x555555ad1690, deadline=...) at src/core/lib/iomgr/ev_epoll1_linux.cc:723
125*cc02d7e2SAndroid Build Coastguard Worker#2  pollset_work (ps=0x555555ad1690, worker_hdl=0x0, deadline=...) at src/core/lib/iomgr/ev_epoll1_linux.cc:1038
126*cc02d7e2SAndroid Build Coastguard Worker#3  0x00007ffff355e002 in pollset_work (pollset=<optimized out>, worker=<optimized out>, deadline=...) at src/core/lib/iomgr/ev_posix.cc:249
127*cc02d7e2SAndroid Build Coastguard Worker#4  0x00007ffff38466e2 in grpc_pollset_work (pollset=<optimized out>, worker=<optimized out>, deadline=...) at src/core/lib/iomgr/pollset.cc:48
128*cc02d7e2SAndroid Build Coastguard Worker#5  0x00007ffff35ba2ea in cq_next (cq=0x555555ad1510, deadline=..., reserved=<optimized out>) at src/core/lib/surface/completion_queue.cc:1043
129*cc02d7e2SAndroid Build Coastguard Worker#6  0x00007ffff34abf6b in run_poll_channels_loop_no_gil (arg=arg@entry=0x0) at ../../../../src/ruby/ext/grpc/rb_channel.c:663
130*cc02d7e2SAndroid Build Coastguard Worker#7  0x00007ffff7c67ca7 in rb_nogvl (func=0x7ffff34abed3 <run_poll_channels_loop_no_gil>, data1=0x0, ubf=<optimized out>, data2=<optimized out>, flags=flags@entry=0) at thread.c:1669
131*cc02d7e2SAndroid Build Coastguard Worker#8  0x00007ffff7c68138 in rb_thread_call_without_gvl (func=<optimized out>, data1=<optimized out>, ubf=<optimized out>, data2=<optimized out>) at thread.c:1785
132*cc02d7e2SAndroid Build Coastguard Worker#9  0x00007ffff34ab110 in run_poll_channels_loop (arg=<optimized out>) at ../../../../src/ruby/ext/grpc/rb_channel.c:734
133*cc02d7e2SAndroid Build Coastguard Worker#10 0x00007ffff7c6780c in thread_do_start (th=0x555555ad16e0) at thread.c:769
134*cc02d7e2SAndroid Build Coastguard Worker#11 thread_start_func_2 (th=th@entry=0x555555ad16e0, stack_start=<optimized out>) at thread.c:822
135*cc02d7e2SAndroid Build Coastguard Worker#12 0x00007ffff7c679a6 in thread_start_func_1 (th_ptr=<optimized out>) at /home/.rvm/src/ruby-3.0.0/thread_pthread.c:994
136*cc02d7e2SAndroid Build Coastguard Worker#13 0x00007ffff78a63ec in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444
137*cc02d7e2SAndroid Build Coastguard Worker#14 0x00007ffff7926a4c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
138*cc02d7e2SAndroid Build Coastguard Worker```
139*cc02d7e2SAndroid Build Coastguard Worker
140*cc02d7e2SAndroid Build Coastguard WorkerThis is better, but if we try to examine a frame closely we'll notice
141*cc02d7e2SAndroid Build Coastguard Workerthat source file information is still missing:
142*cc02d7e2SAndroid Build Coastguard Worker
143*cc02d7e2SAndroid Build Coastguard Worker```
144*cc02d7e2SAndroid Build Coastguard Worker(gdb) up
145*cc02d7e2SAndroid Build Coastguard Worker#1  0x00007ffff383eb9e in do_epoll_wait (ps=0x555555ad1690, deadline=...) at src/core/lib/iomgr/ev_epoll1_linux.cc:723
146*cc02d7e2SAndroid Build Coastguard Worker723	src/core/lib/iomgr/ev_epoll1_linux.cc: No such file or directory.
147*cc02d7e2SAndroid Build Coastguard Worker(gdb) list
148*cc02d7e2SAndroid Build Coastguard Worker718	in src/core/lib/iomgr/ev_epoll1_linux.cc
149*cc02d7e2SAndroid Build Coastguard Worker(gdb)
150*cc02d7e2SAndroid Build Coastguard Worker```
151*cc02d7e2SAndroid Build Coastguard Worker
152*cc02d7e2SAndroid Build Coastguard Worker<h3>3) Resolve source files</h3>
153*cc02d7e2SAndroid Build Coastguard Worker
154*cc02d7e2SAndroid Build Coastguard WorkerFirst, we fetch the *source* `grpc` gem at the **exact same version** of our binary
155*cc02d7e2SAndroid Build Coastguard Worker`grpc` gem:
156*cc02d7e2SAndroid Build Coastguard Worker
157*cc02d7e2SAndroid Build Coastguard Worker```
158*cc02d7e2SAndroid Build Coastguard Workercd /home
159*cc02d7e2SAndroid Build Coastguard Workergem fetch grpc-1.60.1.gem
160*cc02d7e2SAndroid Build Coastguard Workergem unpack grpc-1.60.1.gem
161*cc02d7e2SAndroid Build Coastguard Worker```
162*cc02d7e2SAndroid Build Coastguard Worker
163*cc02d7e2SAndroid Build Coastguard WorkerNow we can load those sources in gdb:
164*cc02d7e2SAndroid Build Coastguard Worker
165*cc02d7e2SAndroid Build Coastguard Worker```
166*cc02d7e2SAndroid Build Coastguard Worker(gdb) dir /home/grpc-1.60.1
167*cc02d7e2SAndroid Build Coastguard WorkerSource directories searched: /home/grpc-1.60.1:$cdir:$cwd
168*cc02d7e2SAndroid Build Coastguard Worker(gdb)
169*cc02d7e2SAndroid Build Coastguard Worker```
170*cc02d7e2SAndroid Build Coastguard Worker
171*cc02d7e2SAndroid Build Coastguard WorkerOur stack frame will might look more like this now:
172*cc02d7e2SAndroid Build Coastguard Worker
173*cc02d7e2SAndroid Build Coastguard Worker```
174*cc02d7e2SAndroid Build Coastguard Worker(gdb) list
175*cc02d7e2SAndroid Build Coastguard Workerwarning: Source file is more recent than executable.
176*cc02d7e2SAndroid Build Coastguard Worker718	  int timeout = poll_deadline_to_millis_timeout(deadline);
177*cc02d7e2SAndroid Build Coastguard Worker719	  if (timeout != 0) {
178*cc02d7e2SAndroid Build Coastguard Worker720	    GRPC_SCHEDULING_START_BLOCKING_REGION;
179*cc02d7e2SAndroid Build Coastguard Worker721	  }
180*cc02d7e2SAndroid Build Coastguard Worker722	  do {
181*cc02d7e2SAndroid Build Coastguard Worker723	    r = epoll_wait(g_epoll_set.epfd, g_epoll_set.events, MAX_EPOLL_EVENTS,
182*cc02d7e2SAndroid Build Coastguard Worker724	                   timeout);
183*cc02d7e2SAndroid Build Coastguard Worker725	  } while (r < 0 && errno == EINTR);
184*cc02d7e2SAndroid Build Coastguard Worker726	  if (timeout != 0) {
185*cc02d7e2SAndroid Build Coastguard Worker727	    GRPC_SCHEDULING_END_BLOCKING_REGION;
186*cc02d7e2SAndroid Build Coastguard Worker(gdb)
187*cc02d7e2SAndroid Build Coastguard Worker```
188*cc02d7e2SAndroid Build Coastguard Worker
189*cc02d7e2SAndroid Build Coastguard WorkerBut if we move up a few stack frames we might *still* be missing
190*cc02d7e2SAndroid Build Coastguard Workersome source information:
191*cc02d7e2SAndroid Build Coastguard Worker
192*cc02d7e2SAndroid Build Coastguard Worker```
193*cc02d7e2SAndroid Build Coastguard Worker(gdb) up
194*cc02d7e2SAndroid Build Coastguard Worker#6  0x00007ffff34abf6b in run_poll_channels_loop_no_gil (arg=arg@entry=0x0) at ../../../../src/ruby/ext/grpc/rb_channel.c:663
195*cc02d7e2SAndroid Build Coastguard Worker663	../../../../src/ruby/ext/grpc/rb_channel.c: No such file or directory.
196*cc02d7e2SAndroid Build Coastguard Worker```
197*cc02d7e2SAndroid Build Coastguard Worker
198*cc02d7e2SAndroid Build Coastguard WorkerA portion of the grpc-ruby native extension is built from a sub-directory:
199*cc02d7e2SAndroid Build Coastguard Worker`src/ruby/ext/grpc`. So we also need to add that sub-directory, to fix this:
200*cc02d7e2SAndroid Build Coastguard Worker
201*cc02d7e2SAndroid Build Coastguard Worker```
202*cc02d7e2SAndroid Build Coastguard Worker(gdb) dir /home/grpc-1.60.1/src/ruby/ext/grpc
203*cc02d7e2SAndroid Build Coastguard WorkerSource directories searched: /home/grpc-1.60.1/src/ruby/ext/grpc:/home/grpc-1.60.1:$cdir:$cwd
204*cc02d7e2SAndroid Build Coastguard Worker```
205*cc02d7e2SAndroid Build Coastguard Worker
206*cc02d7e2SAndroid Build Coastguard WorkerNote the additional info:
207*cc02d7e2SAndroid Build Coastguard Worker
208*cc02d7e2SAndroid Build Coastguard Worker```
209*cc02d7e2SAndroid Build Coastguard Worker(gdb) list
210*cc02d7e2SAndroid Build Coastguard Workerwarning: Source file is more recent than executable.
211*cc02d7e2SAndroid Build Coastguard Worker658	  gpr_mu_lock(&global_connection_polling_mu);
212*cc02d7e2SAndroid Build Coastguard Worker659	  gpr_cv_broadcast(&global_connection_polling_cv);
213*cc02d7e2SAndroid Build Coastguard Worker660	  gpr_mu_unlock(&global_connection_polling_mu);
214*cc02d7e2SAndroid Build Coastguard Worker661
215*cc02d7e2SAndroid Build Coastguard Worker662	  for (;;) {
216*cc02d7e2SAndroid Build Coastguard Worker663	    event = grpc_completion_queue_next(
217*cc02d7e2SAndroid Build Coastguard Worker664	        g_channel_polling_cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
218*cc02d7e2SAndroid Build Coastguard Worker665	    if (event.type == GRPC_QUEUE_SHUTDOWN) {
219*cc02d7e2SAndroid Build Coastguard Worker666	      break;
220*cc02d7e2SAndroid Build Coastguard Worker667	    }
221*cc02d7e2SAndroid Build Coastguard Worker(gdb)
222*cc02d7e2SAndroid Build Coastguard Worker```
223*cc02d7e2SAndroid Build Coastguard Worker
224*cc02d7e2SAndroid Build Coastguard Worker# Support
225*cc02d7e2SAndroid Build Coastguard Worker
226*cc02d7e2SAndroid Build Coastguard Workergrpc-native-debug currently only supports:
227*cc02d7e2SAndroid Build Coastguard Worker
228*cc02d7e2SAndroid Build Coastguard Worker- ruby platforms: `x86_64-linux` and `x86-linux`
229*cc02d7e2SAndroid Build Coastguard Worker
230*cc02d7e2SAndroid Build Coastguard Worker- grpc >= 1.60.0
231