Sign in Join

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

Mailing lists / fpc-pascal / 2000-12

Crashes with multithreading

14 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

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

Andrey Kubyshev

Hello Programmers,

Already 2 months i try to write simples stable WEB server for linux. But without any luck yet. It crashes by some magic reasons. I dont think that i'm newbie programmer i already wrote this web server in c++ and it works perfectly, but unfortunately, i need it in pascal.Becouse webserver is only part of big project. Please see following program and think why it leak 536 bytes. Becouse i think that my web server (based on pthreads) crashes coz of invisible memory leaks. I compiled this example with latest official version 1.0.2 and latest sources from CSV. I choosed pthreads becouse to complitely free memory in fpc i must call .Destroy, but i cant call it from inside thread. So , with pascal hreads , i loose 4 Kb every thread. Maybe i dont understand something here in that moment? With pthreads its all easier.

gzipped pthreads.pas is attached
here is dummy program with emulate some work :

program testthreads;
{$mode objfpc}

uses

heaptrc,lineinfo,classes,sysutils,pthread;
procedure usleep(delay:longint);cdecl;external 'libc.so.6';
type
dummy= class
a:array[0..1000] of char;
fake:integer;
public
constructor Create;
destructor Destroy;override;
procedure setfake;
end;
var
number:integer;
constructor dummy.create;
begin
inherited create;
end;
procedure dummy.setfake;
begin
fake:=1;
end;
destructor dummy.destroy;
begin
//writeln(format('destroy object %d',[number]));
inc(number);
inherited destroy;
end;
//thread body
procedure Execute2(i:integer);
var
co:integer;
a:dummy;
s:string;
begin
        a:=dummy.create;
        // writeln('created');
        co:=10;
        // some work emulation
        while (co>0) do begin
                   usleep(1000);
                   a.setfake;
                   s:=s+'+';
                     dec(co);
        end;
        a.destroy;
end;
procedure Execute(i:integer);
begin
        Execute2(i);        // I do it that way, coz pthread_exit happens before
                            // stack vars clear, so we should not have any stack vars
                            // here
        pthread_exit(nil);
end;
var
attr:pthread_attr_t;
threadid:integer;
const
c:integer=200;
// We going to create some threads.
begin
        while(c>0) do begin
                        dec(c);
                        // Setting attributes to detached state
                        pthread_attr_init(@attr);
                        pthread_attr_setdetachstate(@attr,PTHREAD_CREATE_DETACHED);
                        pthread_create(@threadid, @attr,__START_ROUTINE_T(@Execute),1);
                        usleep(10);
        end;
        usleep(8000000); // some time to wait until all treads finished
end.
Best regards, Kubyshev Andrey

Reply by email

Andrey Kubyshev
to Jonas Maebe: FPC's heap manager and IO functions (writeln/readln) are *not* thread safe. That's…

Hello Jonas,

JM> FPC's heap manager and IO functions (writeln/readln) are *not* thread JM> safe. That's probably what's causing the crashes. Add the cmem unit (from JM> the "packages" units) as the first unit in your "uses" clause, then JM> you're at least safe on the memory management side. You can't use heaptrc JM> with it though.
Thank you for such fast reply. But if IO operations not thread safe, does it means that all file operations also unsafe ?

Best regards, Kubyshev Andrey

Reply by email

Andrey Kubyshev
to Jonas Maebe: FPC's heap manager and IO functions (writeln/readln) are *not* thread safe. That's…

Hello Jonas,

Jonas> FPC's heap manager and IO functions (writeln/readln) are *not* thread Jonas> safe. That's probably what's causing the crashes. Add the cmem unit (from Jonas> the "packages" units) as the first unit in your "uses" clause, then Jonas> you're at least safe on the memory management side. You can't use heaptrc Jonas> with it though.

Hi, with using CMEM, i found that it must come AFTER pthread unit , otherwise progs dont like it cannot init clib or
something. strace output with that below.
Also, when i put it after, that simple prog with i postet previously crashes before exit. all thread finished already, but i got RTE 216. Strace have nothing about that . Thank you for your attention to my problem.

here is strace output :

stat("/usr/lib/zoneinfo/localtime", {st_mode=S_IFREG|0644, st_size=755, ...}) = 0 open("/usr/lib/zoneinfo/localtime", O_RDONLY) = 4
read(4, "TZif\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0\4\0"..., 44) = 44 brk(0) = 0x80b8850 brk(0x80b8880) = 0x80b8880 brk(0x80b9000) = 0x80b9000 read(4, 0, 536) = -1 EFAULT (Bad address) read(4, 0, 134) = -1 EFAULT (Bad address) --- SIGSEGV (Segmentation fault) ---

Best regards, Kubyshev Andrey

Reply by email

Jonas Maebe
Show quoted text 5 lines
it leak 536 bytes. Becouse i think that my web server (based on pthreads) crashes coz of invisible memory leaks. I compiled this example with latest official version 1.0.2 and latest sources from CSV. I choosed pthreads becouse to complitely free memory in fpc i must call .Destroy, but i cant call it from inside thread. So , with

FPC's heap manager and IO functions (writeln/readln) are *not* thread safe. That's probably what's causing the crashes. Add the cmem unit (from the "packages" units) as the first unit in your "uses" clause, then you're at least safe on the memory management side. You can't use heaptrc with it though.

Jonas

Reply by email

Michael Van Canneyt
to Andrey Kubyshev: JM> FPC's heap manager and IO functions (writeln/readln) are *not* thread JM> safe.…
Andrey Kubyshev wrote 9 lines
Hello Jonas, JM> FPC's heap manager and IO functions (writeln/readln) are *not* thread JM> safe. That's probably what's causing the crashes. Add the cmem unit (from JM> the "packages" units) as the first unit in your "uses" clause, then JM> you're at least safe on the memory management side. You can't use heaptrc JM> with it though. Thank you for such fast reply. But if IO operations not thread safe, does it means that all file operations also unsafe ?

Shortly said: Yes. The only solution for this is to use separate streams in each thread, then it'll work fine.

Michael.

Reply by email

Nico Erfurth
to Michael Van Canneyt
Show quoted text 11 lines
> > JM> FPC's heap manager and IO functions (writeln/readln) are *not* thread > JM> safe. That's probably what's causing the crashes. Add the cmem unit (from > JM> the "packages" units) as the first unit in your "uses" clause, then > JM> you're at least safe on the memory management side. You can't use heaptrc > JM> with it though. > Thank you for such fast reply. But if IO operations not thread safe, > does it means that all file operations also unsafe ? Shortly said: Yes. The only solution for this is to use separate streams in each thread, then it'll work fine.

The problem is, nothing in FPC is threadsafe, even the TThread-Class itself (InitThreads/DoneThreads).
The FPC-Team really needs to make the RTL and all other classes threadsafe. Its nearly impossible to trace errors in threaded applications.

regards Nico Erfurth

Reply by email

Unknown author
to Nico Erfurth
Nico Erfurth wrote 16 lines
>> >> JM> FPC's heap manager and IO functions (writeln/readln) are *not* thread >> JM> safe. That's probably what's causing the crashes. Add the cmem unit (from >> JM> the "packages" units) as the first unit in your "uses" clause, then >> JM> you're at least safe on the memory management side. You can't use heaptrc >> JM> with it though. >> Thank you for such fast reply. But if IO operations not thread safe, >> does it means that all file operations also unsafe ? > Shortly said: Yes. The only solution for this is to use separate > streams in each thread, then it'll work fine. The problem is, nothing in FPC is threadsafe, even the TThread-Class itself (InitThreads/DoneThreads). The FPC-Team really needs to make the RTL and all other classes threadsafe. Its nearly impossible to trace errors in threaded applications.

That is not entirely true; the Belgian national phone company collects data from their telephone stations using a multi-threaded Win32 application written in FPC.

After changing the standard memory manager with the memory manager of Windows itself the application runs very stable. It is just a matter of programming it right; there are some small parts that require some attention (such as file IO) but most of the RTL is thread-safe.

The biggest problems are IOResult and the heap manager. Avoiding these two makes FPC apps pretty thread-safe.

Which of course doesn't mean we won't work on thread-safety :-)

Michael.

Reply by email

Nico Erfurth
to Unknown author: That is not entirely true; the Belgian national phone company collects data from their…

Hi,

Show quoted text 25 lines
>> Shortly said: Yes. The only solution for this is to use separate >> streams in each thread, then it'll work fine. > > The problem is, nothing in FPC is threadsafe, even the TThread-Class > itself (InitThreads/DoneThreads). > The FPC-Team really needs to make the RTL and all other classes > threadsafe. Its nearly impossible to trace errors in threaded applications. That is not entirely true; the Belgian national phone company collects data from their telephone stations using a multi-threaded Win32 application written in FPC. After changing the standard memory manager with the memory manager of Windows itself the application runs very stable. It is just a matter of programming it right; there are some small parts that require some attention (such as file IO) but most of the RTL is thread-safe. The biggest problems are IOResult and the heap manager. Avoiding these two makes FPC apps pretty thread-safe. Which of course doesn't mean we won't work on thread-safety :-) Michael.

Sorry, i forget to say that i was talking about the Linux-version. And i think, to provide a class named TThreadList and dont make it thread-safe is not very common ;)

The next problem in linux-version is the lack of
Mutexes/Critical-Sections, which makes real threaded applications nearly impossible with FPC/Linux.

regards Nico Erfurth

P.S. Alltogether the FPC-Team is doing a good job, but maybe they shouldnt "Play around" so much and do some more work to make everything stable (on all plattforms).

Reply by email

md
to Nico Erfurth

Nico:

I would like to suggest that the FPC team is doing an excellent job! Not just a good job. Since they are volunteers,
they are entitled to play around as much as they deem fit. But I think that they also want stability as well, so they won't stray to far in their "playing around"

Michael Van Canneyt and Florian and others are as close as saints as you can get. FPC has been a pleasure to use, even
with some "stability" issues. And it is more multi OS/platform/processor every day. Something Delphi for Linux will never hope to be.

For your critical section/mutex problem, use semaphores. They are multi process safe as well as intraprocess safe, you
just have to use them with some coding discipline. They are 5 times more reliable than Windows NT critical sections because you can safely use IPC_NOWAIT whereas TryCriticalSection under NT is a JOKE!

You can even get the PID of the semaphore to know which process changed the value to zero or one, thus creating a way to test to see if a given process has already locked it and thus prevent deadlock.

The trick to remember is that when you create the semaphore, it is opened with value of zero, which is LOCKED. Then you must add one to its value to unlock it. Do not get caught up in any other values other than one for unlocked or zero for locked. Use IPC_NOWAIT because that means your code will not get stuck on a semaphore.

Also, a semaphore does not get destroyed because you application terminates. A semaphore lives forever until you specifically kill it. You can re-run you application many times and the same kernel memory would be used for each semaphore if you use the same ftok() value to generate it. In fact, I would recommend not killing it, but leave it defined between executions of your application. The application won't care that it is already created.

You can pass the semaphore value between threads AND processes, so it is portable. Any process or thread can unlock the semaphore (root privilege maybe reqd), but I would recommend that only the process that created it should unlock it if you should have some stray code lock the thing, then throw an exception, die, and not unlock it for others to use.

On any command line shell, type: man semget or man semop. This should provide you with information on the semaphores. You can use the IPC unit to get access to the semaphore functions.

Multi threaded applications are supposedly hard to debug with gdb, so be wary of that pitfall when you decide code architecture.

Sincerely,

Mark Diener
Atlanta, GA, USA

Nico Erfurth wrote 46 lines
Hi, >>> Shortly said: Yes. The only solution for this is to use separate >>> streams in each thread, then it'll work fine. >> >> The problem is, nothing in FPC is threadsafe, even the TThread-Class >> itself (InitThreads/DoneThreads). >> The FPC-Team really needs to make the RTL and all other classes >> threadsafe. Its nearly impossible to trace errors in threaded applications. > > > That is not entirely true; the Belgian national phone company collects data > from their telephone stations using a multi-threaded Win32 application > written in FPC. > > After changing the standard memory manager with the memory manager of > Windows itself the application runs very stable. It is just a matter > of programming it right; there are some small parts that require some > attention (such as file IO) but most of the RTL is thread-safe. > > The biggest problems are IOResult and the heap manager. > Avoiding these two makes FPC apps pretty thread-safe. > > Which of course doesn't mean we won't work on thread-safety :-) > > Michael. > Sorry, i forget to say that i was talking about the Linux-version. And i think, to provide a class named TThreadList and dont make it thread-safe is not very common ;) The next problem in linux-version is the lack of Mutexes/Critical-Sections, which makes real threaded applications nearly impossible with FPC/Linux. regards Nico Erfurth P.S. Alltogether the FPC-Team is doing a good job, but maybe they shouldnt "Play around" so much and do some more work to make everything stable (on all plattforms). _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Michael Van Canneyt
to Nico Erfurth: Sorry, i forget to say that i was talking about the Linux-version. And i think, to…
Nico Erfurth wrote 35 lines
Hi, >>> Shortly said: Yes. The only solution for this is to use separate >>> streams in each thread, then it'll work fine. >> >> The problem is, nothing in FPC is threadsafe, even the TThread-Class >> itself (InitThreads/DoneThreads). >> The FPC-Team really needs to make the RTL and all other classes >> threadsafe. Its nearly impossible to trace errors in threaded applications. > > > That is not entirely true; the Belgian national phone company collects data > from their telephone stations using a multi-threaded Win32 application > written in FPC. > > After changing the standard memory manager with the memory manager of > Windows itself the application runs very stable. It is just a matter > of programming it right; there are some small parts that require some > attention (such as file IO) but most of the RTL is thread-safe. > > The biggest problems are IOResult and the heap manager. > Avoiding these two makes FPC apps pretty thread-safe. > > Which of course doesn't mean we won't work on thread-safety :-) > > Michael. > Sorry, i forget to say that i was talking about the Linux-version. And i think, to provide a class named TThreadList and dont make it thread-safe is not very common ;) The next problem in linux-version is the lack of Mutexes/Critical-Sections, which makes real threaded applications nearly impossible with FPC/Linux.

We are aware of this, and we're looking at a cross-platform solution.

Show quoted text 6 lines
regards Nico Erfurth P.S. Alltogether the FPC-Team is doing a good job, but maybe they shouldnt "Play around" so much and do some more work to make everything stable (on all plattforms).

We will make it more stable,
but it must stay fun for us as well, so the 'playing around' is part of the deal :-)

Michael.

Reply by email

Marco van de Voort
to Nico Erfurth: Sorry, i forget to say that i was talking about the Linux-version. And i think, to…
P.S. Alltogether the FPC-Team is doing a good job, but maybe they shouldnt "Play around" so much and do some more work to make everything stable (on all plattforms).

Stabilising a system that can't be expanded anymore is quite useless.

You then get into the VP situation where some bugs aren't fixed (this case it was initialisation of ansistrings in records) because it would introduce more bugs.

Let alone that we would be able to further increase Delphi stability, or start to work (in paralel) on other processors (the Itanium is coming in a few years time, but there is a *lot* of work to be done)

A lot of the post 1.0 rewrites are about restructuring. Also nearly the entire difference between 0.99.14 and 1.0.4 are about bugfixing and stabilising.

Marco van de Voort ( or )

Reply by email

Andrey Kubyshev
to Jonas Maebe: FPC's heap manager and IO functions (writeln/readln) are *not* thread safe. That's…

Hello,

Jonas> FPC's heap manager and IO functions (writeln/readln) are *not* thread Jonas> safe. That's probably what's causing the crashes. Add the cmem unit (from Jonas> the "packages" units) as the first unit in your "uses" clause, then Jonas> you're at least safe on the memory management side. You can't use heaptrc Jonas> with it though.

I was trying to apply CMEM unit to my small example with pthreads, and had following : if i set cmem before pthreads unit it crashes on program initialization before my code executed, if i put cmem after , all works good except that, now its crashes in finalization stage, after my code already executed. But in bigger project which i need to run it doesnt matter where i put it, it crashes at start anyways. Who can give advice how to fix it please ? I can show strace logs where it happens.

Best regards, Kubyshev Andrey

Reply by email

Michael Van Canneyt
to Andrey Kubyshev
Andrey Kubyshev wrote 16 lines
Hello, Jonas> FPC's heap manager and IO functions (writeln/readln) are *not* thread Jonas> safe. That's probably what's causing the crashes. Add the cmem unit (from Jonas> the "packages" units) as the first unit in your "uses" clause, then Jonas> you're at least safe on the memory management side. You can't use heaptrc Jonas> with it though. I was trying to apply CMEM unit to my small example with pthreads, and had following : if i set cmem before pthreads unit it crashes on program initialization before my code executed, if i put cmem after , all works good except that, now its crashes in finalization stage, after my code already executed. But in bigger project which i need to run it doesnt matter where i put it, it crashes at start anyways. Who can give advice how to fix it please ? I can show strace logs where it happens.

Send me all information you have, preferably with a test program.

I'll have a look at it; I implemented the cmem unit...

Michael.

Reply by email