http://qs321.pair.com?node_id=367162

eyepopslikeamosquito has asked for the wisdom of the Perl Monks concerning the following question:

This is the third installment of my Perl threads experiments. Again, I have something I don't understand and seek advice before perl-bugging it.

The test program below crashes for me on both Linux and Windows when you use an external sort function -- but not if you use an inline sort block. I am using Perl 5.8.4. Any explanations?

#!/usr/bin/perl -w use strict; use threads; $|=1; sub mycmp { length($b) <=> length($a) } sub do_one_thread { my $kid = shift; warn "kid $kid before sort\n"; my @list = ( 'x', 'yy', 'zzz', 'a', 'bb', 'ccc', 'aaaaa', 'z', 'hello', 's', 'thisisalongname', '1', '2', '3', 'abc', 'xyz', '1234567890', 'm', 'n', 'p' ); for my $j (1..1000) { # This does not crash # for my $k (sort { length($b) <=> length($a) } @list) {} # Yet this does for my $k (sort mycmp @list) {} } warn "kid $kid after sort\n"; } sub do_threads { my $nthreads = shift; my @kids = (); for my $i (1..$nthreads) { my $t = threads->new(\&do_one_thread, $i); warn "parent $$: continue\n"; push(@kids, $t); } for my $t (@kids) { warn "parent $$: waiting for join\n"; $t->join(); warn "parent $$: thread exited\n"; } } # do_threads(1); # does not crash do_threads(2); # crashes

Replies are listed 'Best First'.
Re: Perl threads sort test program crashes (UPDATED: CAN reproduce win32/5.8.4)
by BrowserUk (Patriarch) on Jun 16, 2004 at 11:19 UTC

    I just re-built 5.8.4 from scratch and ran your test 100 times without failure.

    Update: I can now reproduce the failure--reliably--with 5.8.4. This doesn't happen with 5.8.3/AS809.

    The trick seems to be taking the focus away from the session running the test. If I bring up the task manager while running the loop below, every run will fail whilst the task manager has the focus and every run will complete if the cmd session has the focus.

    A timing issue for sure.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon

      Here's the disassembly of the segfault.


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
Re: Perl threads sort test program crashes
by PodMaster (Abbot) on Jun 16, 2004 at 10:50 UTC
    It crashes for me also, but changing mycmp to sub mycmp { length($main::b) <=> length($main::a) } seems to fix it. I think this is a bug.

    update: This is on v5.8.3 built for i386-linux-thread-multi. I just tried it again and I can't get your original version to crash. Weird.

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Perl threads sort test program crashes (Cannot reproduce (win32/5.8.3/AS809))
by BrowserUk (Patriarch) on Jun 16, 2004 at 10:39 UTC

    It doesn't crash for me?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
Re: Perl threads sort test program crashes
by mpeppler (Vicar) on Jun 16, 2004 at 11:55 UTC
    I get a segfault as well (even if I change $a and $b to $main::a and $main::b). The stack trace shows that it fails in pp_sort.c (sortcv), apparently with NULL pointers for a and b:
    #0 sortcv (my_perl=0x9a4c7a0, a=0x0, b=0x0) at pp_sort.c:1591 1591 pp_sort.c: No such file or directory.
    Running it under the debugger worked a few times, and then crashed with a SEGV, at the same location.

    perl 5.8.3 i386-linux-thread-multi.

    Michael

Re: Perl threads sort test program crashes
by eyepopslikeamosquito (Archbishop) on Jun 17, 2004 at 05:33 UTC

    I hacked the thread-id into deb.c/Perl_vdeb() so that perl -Dt also prints thread-id. The crashes seem to occur when one thread does a POPBLOCK/LEAVE as a sort finishes inside the for(). I further noticed that when I change:

    for my $k (sort mycmp @list) {}

    to simply:

    sort mycmp @list;

    the crashes go away. Edited perl -Dtlsv output follows:

    4440: (p5-5A.pl:7) gvsv(main::a) 4440: (p5-5A.pl:7) length 4440: (p5-5A.pl:7) ncmp 4440: (p5-5A.pl:7) leavesub 4440: (p5-5A.pl:7) nextstate 4440: (p5-5A.pl:7) gvsv(main::b) 4440: (p5-5A.pl:7) length 4440: (p5-5A.pl:7) gvsv(main::a) 4440: (p5-5A.pl:7) length 9432: (p5-5A.pl:7) length 9432: (p5-5A.pl:7) ncmp 9432: (p5-5A.pl:7) leavesub 9432: (p5-5A.pl:7) nextstate 9432: (p5-5A.pl:7) gvsv(main::b) 9432: (p5-5A.pl:7) length 9432: (p5-5A.pl:7) gvsv(main::a) 9432: (p5-5A.pl:7) length 9432: (p5-5A.pl:7) ncmp 4440: (p5-5A.pl:7) ncmp 4440: (p5-5A.pl:7) leavesub 4440: (p5-5A.pl:7) nextstate 4440: (p5-5A.pl:7) gvsv(main::b) 4440: (p5-5A.pl:7) length 4440: (p5-5A.pl:7) gvsv(main::a) 4440: (p5-5A.pl:7) length 4440: (p5-5A.pl:7) ncmp *** tid=4440 crashed around here *** 9432: (p5-5A.pl:7) leavesub 9432: (p5-5A.pl:19) POPBLOCK scope 7 at ..\pp_sort.c:1579 9432: (p5-5A.pl:19) LEAVE scope 7 at ..\pp_sort.c:1627 9432: (p5-5A.pl:19) enteriter 9432: (p5-5A.pl:19) ENTER scope 7 at ..\pp_ctl.c:1666 9432: (p5-5A.pl:19) ENTER scope 8 at ..\pp_ctl.c:1697 9432: (p5-5A.pl:19) iter 9432: (p5-5A.pl:19) and (tid=9432 continues on)
Re: Perl threads sort test program crashes
by eyepopslikeamosquito (Archbishop) on Jun 17, 2004 at 02:42 UTC

    In the test program, I found it useful to change this line in do_one_thread():

    for my $j (1..1000) {

    to:

    for my $j (1..99999999) {

    to demonstrate that the crash is not related to thread destruction.

    As reported by others, the crash occurs when sortcv attempts to read memory at address zero. WinDbg spew of crash follows (perl 5.8.4):

    0:002> ~* kv 0 Id: 2c48.2ad4 Suspend: 1 Teb: 7ffde000 Unfrozen ChildEBP RetAddr Args to Child 0140fbf4 77f5c534 77e7a62d 000007c0 00000000 SharedUserData!SystemCall +Stub+0x4 (FPO: [0,0,0]) 0140fbf8 77e7a62d 000007c0 00000000 00000000 ntdll!NtWaitForSingleObje +ct+0xc (FPO: [3,0,0]) 0140fc5c 77e7ac21 000007c0 ffffffff 00000000 kernel32!WaitForSingleObj +ectEx+0xa8 (FPO: [Non-Fpo]) *** WARNING: Unable to verify checksum for c:\pperl\lib\auto\threads\t +hreads.dll 0140fc6c 10002335 000007c0 ffffffff 00224ff8 kernel32!WaitForSingleObj +ect+0xf (FPO: [2,0,0]) 0140fca8 10002de8 00224fec 00225fa4 00000000 threads!Perl_ithread_join ++0xa5 (CONV: cdecl) [threads.xs @ 573] 0140fce8 280a1cc2 00224fec 01834f20 018e8bc4 threads!XS_threads_join+0 +xc0 (CONV: cdecl) [threads.xs @ 700] 0140fd80 2801d44f 00224fec 0140fda0 28059e3a perl58!Perl_pp_entersub+0 +x748 (CONV: cdecl) [..\pp_hot.c @ 2854] 0140fd8c 28059e3a 00224fec 00000001 0140fdd8 perl58!Perl_runops_debug+ +0x1c0 (CONV: cdecl) [..\dump.c @ 1442] 0140fda0 2805989c 00224fec 00000001 00000ff0 perl58!S_run_body+0x250 ( +CONV: cdecl) [..\perl.c @ 1921] 0140fe1c 2815d038 00224fec 00224fec 00000000 perl58!perl_run+0xb5 (CON +V: cdecl) [..\perl.c @ 1840] *** WARNING: Unable to verify checksum for perl.exe 0140ff38 00401025 00000002 00224e60 00223200 perl58!RunPerl+0xc6 (CONV +: cdecl) [perllib.c @ 202] 0140ff4c 00401113 00000002 00224e60 00223200 perl!main+0x15 (CONV: cde +cl) [perlmain.c @ 18] 0140ffc0 77e814c7 00000000 00000000 7ffdf000 perl!mainCRTStartup+0xe3 0140fff0 00000000 00401030 00000000 00000000 kernel32!BaseProcessStart ++0x23 (FPO: [Non-Fpo]) 1 Id: 2c48.2ed8 Suspend: 1 Teb: 7ffdd000 Unfrozen ChildEBP RetAddr Args to Child 02b1fd70 28100a8f 018d9914 0197e934 00000001 perl58!Perl_sv_grow+0x187 + (CONV: cdecl) [..\sv.c @ 1642] 02b1fdd8 281072c8 018d9914 0197e934 018da290 perl58!Perl_sv_setsv_flag +s+0x16c8 (CONV: cdecl) [..\sv.c @ 4019] 02b1fdf4 2808a343 018d9914 018da290 00000001 perl58!Perl_sv_mortalcopy ++0x8c (CONV: cdecl) [..\sv.c @ 6746] 02b1fe3c 2801d44f 018d9914 02b1fe54 2805ad46 perl58!Perl_pp_leaveloop+ +0x1d5 (CONV: cdecl) [..\pp_ctl.c @ 1774] 02b1fe48 2805ad46 018d9914 02b1ff54 2805a896 perl58!Perl_runops_debug+ +0x1c0 (CONV: cdecl) [..\dump.c @ 1442] 02b1fe54 2805a896 018d9914 02b1ff1c 00000000 perl58!S_call_body+0x50 ( +CONV: cdecl) [..\perl.c @ 2285] 02b1ff54 10001832 018d9914 0197e7cc 00000004 perl58!Perl_call_sv+0x701 + (CONV: cdecl) [..\perl.c @ 2203] 02b1ffb4 77e7d33b 0022e28c 018dd550 0101000b threads!Perl_ithread_run+ +0x219 (CONV: stdcall) [threads.xs @ 300] 02b1ffec 00000000 1000106e 0022e28c 00000000 kernel32!BaseThreadStart+ +0x37 (FPO: [Non-Fpo]) # 2 Id: 2c48.1ce4 Suspend: 1 Teb: 7ffdc000 Unfrozen ChildEBP RetAddr Args to Child 03b1f794 280aee43 0193412c 019ef8a0 019ef888 perl58!sortcv+0x21 (CONV: + cdecl) [..\pp_sort.c @ 1638] 03b1fd08 280aebae 0193412c 019ea658 00000014 perl58!S_mergesortsv+0x28 +e (CONV: cdecl) [..\pp_sort.c @ 424] 03b1fd34 280b1245 0193412c 019ea658 00000014 perl58!Perl_sortsv+0xae ( +CONV: cdecl) [..\pp_sort.c @ 1410] 03b1fe3c 2801d44f 0193412c 03b1fe54 2805ad46 perl58!Perl_pp_sort+0xcde + (CONV: cdecl) [..\pp_sort.c @ 1577] 03b1fe48 2805ad46 0193412c 03b1ff54 2805a896 perl58!Perl_runops_debug+ +0x1c0 (CONV: cdecl) [..\dump.c @ 1442] 03b1fe54 2805a896 0193412c 03b1ff1c 00000000 perl58!S_call_body+0x50 ( +CONV: cdecl) [..\perl.c @ 2285] 03b1ff54 10001832 0193412c 019ef7bc 00000004 perl58!Perl_call_sv+0x701 + (CONV: cdecl) [..\perl.c @ 2203] 03b1ffb4 77e7d33b 01950fac 018e7050 0101000b threads!Perl_ithread_run+ +0x219 (CONV: stdcall) [threads.xs @ 300] 03b1ffec 00000000 1000106e 01950fac 00000000 kernel32!BaseThreadStart+ +0x37 (FPO: [Non-Fpo]) 0:002> u eip perl58!sortcv+0x21 [..\pp_sort.c @ 1638]: 280b1932 8b02 mov eax,[edx] 280b1934 8b4820 mov ecx,[eax+0x20] 280b1937 8b550c mov edx,[ebp+0xc] 280b193a 8911 mov [ecx],edx 280b193c 8b4508 mov eax,[ebp+0x8] 280b193f 8b88a8010000 mov ecx,[eax+0x1a8] 280b1945 8b11 mov edx,[ecx] 280b1947 8b4220 mov eax,[edx+0x20] 0:002> .exr -1 ExceptionAddress: 280b1932 (perl58!sortcv+0x00000021) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 00000000 Parameter[1]: 00000000 Attempt to read from address 00000000