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 "CONSTANT_AST" 254 end 255 if $type == 12 256 printf "indirect: " 257 ____printzv $zvalue->value.zv $arg1 258 end 259 if $type == 13 260 printf "pointer: %p", $zvalue->value.ptr 261 end 262 if $type == 15 263 printf "_ERROR" 264 end 265 if $type == 16 266 printf "_BOOL" 267 end 268 if $type == 17 269 printf "_NUMBER" 270 end 271 if $type > 17 272 printf "unknown type %d", $type 273 end 274 printf "\n" 275end 276 277define ____printzv 278 ____executor_globals 279 set $zvalue = $arg0 280 281 printf "[%p] ", $zvalue 282 283 set $zcontents = (zval*) $zvalue 284 if $arg1 285 ____printzv_contents $zcontents $arg1 286 else 287 ____printzv_contents $zcontents 0 288 end 289end 290 291define print_global_vars 292 ____executor_globals 293 set $symtable = ((HashTable *)&($eg_ptr->symbol_table)) 294 print_ht $symtable 295end 296 297document print_global_vars 298 Prints the global variables 299end 300 301define print_const_table 302 set $ind = 1 303 printf "[%p] {\n", $arg0 304 ____print_ht $arg0 4 305 printf "}\n" 306end 307 308document print_const_table 309 Dumps elements of Constants HashTable 310 Example: print_const_table executor_globals.zend_constants 311end 312 313define ____print_ht 314 set $ht = (HashTable*)$arg0 315 set $n = $ind 316 while $n > 0 317 printf " " 318 set $n = $n - 1 319 end 320 321 if $ht->u.v.flags & 4 322 printf "Packed" 323 else 324 printf "Hash" 325 end 326 printf "(%d)[%p]: {\n", $ht->nNumOfElements, $ht 327 328 set $num = $ht->nNumUsed 329 set $i = 0 330 set $ind = $ind + 1 331 while $i < $num 332 set $p = (Bucket*)($ht->arData + $i) 333 set $n = $ind 334 if $p->val.u1.v.type > 0 335 while $n > 0 336 printf " " 337 set $n = $n - 1 338 end 339 printf "[%d] ", $i 340 if $p->key 341 ____print_str $p->key->val $p->key->len 342 printf " => " 343 else 344 printf "%d => ", $p->h 345 end 346 if $arg1 == 0 347 printf "%p\n", (zval *)&$p->val 348 end 349 if $arg1 == 1 350 set $zval = (zval *)&$p->val 351 ____printzv $zval 1 352 end 353 if $arg1 == 2 354 printf "%s\n", (char*)$p->val.value.ptr 355 end 356 if $arg1 == 3 357 set $func = (zend_function*)$p->val.value.ptr 358 printf "\"%s\"\n", $func->common.function_name->val 359 end 360 if $arg1 == 4 361 set $const = (zend_constant *)$p->val.value.ptr 362 ____printzv $const 1 363 end 364 end 365 set $i = $i + 1 366 end 367 set $ind = $ind - 1 368 printf "}\n" 369end 370 371define print_ht 372 set $ind = 0 373 ____print_ht $arg0 1 374end 375 376document print_ht 377 dumps elements of HashTable made of zval 378end 379 380define print_htptr 381 set $ind = 0 382 ____print_ht $arg0 0 383end 384 385document print_htptr 386 dumps elements of HashTable made of pointers 387end 388 389define print_htstr 390 set $ind = 0 391 ____print_ht $arg0 2 392end 393 394document print_htstr 395 dumps elements of HashTable made of strings 396end 397 398define print_ft 399 set $ind = 0 400 ____print_ht $arg0 3 401end 402 403document print_ft 404 dumps a function table (HashTable) 405end 406 407define ____print_inh_class 408 set $ce = $arg0 409 if $ce->ce_flags & 0x10 || $ce->ce_flags & 0x20 410 printf "abstract " 411 else 412 if $ce->ce_flags & 0x40 413 printf "final " 414 end 415 end 416 printf "class %s", $ce->name->val 417 if $ce->parent != 0 418 printf " extends %s", $ce->parent->name->val 419 end 420 if $ce->num_interfaces != 0 421 printf " implements" 422 set $tmp = 0 423 while $tmp < $ce->num_interfaces 424 printf " %s", $ce->interfaces[$tmp]->name->val 425 set $tmp = $tmp + 1 426 if $tmp < $ce->num_interfaces 427 printf "," 428 end 429 end 430 end 431 set $ce = $ce->parent 432end 433 434define ____print_inh_iface 435 set $ce = $arg0 436 printf "interface %s", $ce->name->val 437 if $ce->num_interfaces != 0 438 set $ce = $ce->interfaces[0] 439 printf " extends %s", $ce->name->val 440 else 441 set $ce = 0 442 end 443end 444 445define print_inh 446 set $ce = $arg0 447 set $depth = 0 448 while $ce != 0 449 set $tmp = $depth 450 while $tmp != 0 451 printf " " 452 set $tmp = $tmp - 1 453 end 454 set $depth = $depth + 1 455 if $ce->ce_flags & 0x80 456 ____print_inh_iface $ce 457 else 458 ____print_inh_class $ce 459 end 460 printf " {\n" 461 end 462 while $depth != 0 463 set $tmp = $depth 464 while $tmp != 1 465 printf " " 466 set $tmp = $tmp - 1 467 end 468 printf "}\n" 469 set $depth = $depth - 1 470 end 471end 472 473define print_pi 474 set $pi = (zend_property_info *)$arg0 475 set $initial_offset = ((uint32_t)(zend_uintptr_t)(&((zend_object*)0)->properties_table[(0)])) 476 set $ptr_to_val = (zval*)((char*)$pi->ce->default_properties_table + $pi->offset - $initial_offset) 477 printf "[%p] {\n", $pi 478 printf " offset = %p\n", $pi->offset 479 printf " ce = [%p] %s\n", $pi->ce, $pi->ce->name->val 480 printf " flags = 0x%x (", $pi->flags 481 if $pi->flags & 0x100 482 printf "ZEND_ACC_PUBLIC" 483 else 484 if $pi->flags & 0x200 485 printf "ZEND_ACC_PROTECTED" 486 else 487 if $pi->flags & 0x400 488 printf "ZEND_ACC_PRIVATE" 489 else 490 if $pi->flags & 0x800 491 printf "ZEND_ACC_EARLY_BINDING" 492 else 493 if $pi->flags & 0x20000 494 printf "ZEND_ACC_SHADOW" 495 end 496 end 497 end 498 end 499 end 500 printf ")\n" 501 printf " name = " 502 print_zstr $pi->name 503 printf " default value: " 504 printzv $ptr_to_val 505 printf "}\n" 506end 507 508document print_pi 509 Takes a pointer to an object's property and prints the property information 510 usage: print_pi <ptr> 511end 512 513define ____print_str 514 set $tmp = 0 515 set $str = $arg0 516 if $argc > 2 517 set $maxlen = $arg2 518 else 519 set $maxlen = 256 520 end 521 522 printf "\"" 523 while $tmp < $arg1 && $tmp < $maxlen 524 if $str[$tmp] > 31 && $str[$tmp] < 127 525 printf "%c", $str[$tmp] 526 else 527 printf "\\%o", $str[$tmp] 528 end 529 set $tmp = $tmp + 1 530 end 531 if $tmp != $arg1 532 printf "..." 533 end 534 printf "\"" 535end 536 537define printzn 538 ____executor_globals 539 set $ind = 0 540 set $znode = $arg0 541 if $znode->op_type == 1 542 set $optype = "IS_CONST" 543 end 544 if $znode->op_type == 2 545 set $optype = "IS_TMP_VAR" 546 end 547 if $znode->op_type == 4 548 set $optype = "IS_VAR" 549 end 550 if $znode->op_type == 8 551 set $optype = "IS_UNUSED" 552 end 553 554 printf "[%p] %s", $znode, $optype 555 556 if $znode->op_type == 1 557 printf ": " 558 ____printzv &$znode->u.constant 0 559 end 560 if $znode->op_type == 2 561 printf ": " 562 set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var) 563 ____printzv ((union _temp_variable *)$tvar)->tmp_var 0 564 end 565 if $znode->op_type == 4 566 printf ": " 567 set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var) 568 ____printzv *$tvar->var.ptr_ptr 0 569 end 570 if $znode->op_type == 8 571 printf "\n" 572 end 573end 574 575document printzn 576 print type and content of znode. 577 usage: printzn &opline->op1 578end 579 580define printzops 581 printf "op1 => " 582 printzn &execute_data->opline.op1 583 printf "op2 => " 584 printzn &execute_data->opline.op2 585 printf "result => " 586 printzn &execute_data->opline.result 587end 588 589document printzops 590 dump operands of the current opline 591end 592 593define print_zstr 594 set $zstr = (zend_string *)$arg0 595 if $argc == 2 596 set $maxlen = $arg1 597 else 598 set $maxlen = $zstr->len 599 end 600 printf "string(%d) ", $zstr->len 601 ____print_str $zstr->val $zstr->len $maxlen 602 printf "\n" 603end 604 605document print_zstr 606 print the length and contents of a zend string 607 usage: print_zstr <ptr> [max length] 608end 609 610define zbacktrace 611 ____executor_globals 612 dump_bt $eg.current_execute_data 613end 614 615document zbacktrace 616 prints backtrace. 617 This command is almost a short cut for 618 > (gdb) ____executor_globals 619 > (gdb) dump_bt $eg.current_execute_data 620end 621 622define lookup_root 623 set $found = 0 624 if gc_globals->roots 625 set $current = gc_globals->roots->next 626 printf "looking ref %p in roots\n", $arg0 627 while $current != &gc_globals->roots 628 if $current->ref == $arg0 629 set $found = $current 630 break 631 end 632 set $current = $current->next 633 end 634 if $found != 0 635 printf "found root %p\n", $found 636 else 637 printf "not found\n" 638 end 639 end 640end 641 642document lookup_root 643 lookup a refcounted in root 644 usage: lookup_root [ptr]. 645end 646