[fpc-pascal] Stack checking in dynamic libraries
cobines
cobines at gmail.com
Sun Nov 8 01:41:10 CET 2009
Hello,
I have found out the following during development of my project and
wanted to ask for some explanation.
I have a dynamic library which is dynamically loaded from the main
thread of my program. I then create a worker thread in the main
program and call the functions in the library from this worker thread.
If I enable stack overflow checking in the library then whenever I
call any function in that library I get a stack overflow error. This
is because the StackBottom variable in fpc_stackcheck function is
taken from the main thread instead of the worker thread. Is this
correct or not?
My system is i386 Debian linux. I am using FPC revision 13700. I build
the library and the main program with "cthreads" unit included.
I made a sample program to show some info (attached with the mail). It
outputs several values describing current thread and the
thread-specific stack info (from rtl/inc/systemh.inc).
The worker thread has default stack size 4MB, main thread stack size
is 8MB. The main thread stack address begins with BF..... , worker
thread with B7..... . This is the output of the program
(checkthreadinfo.lpr):
MainThreadId : 3077936832
< main thread, main program >
CurrentThreadId : 3077936832
Thread ID : 3077479680
Stack ptr : BFDBFF70
Stack top : 00000000
Stack bottom : BF5C008C
Stack length : 8388608
< main thread, library >
Libr. CurrentThreadId: 3077936832
Libr. ThreadId : 3077479680
Libr. Stack ptr : BFDBFF70
Libr. Stack top : 00000000
Libr. Stack bottom : BF5BFC94
Libr. Stack length : 8388608
< worker thread, main program >
CurrentThreadId : 3076807536
Thread ID : 3076807536
Stack ptr : B7645188
Stack top : 00000000
Stack bottom : B7245300
Stack length : 4194304
< worker thread, library >
Libr. CurrentThreadId: 3076807536
Libr. ThreadId : 3077479680
Libr. Stack ptr : B7645188
Libr. Stack top : 00000000
Libr. Stack bottom : BF5BFC94
Libr. Stack length : 8388608
The stack check will fail in < worker thread, library > case, because
the StackBottom is greater than current stack pointer (it is the same
value as in < main thread, library >).
If I change the program so that the worker thread loads its own
instance of the library from itself (attached as
checkthreadinfoV2.lpr) then I get the following:
MainThreadId : 3076835008
< main thread, main program >
CurrentThreadId : 3076835008
Thread ID : 3076377856
Stack ptr : BFFEAA40
Stack top : 00000000
Stack bottom : BF7EAB5C
Stack length : 8388608
< main thread, library > (this library is loaded from main thread)
Libr. CurrentThreadId: 3076835008
Libr. ThreadId : 3076377856
Libr. Stack ptr : BFFEAA40
Libr. Stack top : 00000000
Libr. Stack bottom : BF7EA764
Libr. Stack length : 8388608
< worker thread, main program >
CurrentThreadId : 3076283248
Thread ID : 3076283248
Stack ptr : B75C5188
Stack top : 00000000
Stack bottom : B71C5300
Stack length : 4194304
< worker thread, library > (this library is loaded from worker thread)
Libr. CurrentThreadId: 3076283248
Libr. ThreadId : 3076377856
Libr. Stack ptr : B75C5188
Libr. Stack top : 00000000
Libr. Stack bottom : B6DC4EAC
Libr. Stack length : 8388608
Stack check will now not fail.
But stack length in < worker thread, library > shows 8MB, not 4MB
(which should be the thread's stack size). Does code executed in
dynamic libraries have a different stack? It seems not, because the
current stack pointer is the same in both < worker thread, main
program > and < worker thread, library >. According to the numbers the
stack for < worker thread, main program > is at B71C5300-B75C5300 and
the stack for < worker thread, library > is at B6DC4EAC-B75C4EAC. So
the addresses overlap. Is this correct? Moreover, in < worker thread,
library > the current stack pointer is outside the stack range.
An unrelated question: why there are two thread identifiers? There's
GetCurrentThreadId in rtl/inc/thread.inc and ThreadId in
rtl/inc/systemh.inc. The CurrentThreadId is consistent - the same in
both < main thread, ... > cases, and the same in both <worker thread ,
... > cases. But ThreadId in < worker thread, library > shows the same
value as in < main thread, main program > and in < main thread,
library >.
I'd be grateful for any explanations, or any pointers if I'm doing
anything wrong.
--
cobines
-------------- next part --------------
A non-text attachment was scrubbed...
Name: checkthreadinfo.lpr
Type: application/octet-stream
Size: 1315 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20091108/65e876db/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: checkthreadinfoV2.lpr
Type: application/octet-stream
Size: 1599 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20091108/65e876db/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: threadinfolib.lpr
Type: application/octet-stream
Size: 494 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20091108/65e876db/attachment-0002.obj>
More information about the fpc-pascal
mailing list