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