FpDebug: improve stack unwinding by disassembler, handle frame BP in push/pop / update valid stack area for pop

This commit is contained in:
Martin 2025-02-25 17:45:45 +01:00
parent a625b50890
commit 854c5fe046

View File

@ -5676,6 +5676,7 @@ var
Val: Int64; Val: Int64;
ClearRecValList, ForceDifferentBranch: Boolean; ClearRecValList, ForceDifferentBranch: Boolean;
FullName: String; FullName: String;
PushedNewFrame, PushedNewFrameAddr: TDBGPtr;
begin begin
Result := False; Result := False;
NewAddr := AnAddress; NewAddr := AnAddress;
@ -5701,6 +5702,7 @@ begin
if ClearRecValList then ARegisterValueList.Clear; if ClearRecValList then ARegisterValueList.Clear;
if ForceDifferentBranch or (NewStack = 0) or (NewAddr >= MaxAddr) or( NewAddr > MaxAddrCurrentBlock) then begin if ForceDifferentBranch or (NewStack = 0) or (NewAddr >= MaxAddr) or( NewAddr > MaxAddrCurrentBlock) then begin
PushedNewFrameAddr := 0;
CheckConditionalForwAddr; CheckConditionalForwAddr;
FinishCurAddrBlock; FinishCurAddrBlock;
while (CurConditionalForwardAddr >= 0) and while (CurConditionalForwardAddr >= 0) and
@ -5768,16 +5770,19 @@ begin
ClearRecValList := False; ClearRecValList := False;
if AQuick then if AQuick then
exit; exit;
if (instr.X86Instruction.OperCnt <> 1) or if (instr.X86Instruction.OperCnt <> 1) then begin
IsRegister(instr.X86Instruction.Operand[1].Value, 'bp') or
IsRegister(instr.X86Instruction.Operand[1].Value, 'sp')
then begin
ForceDifferentBranch := True; ForceDifferentBranch := True;
continue; continue;
end; end;
if StartStack < NewStack then
StartStack := NewStack;
{$PUSH}{$R-}{$Q-} {$PUSH}{$R-}{$Q-}
NewStack := NewStack - RegisterSize(instr.X86Instruction.Operand[1].Value); NewStack := NewStack - RegisterSize(instr.X86Instruction.Operand[1].Value);
{$POP} {$POP}
if (IsRegister(instr.X86Instruction.Operand[1].Value, 'bp')) and (NewFrame <> 0) then begin
PushedNewFrame := NewFrame;
PushedNewFrameAddr := NewStack;
end;
end; end;
OPpusha: OPpusha:
begin begin
@ -5787,6 +5792,8 @@ begin
continue; continue;
end; end;
// push 8 registers // push 8 registers
if StartStack < NewStack then
StartStack := NewStack;
{$PUSH}{$R-}{$Q-} {$PUSH}{$R-}{$Q-}
NewStack := NewStack - (8*4); NewStack := NewStack - (8*4);
{$POP} {$POP}
@ -5818,14 +5825,19 @@ begin
end; end;
if IsRegister(instr.X86Instruction.Operand[1].Value, 'bp') if IsRegister(instr.X86Instruction.Operand[1].Value, 'bp')
then begin then begin
if NewStack < StartStack then
exit;
NewFrame := 0; NewFrame := 0;
if NewStack >= StartStack then begin
RSize := RegisterSize(instr.X86Instruction.Operand[1].Value); RSize := RegisterSize(instr.X86Instruction.Operand[1].Value);
if not FProcess.ReadData(NewStack, RSize, NewFrame, RSize) then if not FProcess.ReadData(NewStack, RSize, NewFrame, RSize) then
exit; exit;
end end
else else
if (PushedNewFrameAddr = NewStack) then begin
NewFrame := PushedNewFrame;
PushedNewFrameAddr := 0;
end;
end
else
if NewStack >= StartStack then begin if NewStack >= StartStack then begin
Tmp := 0; Tmp := 0;
RSize := RegisterSize(instr.X86Instruction.Operand[1].Value); RSize := RegisterSize(instr.X86Instruction.Operand[1].Value);
@ -5834,6 +5846,8 @@ begin
ARegisterValueList.DbgRegisterAutoCreate[FullName].SetValue(Tmp, IntToStr(Tmp), RSize, 0); ARegisterValueList.DbgRegisterAutoCreate[FullName].SetValue(Tmp, IntToStr(Tmp), RSize, 0);
end; end;
end; end;
if NewStack >= PushedNewFrameAddr then
PushedNewFrameAddr := 0;
{$PUSH}{$R-}{$Q-} {$PUSH}{$R-}{$Q-}
NewStack := NewStack + RegisterSize(instr.X86Instruction.Operand[1].Value); NewStack := NewStack + RegisterSize(instr.X86Instruction.Operand[1].Value);
{$POP} {$POP}