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 ____executor_globals 33 set $p = $eg.current_execute_data.CVs 34 set $c = $eg.current_execute_data.op_array.last_var 35 set $v = $eg.current_execute_data.op_array.vars 36 set $i = 0 37 38 printf "Compiled variables count: %d\n", $c 39 while $i < $c 40 printf "%d = %s\n", $i, $v[$i].name 41 if $p[$i] != 0 42 printzv *$p[$i] 43 else 44 printf "*uninitialized*\n" 45 end 46 set $i = $i + 1 47 end 48end 49 50define dump_bt 51 set $t = $arg0 52 while $t 53 printf "[%p] ", $t 54 set $fst = $t->function_state 55 if $fst.function->common.function_name 56 if $fst.arguments 57 set $count = (int)*($fst.arguments) 58 59 if $t->object 60 if $fst.function.common.scope 61 printf "%s->", $fst.function.common.scope->name 62 else 63 if !$eg 64 ____executor_globals 65 end 66 67 set $known_class = 0 68 if $eg 69 set $handle = $t->object.value.obj.handle 70 set $handlers = $t->object.value.obj.handlers 71 set $zobj = (zend_object *)$eg.objects_store.object_buckets[$handle].bucket.obj.object 72 73 if $handlers->get_class_entry == &zend_std_object_get_class 74 set $known_class = 1 75 76 if $handlers.get_class_name 77 if $handlers.get_class_name != &zend_std_object_get_class_name 78 set $known_class = 0 79 end 80 end 81 82 if $known_class 83 printf "%s->", $zobj->ce.name 84 end 85 end 86 end 87 88 if !$known_class 89 printf "(Unknown)->" 90 end 91 end 92 else 93 if $fst.function.common.scope 94 printf "%s::", $fst.function.common.scope->name 95 end 96 end 97 98 printf "%s(", $fst.function->common.function_name 99 while $count > 0 100 set $zvalue = *(zval **)($fst.arguments - $count) 101 set $type = $zvalue->type 102 if $type == 0 103 printf "NULL" 104 end 105 if $type == 1 106 printf "%ld", $zvalue->value.lval 107 end 108 if $type == 2 109 printf "%lf", $zvalue->value.dval 110 end 111 if $type == 3 112 if $zvalue->value.lval 113 printf "true" 114 else 115 printf "false" 116 end 117 end 118 if $type == 4 119 printf "array(%d)[%p]", $zvalue->value.ht->nNumOfElements, $zvalue 120 end 121 if $type == 5 122 printf "object[%p]", $zvalue 123 end 124 if $type == 6 125 ____print_str $zvalue->value.str.val $zvalue->value.str.len 126 end 127 if $type == 7 128 printf "resource(#%d)", $zvalue->value.lval 129 end 130 if $type == 8 131 printf "constant" 132 end 133 if $type == 9 134 printf "const_array" 135 end 136 if $type > 9 137 printf "unknown type %d", $type 138 end 139 set $count = $count -1 140 if $count > 0 141 printf ", " 142 end 143 end 144 printf ") " 145 else 146 printf "%s() ", $fst.function->common.function_name 147 end 148 else 149 printf "??? " 150 end 151 if $t->op_array != 0 152 printf "%s:%d ", $t->op_array->filename, $t->opline->lineno 153 end 154 set $t = $t->prev_execute_data 155 printf "\n" 156 end 157end 158 159document dump_bt 160 dumps the current execution stack. usage: dump_bt executor_globals.current_execute_data 161end 162 163define printzv 164 set $ind = 1 165 ____printzv $arg0 0 166end 167 168document printzv 169 prints zval contents 170end 171 172define ____printzv_contents 173 set $zvalue = $arg0 174 set $type = $zvalue->type 175 176 printf "(refcount=%d", $zvalue->refcount__gc 177 if $zvalue->is_ref__gc 178 printf ",is_ref" 179 end 180 printf ") " 181 if $type == 0 182 printf "NULL" 183 end 184 if $type == 1 185 printf "long: %ld", $zvalue->value.lval 186 end 187 if $type == 2 188 printf "double: %lf", $zvalue->value.dval 189 end 190 if $type == 3 191 printf "bool: " 192 if $zvalue->value.lval 193 printf "true" 194 else 195 printf "false" 196 end 197 end 198 if $type == 4 199 printf "array(%d): ", $zvalue->value.ht->nNumOfElements 200 if ! $arg1 201 printf "{\n" 202 set $ind = $ind + 1 203 ____print_ht $zvalue->value.ht 1 204 set $ind = $ind - 1 205 set $i = $ind 206 while $i > 0 207 printf " " 208 set $i = $i - 1 209 end 210 printf "}" 211 end 212 set $type = 0 213 end 214 if $type == 5 215 printf "object" 216 ____executor_globals 217 set $handle = $zvalue->value.obj.handle 218 set $handlers = $zvalue->value.obj.handlers 219 if basic_functions_module.zts 220 set $zobj = zend_objects_get_address($zvalue, $tsrm_ls) 221 else 222 set $zobj = zend_objects_get_address($zvalue) 223 end 224 if $handlers->get_class_entry == &zend_std_object_get_class 225 set $cname = $zobj->ce.name 226 else 227 set $cname = "Unknown" 228 end 229 printf "(%s) #%d", $cname, $handle 230 if ! $arg1 231 if $handlers->get_properties == &zend_std_get_properties 232 set $ht = $zobj->properties 233 if $ht 234 printf "(%d): ", $ht->nNumOfElements 235 printf "{\n" 236 set $ind = $ind + 1 237 ____print_ht $ht 1 238 set $ind = $ind - 1 239 set $i = $ind 240 while $i > 0 241 printf " " 242 set $i = $i - 1 243 end 244 printf "}" 245 else 246 echo "no properties found" 247 end 248 end 249 end 250 set $type = 0 251 end 252 if $type == 6 253 printf "string(%d): ", $zvalue->value.str.len 254 ____print_str $zvalue->value.str.val $zvalue->value.str.len 255 end 256 if $type == 7 257 printf "resource: #%d", $zvalue->value.lval 258 end 259 if $type == 8 260 printf "constant" 261 end 262 if $type == 9 263 printf "const_array" 264 end 265 if $type > 9 266 printf "unknown type %d", $type 267 end 268 printf "\n" 269end 270 271define ____printzv 272 ____executor_globals 273 set $zvalue = $arg0 274 275 printf "[%p] ", $zvalue 276 277 if $zvalue == $eg.uninitialized_zval_ptr 278 printf "*uninitialized* " 279 end 280 281 set $zcontents = (zval*) $zvalue 282 if $arg1 283 ____printzv_contents $zcontents $arg1 284 else 285 ____printzv_contents $zcontents 0 286 end 287end 288 289define ____print_const_table 290 set $ht = $arg0 291 set $p = $ht->pListHead 292 293 while $p != 0 294 set $const = (zend_constant *) $p->pData 295 296 set $i = $ind 297 while $i > 0 298 printf " " 299 set $i = $i - 1 300 end 301 302 if $p->nKeyLength > 0 303 ____print_str $p->arKey $p->nKeyLength 304 printf " => " 305 else 306 printf "%d => ", $p->h 307 end 308 309 ____printzv_contents &$const->value 0 310 set $p = $p->pListNext 311 end 312end 313 314define print_const_table 315 set $ind = 1 316 printf "[%p] {\n", $arg0 317 ____print_const_table $arg0 318 printf "}\n" 319end 320 321define ____print_ht 322 set $ht = (HashTable*)$arg0 323 set $p = $ht->pListHead 324 325 while $p != 0 326 set $i = $ind 327 while $i > 0 328 printf " " 329 set $i = $i - 1 330 end 331 332 if $p->nKeyLength > 0 333 ____print_str $p->arKey $p->nKeyLength 334 printf " => " 335 else 336 printf "%d => ", $p->h 337 end 338 339 if $arg1 == 0 340 printf "%p\n", (void*)$p->pData 341 end 342 if $arg1 == 1 343 set $zval = *(zval **)$p->pData 344 ____printzv $zval 1 345 end 346 if $arg1 == 2 347 printf "%s\n", (char*)$p->pData 348 end 349 350 set $p = $p->pListNext 351 end 352end 353 354define print_ht 355 set $ind = 1 356 printf "[%p] {\n", $arg0 357 ____print_ht $arg0 1 358 printf "}\n" 359end 360 361document print_ht 362 dumps elements of HashTable made of zval 363end 364 365define print_htptr 366 set $ind = 1 367 printf "[%p] {\n", $arg0 368 ____print_ht $arg0 0 369 printf "}\n" 370end 371 372document print_htptr 373 dumps elements of HashTable made of pointers 374end 375 376define print_htstr 377 set $ind = 1 378 printf "[%p] {\n", $arg0 379 ____print_ht $arg0 2 380 printf "}\n" 381end 382 383document print_htstr 384 dumps elements of HashTable made of strings 385end 386 387define ____print_ft 388 set $ht = $arg0 389 set $p = $ht->pListHead 390 391 while $p != 0 392 set $func = (zend_function*)$p->pData 393 394 set $i = $ind 395 while $i > 0 396 printf " " 397 set $i = $i - 1 398 end 399 400 if $p->nKeyLength > 0 401 ____print_str $p->arKey $p->nKeyLength 402 printf " => " 403 else 404 printf "%d => ", $p->h 405 end 406 407 printf "\"%s\"\n", $func->common.function_name 408 set $p = $p->pListNext 409 end 410end 411 412define print_ft 413 set $ind = 1 414 printf "[%p] {\n", $arg0 415 ____print_ft $arg0 416 printf "}\n" 417end 418 419document print_ft 420 dumps a function table (HashTable) 421end 422 423define ____print_inh_class 424 set $ce = $arg0 425 if $ce->ce_flags & 0x10 || $ce->ce_flags & 0x20 426 printf "abstract " 427 else 428 if $ce->ce_flags & 0x40 429 printf "final " 430 end 431 end 432 printf "class %s", $ce->name 433 if $ce->parent != 0 434 printf " extends %s", $ce->parent->name 435 end 436 if $ce->num_interfaces != 0 437 printf " implements" 438 set $tmp = 0 439 while $tmp < $ce->num_interfaces 440 printf " %s", $ce->interfaces[$tmp]->name 441 set $tmp = $tmp + 1 442 if $tmp < $ce->num_interfaces 443 printf "," 444 end 445 end 446 end 447 set $ce = $ce->parent 448end 449 450define ____print_inh_iface 451 set $ce = $arg0 452 printf "interface %s", $ce->name 453 if $ce->num_interfaces != 0 454 set $ce = $ce->interfaces[0] 455 printf " extends %s", $ce->name 456 else 457 set $ce = 0 458 end 459end 460 461define print_inh 462 set $ce = $arg0 463 set $depth = 0 464 while $ce != 0 465 set $tmp = $depth 466 while $tmp != 0 467 printf " " 468 set $tmp = $tmp - 1 469 end 470 set $depth = $depth + 1 471 if $ce->ce_flags & 0x80 472 ____print_inh_iface $ce 473 else 474 ____print_inh_class $ce 475 end 476 printf " {\n" 477 end 478 while $depth != 0 479 set $tmp = $depth 480 while $tmp != 1 481 printf " " 482 set $tmp = $tmp - 1 483 end 484 printf "}\n" 485 set $depth = $depth - 1 486 end 487end 488 489define print_pi 490 set $pi = $arg0 491 printf "[%p] {\n", $pi 492 printf " h = %lu\n", $pi->h 493 printf " flags = %d (", $pi->flags 494 if $pi->flags & 0x100 495 printf "ZEND_ACC_PUBLIC" 496 else 497 if $pi->flags & 0x200 498 printf "ZEND_ACC_PROTECTED" 499 else 500 if $pi->flags & 0x400 501 printf "ZEND_ACC_PRIVATE" 502 else 503 if $pi->flags & 0x800 504 printf "ZEND_ACC_CHANGED" 505 end 506 end 507 end 508 end 509 printf ")\n" 510 printf " name = " 511 ____print_str $pi->name $pi->name_length 512 printf "\n}\n" 513end 514 515define ____print_str 516 set $tmp = 0 517 set $str = $arg0 518 printf "\"" 519 while $tmp < $arg1 520 if $str[$tmp] > 32 && $str[$tmp] < 127 521 printf "%c", $str[$tmp] 522 else 523 printf "\\%o", $str[$tmp] 524 end 525 set $tmp = $tmp + 1 526 end 527 printf "\"" 528end 529 530define printzn 531 ____executor_globals 532 set $ind = 0 533 set $znode = $arg0 534 if $znode->op_type == 1 535 set $optype = "IS_CONST" 536 end 537 if $znode->op_type == 2 538 set $optype = "IS_TMP_VAR" 539 end 540 if $znode->op_type == 4 541 set $optype = "IS_VAR" 542 end 543 if $znode->op_type == 8 544 set $optype = "IS_UNUSED" 545 end 546 547 printf "[%p] %s", $znode, $optype 548 549 if $znode->op_type == 1 550 printf ": " 551 ____printzv &$znode->u.constant 0 552 end 553 if $znode->op_type == 2 554 printf ": " 555 set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var) 556 ____printzv ((union _temp_variable *)$tvar)->tmp_var 0 557 end 558 if $znode->op_type == 4 559 printf ": " 560 set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var) 561 ____printzv *$tvar->var.ptr_ptr 0 562 end 563 if $znode->op_type == 8 564 printf "\n" 565 end 566end 567 568document printzn 569 print type and content of znode. 570 usage: printzn &opline->op1 571end 572 573define printzops 574 printf "op1 => " 575 printzn &execute_data->opline.op1 576 printf "op2 => " 577 printzn &execute_data->opline.op2 578 printf "result => " 579 printzn &execute_data->opline.result 580end 581 582document printzops 583 dump operands of the current opline 584end 585 586define zbacktrace 587 ____executor_globals 588 dump_bt $eg.current_execute_data 589end 590 591document zbacktrace 592 prints backtrace. 593 This command is almost a short cut for 594 > (gdb) ____executor_globals 595 > (gdb) dump_bt $eg.current_execute_data 596end 597 598define zmemcheck 599 set $p = alloc_globals.head 600 set $stat = "?" 601 set $total_size = 0 602 if $arg0 != 0 603 set $not_found = 1 604 else 605 set $not_found = 0 606 end 607 printf " block size status file:line\n" 608 printf "-------------------------------------------------------------------------------\n" 609 while $p 610 set $aptr = $p + sizeof(struct _zend_mem_header) + sizeof(align_test) 611 if $arg0 == 0 || (void *)$aptr == (void *)$arg0 612 if $p->magic == 0x7312f8dc 613 set $stat = "OK" 614 end 615 if $p->magic == 0x99954317 616 set $stat = "FREED" 617 end 618 if $p->magic == 0xfb8277dc 619 set $stat = "CACHED" 620 end 621 set $filename = strrchr($p->filename, '/') 622 if !$filename 623 set $filename = $p->filename 624 else 625 set $filename = $filename + 1 626 end 627 printf " %p ", $aptr 628 if $p->size == sizeof(struct _zval_struct) && ((struct _zval_struct *)$aptr)->type >= 0 && ((struct _zval_struct *)$aptr)->type < 10 629 printf "ZVAL?(%-2d) ", $p->size 630 else 631 printf "%-9d ", $p->size 632 end 633 set $total_size = $total_size + $p->size 634 printf "%-06s %s:%d", $stat, $filename, $p->lineno 635 if $p->orig_filename 636 set $orig_filename = strrchr($p->orig_filename, '/') 637 if !$orig_filename 638 set $orig_filename = $p->orig_filename 639 else 640 set $orig_filename = $orig_filename + 1 641 end 642 printf " <= %s:%d\n", $orig_filename, $p->orig_lineno 643 else 644 printf "\n" 645 end 646 if $arg0 != 0 647 set $p = 0 648 set $not_found = 0 649 else 650 set $p = $p->pNext 651 end 652 else 653 set $p = $p->pNext 654 end 655 end 656 if $not_found 657 printf "no such block that begins at %p.\n", $aptr 658 end 659 if $arg0 == 0 660 printf "-------------------------------------------------------------------------------\n" 661 printf " total: %d bytes\n", $total_size 662 end 663end 664 665document zmemcheck 666 show status of a memory block. 667 usage: zmemcheck [ptr]. 668 if ptr is 0, all blocks will be listed. 669end 670