@@ -28,11 +28,13 @@ Scanning heap for Fiber objects...
2828
2929Found 12 fiber(s):
3030
31- Fiber #0: <VALUE:0x7f8a1c800000>
32- Status: RESUMED
33- Stack: 0x7f8a1d000000
31+ Fiber #0: <T_DATA@...> → <struct rb_fiber_struct@...>
32+ Status: SUSPENDED
33+ Stack: <void *@...>
34+ VM Stack: <VALUE *@...>
35+ CFP: <rb_control_frame_t@...>
3436
35- Fiber #1: <VALUE:0x7f8a1c800100 >
37+ Fiber #1: <T_DATA@...> → <struct rb_fiber_struct@... >
3638 Status: SUSPENDED
3739 ...
3840~~~
@@ -75,18 +77,18 @@ See Ruby-level call stacks for all fibers at once:
7577(gdb) rb-fiber-scan-stack-trace-all
7678Found 12 fiber(s)
7779
78- Fiber #0: <VALUE:0x7f8a1c800000 >
80+ Fiber #0: <T_DATA@...> → <struct rb_fiber_struct@... >
7981 Status: RESUMED
8082 [No backtrace - fiber is running]
8183
82- Fiber #1: <VALUE:0x7f8a1c800100 >
84+ Fiber #1: <T_DATA@...> → <struct rb_fiber_struct@... >
8385 Status: SUSPENDED
8486 /app/lib/connection.rb:123:in `read'
8587 /app/lib/connection.rb:89:in `receive'
8688 /app/lib/server.rb:56:in `handle_client'
8789 ...
8890
89- Fiber #5: <VALUE:0x7f8a1c800500 >
91+ Fiber #5: <T_DATA@...> → <struct rb_fiber_struct@... >
9092 Status: SUSPENDED
9193 Exception: IOError: Connection reset
9294 /app/lib/connection.rb:45:in `write'
@@ -104,13 +106,20 @@ The most powerful feature: switch GDB's view to a fiber's stack (even in core du
104106~~~
105107(gdb) rb-fiber-scan-heap
106108(gdb) rb-fiber-scan-switch 5
107- Switched to Fiber #5
109+ Switching to Fiber #5: VALUE 0x...
110+ Switched to Fiber: <T_DATA@...> → <struct rb_fiber_struct@...>
108111 Status: SUSPENDED
109-
110- Now you can use standard GDB commands with this fiber's context:
111- rb-stack-trace # Show combined backtrace
112- bt # Show C backtrace
113- info locals # Show C local variables
112+
113+ Convenience variables set:
114+ $fiber = Current fiber VALUE
115+ $fiber_ptr = Current fiber pointer (struct rb_fiber_struct *)
116+ $ec = Execution context (rb_execution_context_t *)
117+ $errinfo = Exception being handled (VALUE)
118+
119+ Now try:
120+ bt # Show C backtrace of fiber
121+ rb-stack-trace # Show combined Ruby/C backtrace
122+ info locals # Show local variables
114123~~~
115124
116125After switching, all standard GDB commands work with the fiber's context:
@@ -145,147 +154,21 @@ Return to normal stack view:
145154
146155## Analyzing Fiber State
147156
148- ### VM Stack Inspection
149-
150- View the Ruby VM stack for a fiber:
151-
152- ~~~
153- (gdb) rb-fiber-vm-stack 5
154- VM Stack for Fiber #5:
155- Base: 0x7f8a1c950000
156- Size: 4096 VALUEs (32768 bytes)
157- CFP: 0x7f8a1c951000
158- ~~~
159-
160- ### VM Control Frames
161-
162- Walk through each Ruby method frame:
163-
164- ~~~
165- (gdb) rb-fiber-vm-frames 5
166- VM Control Frames for Fiber #5:
167- ...
168-
169- Frame #0 (depth 45):
170- CFP Address: 0x7f8a1c951000
171- PC: 0x7f8a1c234500
172- SP: 0x7f8a1c950100
173- Location: /app/lib/connection.rb:123
174- Method: read
175- Frame Type: VM_FRAME_MAGIC_METHOD
176- Stack Depth: 256 slots
177- ~~~
178-
179- ### Stack Top Values
180-
181- See what's on top of the VM stack:
182-
183- ~~~
184- (gdb) rb-fiber-stack-top 5 20
185- VM Stack Top for Fiber #5:
186-
187- Top 20 VALUE(s) on stack (newest first):
188-
189- [ -1] 0x00007f8a1c888888 T_STRING "Hello"
190- [ -2] 0x0000000000000015 Fixnum(10) Fixnum: 10
191- [ -3] 0x00007f8a1c999999 T_HASH <hash:0x7f8a1c999999>
192- ...
193- ~~~
194-
195- ## Diagnosing Crashes
196-
197- When Ruby crashes, find out why:
198-
199- ~~~
200- (gdb) rb-diagnose-exit
201- ================================================================================
202- DIAGNOSING RUBY EXIT/CRASH
203- ================================================================================
204-
205- [1] Main Thread Exception:
206- --------------------------------------------------------------------------------
207- Main thread has exception: NoMethodError
208- VALUE: 0x7f8a1c777777
209- Use: rb-object-print (VALUE)0x7f8a1c777777
210-
211- [2] Fibers with Exceptions:
212- --------------------------------------------------------------------------------
213- Fiber #5 (SUSPENDED): RuntimeError
214- Fiber: 0x7f8a1c800500, errinfo: 0x7f8a1c666666
215- Fiber #8 (SUSPENDED): IOError
216- Fiber: 0x7f8a1c800800, errinfo: 0x7f8a1c555555
217-
218- [3] Interrupt Flags:
219- --------------------------------------------------------------------------------
220- interrupt_flag: 0x00000002
221- interrupt_mask: 0x00000000
222- WARNING: Interrupts pending!
223- - TRAP
224-
225- [4] Signal Information (from core dump):
226- --------------------------------------------------------------------------------
227- Program terminated with signal SIGSEGV, Segmentation fault.
228- ...
229- ~~~
230-
231- This comprehensive overview helps quickly identify the root cause.
232-
233- ## Advanced Techniques
234-
235- ### Finding Fibers by Stack Address
236-
237- If you know a stack address, find the owning fiber:
157+ After switching to a fiber with ` rb-fiber-scan-switch ` , you can use standard GDB commands to inspect the fiber's state:
238158
239159~~~
240- (gdb) info frame
241- ... rsp = 0x7f8a1e000500 ...
242-
243- (gdb) rb-fiber-from-stack 0x7f8a1e000000
244- Searching for fiber with stack base 0x7f8a1e000000...
245-
246- Found fiber: 0x7f8a1c800300
247- Status: SUSPENDED
248- Stack: base=0x7f8a1e000000, size=1048576
249- ~~~
250-
251- ### Searching Fibers by Function
252-
253- Find which fibers are blocked in a specific C function:
254-
255- ~~~
256- (gdb) rb-fiber-c-stack-search pthread_cond_wait
257- Scanning 12 fiber(s)...
258-
259- Match: Fiber #3 - found at 0x7f8a1e000450
260- Match: Fiber #7 - found at 0x7f8a1e100780
261-
262- Search complete: 2 fiber(s) matched.
263- ~~~
264-
265- Use this to find all fibers waiting on locks or I/O.
266-
267- ### Debug Unwinder Issues
268-
269- If fiber switching doesn't work as expected:
270-
160+ (gdb) rb-fiber-scan-switch 5
161+ (gdb) bt # Show C backtrace
162+ (gdb) frame <n> # Switch to specific frame
163+ (gdb) info locals # Show local variables
164+ (gdb) rb-object-print $errinfo # Print exception if present
271165~~~
272- (gdb) rb-fiber-debug-unwind 5
273- Debug unwinding for Fiber #5: 0x7f8a1c800500
274-
275- Coroutine context:
276- fiber->context.stack_pointer = 0x7f8a1e000480
277166
278- Saved registers on coroutine stack:
279- [0x7f8a1e000480+0] = R15: 0x0000000000000000
280- [0x7f8a1e000480+8] = R14: 0x00007f8a1c567890
281- ...
282- [0x7f8a1e000480+48] = RIP: 0x00007f8a1ab12345
283-
284- Validation:
285- ✓ RIP looks like a valid code address
286- Symbol: fiber_setcontext + 123
287- ✓ RSP is within fiber's stack range
288- ~~~
167+ The fiber switch command sets up several convenience variables:
168+ - ` $fiber ` - The fiber VALUE
169+ - ` $fiber_ptr ` - Pointer to ` struct rb_fiber_struct `
170+ - ` $ec ` - The fiber's execution context
171+ - ` $errinfo ` - Exception being handled (if any)
289172
290173## Best Practices
291174
@@ -306,10 +189,10 @@ The cache persists throughout your GDB session.
306189CREATED and TERMINATED fibers may not have valid saved contexts. The scan output shows status:
307190
308191~~~
309- Fiber #5: <VALUE:0x7f8a1c800500 >
192+ Fiber #5: <T_DATA@...> → <struct rb_fiber_struct@... >
310193 Status: TERMINATED # Won't have useful context
311194
312- Fiber #3: <VALUE:0x7f8a1c800300 >
195+ Fiber #3: <T_DATA@...> → <struct rb_fiber_struct@... >
313196 Status: SUSPENDED # Good candidate for inspection
314197~~~
315198
0 commit comments