├── README.md └── gdb_macros_for_ruby /README.md: -------------------------------------------------------------------------------- 1 | A collection of macros for GNU debugger (gdb), useful for 2 | inspection of Ruby processes. 3 | 4 | Originally written by Jamis Buck and Mauricio Fernandez, 5 | collected by Phillippe Hanrigou. 6 | 7 | And slightly improved by @the83 and @ebenoist 8 | 9 | Command | Description 10 | -------------- |------------ 11 | reval | Evaluate an arbitrary Ruby expression from current gdb context. 12 | rb_bt | Print the ruby stack trace interpreting backtrace as a Ruby array of string. 13 | rb_raise | Raise a Ruby exception from gdb. 14 | redirect_stdout | Hijack Ruby $stdout and redirect it to /tmp/ruby-debug-. 15 | restore_stdout | Restore Ruby $stdout to its original value after hijacking it> 16 | rb_finish | Execute the current Ruby method until it returns and interrupts th> 17 | rb_object_counts| Count and print all living objects by type. 18 | rb_locals | Print local variables and their values. 19 | rb_backtrace | Print the Ruby backtrace. 20 | rb_classname | 21 | rb_p | 22 | rb_help | Print a list of all ruby macros 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /gdb_macros_for_ruby: -------------------------------------------------------------------------------- 1 | ################################################################### 2 | # Jamis Buck's Tricks 3 | ################################################################### 4 | 5 | define rb_bt 6 | set $ary = backtrace(-1) 7 | set $count = ((struct RArray) *$ary).len 8 | set $index = 0 9 | while $index < $count 10 | x/1s ((struct RString) *rb_ary_entry($ary, $index) ).ptr 11 | set $index = $index + 1 12 | end 13 | end 14 | document rb_bt 15 | Print the ruby stack trace interpreting backtrace as a Ruby array of string. 16 | end 17 | 18 | define rb_raise 19 | call rb_raise(rb_eException, "Forced exception from GDB to get a valid ruby stack trace") 20 | end 21 | document rb_raise 22 | Raise a Ruby exception from gdb. 23 | end 24 | 25 | ################################################################### 26 | # Mauricio Fernandez's Ruby macros (Eigenclass.org) 27 | ################################################################### 28 | 29 | define reval 30 | call(rb_p(rb_eval_string_protect($arg0,(int*)0))) 31 | end 32 | document reval 33 | Evaluate an arbitrary Ruby expression from current gdb context. You should always call rb_finish before calling reval for the first time. 34 | end 35 | 36 | define redirect_stdout 37 | call rb_eval_string("$_old_stdout, $stdout = $stdout, File.open('/tmp/ruby-debug.' + Process.pid.to_s, 'a'); $stdout.sync = true") 38 | end 39 | document redirect_stdout 40 | Hijack Ruby $stdout and redirect it to /tmp/ruby-debug-. 41 | Useful to redirect ruby macro output to a separate file. 42 | end 43 | 44 | define restore_stdout 45 | call rb_eval_string("$stdout = $_old_stdout") 46 | end 47 | document restore_stdout 48 | Restore Ruby $stdout to its original value after hijacking it with 49 | redirect_stdout. 50 | end 51 | 52 | define rb_finish 53 | call rb_eval_string_protect("set_trace_func lambda{|event, file, line, id, binding, classname| if /return/ =~ event; sleep 0; set_trace_func(nil) end}",(int*)0) 54 | tbreak rb_f_sleep 55 | cont 56 | end 57 | document rb_finish 58 | Execute the current Ruby method until it returns and interrupts the 59 | process at a safe point (the rb_f_sleep function). You should 60 | always call this macro before evaling Ruby code in gdb. 61 | end 62 | 63 | define rb_object_counts 64 | call rb_eval_string_protect("counts = Hash.new{|h,k| h[k] = 0}; ObjectSpace.each_object{|o| counts[o.class] += 1}; counts.sort_by{|k,c| c}.reverse.each{|k,c| puts '%7d %s' % [c, k] } ",(int*)0) 65 | end 66 | document rb_object_counts 67 | Count and print all living objects by type. 68 | end 69 | 70 | define rb_locals 71 | reval "local_variables.each{|x| puts '%s = %s' % [x, eval(x.to_s)]};nil" 72 | end 73 | document rb_locals 74 | Print local variables and their values. 75 | end 76 | 77 | define rp 78 | if ($arg0 & 0x1) 79 | echo T_FIXNUM\n 80 | print (long)$arg0 >> 1 81 | else 82 | if ($arg0 == 0) 83 | echo T_FALSE\n 84 | else 85 | if ($arg0 == 2) 86 | echo T_TRUE\n 87 | else 88 | if ($arg0 == 4) 89 | echo T_NIL\n 90 | else 91 | if ($arg0 == 6) 92 | echo T_UNDEF\n 93 | else 94 | if (($arg0 & 0xff) == 0x0e) 95 | echo T_SYMBOL\n 96 | output $arg0 >> 8 97 | echo \n 98 | call rb_id2name($arg0 >> 8) 99 | else 100 | set $rbasic = (struct RBasic*)$arg0 101 | # output $rbasic 102 | # echo \ =\ 103 | # output *$rbasic 104 | # echo \n 105 | set $flags = (*$rbasic).flags & 0x3f 106 | if ($flags == 0x01) 107 | echo T_NIL\n 108 | echo impossible\n 109 | else 110 | if ($flags == 0x02) 111 | echo T_OBJECT\n 112 | print *(struct RObject*)$rbasic 113 | else 114 | if ($flags == 0x03) 115 | echo T_CLASS\n 116 | # rb_classname($arg0) 117 | else 118 | if ($flags == 0x04) 119 | echo T_ICLASS\n 120 | print *(struct RClass*)$rbasic 121 | else 122 | if ($flags == 0x05) 123 | echo T_MODULE\n 124 | print *(struct RClass*)$rbasic 125 | else 126 | if ($flags == 0x06) 127 | echo T_FLOAT\n 128 | print *(struct RFloat*)$rbasic 129 | else 130 | if ($flags == 0x07) 131 | echo T_STRING\n 132 | print *(struct RString*)$rbasic 133 | else 134 | if ($flags == 0x08) 135 | echo T_REGEXP\n 136 | print *(struct RRegexp*)$rbasic 137 | else 138 | if ($flags == 0x09) 139 | echo T_ARRAY\n 140 | print *(struct RArray*)$rbasic 141 | else 142 | if ($flags == 0x0a) 143 | echo T_FIXNUM\n 144 | echo impossible\n 145 | else 146 | if ($flags == 0x0b) 147 | echo T_HASH\n 148 | print *(struct RHash*)$rbasic 149 | else 150 | if ($flags == 0x0c) 151 | echo T_STRUCT\n 152 | print *(struct RStruct*)$rbasic 153 | else 154 | if ($flags == 0x0d) 155 | echo T_BIGNUM\n 156 | print *(struct RBignum*)$rbasic 157 | else 158 | if ($flags == 0x0e) 159 | echo T_FILE\n 160 | print *(struct RFile*)$rbasic 161 | else 162 | if ($flags == 0x20) 163 | echo T_TRUE\n 164 | echo impossible\n 165 | else 166 | if ($flags == 0x21) 167 | echo T_FALSE\n 168 | echo impossible\n 169 | else 170 | if ($flags == 0x22) 171 | echo T_DATA\n 172 | print *(struct RData*)$rbasic 173 | else 174 | if ($flags == 0x23) 175 | echo T_MATCH\n 176 | print *(struct RMatch*)$rbasic 177 | else 178 | if ($flags == 0x24) 179 | echo T_SYMBOL\n 180 | echo impossible\n 181 | else 182 | if ($flags == 0x3c) 183 | echo T_UNDEF\n 184 | echo impossible\n 185 | else 186 | if ($flags == 0x3d) 187 | echo T_VARMAP\n 188 | else 189 | if ($flags == 0x3e) 190 | echo T_SCOPE\n 191 | else 192 | if ($flags == 0x3f) 193 | echo T_NODE\n 194 | print (NODE*)$arg0 195 | else 196 | echo Unknown\n 197 | end 198 | end 199 | end 200 | end 201 | end 202 | end 203 | end 204 | end 205 | end 206 | end 207 | end 208 | end 209 | end 210 | end 211 | end 212 | end 213 | end 214 | end 215 | end 216 | end 217 | end 218 | end 219 | end 220 | 221 | end 222 | end 223 | end 224 | end 225 | end 226 | end 227 | end 228 | document rp 229 | rubyの組み込みオブジェクトを表示する 230 | end 231 | 232 | define nd_type 233 | print nodetype($arg0) 234 | end 235 | document nd_type 236 | ruby node の型を表示 237 | end 238 | 239 | define nd_file 240 | print ((NODE*)$arg0)->nd_file 241 | end 242 | document nd_file 243 | node のソースファイル名を表示 244 | end 245 | 246 | define nd_line 247 | print nodeline($arg0) 248 | end 249 | document nd_line 250 | node の行番号を表示 251 | end 252 | 253 | # ruby node のメンバを表示 254 | 255 | define nd_head 256 | print "u1.node" 257 | what $arg0.u1.node 258 | p $arg0.u1.node 259 | end 260 | 261 | define nd_alen 262 | print "u2.argc" 263 | what $arg0.u2.argc 264 | p $arg0.u2.argc 265 | end 266 | 267 | define nd_next 268 | print "u3.node" 269 | what $arg0.u3.node 270 | p $arg0.u3.node 271 | end 272 | 273 | 274 | define nd_cond 275 | print "u1.node" 276 | what $arg0.u1.node 277 | p $arg0.u1.node 278 | end 279 | 280 | define nd_body 281 | print "u2.node" 282 | what $arg0.u2.node 283 | p $arg0.u2.node 284 | end 285 | 286 | define nd_else 287 | print "u3.node" 288 | what $arg0.u3.node 289 | p $arg0.u3.node 290 | end 291 | 292 | 293 | define nd_orig 294 | print "u3.value" 295 | what $arg0.u3.value 296 | p $arg0.u3.value 297 | end 298 | 299 | 300 | define nd_resq 301 | print "u2.node" 302 | what $arg0.u2.node 303 | p $arg0.u2.node 304 | end 305 | 306 | define nd_ensr 307 | print "u3.node" 308 | what $arg0.u3.node 309 | p $arg0.u3.node 310 | end 311 | 312 | 313 | define nd_1st 314 | print "u1.node" 315 | what $arg0.u1.node 316 | p $arg0.u1.node 317 | end 318 | 319 | define nd_2nd 320 | print "u2.node" 321 | what $arg0.u2.node 322 | p $arg0.u2.node 323 | end 324 | 325 | 326 | define nd_stts 327 | print "u1.node" 328 | what $arg0.u1.node 329 | p $arg0.u1.node 330 | end 331 | 332 | 333 | define nd_entry 334 | print "u3.entry" 335 | what $arg0.u3.entry 336 | p $arg0.u3.entry 337 | end 338 | 339 | define nd_vid 340 | print "u1.id" 341 | what $arg0.u1.id 342 | p $arg0.u1.id 343 | end 344 | 345 | define nd_cflag 346 | print "u2.id" 347 | what $arg0.u2.id 348 | p $arg0.u2.id 349 | end 350 | 351 | define nd_cval 352 | print "u3.value" 353 | what $arg0.u3.value 354 | p $arg0.u3.value 355 | end 356 | 357 | 358 | define nd_cnt 359 | print "u3.cnt" 360 | what $arg0.u3.cnt 361 | p $arg0.u3.cnt 362 | end 363 | 364 | define nd_tbl 365 | print "u1.tbl" 366 | what $arg0.u1.tbl 367 | p $arg0.u1.tbl 368 | end 369 | 370 | 371 | define nd_var 372 | print "u1.node" 373 | what $arg0.u1.node 374 | p $arg0.u1.node 375 | end 376 | 377 | define nd_ibdy 378 | print "u2.node" 379 | what $arg0.u2.node 380 | p $arg0.u2.node 381 | end 382 | 383 | define nd_iter 384 | print "u3.node" 385 | what $arg0.u3.node 386 | p $arg0.u3.node 387 | end 388 | 389 | 390 | define nd_value 391 | print "u2.node" 392 | what $arg0.u2.node 393 | p $arg0.u2.node 394 | end 395 | 396 | define nd_aid 397 | print "u3.id" 398 | what $arg0.u3.id 399 | p $arg0.u3.id 400 | end 401 | 402 | 403 | define nd_lit 404 | print "u1.value" 405 | what $arg0.u1.value 406 | p $arg0.u1.value 407 | end 408 | 409 | 410 | define nd_frml 411 | print "u1.node" 412 | what $arg0.u1.node 413 | p $arg0.u1.node 414 | end 415 | 416 | define nd_rest 417 | print "u2.argc" 418 | what $arg0.u2.argc 419 | p $arg0.u2.argc 420 | end 421 | 422 | define nd_opt 423 | print "u1.node" 424 | what $arg0.u1.node 425 | p $arg0.u1.node 426 | end 427 | 428 | 429 | define nd_recv 430 | print "u1.node" 431 | what $arg0.u1.node 432 | p $arg0.u1.node 433 | end 434 | 435 | define nd_mid 436 | print "u2.id" 437 | what $arg0.u2.id 438 | p $arg0.u2.id 439 | end 440 | 441 | define nd_args 442 | print "u3.node" 443 | what $arg0.u3.node 444 | p $arg0.u3.node 445 | end 446 | 447 | 448 | define nd_noex 449 | print "u1.id" 450 | what $arg0.u1.id 451 | p $arg0.u1.id 452 | end 453 | 454 | define nd_defn 455 | print "u3.node" 456 | what $arg0.u3.node 457 | p $arg0.u3.node 458 | end 459 | 460 | 461 | define nd_old 462 | print "u1.id" 463 | what $arg0.u1.id 464 | p $arg0.u1.id 465 | end 466 | 467 | define nd_new 468 | print "u2.id" 469 | what $arg0.u2.id 470 | p $arg0.u2.id 471 | end 472 | 473 | 474 | define nd_cfnc 475 | print "u1.cfunc" 476 | what $arg0.u1.cfunc 477 | p $arg0.u1.cfunc 478 | end 479 | 480 | define nd_argc 481 | print "u2.argc" 482 | what $arg0.u2.argc 483 | p $arg0.u2.argc 484 | end 485 | 486 | 487 | define nd_cname 488 | print "u1.id" 489 | what $arg0.u1.id 490 | p $arg0.u1.id 491 | end 492 | 493 | define nd_super 494 | print "u3.node" 495 | what $arg0.u3.node 496 | p $arg0.u3.node 497 | end 498 | 499 | 500 | define nd_modl 501 | print "u1.id" 502 | what $arg0.u1.id 503 | p $arg0.u1.id 504 | end 505 | 506 | define nd_clss 507 | print "u1.value" 508 | what $arg0.u1.value 509 | p $arg0.u1.value 510 | end 511 | 512 | 513 | define nd_beg 514 | print "u1.node" 515 | what $arg0.u1.node 516 | p $arg0.u1.node 517 | end 518 | 519 | define nd_end 520 | print "u2.node" 521 | what $arg0.u2.node 522 | p $arg0.u2.node 523 | end 524 | 525 | define nd_state 526 | print "u3.state" 527 | what $arg0.u3.state 528 | p $arg0.u3.state 529 | end 530 | 531 | define nd_rval 532 | print "u2.value" 533 | what $arg0.u2.value 534 | p $arg0.u2.value 535 | end 536 | 537 | 538 | define nd_nth 539 | print "u2.argc" 540 | what $arg0.u2.argc 541 | p $arg0.u2.argc 542 | end 543 | 544 | 545 | define nd_tag 546 | print "u1.id" 547 | what $arg0.u1.id 548 | p $arg0.u1.id 549 | end 550 | 551 | define nd_tval 552 | print "u2.value" 553 | what $arg0.u2.value 554 | p $arg0.u2.value 555 | end 556 | 557 | define rb_p 558 | call rb_p($arg0) 559 | end 560 | 561 | define rb_id2name 562 | call rb_id2name($arg0) 563 | end 564 | 565 | define rb_classname 566 | call classname($arg0) 567 | rb_p $ 568 | p *(struct RClass*)$arg0 569 | end 570 | 571 | define rb_backtrace 572 | call rb_backtrace() 573 | end 574 | 575 | define rb_help 576 | printf "List of Ruby Macros:\n" 577 | printf "\n" 578 | printf "rb_bt -- Print the ruby stack trace interpreting backtrace as a Ruby array of string.\n" 579 | printf "rb_raise -- Raise a Ruby exception from gdb.\n" 580 | printf "reval -- Evaluate an arbitrary Ruby expression from current gdb context.\n" 581 | printf "redirect_stdout -- Hijack Ruby $stdout and redirect it to /tmp/ruby-debug-.\n" 582 | printf "restore_stdout -- Restore Ruby $stdout to its original value after hijacking it with redirect_stdout.\n" 583 | printf "rb_finish -- Execute the current Ruby method until it returns and interrupts the process at a safe point (the rb_f_sleep function).\n" 584 | printf "rb_object_counts -- Count and print all living objects by type.\n" 585 | printf "rb_locals -- Print local variables and their values.\n" 586 | printf "rb_backtrace -- Print the Ruby backtrace.\n" 587 | printf "rb_classname -- \n" 588 | printf "rb_p -- \n" 589 | printf "rb_help -- Print a list of all ruby macros\n" 590 | end 591 | 592 | 593 | echo \n\n*********** Loaded Ruby Macros Successfully **********\n 594 | echo \n**** Use rb_help to see all available Ruby Macros ****\n 595 | --------------------------------------------------------------------------------