[fpc-devel] finally block entered twice, for only one "try". win64 seh

Martin fpc at mfriebe.de
Fri Dec 28 03:53:04 CET 2018


Ok I have this really weird issue. fpc 3.0.4 64 bit / built from svn tag.

At this stage I am just happy for any idea....

There is a function with several try finally blocks.
It also has one implicit finally block. This is for freeing the memory 
of an open array.

When the open array gets passed in, memory is allocated and a copy is made.
Then the function runs. To the best of my knowledge without exception... 
There may (well I guess there must) be something going wrong. But no 
idea yet. (I tried valgrind-ing it, but on Linux the code has no issues. 
Though it is fpdebug, and some code is written per OS....)

So then in the middle of the function "If will_be_true then exit". The 
exit is executed and unwind is called.

- I have a breakpoint on the entry of the function it is not re-entered 
(actually it was entered only the one time, for which it currently runs)
- I set a breakpoint (by following asm) in the implicit finally handler
   I compared this with the -al asm to be sure I have the right code.

The implicit finally handler calls freemem for the copy of the open array

And the breakpoint in this code is reached twice. Freemem is called 
twice (for memory allocated only once).
=> boom, of course. freeing mem that was freed already. heaptrc detects 
this.

Here is the code (disassembled by gdb from the running app) for the 
implicit exception handler
00000001003B8990 55                       push   %rbp
00000001003B8991 4889cd                   mov    %rcx,%rbp
00000001003B8994 488d6424e0               lea    -0x20(%rsp),%rsp
00000001003B8999 488b4df0                 mov    -0x10(%rbp),%rcx
00000001003B899D e8aebac5ff               callq  0x100014450 <fpc_freemem>
00000001003B89A2 90                       nop
00000001003B89A3 488d642420               lea    0x20(%rsp),%rsp
00000001003B89A8 5d                       pop    %rbp
00000001003B89A9 c3909090909090           retq

there is no loop. It is definitely entered twice.

I stepped out to __FPC_specific_handler
and here are the locals and args during the first call

REC={EXCEPTIONCODE = 3221225511, EXCEPTIONFLAGS = 34, EXCEPTIONRECORD = 
0x0, EXCEPTIONADDRESS = 0x7fff0dfd7018, NUMBERPARAMETERS = 0, 
EXCEPTIONINFORMATION = {0x13fd0b0, 0x1001fe305, 0x5555555555555555, 
0x5555555555555555, 0x0, 0x7fff0dfe11d7, 0x13fd0b0, 0x1001fe3b5, 
0x13fd0b0, 0x10000384a, 0xcaba6e0, 0x7fff0dfdeed3, 0x6196550, 0x0, 0x0}}
FRAME=0x13fda90
CONTEXT={P1HOME = 52362832398173, P2HOME = 1042714, P3HOME = 20960848, 
P4HOME = 4295060357, P5HOME = 1042714, P6HOME = 219971768, CONTEXTFLAGS 
= 1048591, MXCSR = 6432, SEGCS = 51, SEGDS = 43, SEGES = 43, SEGFS = 83, 
SEGGS = 43, SEGSS = 43, EFLAGS = 514, DR0 = 192, DR1 = 219970424, DR2 = 
1042714, DR3 = 20960928, DR6 = 4295056004, DR7 = 52362832397485, RAX = 
0, RCX = 20960752, RDX = 20959104, RBX = 1600832, RSP = 20961936, RBP = 
20962272, RSI = 8, RDI = 1264352, R8 = 3661824, R9 = 20958936, R10 = 
8387188145643678817, R11 = 20960112, R12 = 20962544, R13 = 212575968, 
R14 = 0, R15 = 0, RIP = 4298869942, HEADER = {{LOW = 4978, HIGH = 0}, 
{LOW = 0, HIGH = 281470681749792}}, LEGACY = {{LOW = 0, HIGH = 0}, {LOW 
= 0, HIGH = 0}, {LOW = 0, HIGH = 0}, {LOW = 0, HIGH = 0}, {LOW = 0, HIGH 
= 0}, {LOW = 0, HIGH = 0}, {LOW = 0, HIGH = 0}, {LOW = 0, HIGH = 0}}, 
XMM0 = {LOW = 4301053952, HIGH = 4294967296}, XMM1 = {LOW = 
950441947414528, HIGH = 0}, XMM2 = {LOW = 0, HIGH = 0}, XMM3 = {LOW = 0, 
HIGH = 0}, XMM4 = {LOW = 0, HIGH = 0}, XMM5 = {LOW = 0, HIGH = 0}, XMM6 
= {LOW = 0, HIGH = 0}, XMM7 = {LOW = 0, HIGH = 0}, XMM8 = {LOW = 0, HIGH 
= 0}, XMM9 = {LOW = 0, HIGH = 0}, XMM10 = {LOW = 0, HIGH = 0}, XMM11 = 
{LOW = 0, HIGH = 0}, XMM12 = {LOW = 0, HIGH = 0}, XMM13 = {LOW = 0, HIGH 
= 0}, XMM14 = {LOW = 0, HIGH = 0}, XMM15 = {LOW = 0, HIGH = 0}, 
VECTORREGISTER = {{LOW = 20961520, HIGH = 220171680}, {LOW = 4299608352, 
HIGH = 20961856}, {LOW = 20961536, HIGH = 4295033198}, {LOW = 20961728, 
HIGH = 4298838594}, {LOW = 217347984, HIGH = 4299640304}, {LOW = 1, HIGH 
= 4299608352}, {LOW = 220171696, HIGH = 20961856}, {LOW = 4299608352, 
HIGH = 20961688}, {LOW = 20961728, HIGH = 4298718201}, {LOW = 217348336, 
HIGH = 217347984}, {LOW = 0, HIGH = 4295033144}, {LOW = 20961728, HIGH = 
4295032966}, {LOW = 20962544, HIGH = 0}, {LOW = 4299608352, HIGH = 
212578368}, {LOW = 20961728, HIGH = 220171680}, {LOW = 4299608352, HIGH 
= 20961864}, {LOW = 20961920, HIGH = 4298801897}, {LOW = 217347841, HIGH 
= 4299608352}, {LOW = 220171696, HIGH = 212578368}, {LOW = 20961920, 
HIGH = 4298803146}, {LOW = 219970560, HIGH = 4300288864}, {LOW = 
4300288864, HIGH = 4300710680}, {LOW = 1600832, HIGH = 20962544}, {LOW = 
212575968, HIGH = 1600832}, {LOW = 1264352, HIGH = 8}...}, VECTORCONTROL 
= 20961920, DEBUGCONTROL = 4295034290, LASTBRANCHTORIP = 0, 
LASTBRANCHFROMRIP = 0, LASTEXCEPTIONTORIP = 20961793, 
LASTEXCEPTIONFROMRIP = 1431655765}
DISPATCH={CONTROLPC = 4298869942, IMAGEBASE = 4294967296, FUNCTIONENTRY 
= 0x100600ec8, ESTABLISHERFRAME = 20961936, TARGETIP = 4298871252, 
CONTEXTRECORD = 0x13fd5f0, LANGUAGEHANDLER = {function 
(TEXCEPTIONRECORD, POINTER, TCONTEXT, POINTER) : EXCEPTION_DISPOSITION} 
0x13fcfa0, HANDLERDATA = 0x1005c8fb4, HISTORYTABLE = 0x0, SCOPEINDEX = 
4, FILL0 = 1}
RESULT=EXCEPTIONCONTINUESEARCH
__FPC_SPECIFIC_HANDLER=EXCEPTIONCONTINUESEARCH
TARGETRVA=3903956
CONTROLRVA=3902646
SCOPE=0x1005c8fe8
SCOPEIDX=3
TARGETADDR=0x2f9f00000004
OBJ=0x1c6b00001c7b


and then I set a breakpoint in __FPC_specific_handler
but the 2nd call to the implicit finally handler does not seem to go 
through it at all.

While gdb can not propper show the stack (absent stackframes), I did get 
the raw memory address at rsp, and it seems the call was made from the 
normal epilogue.
Meaning the finally was called during unwind, and regularly at the end 
of function

This is from the asm done by -al

.seh_handler __FPC_specific_handler, at except, at unwind
.seh_handlerdata
     .long    4
     .long    1
     .rva    .Lj12755
     .rva    .Lj12752
     .rva    .Lj12753
     .long    0
     .rva    .Lj12740
     .rva    .Lj12741
     .rva 
FPDBGDWARF$_$TFPDWARFSYMBOLTYPEARRAY_$_GETMEMBERADDRESS$crcEDA43A29_$$_fin$41
     .long    0
     .rva    .Lj12686
     .rva    .Lj12687
     .rva 
FPDBGDWARF$_$TFPDWARFSYMBOLTYPEARRAY_$_GETMEMBERADDRESS$crcEDA43A29_$$_fin$42
     .long    0
     .rva    .Lj12653
     .rva    .Lj12654
     .rva 
FPDBGDWARF$_$TFPDWARFSYMBOLTYPEARRAY_$_GETMEMBERADDRESS$crcEDA43A29_$$_fin$43

.section 
.text.n_fpdbgdwarf$_$tfpdwarfsymboltypearray_$__$$_getmemberaddress$crceda43a29,"x"
.seh_endproc


Lj12654 is a label in front of the call to the implicit finally handler.


------------------
Any idea what I might be looking for?

I can provide code to reproduce it on win64.
However this is rather big. You need the current trunk of fpdebug + 
patch + updated test project. (And set up local config for the test 
project too)





More information about the fpc-devel mailing list