1define set_ts 2 set $tsrm_ls = $arg0 3end 4 5document set_ts 6 set the ts resource, it is impossible for gdb to 7 call ts_resource_ex while no process is running, 8 but we could get the resource from the argument 9 of frame info. 10end 11 12define ____executor_globals 13 if basic_functions_module.zts 14 set $tsrm_ls = _tsrm_ls_cache 15 set $eg = ((zend_executor_globals*) (*((void ***) $tsrm_ls))[executor_globals_id-1]) 16 set $cg = ((zend_compiler_globals*) (*((void ***) $tsrm_ls))[compiler_globals_id-1]) 17 set $eg_ptr = $eg 18 else 19 set $eg = executor_globals 20 set $cg = compiler_globals 21 set $eg_ptr = (zend_executor_globals*) &executor_globals 22 end 23end 24 25document ____executor_globals 26 portable way of accessing executor_globals, set $eg 27 this also sets compiler_globals to $cg 28 ZTS detection is automatically based on ext/standard module struct 29end 30 31define print_cvs 32 if $argc == 0 33 ____executor_globals 34 set $cv_ex_ptr = $eg.current_execute_data 35 else 36 set $cv_ex_ptr = (zend_execute_data *)$arg0 37 end 38 set $cv_count = $cv_ex_ptr.func.op_array.last_var 39 set $cv = $cv_ex_ptr.func.op_array.vars 40 set $cv_idx = 0 41 set $callFrameSize = (sizeof(zend_execute_data) + sizeof(zval) - 1) / sizeof(zval) 42 43 printf "Compiled variables count: %d\n\n", $cv_count 44 while $cv_idx < $cv_count 45 printf "[%d] '%s'\n", $cv_idx, $cv[$cv_idx].val 46 set $zvalue = ((zval *) $cv_ex_ptr) + $callFrameSize + $cv_idx 47 printzv $zvalue 48 set $cv_idx = $cv_idx + 1 49 end 50end 51 52document print_cvs 53 Prints the compiled variables and their values. 54 If a zend_execute_data pointer is set this will print the compiled 55 variables of that scope. If no parameter is used it will use 56 current_execute_data for scope. 57 58 usage: print_cvs [zend_execute_data *] 59end 60 61define dump_bt 62 set $ex = $arg0 63 while $ex 64 printf "[%p] ", $ex 65 set $func = $ex->func 66 if $func 67 if $ex->This->value.obj 68 if $func->common.scope 69 printf "%s->", $func->common.scope->name->val 70 else 71 printf "%s->", $ex->This->value.obj->ce.name->val 72 end 73 else 74 if $func->common.scope 75 printf "%s::", $func->common.scope->name->val 76 end 77 end 78 79 if $func->common.function_name 80 printf "%s(", $func->common.function_name->val 81 else 82 printf "(main" 83 end 84 85 set $callFrameSize = (sizeof(zend_execute_data) + sizeof(zval) - 1) / sizeof(zval) 86 87 set $count = $ex->This.u2.num_args 88 set $arg = 0 89 while $arg < $count 90 if $arg > 0 91 printf ", " 92 end 93 94 set $zvalue = (zval *) $ex + $callFrameSize + $arg 95 set $type = $zvalue->u1.v.type 96 if $type == 1 97 printf "NULL" 98 end 99 if $type == 2 100 printf "false" 101 end 102 if $type == 3 103 printf "true" 104 end 105 if $type == 4 106 printf "%ld", $zvalue->value.lval 107 end 108 if $type == 5 109 printf "%f", $zvalue->value.dval 110 end 111 if $type == 6 112 ____print_str $zvalue->value.str->val $zvalue->value.str->len 113 end 114 if $type == 7 115 printf "array(%d)[%p]", $zvalue->value.arr->nNumOfElements, $zvalue 116 end 117 if $type == 8 118 printf "object[%p]", $zvalue 119 end 120 if $type == 9 121 printf "resource(#%d)", $zvalue->value.lval 122 end 123 if $type == 10 124 printf "reference" 125 end 126 if $type > 10 127 printf "unknown type %d", $type 128 end 129 set $arg = $arg + 1 130 end 131 132 printf ") " 133 else 134 printf "??? " 135 end 136 if $func != 0 137 if $func->type == 2 138 printf "%s:%d ", $func->op_array.filename->val, $ex->opline->lineno 139 else 140 printf "[internal function]" 141 end 142 end 143 set $ex = $ex->prev_execute_data 144 printf "\n" 145 end 146end 147 148document dump_bt 149 dumps the current execution stack. usage: dump_bt executor_globals.current_execute_data 150end 151 152define printzv 153 set $ind = 1 154 ____printzv $arg0 0 155end 156 157document printzv 158 prints zval contents 159end 160 161define ____printzv_contents 162 set $zvalue = $arg0 163 set $type = $zvalue->u1.v.type 164 165 # 15 == IS_INDIRECT 166 if $type > 5 && $type < 12 167 printf "(refcount=%d) ", $zvalue->value.counted->gc.refcount 168 end 169 170 if $type == 0 171 printf "UNDEF" 172 end 173 if $type == 1 174 printf "NULL" 175 end 176 if $type == 2 177 printf "bool: false" 178 end 179 if $type == 3 180 printf "bool: true" 181 end 182 if $type == 4 183 printf "long: %ld", $zvalue->value.lval 184 end 185 if $type == 5 186 printf "double: %f", $zvalue->value.dval 187 end 188 if $type == 6 189 printf "string: %s", $zvalue->value.str->val 190 end 191 if $type == 7 192 printf "array: " 193 if ! $arg1 194 set $ind = $ind + 1 195 ____print_ht $zvalue->value.arr 1 196 set $ind = $ind - 1 197 set $i = $ind 198 while $i > 0 199 printf " " 200 set $i = $i - 1 201 end 202 end 203 set $type = 0 204 end 205 if $type == 8 206 printf "object" 207 ____executor_globals 208 set $handle = $zvalue->value.obj.handle 209 set $handlers = $zvalue->value.obj.handlers 210 set $zobj = $zvalue->value.obj 211 set $cname = $zobj->ce->name->val 212 printf "(%s) #%d", $cname, $handle 213 if ! $arg1 214 if $handlers->get_properties == &zend_std_get_properties 215 if $zobj->properties 216 printf "\nProperties " 217 set $ht = $zobj->properties 218 set $ind = $ind + 1 219 ____print_ht $ht 1 220 set $ind = $ind - 1 221 set $i = $ind 222 while $i > 0 223 printf " " 224 set $i = $i - 1 225 end 226 else 227 printf " {\n" 228 set $ht = &$zobj->ce->properties_info 229 set $k = 0 230 set $num = $ht->nNumUsed 231 while $k < $num 232 set $p = (Bucket*)($ht->arData + $k) 233 set $name = $p->key 234 set $prop = (zend_property_info*)$p->val.value.ptr 235 set $val = (zval*)((char*)$zobj + $prop->offset) 236 printf "%s => ", $name->val 237 printzv $val 238 set $k = $k + 1 239 end 240 end 241 end 242 end 243 set $type = 0 244 end 245 if $type == 9 246 printf "resource: #%d", $zvalue->value.res->handle 247 end 248 if $type == 10 249 printf "reference: " 250 ____printzv &$zvalue->value.ref->val $arg1 251 end 252 if $type == 11 253 printf "const: %s", $zvalue->value.str->val 254 end 255 if $type == 12 256 printf "CONSTANT_AST" 257 end 258 if $type == 13 259 printf "indirect: " 260 ____printzv $zvalue->value.zv $arg1 261 end 262 if $type == 14 263 printf "pointer: %p", $zvalue->value.ptr 264 end 265 if $type == 15 266 printf "_ERROR" 267 end 268 if $type == 16 269 printf "_BOOL" 270 end 271 if $type == 17 272 printf "CALLABLE" 273 end 274 if $type == 18 275 printf "ITERABLE" 276 end 277 if $type == 19 278 printf "VOID" 279 end 280 if $type == 20 281 printf "_NUMBER" 282 end 283 if $type > 20 284 printf "unknown type %d", $type 285 end 286 printf "\n" 287end 288 289define ____printzv 290 ____executor_globals 291 set $zvalue = $arg0 292 293 printf "[%p] ", $zvalue 294 295 set $zcontents = (zval*) $zvalue 296 if $arg1 297 ____printzv_contents $zcontents $arg1 298 else 299 ____printzv_contents $zcontents 0 300 end 301end 302 303define print_global_vars 304 ____executor_globals 305 set $symtable = ((HashTable *)&($eg_ptr->symbol_table)) 306 print_ht $symtable 307end 308 309document print_global_vars 310 Prints the global variables 311end 312 313define print_const_table 314 set $ind = 1 315 printf "[%p] {\n", $arg0 316 ____print_ht $arg0 4 317 printf "}\n" 318end 319 320document print_const_table 321 Dumps elements of Constants HashTable 322 Example: print_const_table executor_globals.zend_constants 323end 324 325define ____print_ht 326 set $ht = (HashTable*)$arg0 327 set $n = $ind 328 while $n > 0 329 printf " " 330 set $n = $n - 1 331 end 332 333 if $ht->u.v.flags & 4 334 printf "Packed" 335 else 336 printf "Hash" 337 end 338 printf "(%d)[%p]: {\n", $ht->nNumOfElements, $ht 339 340 set $num = $ht->nNumUsed 341 set $i = 0 342 set $ind = $ind + 1 343 while $i < $num 344 set $p = (Bucket*)($ht->arData + $i) 345 set $n = $ind 346 if $p->val.u1.v.type > 0 347 while $n > 0 348 printf " " 349 set $n = $n - 1 350 end 351 printf "[%d] ", $i 352 if $p->key 353 ____print_str $p->key->val $p->key->len 354 printf " => " 355 else 356 printf "%d => ", $p->h 357 end 358 if $arg1 == 0 359 printf "%p\n", (zval *)&$p->val 360 end 361 if $arg1 == 1 362 set $zval = (zval *)&$p->val 363 ____printzv $zval 1 364 end 365 if $arg1 == 2 366 printf "%s\n", (char*)$p->val.value.ptr 367 end 368 if $arg1 == 3 369 set $func = (zend_function*)$p->val.value.ptr 370 printf "\"%s\"\n", $func->common.function_name->val 371 end 372 if $arg1 == 4 373 set $const = (zend_constant *)$p->val.value.ptr 374 ____printzv $const 1 375 end 376 end 377 set $i = $i + 1 378 end 379 set $ind = $ind - 1 380 printf "}\n" 381end 382 383define print_ht 384 set $ind = 0 385 ____print_ht $arg0 1 386end 387 388document print_ht 389 dumps elements of HashTable made of zval 390end 391 392define print_htptr 393 set $ind = 0 394 ____print_ht $arg0 0 395end 396 397document print_htptr 398 dumps elements of HashTable made of pointers 399end 400 401define print_htstr 402 set $ind = 0 403 ____print_ht $arg0 2 404end 405 406document print_htstr 407 dumps elements of HashTable made of strings 408end 409 410define print_ft 411 set $ind = 0 412 ____print_ht $arg0 3 413end 414 415document print_ft 416 dumps a function table (HashTable) 417end 418 419define ____print_inh_class 420 set $ce = $arg0 421 if $ce->ce_flags & 0x10 || $ce->ce_flags & 0x20 422 printf "abstract " 423 else 424 if $ce->ce_flags & 0x40 425 printf "final " 426 end 427 end 428 printf "class %s", $ce->name->val 429 if $ce->parent != 0 430 printf " extends %s", $ce->parent->name->val 431 end 432 if $ce->num_interfaces != 0 433 printf " implements" 434 set $tmp = 0 435 while $tmp < $ce->num_interfaces 436 printf " %s", $ce->interfaces[$tmp]->name->val 437 set $tmp = $tmp + 1 438 if $tmp < $ce->num_interfaces 439 printf "," 440 end 441 end 442 end 443 set $ce = $ce->parent 444end 445 446define ____print_inh_iface 447 set $ce = $arg0 448 printf "interface %s", $ce->name->val 449 if $ce->num_interfaces != 0 450 set $ce = $ce->interfaces[0] 451 printf " extends %s", $ce->name->val 452 else 453 set $ce = 0 454 end 455end 456 457define print_inh 458 set $ce = $arg0 459 set $depth = 0 460 while $ce != 0 461 set $tmp = $depth 462 while $tmp != 0 463 printf " " 464 set $tmp = $tmp - 1 465 end 466 set $depth = $depth + 1 467 if $ce->ce_flags & 0x80 468 ____print_inh_iface $ce 469 else 470 ____print_inh_class $ce 471 end 472 printf " {\n" 473 end 474 while $depth != 0 475 set $tmp = $depth 476 while $tmp != 1 477 printf " " 478 set $tmp = $tmp - 1 479 end 480 printf "}\n" 481 set $depth = $depth - 1 482 end 483end 484 485define print_pi 486 set $pi = (zend_property_info *)$arg0 487 set $initial_offset = ((uint32_t)(zend_uintptr_t)(&((zend_object*)0)->properties_table[(0)])) 488 set $ptr_to_val = (zval*)((char*)$pi->ce->default_properties_table + $pi->offset - $initial_offset) 489 printf "[%p] {\n", $pi 490 printf " offset = %p\n", $pi->offset 491 printf " ce = [%p] %s\n", $pi->ce, $pi->ce->name->val 492 printf " flags = 0x%x (", $pi->flags 493 if $pi->flags & 0x100 494 printf "ZEND_ACC_PUBLIC" 495 else 496 if $pi->flags & 0x200 497 printf "ZEND_ACC_PROTECTED" 498 else 499 if $pi->flags & 0x400 500 printf "ZEND_ACC_PRIVATE" 501 else 502 if $pi->flags & 0x800 503 printf "ZEND_ACC_EARLY_BINDING" 504 else 505 if $pi->flags & 0x20000 506 printf "ZEND_ACC_SHADOW" 507 end 508 end 509 end 510 end 511 end 512 printf ")\n" 513 printf " name = " 514 print_zstr $pi->name 515 printf " default value: " 516 printzv $ptr_to_val 517 printf "}\n" 518end 519 520document print_pi 521 Takes a pointer to an object's property and prints the property information 522 usage: print_pi <ptr> 523end 524 525define ____print_str 526 set $tmp = 0 527 set $str = $arg0 528 if $argc > 2 529 set $maxlen = $arg2 530 else 531 set $maxlen = 256 532 end 533 534 printf "\"" 535 while $tmp < $arg1 && $tmp < $maxlen 536 if $str[$tmp] > 31 && $str[$tmp] < 127 537 printf "%c", $str[$tmp] 538 else 539 printf "\\%o", $str[$tmp] 540 end 541 set $tmp = $tmp + 1 542 end 543 if $tmp != $arg1 544 printf "..." 545 end 546 printf "\"" 547end 548 549define printzn 550 ____executor_globals 551 set $ind = 0 552 set $znode = $arg0 553 if $znode->op_type == 1 554 set $optype = "IS_CONST" 555 end 556 if $znode->op_type == 2 557 set $optype = "IS_TMP_VAR" 558 end 559 if $znode->op_type == 4 560 set $optype = "IS_VAR" 561 end 562 if $znode->op_type == 8 563 set $optype = "IS_UNUSED" 564 end 565 566 printf "[%p] %s", $znode, $optype 567 568 if $znode->op_type == 1 569 printf ": " 570 ____printzv &$znode->u.constant 0 571 end 572 if $znode->op_type == 2 573 printf ": " 574 set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var) 575 ____printzv ((union _temp_variable *)$tvar)->tmp_var 0 576 end 577 if $znode->op_type == 4 578 printf ": " 579 set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var) 580 ____printzv *$tvar->var.ptr_ptr 0 581 end 582 if $znode->op_type == 8 583 printf "\n" 584 end 585end 586 587document printzn 588 print type and content of znode. 589 usage: printzn &opline->op1 590end 591 592define printzops 593 printf "op1 => " 594 printzn &execute_data->opline.op1 595 printf "op2 => " 596 printzn &execute_data->opline.op2 597 printf "result => " 598 printzn &execute_data->opline.result 599end 600 601document printzops 602 dump operands of the current opline 603end 604 605define print_zstr 606 set $zstr = (zend_string *)$arg0 607 if $argc == 2 608 set $maxlen = $arg1 609 else 610 set $maxlen = $zstr->len 611 end 612 printf "string(%d) ", $zstr->len 613 ____print_str $zstr->val $zstr->len $maxlen 614 printf "\n" 615end 616 617document print_zstr 618 print the length and contents of a zend string 619 usage: print_zstr <ptr> [max length] 620end 621 622define zbacktrace 623 ____executor_globals 624 dump_bt $eg.current_execute_data 625end 626 627document zbacktrace 628 prints backtrace. 629 This command is almost a short cut for 630 > (gdb) ____executor_globals 631 > (gdb) dump_bt $eg.current_execute_data 632end 633 634define lookup_root 635 set $found = 0 636 if gc_globals->roots 637 set $current = gc_globals->roots->next 638 printf "looking ref %p in roots\n", $arg0 639 while $current != &gc_globals->roots 640 if $current->ref == $arg0 641 set $found = $current 642 break 643 end 644 set $current = $current->next 645 end 646 if $found != 0 647 printf "found root %p\n", $found 648 else 649 printf "not found\n" 650 end 651 end 652end 653 654document lookup_root 655 lookup a refcounted in root 656 usage: lookup_root [ptr]. 657end 658