Einzelnen Beitrag anzeigen

prognase

Registriert seit: 30. Apr 2012
4 Beiträge
 
#1

try..finally verursacht korrupte Variablen

  Alt 17. Jul 2019, 11:10
Hi,

ich stehe etwas auf dem Schlauch, leider sind meine Assembler-Kenntnisse gefühlt auf 80er Jahre 8bit-Zeiten. Somit ist das Debugging meines fehlerhaften Codes schwierig.

Ich habe eine Methode, in der ich einen TRY..FINALLY-Block nutze, dort setze ich Flags zur späteren Analyse. Beim Debugging fiel mir auf, dass >nach< dem ersten Befehl im FINALLY, wenn der durch exit oder abort ausgelöst wird, meine lokalen Variablen initialisiert bzw falsch sind, plus SELF plötzlich ein "inaccessible value" ist. Den Block habe ich immer mehr reduziert, bis nur noch dieses Fragment übrig geblieben ist:

Delphi-Quellcode:
procedure TFORM_LFH.BadBadTry;
var
  closeLog: Boolean;
begin
  closeLog := False;
  try
    closeLog := True;
    exit;
  finally
    Screen.Cursor := crDefault;
    //-- some nonsense further code...
    if closeLog then
      closeLog := not CloseLog;
  end;
end;
Ich setze einen Breakpoint auf "Screen.Cursor ...", an dieser Stelle ist closeLog wahr, SELF hat einen Wert. Nach diesem Befehl ist closeLog falsch, i.e. $00, und auf SELF kann nicht zugegriffen werden.

Der ASM-Code dazu:

Code:
LFH_Main.pas.1900: BadBadTry;
0000000001467E5B 488B8D80000000   mov rcx,[rbp+$00000080]
0000000001467E62 E8A9C2FFFF      call TFORM_LFH.BadBadTry

...

LFH_Main.pas.1135: begin
0000000001464110 55               push rbp
0000000001464111 4883EC40         sub rsp,$40
0000000001464115 488BEC          mov rbp,rsp
0000000001464118 48896D28         mov [rbp+$28],rbp
000000000146411C 48894D50         mov [rbp+$50],rcx
LFH_Main.pas.1136: closeLog := False;
0000000001464120 C6453F00         mov byte ptr [rbp+$3f],$00
LFH_Main.pas.1137: try
0000000001464124 90               nop
LFH_Main.pas.1139: closeLog := True;
0000000001464125 C6453F01         mov byte ptr [rbp+$3f],$01
LFH_Main.pas.1140: exit;
0000000001464129 EB24             jmp TFORM_LFH.BadBadTry + $3F <- zu FINALLY
LFH_Main.pas.1142: Screen.Cursor := crDefault;
000000000146412B 90               nop
000000000146412C 488B0525AD1600   mov rax,[rel $0016ad25]
0000000001464133 488B08           mov rcx,[rax]
0000000001464136 33D2             xor edx,edx
0000000001464138 E8D3733FFF      call TScreen.SetCursor
LFH_Main.pas.1144: if closeLog then
000000000146413D 807D3F00         cmp byte ptr [rbp+$3f],$00
0000000001464141 7417             jz TFORM_LFH.BadBadTry + $4A
LFH_Main.pas.1145: closeLog := not CloseLog;
0000000001464143 807D3F00         cmp byte ptr [rbp+$3f],$00
0000000001464147 0F94C0           setz al
000000000146414A 88453F          mov [rbp+$3f],al
000000000146414D EB0B            jmp TFORM_LFH.BadBadTry + $4A
000000000146414F 33C9             xor ecx,ecx                   <- Ziel FINALLY
0000000001464151 488B5528         mov rdx,[rbp+$28]
0000000001464155 E806000000       call TFORM_LFH.BadBadTry + $50 <- zu $50
LFH_Main.pas.1147: end;
000000000146415A 488D6540         lea rsp,[rbp+$40]
000000000146415E 5D              pop rbp
000000000146415F C3               ret
LFH_Main.pas.1142: Screen.Cursor := crDefault;                  <- Ziel $50
0000000001464160 55               push rbp
0000000001464161 53               push rbx
0000000001464162 4883EC28         sub rsp,$28                    <- danach §$%
0000000001464166 488BEC          mov rbp,rsp
0000000001464169 4889D3           mov rbx,rdx
000000000146416C 488B05E5AC1600   mov rax,[rel $0016ace5]
0000000001464173 488B08           mov rcx,[rax]
0000000001464176 33D2             xor edx,edx
0000000001464178 E893733FFF      call TScreen.SetCursor
LFH_Main.pas.1144: if closeLog then
000000000146417D 807B3F00         cmp byte ptr [rbx+$3f],$00
0000000001464181 740A            jz TFORM_LFH.BadBadTry + $7D
Wenn ich den Code in einem neuen Projekt nur mit einem Button als Auslöser nutze, habe ich das Problem nicht. Da sieht der ASM-Code auch anders aus.

Hat irgendwer eine Idee, was da nicht stimmen könnte? Jede Idee willkommen

Matthias
  Mit Zitat antworten Zitat