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