xref: /PHP-8.4/.gdbinit (revision f18710e3)
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