Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SEGV from sprintf in a thread #2697

Closed
p5pRT opened this issue Oct 9, 2000 · 3 comments
Closed

SEGV from sprintf in a thread #2697

p5pRT opened this issue Oct 9, 2000 · 3 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 9, 2000

Migrated from rt.perl.org#4412 (status was 'resolved')

Searchable as RT4412$

@p5pRT
Copy link
Author

p5pRT commented Oct 9, 2000

From hv@hugo.hybyte.com

Created by hv@hugo.hybyte.com

Hugo% perl -MThread -wl
my $t = new Thread \&a;
sub a {
  my $cost = 1;
  print "a";
  sprintf "%.0f", $cost;
  print "b"
}
print $t->join
__END__
Useless use of sprintf in void context at - line 5.
a
Segmentation fault (core dumped)
Hugo%

I don't see the same problem on another machine built similarly
except for osvers=2.2.12-20, optimize=-O2 (no debugging) and
libc=/lib/libc-2.1.2.so. Is this perhaps a known problem with
libc-2.1.3?

gdb only seems to know about the main thread in the core dump,
but I've not tried to use gdb's threading commands before; "thread
apply all bt" gives me a backtrace for 'Thread 1' but nothing else.
(gdb is version 'GNU gdb 19991004'.)

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl v5.6.0:

Configured by hv at Fri Oct  6 15:34:17 BST 2000.

Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.2.14-5.0, archname=i686-linux-thread
    uname='linux hugo 2.2.14-5.0 #1 tue mar 7 21:07:39 est 2000 i686 unknown '
    config_args='-des -Doptimize=-g -O6 -Dprefix=/opt/perl-5.6.0 -Dusethreads -Duse5005threads -Dusedevel'
    hint=previous, useposix=true, d_sigaction=define
    usethreads=define use5005threads=define useithreads=undef usemultiplicity=undef
    useperlio=undef d_sfio=undef uselargefiles=define 
    use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef
  Compiler:
    cc='cc', optimize='-g -O6', gccversion=egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
    cppflags='-D_REENTRANT -DDEBUGGING -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    ccflags ='-D_REENTRANT -DDEBUGGING -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    stdchar='char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lpthread -lc -lposix -lcrypt
    libc=/lib/libc-2.1.3.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.6.0:
    /opt/perl-5.6.0/lib/5.6.0/i686-linux-thread
    /opt/perl-5.6.0/lib/5.6.0
    /opt/perl-5.6.0/lib/site_perl/5.6.0/i686-linux-thread
    /opt/perl-5.6.0/lib/site_perl/5.6.0
    /opt/perl-5.6.0/lib/site_perl
    .


Environment for perl v5.6.0:
    HOME=/home/hv
    LANG=en_US
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/hv/bin:/usr/bin:/usr/local/bin:/bin:/usr/X11R6/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash


@p5pRT
Copy link
Author

p5pRT commented Oct 9, 2000

From [Unknown Contact. See original ticket]

In <200010091415.PAA14426@​hugo.hybyte.com>, hv@​hugo.hybyte.com writes​:
:Hugo% perl -MThread -wl
:my $t = new Thread \&a;
:sub a {
: my $cost = 1;
: print "a";
: sprintf "%.0f", $cost;
: print "b"
:}
:print $t->join
:__END__
:Useless use of sprintf in void context at - line 5.
:a
:Segmentation fault (core dumped)
:Hugo%

This appears to have been an optimisation problem​: rebuilding perl
with "-g -O2" instead of "-g -O6" fixed the problem.

If time permits I'll try to narrow down the problem region.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Oct 10, 2000

From [Unknown Contact. See original ticket]

In <200010091654.RAA07052@​hugo.hybyte.com>, hv@​hugo.hybyte.com writes​:
:In <200010091415.PAA14426@​hugo.hybyte.com>, hv@​hugo.hybyte.com writes​:
:​:Hugo% perl -MThread -wl
:​:my $t = new Thread \&a;
:​:sub a {
:​: my $cost = 1;
:​: print "a";
:​: sprintf "%.0f", $cost;
:​: print "b"
:​:}
:​:print $t->join
:​:__END__
:​:Useless use of sprintf in void context at - line 5.
:​:a
:​:Segmentation fault (core dumped)
:​:Hugo%
:
:This appears to have been an optimisation problem​: rebuilding perl
:with "-g -O2" instead of "-g -O6" fixed the problem.

Ah, no. It is a -DDEBUGGING problem​: PL_efloat{buf,size} are wrongly
initialised to 0xabababab in additional threads if DEBUGGING is
enabled. This bad pointer is then passed to the libc sprintf.

I think the attached patch puts the fix in the right place. I haven't
checked the rest of struct perl_thread for similar problems, but I'm
sure someone should.

I think this patch should be suitable for both 5.6.1 and 5.7.x.

Hugo

Inline Patch
--- util.c.old	Wed Mar 22 15:19:01 2000
+++ util.c	Tue Oct 10 13:53:32 2000
@@ -3479,6 +3479,8 @@
     PL_dirty = 0;
     PL_localizing = 0;
     Zero(&PL_hv_fetch_ent_mh, 1, HE);
+    PL_efloatbuf = (char*)NULL;
+    PL_efloatsize = 0;
 #else
     Zero(thr, 1, struct perl_thread);
 #endif
--- t/lib/thr5005.t.old	Wed Mar 22 14:43:18 2000
+++ t/lib/thr5005.t	Tue Oct 10 14:03:04 2000
@@ -13,7 +13,7 @@
     $ENV{PERL_DESTRUCT_LEVEL} = 0 unless $ENV{PERL_DESTRUCT_LEVEL} > 3;
 }
 $| = 1;
-print "1..21\n";
+print "1..22\n";
 use Thread 'yield';
 print "ok 1\n";
 
@@ -89,6 +89,18 @@
 my $longe  = " short.";
 my $thr1 = new Thread \&threaded, $short, $shorte, "19";
 my $thr2 = new Thread \&threaded, $long, $longe, "20";
+my $thr3 = new Thread \&testsprintf, "21";
+
+sub testsprintf {
+  my $testno = shift;
+  # this may coredump if thread vars are not properly initialised
+  my $same = sprintf "%.0f", $testno;
+  if ($testno eq $same) {
+    print "ok $testno\n";
+  } else {
+    print "not ok $testno\t# '$testno' ne '$same'\n";
+  }
+}
 
 sub threaded {
   my ($string, $string_end, $testno) = @_;
@@ -115,4 +127,5 @@
 }
 $thr1->join;
 $thr2->join;
-print "ok 21\n";
+$thr3->join;
+print "ok 22\n";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant