Я сделал некоторые изменения в своем коде абстракции БД, и теперь он работает с ошибками, и я не уверен, как это исправить.
Изменить: я нашел причину моей проблемы, и, к сожалению, это не имеет ничего общего с тем, что я написал в этом вопросе. Смотрите мой ответ ниже для более подробной информации о том, что я испортил.
Мои изменения включали изменение с инкапсулирующая объект 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, 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.
Использование версии 5.6.24+dfsg-0+deb8u1
(Стабильная версия Debian) работает как PHP-FPM.
Мой конкретный вопрос
Что мне теперь делать, чтобы заставить мой код работать (beginTransaction работает без segfaulting)? Было бы лучше вернуться к инкапсуляции, чтобы избежать расширения класса PDO?
Было ли плохой идеей расширить нативный класс PHP? Это может привести к странным проблемам?
Я нашел причину своей проблемы, и это смущающе просто. Это не связано с расширением класса PDO. Вместо этого это связано с тем, что я не понимаю, что имена методов не чувствительны к регистру.
В моем исходном классе базы данных была функция для начала транзакции:
function begintransaction() {
...
Обратите внимание, что буква «t» в нижнем регистре.
При внесении изменений в мой класс базы данных я помещаю это в:
function begintransaction() {
return $this->beginTransaction();
}
Цель этого состояла в том, чтобы позволить все строчные begintransaction
продолжать функционировать везде, где это появилось в старом коде, выступая в качестве оболочки для PDO beginTransaction
(с большой буквы «Т»).
Однако, поскольку имена методов не чувствительны к регистру в PHP, все, что он делает, это вызывает сам себя, создавая бесконечную рекурсию, которая приводит к ошибке сегментации.
Мои навыки отладки ошибки сегментации были достаточно плохими, поэтому я не осознавал, что это из-за бесконечной рекурсии.
Других решений пока нет …