我对我的数据库抽象代码进行了一些更改,现在它是segfaulting,我不知道如何修复它。
编辑:我找到了问题的原因,不幸的是,这与我在这个问题中所写的内容无关。请参阅下面的答案,了解我搞砸的更多细节。
我的更改包括从封装 PDO对象更改为从PDO类继承。
例如来自
OsStr
到
class DBConnection {
private $pdo;
现在在调用class DBConnection extends PDO {
期间发生分段错误。其他数据库查询仍然有效,如果我删除了对$db->beginTransaction();
及其匹配beginTransaction()
的违规电话,则可以正常使用。
违规代码:
commit()
当我封装PDO对象而不是继承时,相同的代码有效。
使用 public function getdelay($action, $interval, $tolerance = 2) {
...
$this->db->begintransaction();
...
我可以通过附加到进程并等到发生段错误(完全回溯从第6行开始)来获得以下回溯:
gdb
使用以PHP-FPM运行的版本Core was generated by `php-fpm: pool www'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 memset (__len=<optimized out>, __ch=<optimized out>, __dest=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/string3.h:84
84 /usr/include/x86_64-linux-gnu/bits/string3.h: No such file or directory.
(gdb) bt full
#0 memset (__len=<optimized out>, __ch=<optimized out>, __dest=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/string3.h:84
No locals.
#1 i_create_execute_data_from_op_array (nested=<optimized out>, op_array=<optimized out>)
at /build/php5-5.6.24+dfsg/Zend/zend_execute.c:1679
execute_data = 0x7f2cf1e3a890
CVs_size = 0
Ts_size = 139831013517456
total_size = 139831013517248
#2 zend_execute (op_array=0x7f2cf1e3a918, op_array@entry=<error reading variable: Cannot access memory at address 0x7ffcf6731048>)
at /build/php5-5.6.24+dfsg/Zend/zend_vm_execute.h:388
No locals.
(Debian稳定版本)。
我的具体问题
我现在该怎么做才能让我的代码正常工作(beginTransaction无需segfaulting工作)?是否最好回到封装,以避免扩展PDO类?
扩展本机PHP类是不是一个坏主意?这有可能导致奇怪的问题吗?
答案 0 :(得分:1)
我找到了问题的原因,这简直太令人尴尬了。它与扩展PDO类无关。相反,它与我没有意识到方法名称不区分大小写。
我的原始数据库类具有开始事务的功能:
function begintransaction() {
...
请注意't'是小写的。
在对我的数据库类进行修改时,我将其放入:
function begintransaction() {
return $this->beginTransaction();
}
这背后的意图是允许全小写begintransaction
继续在旧代码中出现的地方运行,作为PDO beginTransaction
的包装器(带有大写'T') )。
但是,由于方法名称在PHP中不区分大小写,因此所有这些操作都会调用自身,从而产生无限递归,从而导致分段错误。
我调试分段错误的技巧很差,我没有意识到这是由于无限递归。