我有一个webapp,当数据库重新启动并尝试使用旧连接时会发生段错误。在gdb --args apache -X
下运行它会产生以下输出:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1212868928 (LWP 16098)]
0xb7471c20 in mysql_send_query () from /usr/lib/libmysqlclient.so.15
我已经检查过驱动程序和数据库都是最新的(DBD::mysql 4.0008,MySQL 5.0.32-Debian_7etch6-log)。
令人讨厌的是,我不能用一个简单的脚本重现这个:
use DBI;
use Test::More tests => 2;
my $dbh = DBI->connect( "dbi:mysql:test", 'root' );
sub test_db {
my ($number) = $dbh->selectrow_array("select 1 ");
return $number;
}
is test_db, 1, "connected to db";
warn "restart db now";
getc;
is test_db, 1, "connected to db";
其中包含以下内容:
ok 1 - connected to db
restart db now at dbd-mysql-test.pl line 23.
DBD::mysql::db selectrow_array failed: MySQL server has gone away at dbd-mysql-test.pl line 17.
not ok 2 - connected to db
# Failed test 'connected to db'
# at dbd-mysql-test.pl line 26.
# got: undef
# expected: '1'
这行为正确,告诉我请求失败的原因。
让我感到困惑的是它是segfaulting,它不应该这样做。因为它似乎只在整个应用程序运行时发生(使用DBIx::Class),所以很难将其减少到测试用例。
我应该从哪里开始调试这个?有没有人见过这个?
更新:进一步的刺激显示它在mod_perl下是一个红鲱鱼。将其缩减为简单的测试脚本后,我现在已发布到DBI mailing list。谢谢你的回答。
答案 0 :(得分:3)
这可能意味着您的mod_perl环境与您通过脚本测试的环境之间存在差异。有些事要检查:
您的mod_perl是否使用相同版本的Perl编译
对于
您是否在mod_perl设置中使用线程?我不相信DBD :: mysql完全是线程安全的。
答案 1 :(得分:2)
我已经看到了这个问题,但我不确定它和你的原因有什么相同。您是否偶然使用某个模块从您的应用程序发送邮件(忘记了名字,对不起)?当我们在一个项目中遇到问题时,经过几天的调试我们发现这个邮件模块用打开的文件描述符做了一些奇怪的事情,然后分叉了另一个调用控制台工具sendmail的进程,这个进程再次对文件描述符做了一些奇怪的事情。我猜其中的一个文件描述符是与数据库的连接,但我仍然不确定。当我们切换到另一个模块发送邮件时,问题就消失了。也许值得一看你。
答案 2 :(得分:2)
如果您遇到段错误,是否有核心文件?如果没有,请检查ulimit -c。如果返回0,则系统不会创建核心文件,您必须更改它。如果您有核心文件,可以使用gdb或类似工具进行调试。它不是特别有趣,但它是可能的。命令的开头看起来像:
gbd /usr/bin/httpd core
网上有很多关于debugging core files的教程。
更新:刚刚找到了ensuring you get core dumps from mod_perl的参考资料。这应该会有所帮助。
答案 3 :(得分:1)
这是旧DBD :: mysql中的一个已知问题。升级它(4.008 不最新)。
https://rt.cpan.org/Public/Bug/Display.html?id=37027附有一个简单的测试脚本 这将触发这个错误。