Sign in Join

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

Mailing lists / fpc-devel / 2018-12

finally block entered twice, for only one "try". win64 seh

3 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Martin

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 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,@except,@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)

Reply by email

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

Seem to me it is a bug in fpc, including todays trunk

program project1;
{$mode objfpc}
uses
   Classes;
procedure Foo(a: array of integer);
begin
   try
     writeln(a[0]);
     if a[0] = 1 then exit;
     writeln(a[0]);
   finally
     writeln(a[0]);
   end;
end;
begin
   foo([1]);
end.

On win64
compiled with todays trunk. -gh -gt -gw -O-

crashes, because the memory for "a" is freed twice. (the implicit finally block is called twice).

Reply by email