5

我有一个 web 应用程序,当数据库重新启动并尝试使用旧连接时会出现段错误。在下运行它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'

这行为正确,告诉我请求失败的原因。

让我难过的是它是段错误,它不应该这样做。由于它似乎只在整个应用程序运行(使用DBIx::Class)时发生,因此很难将其简化为测试用例。

我应该从哪里开始调试呢?有没有其他人看过这个?

更新:进一步的刺激表明它在 mod_perl 之下是一个红鲱鱼。将其简化为一个简单的测试脚本后,我现在已将其发布到DBI 邮件列表。感谢您的回答。

4

4 回答 4

3

这可能意味着您的 mod_perl 环境与您通过脚本测试的环境之间存在差异。需要检查的一些事项:

  • 你的 mod_perl 是用相同版本的 Perl 编译的吗

  • 两者的@INC 是否相同

  • 你在你的 mod_perl 设置中使用线程吗?我不相信 DBD::mysql 是完全线程安全的。

于 2008-10-08T13:30:50.483 回答
2

我已经看到了这个问题,但我不确定它与您的原因相同。您是否偶然使用某个模块从您的应用程序中发送邮件(忘记名称,抱歉)?当我们在一个项目中遇到问题时,经过几天的调试,我们发现这个邮件模块对打开的文件描述符做了奇怪的事情,然后分叉了另一个名为控制台工具 sendmail 的进程,它再次对文件描述符做了奇怪的事情。我猜它弄乱的文件描述符之一是与数据库的连接,但我仍然不确定。当我们切换到另一个模块发送邮件时,问题就消失了。也许它也值得你看看。

于 2008-10-08T22:31:10.673 回答
2

如果您遇到段错误,您是否有一个核心文件?如果没有,请检查 ulimit -c。如果返回 0,您的系统将不会创建核心文件,您必须更改它。如果您确实有核心文件,则可以使用 gdb 或类似工具对其进行调试。这不是特别有趣,但有可能。该命令的开头将类似于:

gbd /usr/bin/httpd core

有很多教程用于调试分散在 Web 上的核心文件。

更新:刚刚找到了确保您从 mod_perl 获得核心转储的参考。那应该有帮助。

于 2008-10-09T07:12:36.313 回答
1

这是旧 DBD::mysql 中的一个已知问题。升级它(4.008不是最新的)。

https://rt.cpan.org/Public/Bug/Display.html?id=37027附有一个简单的测试脚本 ,将触发此错误。

于 2010-08-15T22:56:28.493 回答