Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2011-11

threads crash on FreeBSD 9 RC1, FPC 2.6RC1

6 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Helmut Hartl

Hi,

while testing our code on freebsd 9RC1/32 bit with fpc 2.6rc1 it seems that all programs compiled on that system using threads crash with an "Illegal Instruction 4 (core dumped)" error. Binaries compiled on Freebsd 8.2/32 and transferred to the 9RC1 box work, which is a bit strange.

Any ideas ?

further details below:

Simple test case:

---
program thrd;
{$mode objfpc}{$H+}
uses
   cthreads,Classes;
type
    T=class(TThread)
    private
     i:integer;
     procedure Execute;override;
    end;
procedure T.Execute;
begin
   inc(i);
end;
begin
   T.create(false);
end.

---

After compiling fpc 2_6 fixes with debug info, and running the program gdb stops at the below marked line in cthreads.pp

     procedure CAllocateThreadVars;
       var
         dataindex : pointer;
       begin
         { we've to allocate the memory from system  }
         { because the FPC heap management uses      }
         { exceptions which use threadvars but       }
         { these aren't allocated yet ...            }
         { allocate room on the heap for the thread vars }
>>>>
DataIndex:=Pointer(Fpmmap(nil,threadvarblocksize,3,MAP_PRIVATE+MAP_ANONYMOUS,-1,0));
         FillChar(DataIndex^,threadvarblocksize,0);
         pthread_setspecific(tlskey,dataindex);
       end;
helmut

Reply by email

Pierre Free Pascal
to Helmut Hartl
Show quoted text 5 lines
while testing our code on freebsd 9RC1/32 bit with fpc 2.6rc1 it seems that all programs compiled on that system using threads crash with an "Illegal Instruction 4 (core dumped)" error. Binaries compiled on Freebsd 8.2/32 and transferred to the 9RC1 box work, which is a bit strange.

There is no warranty that an executable for a given version will work on a later...
If only one system call interface is changed, this is enough to break everything!

Show quoted text 42 lines
Any ideas ? further details below: Simple test case: --- program thrd; {$mode objfpc}{$H+} uses cthreads,Classes; type T=class(TThread) private i:integer; procedure Execute;override; end; procedure T.Execute; begin inc(i); end; begin T.create(false); end. --- After compiling fpc 2_6 fixes with debug info, and running the program gdb stops at the below marked line in cthreads.pp procedure CAllocateThreadVars; var dataindex : pointer; begin { we've to allocate the memory from system } { because the FPC heap management uses } { exceptions which use threadvars but } { these aren't allocated yet ... } { allocate room on the heap for the thread vars } >>>>>
DataIndex:=Pointer(Fpmmap(nil,threadvarblocksize,3,MAP_PRIVATE+MAP_ANONYMOUS
,-1,0)); FillChar(DataIndex^,threadvarblocksize,0); pthread_setspecific(tlskey,dataindex); end;

What does
(gdb) x /10i $rip
(or $eip if it is an i386 executable)
give as output?

Pierre Muller

Reply by email

Helmut Hartl
to Pierre Free Pascal
Pierre Free Pascal wrote 10 lines
> while testing our code on freebsd 9RC1/32 bit with fpc 2.6rc1 > it seems that all programs compiled on that system using threads crash > with an "Illegal Instruction 4 (core dumped)" error. > Binaries compiled on Freebsd 8.2/32 and transferred to the 9RC1 box work, > which is a bit strange. There is no warranty that an executable for a given version will work on a later... If only one system call interface is changed, this is enough to break everything!

What made me wonder was, that the (old) binary compiled on 8.2 still worked on 9.0RC1
after the upgrade from 8.2 -> 9.0 (same machine) while the new one compiled with the same
compiler after the upgrade crashed.
If I copy back the new binary (same source) to a 8.2 machine it fails with a linker failure
unresolved symbol "sem_init". But thats only a observation that i am too dumb to
understand atm, and maybe unrelated to the main problem.

My (quick) deduction from the output below was that somewhow the initialisation of the memory
managment for the new thread gone bad, as the crash seems to be in the new thread.
Hence I changed the memorymanager to cmem and the problem goes away, now our software works and passes it's testsuites.

Show quoted text 7 lines
> Any ideas ? > .... > What does (gdb) x /10i $rip (or $eip if it is an i386 executable) give as output?

Here what Is what I have got on that:

/usr/home/helly/pascal/fpctest]$ /usr/local/bin/gdb73.1 ./project_test
GNU gdb (GDB) 7.3.1 [GDB v7.3.1 for FreeBSD]
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details.
This GDB was configured as "i386-portbld-freebsd9.0". For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/home/helly/pascal/fpctest/project_test...done. (gdb) r
Starting program: /usr/home/helly/pascal/fpctest/project_test [New LWP 100461]

Program received signal SIGTRAP, Trace/breakpoint trap. [Switching to LWP 100461]
0x280a0e71 in r_debug_state () from /usr/libexec/ld-elf.so.1 (gdb) c
Continuing.
[New Thread 28404300 (LWP 100461)]
test
[New Thread 28404900 (LWP 100465)]

Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 28404900 (LWP 100465)]
0x0805c34d in WAITFREE_VAR (PMCV=0x282d10a4) at
/usr/home/helly/pascal/fpc_fixes_2_6/rtl/inc/heap.inc:1084 1084 pmcv^.next_var := pmcv^.freelists^.waitvar; (gdb) bt full
#0 0x0805c34d in WAITFREE_VAR (PMCV=0x282d10a4) at /usr/home/helly/pascal/fpc_fixes_2_6/rtl/inc/heap.inc:1084 No locals.
#1 0x282d10b0 in ?? ()
No symbol table info available.
#2 0x280ec46a in ?? () from /lib/libthr.so.3
No symbol table info available.
#3 0x00000000 in ?? ()
No symbol table info available.
(gdb) x /10i $eip
=> 0x805c34d <WAITFREE_VAR+21>: mov 0xa0(%eax),%eax 0x805c353 <WAITFREE_VAR+27>: mov %eax,0xc(%ebx) 0x805c356 <WAITFREE_VAR+30>: mov 0x4(%ebx),%eax 0x805c359 <WAITFREE_VAR+33>: mov %ebx,0xa0(%eax) 0x805c35f <WAITFREE_VAR+39>: mov $0x80e5698,%eax 0x805c364 <WAITFREE_VAR+44>: call 0x805cd28 <LEAVECRITICALSECTION> 0x805c369 <WAITFREE_VAR+49>: mov (%esp),%ebx 0x805c36c <WAITFREE_VAR+52>: add $0x4,%esp
0x805c36f <WAITFREE_VAR+55>: ret
0x805c370 <SYSFREEMEM_FIXED>: sub $0xc,%esp
(gdb)

Reply by email

Sergei Gorelkin
to Helmut Hartl

09.11.2011 22:58, Helmut Hartl пишет:

Show quoted text 6 lines
My (quick) deduction from the output below was that somewhow the initialisation of the memory managment for the new thread gone bad, as the crash seems to be in the new thread. Hence I changed the memorymanager to cmem and the problem goes away, now our software works and passes it's testsuites.

Unfortunately there is a major flaw in thread initialization sequence: using memory manager before it is initialized. E.g. in rtl/unix/cthreads.pp, around line 280 there is the following code:

    ti:=pthreadinfo(param)^;
    dispose(pthreadinfo(param));        <- memory manager used
    { Initialize thread }
    InitThread(ti.stklen);              <- memory manager initialized (among other stuff)
    { Start thread function }

This applies to all targets except Windows (which I fixed in rev.17938). How it happened to work without crashing until now, I don't know. I also won't claim that it *is* the reason of crash in your program, but it may be a reason.

Regards,
Sergei

Reply by email

Pierre Free Pascal
to Helmut Hartl: while testing our code on freebsd 9RC1/32 bit with fpc 2.6rc1 it seems that all programs…

Tanks to Helmut,
we now also have a FreeBSD with OS 9RC1
to test Free Pascal on:

The testsuite reveals no difference between
native OS8 or OS9RC1:
http://www.freepascal.org/testsuite/cgi-bin/testsuite.cgi?action=1&run1id=97 488&run2id=97496&noskipped=1&failedonly=1

I will also try to test in cross configuration to see what happens.

On i386, I get:
http://www.freepascal.org/testsuite/cgi-bin/testsuite.cgi?action=1&run1id=97 491&run2id=97501&noskipped=1&failedonly=1
but the difference is simply due to a change in installed libraries....

So FreBSD 8 and 9RC1 seem to be quite perfectly binary compatible....

Pierre Muller

FreeBSD compilation on 8.2 and test run on 9RC1 gives no noticeable changes:

http://www.freepascal.org/testsuite/cgi-bin/testsuite.cgi?action=1&run1id=97 552&run2id=97574&noskipped=1&failedonly=1

The two changes are simply due to the fact
that zlib shared library probably is also installed on the 8.2 VM and not on the 9RC1.
The second change is due to the fact that on 8.2 the RTL was compiled using DEUG=1 make option,
which changed the outcome of that particular test
about setting position of a stream to -1.

Reply by email

Pierre Free Pascal
to Helmut Hartl: What made me wonder was, that the (old) binary compiled on 8.2 still worked on 9.0RC1…
Show quoted text 12 lines
-----Message d'origine----- De : [mailto:fpc-devel- De la part de Helmut Hartl Envoyé : mercredi 9 novembre 2011 20:58 À : Objet : Re: [fpc-devel] threads crash on FreeBSD 9 RC1, FPC 2.6RC1 Am 09.11.11 14:12, schrieb Pierre Free Pascal: >> while testing our code on freebsd 9RC1/32 bit with fpc 2.6rc1 >> it seems that all programs compiled on that system using threads crash >> with an "Illegal Instruction 4 (core dumped)" error. >> Binaries compiled on Freebsd 8.2/32 and transferred to the 9RC1 box

work,

Show quoted text 16 lines
>> which is a bit strange. > There is no warranty that an executable for a given version > will work on a later... > If only one system call interface is changed, this is enough to break > everything! > What made me wonder was, that the (old) binary compiled on 8.2 still worked on 9.0RC1 after the upgrade from 8.2 -> 9.0 (same machine) while the new one compiled with the same compiler after the upgrade crashed. If I copy back the new binary (same source) to a 8.2 machine it fails with a linker failure unresolved symbol "sem_init". But thats only a observation that i am too dumb to understand atm, and maybe unrelated to the main problem.

I retested your test source.

test-9rc1 was compiled on 9RC1 machine and copied back to 8.2 machine.

On 8.2 machine:
~/pas/test]$ ./test-9rc1
/usr/libexec/ld-elf.so.1: /usr/home/pierre/pas/test/test-9rc1: Undefined symbol
"sem_init"
~/pas/test]$ objdump -T ./test-9rc1 | grep sem_
0000000000000000 DF *UND* 0000000000000056 FBSD_1.2 sem_trywait 0000000000000000 DF *UND* 000000000000004a FBSD_1.2 sem_init 0000000000000000 DF *UND* 0000000000000007 FBSD_1.2 sem_wait 0000000000000000 DF *UND* 000000000000004f FBSD_1.2 sem_post 0000000000000000 DF *UND* 0000000000000031 FBSD_1.2 sem_destroy ~/pas/test]$ objdump -T ./test | grep sem_
0000000000400e38 DF *UND* 0000000000000141 FBSD_1.0 sem_wait 0000000000400ea8 DF *UND* 0000000000000073 FBSD_1.0 sem_post 0000000000400f18 DF *UND* 0000000000000081 FBSD_1.0 sem_trywait 0000000000401008 DF *UND* 0000000000000051 FBSD_1.0 sem_destroy 0000000000401068 DF *UND* 00000000000000f4 FBSD_1.0 sem_init

~/pas/trunk/rtl/freebsd]$ objdump -T /lib/libthr.so.3 |grep
sem_init
00000000000079e0 g DF .text 00000000000000f4 FBSDprivate_1.0 _sem_init 00000000000079e0 w DF .text 00000000000000f4 FBSD_1.0 sem_init 0000000000000000 DF *UND* 0000000000000000 FBSD_1.0 ksem_init

On the 9RC1 machine:
~/pas/test]$ objdump -T /lib/libthr.so.3 |grep
sem_init
0000000000007cc0 w DF .text 0000000000000005 (FBSD_1.0) sem_init 0000000000000000 DF *UND* 0000000000000083 FBSDprivate_1.0 _libc_sem_init_compat

I still don't understand much about shared library versioning, so maybe someone with more
knowledge could help us here...

I suspect that it is due to the fact that the FBSD_1.2 version is required by the
9RC1 compiled executable, but why does it find the FBSD_1.0 sem_init symbol on 9RC1 and not on 8.2?

Pierre Muller

Reply by email