mirror of
https://github.com/php/php-src.git
synced 2024-12-27 19:00:27 +08:00
5c8df5e0f8
Use %p instead of "0x08x" (IMO this is used for print pointer, which, unfortunately, don't work under x64) If there is any wrong, plz revert this, thanks
616 lines
12 KiB
Plaintext
616 lines
12 KiB
Plaintext
define ____executor_globals
|
|
if basic_functions_module.zts
|
|
set $tsrm_ls = ts_resource_ex(0, 0)
|
|
set $eg = ((zend_executor_globals) (*((void ***) $tsrm_ls))[executor_globals_id-1])
|
|
set $cg = ((zend_compiler_globals) (*((void ***) $tsrm_ls))[compiler_globals_id-1])
|
|
else
|
|
set $eg = executor_globals
|
|
set $cg = compiler_globals
|
|
end
|
|
end
|
|
|
|
document ____executor_globals
|
|
portable way of accessing executor_globals, set $eg
|
|
this also sets compiler_globals to $cg
|
|
ZTS detection is automatically based on ext/standard module struct
|
|
end
|
|
|
|
define print_cvs
|
|
____executor_globals
|
|
set $p = $eg.current_execute_data.CVs
|
|
set $c = $eg.current_execute_data.op_array.last_var
|
|
set $v = $eg.current_execute_data.op_array.vars
|
|
set $i = 0
|
|
|
|
printf "Compiled variables count: %d\n", $c
|
|
while $i < $c
|
|
printf "%d = %s\n", $i, $v[$i].name
|
|
if $p[$i] != 0
|
|
printzv *$p[$i]
|
|
else
|
|
printf "*uninitialized*\n"
|
|
end
|
|
set $i = $i + 1
|
|
end
|
|
end
|
|
|
|
define dump_bt
|
|
set $t = $arg0
|
|
while $t
|
|
printf "[%p] ", $t
|
|
if $t->function_state.function->common.function_name
|
|
if $t->function_state.arguments
|
|
set $count = (int)*($t->function_state.arguments)
|
|
printf "%s(", $t->function_state.function->common.function_name
|
|
while $count > 0
|
|
set $zvalue = *(zval **)($t->function_state.arguments - $count)
|
|
set $type = $zvalue->type
|
|
if $type == 0
|
|
printf "NULL"
|
|
end
|
|
if $type == 1
|
|
printf "%ld", $zvalue->value.lval
|
|
end
|
|
if $type == 2
|
|
printf "%lf", $zvalue->value.dval
|
|
end
|
|
if $type == 3
|
|
if $zvalue->value.lval
|
|
printf "true"
|
|
else
|
|
printf "false"
|
|
end
|
|
end
|
|
if $type == 4
|
|
printf "array(%d)[%p]", $zvalue->value.ht->nNumOfElements, $zvalue
|
|
end
|
|
if $type == 5
|
|
printf "object[%p]", $zvalue
|
|
end
|
|
if $type == 6
|
|
____print_str $zvalue->value.str.val $zvalue->value.str.len
|
|
end
|
|
if $type == 7
|
|
printf "resource(#%d)", $zvalue->value.lval
|
|
end
|
|
if $type == 8
|
|
printf "constant"
|
|
end
|
|
if $type == 9
|
|
printf "const_array"
|
|
end
|
|
if $type > 9
|
|
printf "unknown type %d", $type
|
|
end
|
|
set $count = $count -1
|
|
if $count > 0
|
|
printf ", "
|
|
end
|
|
end
|
|
printf ") "
|
|
else
|
|
printf "%s() ", $t->function_state.function->common.function_name
|
|
end
|
|
else
|
|
printf "??? "
|
|
end
|
|
if $t->op_array != 0
|
|
printf "%s:%d ", $t->op_array->filename, $t->opline->lineno
|
|
end
|
|
set $t = $t->prev_execute_data
|
|
printf "\n"
|
|
end
|
|
end
|
|
|
|
document dump_bt
|
|
dumps the current execution stack. usage: dump_bt executor_globals.current_execute_data
|
|
end
|
|
|
|
define printzv
|
|
set $ind = 1
|
|
____printzv $arg0 0
|
|
end
|
|
|
|
document printzv
|
|
prints zval contents
|
|
end
|
|
|
|
define ____printzv_contents
|
|
set $zvalue = $arg0
|
|
set $type = $zvalue->type
|
|
|
|
printf "(refcount=%d", $zvalue->refcount__gc
|
|
if $zvalue->is_ref__gc
|
|
printf ",is_ref"
|
|
end
|
|
printf ") "
|
|
if $type == 0
|
|
printf "NULL"
|
|
end
|
|
if $type == 1
|
|
printf "long: %ld", $zvalue->value.lval
|
|
end
|
|
if $type == 2
|
|
printf "double: %lf", $zvalue->value.dval
|
|
end
|
|
if $type == 3
|
|
printf "bool: "
|
|
if $zvalue->value.lval
|
|
printf "true"
|
|
else
|
|
printf "false"
|
|
end
|
|
end
|
|
if $type == 4
|
|
printf "array(%d): ", $zvalue->value.ht->nNumOfElements
|
|
if ! $arg1
|
|
printf "{\n"
|
|
set $ind = $ind + 1
|
|
____print_ht $zvalue->value.ht 1
|
|
set $ind = $ind - 1
|
|
set $i = $ind
|
|
while $i > 0
|
|
printf " "
|
|
set $i = $i - 1
|
|
end
|
|
printf "}"
|
|
end
|
|
set $type = 0
|
|
end
|
|
if $type == 5
|
|
printf "object"
|
|
____executor_globals
|
|
set $handle = $zvalue->value.obj.handle
|
|
set $handlers = $zvalue->value.obj.handlers
|
|
if basic_functions_module.zts
|
|
set $zobj = zend_objects_get_address($zvalue, $tsrm_ls)
|
|
else
|
|
set $zobj = zend_objects_get_address($zvalue)
|
|
end
|
|
if $handlers->get_class_entry == &zend_std_object_get_class
|
|
set $cname = $zobj->ce.name
|
|
else
|
|
set $cname = "Unknown"
|
|
end
|
|
printf "(%s) #%d", $cname, $handle
|
|
if ! $arg1
|
|
if $handlers->get_properties == &zend_std_get_properties
|
|
set $ht = $zobj->properties
|
|
if $ht
|
|
printf "(%d): ", $ht->nNumOfElements
|
|
printf "{\n"
|
|
set $ind = $ind + 1
|
|
____print_ht $ht 1
|
|
set $ind = $ind - 1
|
|
set $i = $ind
|
|
while $i > 0
|
|
printf " "
|
|
set $i = $i - 1
|
|
end
|
|
printf "}"
|
|
else
|
|
echo "no properties found"
|
|
end
|
|
end
|
|
end
|
|
set $type = 0
|
|
end
|
|
if $type == 6
|
|
printf "string(%d): ", $zvalue->value.str.len
|
|
____print_str $zvalue->value.str.val $zvalue->value.str.len
|
|
end
|
|
if $type == 7
|
|
printf "resource: #%d", $zvalue->value.lval
|
|
end
|
|
if $type == 8
|
|
printf "constant"
|
|
end
|
|
if $type == 9
|
|
printf "const_array"
|
|
end
|
|
if $type > 9
|
|
printf "unknown type %d", $type
|
|
end
|
|
printf "\n"
|
|
end
|
|
|
|
define ____printzv
|
|
____executor_globals
|
|
set $zvalue = $arg0
|
|
|
|
printf "[%p] ", $zvalue
|
|
|
|
if $zvalue == $eg.uninitialized_zval_ptr
|
|
printf "*uninitialized* "
|
|
end
|
|
|
|
set $zcontents = (zval*) $zvalue
|
|
if $arg1
|
|
____printzv_contents $zcontents $arg1
|
|
else
|
|
____printzv_contents $zcontents 0
|
|
end
|
|
end
|
|
|
|
define ____print_const_table
|
|
set $ht = $arg0
|
|
set $p = $ht->pListHead
|
|
|
|
while $p != 0
|
|
set $const = (zend_constant *) $p->pData
|
|
|
|
set $i = $ind
|
|
while $i > 0
|
|
printf " "
|
|
set $i = $i - 1
|
|
end
|
|
|
|
if $p->nKeyLength > 0
|
|
____print_str $p->arKey $p->nKeyLength
|
|
printf " => "
|
|
else
|
|
printf "%d => ", $p->h
|
|
end
|
|
|
|
____printzv_contents &$const->value 0
|
|
set $p = $p->pListNext
|
|
end
|
|
end
|
|
|
|
define print_const_table
|
|
set $ind = 1
|
|
printf "[%p] {\n", $arg0
|
|
____print_const_table $arg0
|
|
printf "}\n"
|
|
end
|
|
|
|
define ____print_ht
|
|
set $ht = (HashTable*)$arg0
|
|
set $p = $ht->pListHead
|
|
|
|
while $p != 0
|
|
set $i = $ind
|
|
while $i > 0
|
|
printf " "
|
|
set $i = $i - 1
|
|
end
|
|
|
|
if $p->nKeyLength > 0
|
|
____print_str $p->arKey $p->nKeyLength
|
|
printf " => "
|
|
else
|
|
printf "%d => ", $p->h
|
|
end
|
|
|
|
if $arg1 == 0
|
|
printf "%p\n", (void*)$p->pData
|
|
end
|
|
if $arg1 == 1
|
|
set $zval = *(zval **)$p->pData
|
|
____printzv $zval 1
|
|
end
|
|
if $arg1 == 2
|
|
printf "%s\n", (char*)$p->pData
|
|
end
|
|
|
|
set $p = $p->pListNext
|
|
end
|
|
end
|
|
|
|
define print_ht
|
|
set $ind = 1
|
|
printf "[%p] {\n", $arg0
|
|
____print_ht $arg0 1
|
|
printf "}\n"
|
|
end
|
|
|
|
document print_ht
|
|
dumps elements of HashTable made of zval
|
|
end
|
|
|
|
define print_htptr
|
|
set $ind = 1
|
|
printf "[%p] {\n", $arg0
|
|
____print_ht $arg0 0
|
|
printf "}\n"
|
|
end
|
|
|
|
document print_htptr
|
|
dumps elements of HashTable made of pointers
|
|
end
|
|
|
|
define print_htstr
|
|
set $ind = 1
|
|
printf "[%p] {\n", $arg0
|
|
____print_ht $arg0 2
|
|
printf "}\n"
|
|
end
|
|
|
|
document print_htstr
|
|
dumps elements of HashTable made of strings
|
|
end
|
|
|
|
define ____print_ft
|
|
set $ht = $arg0
|
|
set $p = $ht->pListHead
|
|
|
|
while $p != 0
|
|
set $func = (zend_function*)$p->pData
|
|
|
|
set $i = $ind
|
|
while $i > 0
|
|
printf " "
|
|
set $i = $i - 1
|
|
end
|
|
|
|
if $p->nKeyLength > 0
|
|
____print_str $p->arKey $p->nKeyLength
|
|
printf " => "
|
|
else
|
|
printf "%d => ", $p->h
|
|
end
|
|
|
|
printf "\"%s\"\n", $func->common.function_name
|
|
set $p = $p->pListNext
|
|
end
|
|
end
|
|
|
|
define print_ft
|
|
set $ind = 1
|
|
printf "[%p] {\n", $arg0
|
|
____print_ft $arg0
|
|
printf "}\n"
|
|
end
|
|
|
|
document print_ft
|
|
dumps a function table (HashTable)
|
|
end
|
|
|
|
define ____print_inh_class
|
|
set $ce = $arg0
|
|
if $ce->ce_flags & 0x10 || $ce->ce_flags & 0x20
|
|
printf "abstract "
|
|
else
|
|
if $ce->ce_flags & 0x40
|
|
printf "final "
|
|
end
|
|
end
|
|
printf "class %s", $ce->name
|
|
if $ce->parent != 0
|
|
printf " extends %s", $ce->parent->name
|
|
end
|
|
if $ce->num_interfaces != 0
|
|
printf " implements"
|
|
set $tmp = 0
|
|
while $tmp < $ce->num_interfaces
|
|
printf " %s", $ce->interfaces[$tmp]->name
|
|
set $tmp = $tmp + 1
|
|
if $tmp < $ce->num_interfaces
|
|
printf ","
|
|
end
|
|
end
|
|
end
|
|
set $ce = $ce->parent
|
|
end
|
|
|
|
define ____print_inh_iface
|
|
set $ce = $arg0
|
|
printf "interface %s", $ce->name
|
|
if $ce->num_interfaces != 0
|
|
set $ce = $ce->interfaces[0]
|
|
printf " extends %s", $ce->name
|
|
else
|
|
set $ce = 0
|
|
end
|
|
end
|
|
|
|
define print_inh
|
|
set $ce = $arg0
|
|
set $depth = 0
|
|
while $ce != 0
|
|
set $tmp = $depth
|
|
while $tmp != 0
|
|
printf " "
|
|
set $tmp = $tmp - 1
|
|
end
|
|
set $depth = $depth + 1
|
|
if $ce->ce_flags & 0x80
|
|
____print_inh_iface $ce
|
|
else
|
|
____print_inh_class $ce
|
|
end
|
|
printf " {\n"
|
|
end
|
|
while $depth != 0
|
|
set $tmp = $depth
|
|
while $tmp != 1
|
|
printf " "
|
|
set $tmp = $tmp - 1
|
|
end
|
|
printf "}\n"
|
|
set $depth = $depth - 1
|
|
end
|
|
end
|
|
|
|
define print_pi
|
|
set $pi = $arg0
|
|
printf "[%p] {\n", $pi
|
|
printf " h = %lu\n", $pi->h
|
|
printf " flags = %d (", $pi->flags
|
|
if $pi->flags & 0x100
|
|
printf "ZEND_ACC_PUBLIC"
|
|
else
|
|
if $pi->flags & 0x200
|
|
printf "ZEND_ACC_PROTECTED"
|
|
else
|
|
if $pi->flags & 0x400
|
|
printf "ZEND_ACC_PRIVATE"
|
|
else
|
|
if $pi->flags & 0x800
|
|
printf "ZEND_ACC_CHANGED"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
printf ")\n"
|
|
printf " name = "
|
|
____print_str $pi->name $pi->name_length
|
|
printf "\n}\n"
|
|
end
|
|
|
|
define ____print_str
|
|
set $tmp = 0
|
|
set $str = $arg0
|
|
printf "\""
|
|
while $tmp < $arg1
|
|
if $str[$tmp] > 32 && $str[$tmp] < 127
|
|
printf "%c", $str[$tmp]
|
|
else
|
|
printf "\\%o", $str[$tmp]
|
|
end
|
|
set $tmp = $tmp + 1
|
|
end
|
|
printf "\""
|
|
end
|
|
|
|
define printzn
|
|
____executor_globals
|
|
set $ind = 0
|
|
set $znode = $arg0
|
|
if $znode->op_type == 1
|
|
set $optype = "IS_CONST"
|
|
end
|
|
if $znode->op_type == 2
|
|
set $optype = "IS_TMP_VAR"
|
|
end
|
|
if $znode->op_type == 4
|
|
set $optype = "IS_VAR"
|
|
end
|
|
if $znode->op_type == 8
|
|
set $optype = "IS_UNUSED"
|
|
end
|
|
|
|
printf "[%p] %s", $znode, $optype
|
|
|
|
if $znode->op_type == 1
|
|
printf ": "
|
|
____printzv &$znode->u.constant 0
|
|
end
|
|
if $znode->op_type == 2
|
|
printf ": "
|
|
set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var)
|
|
____printzv ((union _temp_variable *)$tvar)->tmp_var 0
|
|
end
|
|
if $znode->op_type == 4
|
|
printf ": "
|
|
set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var)
|
|
____printzv *$tvar->var.ptr_ptr 0
|
|
end
|
|
if $znode->op_type == 8
|
|
printf "\n"
|
|
end
|
|
end
|
|
|
|
document printzn
|
|
print type and content of znode.
|
|
usage: printzn &opline->op1
|
|
end
|
|
|
|
define printzops
|
|
printf "op1 => "
|
|
printzn &execute_data->opline.op1
|
|
printf "op2 => "
|
|
printzn &execute_data->opline.op2
|
|
printf "result => "
|
|
printzn &execute_data->opline.result
|
|
end
|
|
|
|
document printzops
|
|
dump operands of the current opline
|
|
end
|
|
|
|
define zbacktrace
|
|
____executor_globals
|
|
dump_bt $eg.current_execute_data
|
|
end
|
|
|
|
document zbacktrace
|
|
prints backtrace.
|
|
This command is almost a short cut for
|
|
> (gdb) ____executor_globals
|
|
> (gdb) dump_bt $eg.current_execute_data
|
|
end
|
|
|
|
define zmemcheck
|
|
set $p = alloc_globals.head
|
|
set $stat = "?"
|
|
set $total_size = 0
|
|
if $arg0 != 0
|
|
set $not_found = 1
|
|
else
|
|
set $not_found = 0
|
|
end
|
|
printf " block size status file:line\n"
|
|
printf "-------------------------------------------------------------------------------\n"
|
|
while $p
|
|
set $aptr = $p + sizeof(struct _zend_mem_header) + sizeof(align_test)
|
|
if $arg0 == 0 || (void *)$aptr == (void *)$arg0
|
|
if $p->magic == 0x7312f8dc
|
|
set $stat = "OK"
|
|
end
|
|
if $p->magic == 0x99954317
|
|
set $stat = "FREED"
|
|
end
|
|
if $p->magic == 0xfb8277dc
|
|
set $stat = "CACHED"
|
|
end
|
|
set $filename = strrchr($p->filename, '/')
|
|
if !$filename
|
|
set $filename = $p->filename
|
|
else
|
|
set $filename = $filename + 1
|
|
end
|
|
printf " %p ", $aptr
|
|
if $p->size == sizeof(struct _zval_struct) && ((struct _zval_struct *)$aptr)->type >= 0 && ((struct _zval_struct *)$aptr)->type < 10
|
|
printf "ZVAL?(%-2d) ", $p->size
|
|
else
|
|
printf "%-9d ", $p->size
|
|
end
|
|
set $total_size = $total_size + $p->size
|
|
printf "%-06s %s:%d", $stat, $filename, $p->lineno
|
|
if $p->orig_filename
|
|
set $orig_filename = strrchr($p->orig_filename, '/')
|
|
if !$orig_filename
|
|
set $orig_filename = $p->orig_filename
|
|
else
|
|
set $orig_filename = $orig_filename + 1
|
|
end
|
|
printf " <= %s:%d\n", $orig_filename, $p->orig_lineno
|
|
else
|
|
printf "\n"
|
|
end
|
|
if $arg0 != 0
|
|
set $p = 0
|
|
set $not_found = 0
|
|
else
|
|
set $p = $p->pNext
|
|
end
|
|
else
|
|
set $p = $p->pNext
|
|
end
|
|
end
|
|
if $not_found
|
|
printf "no such block that begins at %p.\n", $aptr
|
|
end
|
|
if $arg0 == 0
|
|
printf "-------------------------------------------------------------------------------\n"
|
|
printf " total: %d bytes\n", $total_size
|
|
end
|
|
end
|
|
|
|
document zmemcheck
|
|
show status of a memory block.
|
|
usage: zmemcheck [ptr].
|
|
if ptr is 0, all blocks will be listed.
|
|
end
|