perl5-dbi / dbi

DBI - The Perl 5 Database Interface

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Segfault from XS_DBI_dispatch

horgh opened this issue · comments

This might be the same thing as #51, but the backtrace looks a little different: It looks different now that I see both with line numbers!

#0  0x00000000004ec6e6 in Perl_mg_get (sv=0xad21190) at mg.c:185
185         newmg = cur = head = mg = SvMAGIC(sv);
(gdb) bt
#0  0x00000000004ec6e6 in Perl_mg_get (sv=0xad21190) at mg.c:185
#1  0x000000000052b50d in Perl_sv_2pv_flags (sv=0xad21190, lp=lp@entry=0x0, flags=flags@entry=2) at sv.c:2943
#2  0x00007f3074dcb6b4 in err_hash (imp_xxh=0x296e60b0, imp_xxh=0x296e60b0) at DBI.xs:891
#3  0x00007f3074de10d7 in XS_DBI_dispatch (cv=0x8c6cd08) at DBI.xs:3565
#4  0x000000000051286d in Perl_pp_entersub () at pp_hot.c:4228
#5  0x000000000044a666 in Perl_call_sv (sv=sv@entry=0x8c6cd08, flags=<optimized out>, flags@entry=45) at perl.c:2856
#6  0x000000000051968d in S_curse (sv=sv@entry=0x2a1723e0, check_refcnt=check_refcnt@entry=true) at sv.c:6972
#7  0x0000000000519edc in Perl_sv_clear (orig_sv=orig_sv@entry=0x2a1723e0) at sv.c:6576
#8  0x000000000051ae5e in Perl_sv_free2 (sv=0x2a1723e0, rc=<optimized out>) at sv.c:7073
#9  0x00000000005172d2 in S_visit (f=0x51aff0 <do_clean_objs>, flags=2048, mask=2048) at sv.c:476
#10 0x000000000051b40c in Perl_sv_clean_objs () at sv.c:627
#11 0x000000000044e499 in perl_destruct (my_perl=<optimized out>) at perl.c:864
#12 0x00000000004224c4 in main (argc=3, argv=0x7ffe980cfa08, env=0x7ffe980cfa28) at perlmain.c:134

This is with Perl 5.26.2 and DBI 1.641.

Unfortunately the program I'm running is very large and I can't share it. I don't have a small test case. I can't explain what's happening. It looks like it happens during program shutdown though.

Thank you!

By the way, I'd be happy to re-run my program (or #51's) with any changes if that would help figure out the problem. I took a look at the function in question and feel out of my depth!

It's something in err_hash().

Since the world is falling apart around us during global destruction nothing can be relied upon. In that situation err_hash isn't providing enough value to worry about. You could make it return early if PL_dirty is true.

Thanks for the tip!

I tried it. Here's the change I made:

diff --git a/DBI.xs b/DBI.xs
index 3b55e56..16c81eb 100644
--- a/DBI.xs
+++ b/DBI.xs
@@ -882,6 +882,9 @@ set_err_sv(SV *h, imp_xxh_t *imp_xxh, SV *err, SV *errstr, SV *state, SV *method
 static U32
 err_hash(pTHX_ imp_xxh_t *imp_xxh)
 {
+    if (PL_dirty) {
+        return 1;
+    }
     SV *err_sv = DBIc_ERR(imp_xxh);
     SV *errstr_sv;
     I32 hash = 1;

With it, we still segfault, but the backtrace looks different:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f2225c6a9c3 in XS_DBI_dispatch (cv=0x8514b28) at DBI.xs:3375
3375        if ((i = DBIc_DEBUGIV(imp_xxh))) { /* merge handle into global */
(gdb) bt
#0  0x00007f2225c6a9c3 in XS_DBI_dispatch (cv=0x8514b28) at DBI.xs:3375
#1  0x000000000051286d in Perl_pp_entersub () at pp_hot.c:4228
#2  0x000000000044a666 in Perl_call_sv (sv=sv@entry=0x8514b28, flags=<optimized out>, flags@entry=45) at perl.c:2856
#3  0x000000000051968d in S_curse (sv=sv@entry=0x29628458, check_refcnt=check_refcnt@entry=true) at sv.c:6972
#4  0x0000000000519edc in Perl_sv_clear (orig_sv=orig_sv@entry=0x29628458) at sv.c:6576
#5  0x000000000051ae5e in Perl_sv_free2 (sv=0x29628458, rc=<optimized out>) at sv.c:7073
#6  0x00000000005172d2 in S_visit (f=0x51aff0 <do_clean_objs>, flags=2048, mask=2048) at sv.c:476
#7  0x000000000051b40c in Perl_sv_clean_objs () at sv.c:627
#8  0x000000000044e499 in perl_destruct (my_perl=<optimized out>) at perl.c:864
#9  0x00000000004224c4 in main (argc=3, argv=0x7ffefb8ca468, env=0x7ffefb8ca488) at perlmain.c:134

Actually, that is the same line as the crash in #51 now. So possibly they are related after all!

Yes, looks like this issue is a duplicate of #51.