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 else 20 set $eg = executor_globals 21 set $cg = compiler_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 != 15 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 set $ht = $zobj->properties 217 else 218 set $ht = &$zobj->ce->properties_info 219 end 220 printf "\nProperties " 221 if $ht 222 set $ind = $ind + 1 223 ____print_ht $ht 1 224 set $ind = $ind - 1 225 set $i = $ind 226 while $i > 0 227 printf " " 228 set $i = $i - 1 229 end 230 else 231 echo "not found" 232 end 233 end 234 end 235 set $type = 0 236 end 237 if $type == 9 238 printf "resource: #%d", $zvalue->value.res->handle 239 end 240 if $type == 10 241 printf "reference: " 242 ____printzv &$zvalue->value.ref->val $arg1 243 end 244 if $type == 11 245 printf "const: %s", $zvalue->value.str->val 246 end 247 if $type == 12 248 printf "const_ast" 249 end 250 if $type == 13 251 printf "_IS_BOOL" 252 end 253 if $type == 14 254 printf "IS_CALLABLE" 255 end 256 if $type == 15 257 printf "indirect: " 258 ____printzv $zvalue->value.zv $arg1 259 end 260 if $type == 16 261 printf "string_offset" 262 end 263 if $type == 17 264 printf "pointer: %p", $zvalue->value.ptr 265 end 266 if $type > 17 267 printf "unknown type %d", $type 268 end 269 printf "\n" 270end 271 272define ____printzv 273 ____executor_globals 274 set $zvalue = $arg0 275 276 printf "[%p] ", $zvalue 277 278 set $zcontents = (zval*) $zvalue 279 if $arg1 280 ____printzv_contents $zcontents $arg1 281 else 282 ____printzv_contents $zcontents 0 283 end 284end 285 286define ____print_const_table 287 set $ht = $arg0 288 set $p = $ht->pListHead 289 290 while $p != 0 291 set $const = (zend_constant *) $p->pData 292 293 set $i = $ind 294 while $i > 0 295 printf " " 296 set $i = $i - 1 297 end 298 299 if $p->nKeyLength > 0 300 ____print_str $p->arKey $p->nKeyLength 301 printf " => " 302 else 303 printf "%d => ", $p->h 304 end 305 306 ____printzv_contents &$const->value 0 307 set $p = $p->pListNext 308 end 309end 310 311define print_const_table 312 set $ind = 1 313 printf "[%p] {\n", $arg0 314 ____print_const_table $arg0 315 printf "}\n" 316end 317 318define ____print_ht 319 set $ht = (HashTable*)$arg0 320 set $n = $ind 321 while $n > 0 322 printf " " 323 set $n = $n - 1 324 end 325 326 if $ht->u.v.flags & 4 327 printf "Packed" 328 else 329 printf "Hash" 330 end 331 printf "(%d)[%p]: {\n", $ht->nNumOfElements, $ht 332 333 set $num = $ht->nNumUsed 334 set $i = 0 335 set $ind = $ind + 1 336 while $i < $num 337 set $p = (Bucket*)($ht->arData + $i) 338 set $n = $ind 339 if $p->val.u1.v.type > 0 340 while $n > 0 341 printf " " 342 set $n = $n - 1 343 end 344 printf "[%d] ", $i 345 if $p->key 346 printf "%s => ", $p->key->val 347 else 348 printf "%d => ", $p->h 349 end 350 if $arg1 == 0 351 printf "%p\n", (zval *)&$p->val 352 end 353 if $arg1 == 1 354 set $zval = (zval *)&$p->val 355 ____printzv $zval 1 356 end 357 if $arg1 == 2 358 printf "%s\n", (char*)$p->val.value.ptr 359 end 360 if $arg1 == 3 361 set $func = (zend_function*)$p->val.value.ptr 362 printf "\"%s\"\n", $func->common.function_name->val 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 printf "[%p] {\n", $pi 476 printf " ce = [%p] %s\n", $pi->ce, $pi->ce->name->val 477 printf " flags = %d (", $pi->flags 478 if $pi->flags & 0x100 479 printf "ZEND_ACC_PUBLIC" 480 else 481 if $pi->flags & 0x200 482 printf "ZEND_ACC_PROTECTED" 483 else 484 if $pi->flags & 0x400 485 printf "ZEND_ACC_PRIVATE" 486 else 487 if $pi->flags & 0x800 488 printf "ZEND_ACC_CHANGED" 489 end 490 end 491 end 492 end 493 printf ")\n" 494 printf " name = " 495 print_zstr $pi->name 496 printf "}\n" 497end 498 499document print_pi 500 Takes a pointer to an object's property and prints the property information 501 usage: print_pi <ptr> 502end 503 504define ____print_str 505 set $tmp = 0 506 set $str = $arg0 507 if $argc > 2 508 set $maxlen = $arg2 509 else 510 set $maxlen = 256 511 end 512 513 printf "\"" 514 while $tmp < $arg1 && $tmp < $maxlen 515 if $str[$tmp] > 31 && $str[$tmp] < 127 516 printf "%c", $str[$tmp] 517 else 518 printf "\\%o", $str[$tmp] 519 end 520 set $tmp = $tmp + 1 521 end 522 if $tmp != $arg1 523 printf "..." 524 end 525 printf "\"" 526end 527 528define printzn 529 ____executor_globals 530 set $ind = 0 531 set $znode = $arg0 532 if $znode->op_type == 1 533 set $optype = "IS_CONST" 534 end 535 if $znode->op_type == 2 536 set $optype = "IS_TMP_VAR" 537 end 538 if $znode->op_type == 4 539 set $optype = "IS_VAR" 540 end 541 if $znode->op_type == 8 542 set $optype = "IS_UNUSED" 543 end 544 545 printf "[%p] %s", $znode, $optype 546 547 if $znode->op_type == 1 548 printf ": " 549 ____printzv &$znode->u.constant 0 550 end 551 if $znode->op_type == 2 552 printf ": " 553 set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var) 554 ____printzv ((union _temp_variable *)$tvar)->tmp_var 0 555 end 556 if $znode->op_type == 4 557 printf ": " 558 set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var) 559 ____printzv *$tvar->var.ptr_ptr 0 560 end 561 if $znode->op_type == 8 562 printf "\n" 563 end 564end 565 566document printzn 567 print type and content of znode. 568 usage: printzn &opline->op1 569end 570 571define printzops 572 printf "op1 => " 573 printzn &execute_data->opline.op1 574 printf "op2 => " 575 printzn &execute_data->opline.op2 576 printf "result => " 577 printzn &execute_data->opline.result 578end 579 580document printzops 581 dump operands of the current opline 582end 583 584define print_zstr 585 set $zstr = (zend_string *)$arg0 586 if $argc == 2 587 set $maxlen = $arg1 588 else 589 set $maxlen = $zstr->len 590 end 591 printf "string(%d) ", $zstr->len 592 ____print_str $zstr->val $zstr->len $maxlen 593 printf "\n" 594end 595 596document print_zstr 597 print the length and contents of a zend string 598 usage: print_zstr <ptr> [max length] 599end 600 601define zbacktrace 602 ____executor_globals 603 dump_bt $eg.current_execute_data 604end 605 606document zbacktrace 607 prints backtrace. 608 This command is almost a short cut for 609 > (gdb) ____executor_globals 610 > (gdb) dump_bt $eg.current_execute_data 611end 612 613define lookup_root 614 set $found = 0 615 if gc_globals->roots 616 set $current = gc_globals->roots->next 617 printf "looking ref %p in roots\n", $arg0 618 while $current != &gc_globals->roots 619 if $current->ref == $arg0 620 set $found = $current 621 break 622 end 623 set $current = $current->next 624 end 625 if $found != 0 626 printf "found root %p\n", $found 627 else 628 printf "not found\n" 629 end 630 end 631end 632 633document lookup_root 634 lookup a refcounted in root 635 usage: lookup_root [ptr]. 636end 637