extends('layout.php', ['title' => 'Generating a gdb backtrace']) ?> start('content') ?>
Unix | Windows
After that any process crashing in your system, including PHP, will leave its core file in the directory you've specified in core_pattern.
gdb /usr/local/apache/sbin/httpd /usr/local/apache/sbin/core
gdb /home/user/dev/php-snaps/sapi/cli/php /home/user/dev/testing/core
(gdb) bt
gdb /usr/local/apache/sbin/httpd
(gdb) bt
(gdb) run /path/to/script.php
(gdb) bt
This should generate a backtrace, that you should submit in the bug report, along with any other details you can give us about your setup, and offending script.
You can locate the function call that caused a segfault, easily, with gdb. First, you need a core file or to generate a segfault under gdb as described above.
In PHP, each function is executed by an internal function called
execute()
and has its own stack. Each line generated by the
bt
command represents a function call stack. Typically, you
will see several execute()
lines when you issue
bt
. You are interested in the last
execute()
stack (i.e. smallest frame number). You can move
the current working stack with the up
, down
or
frame
commands. Below is an example gdb session that can be
used as a guideline on how to handle your segfault.
(gdb) bt
#0 0x080ca21b in _efree (ptr=0xbfffdb9b) at zend_alloc.c:240
#1 0x080d691a in _zval_dtor (zvalue=0x8186b94) at zend_variables.c:44
#2 0x080cfab3 in _zval_ptr_dtor (zval_ptr=0xbfffdbfc) at zend_execute_API.c:274
#3 0x080f1cc4 in execute (op_array=0x816c670) at ./zend_execute.c:1605
#4 0x080f1e06 in execute (op_array=0x816c530) at ./zend_execute.c:1638
#5 0x080f1e06 in execute (op_array=0x816c278) at ./zend_execute.c:1638
#6 0x080f1e06 in execute (op_array=0x8166eec) at ./zend_execute.c:1638
#7 0x080d7b93 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at zend.c:810
#8 0x0805ea75 in php_execute_script (primary_file=0xbffff650) at main.c:1310
#9 0x0805cdb3 in main (argc=2, argv=0xbffff6fc) at cgi_main.c:753
#10 0x400c91be in __libc_start_main (main=0x805c580 , argc=2, ubp_av=0xbffff6fc,
init=0x805b080 <_init>, fini=0x80f67b4 <_fini>, rtld_fini=0x4000ddd0 <_dl_fini>,
stack_end=0xbffff6ec) at ../sysdeps/generic/libc-start.c:129
(gdb) frame 3
#3 0x080f1cc4 in execute (op_array=0x816c670) at ./zend_execute.c:1605
(gdb) print (char *)(executor_globals.function_state_ptr->function)->common.function_name
$14 = 0x80fa6fa "pg_result_error"
(gdb) print (char *)executor_globals.active_op_array->function_name
$15 = 0x816cfc4 "result_error"
(gdb) print (char *)executor_globals.active_op_array->filename
$16 = 0x816afbc "/home/yohgaki/php/DEV/segfault.php"
(gdb)
In this session, frame 3 is the last execute()
call. The
frame 3
command moves the current working stack to the
proper frame.
print (char *)(executor_globals.function_state_ptr->function)->common.function_name
prints the function name. In the sample gdb session, the
pg_result_error()
call is causing the segfault. You can print any
internal data that you like, if you know the internal data structure. Please do
not ask how to use gdb or about the internal data structure. Refer to gdb manual
for gdb usage and to the PHP source for the internal data structure.
You may not see execute
if the segfault happens without
calling any functions.