2016-09-15 136 views
1

我對數據庫抽象代碼做了一些更改,現在它是segfaulting,我不知道如何解決它。當擴展PDO類時,PDO :: beginTransaction上的Segfault

編輯:我找到了我的問題的原因,不幸的是,這與我在這個問題中寫到的無關。看到我的答案下面有關我搞砸了什麼的更多細節。

我的更改包括將封裝爲將PDO對象從PDO類繼承。

例如從

class DBConnection { 
    private $pdo; 

class DBConnection extends PDO { 

分段故障現在發生$db->beginTransaction();的呼叫期間。其他數據庫查詢仍然有效,如果我刪除對beginTransaction()及其匹配的commit()的違規呼叫,它可以正常工作。

違規代碼:

public function getdelay($action, $interval, $tolerance = 2) { 
    ... 
    $this->db->begintransaction(); 
    ... 

當我被封裝PDO對象,而不是繼承相同的代碼工作。

使用gdb我能夠通過附加到進程,等待獲得以下回溯,直到發生段錯誤(全回溯開始於6號線):

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, [email protected]=<error reading variable: Cannot access memory at address 0x7ffcf6731048>) 
    at /build/php5-5.6.24+dfsg/Zend/zend_vm_execute.h:388 
No locals. 

使用版本5.6.24+dfsg-0+deb8u1(Debian的穩定提供的版本)作爲PHP-FPM運行。

我的具體問題

我現在應該做的,爲了讓我的代碼工作(工作的BeginTransaction不段錯誤)?是否最好回到封裝,以避免擴展PDO類?

擴展一個本地PHP類是一個壞主意嗎?這可能會導致奇怪的問題?

+0

我懷疑你已經重寫了一個調用某個驅動程序初始化代碼的類的方法,結果它後來使用了未初始化的變量。 – Barmar

+0

如果你重寫一個方法,你需要確保它完成原始方法所做的一切,或者調用'parent :: methodName()'來傳遞它。 – Barmar

+0

在沒有看到代碼的情況下,無法具體瞭解您做錯了什麼。 – Barmar

回答

1

我發現了我的問題的原因,而且這很令人尷尬地簡單。它與擴展PDO類無關。相反,它與我沒有意識到方法名不區分大小寫。

我原來的數據庫類不得不開始交易的功能:

function begintransaction() { 
    ... 

注意,「T」是小寫。

製作時修改我的數據庫類,我把這個在:

function begintransaction() { 
    return $this->beginTransaction(); 
} 

這樣做的目的是讓所有的小寫begintransaction繼續起作用,其中的一次它出現在舊代碼,作爲PDO的beginTransaction(大寫'T')的包裝。

但是,由於PHP中的方法名稱不區分大小寫,所有這些都是調用自己,創建無限遞歸,從而導致分段錯誤。

我在調試分段錯誤方面的技能很差,我不知道這是由於無限遞歸。