Recent

Author Topic: GPF on calling free.  (Read 2025 times)

Prime

  • Jr. Member
  • **
  • Posts: 62
GPF on calling free.
« on: April 15, 2018, 10:10:51 pm »
Hi all,

I am writing a multi CPU disassembler, so am trying to abstract out the bits that are common to all target CPUs and just have the CPU specific stuff implemented in decendent classes.

So I have an abstract disassembler class :

Code: Pascal  [Select][+][-]
  1.     TCPU    = (tcNone,tc6502, tc65c02, tc65c02wd, tc6512, tc6809);
  2.     TCPUSet = SET OF TCPU;
  3.  
  4.     TOpCode = Class(TObject)
  5.       OpStr     : STRING;
  6.       OpBytes   : INTEGER;
  7.       CPU           : TCPUSet;
  8.       Valid         : BOOLEAN;
  9.       CONSTRUCTOR Create;
  10.     END;
  11.  
  12.     TADisassembler = Class(TObject)
  13.     PROTECTED
  14.       FOpCodes  : ARRAY[$00..$FF]OF TOpCode;
  15.       FVerbose  : BOOLEAN;
  16.       FCPU      : TCPU;
  17.  
  18.       FUNCTION CalcRelative8(RelOffset     : BYTE) : WORD;
  19.       FUNCTION CalcRelative16(RelOffset     : WORD) : WORD;
  20.       PROCEDURE DecodeInstruction;   virtual; abstract;
  21.       PROCEDURE InitOpcodes;         virtual; abstract;
  22.       PROCEDURE SetVerbose(NewValue     : BOOLEAN);
  23.     PUBLIC
  24.       SymbolList                : TSymbolList;
  25.       EntryPoints               : TSymbolList;
  26.       Memory                    : TCPUmemory;
  27.       MemoryList                : TMemoryList;
  28.       PROPERTY Verbose  : BOOLEAN READ FVerbose WRITE SetVerbose;
  29.       PROPERTY CPU      : TCPU READ FCPU WRITE FCPU;
  30.  
  31.       CONSTRUCTOR Create;
  32.       DESTRUCTOR Destroy; override;
  33.       PROCEDURE Go; virtual; abstract;
  34.       PROCEDURE LoadFromFile(FileName   : STRING;
  35.                                    PBaseAddr    : DWORD);
  36.       PROCEDURE SetCPU(CPUType     : INTEGER);
  37.     END;
  38.  

Then my CPU specific stuff overrides / inherits. :

Code: Pascal  [Select][+][-]
  1.    
  2.     TBranch = (brNone,brRelative,brAbsolute,brRtsRti,brZPRelative);
  3.  
  4.  
  5.     TOpCode6502 = Class(TOpCode)
  6.       OpStr     : STRING;
  7.       OpBytes   : INTEGER;
  8.       CPU           : TCPUSet;
  9.       Branch    : TBranch;
  10.       Valid         : BOOLEAN;
  11.     END;
  12.  
  13.     TDisassembler6502 = Class(TADisassembler)
  14.     PROTECTED
  15.       PROCEDURE DecodeInstruction;  override;
  16.           PROCEDURE InitOpcodes;        override;
  17.           PROCEDURE MakeOpCode(OpNo             : INTEGER;
  18.                                InOpStr      : STRING;
  19.                                        InOpBytes        : INTEGER;
  20.                                        InCPU        : TCPUSet;
  21.                                        InBranch     : TBranch = brNone);
  22.     PUBLIC
  23.       CONSTRUCTOR Create;
  24.       DESTRUCTOR Destroy; override;
  25.       PROCEDURE Go;  override;
  26.     END;
  27.  

These are in seperate unit files. I have also written code for the virtual methods in TDisassembler6502.
When run the units appear to work however when The free method of TDisassembler6502 is called the program causes a GPF.

In my main program the disassembler is defined as :

Code: Pascal  [Select][+][-]
  1. VAR Disassember     : TDisassembler6502;    
  2.  

It is createed in my initaliasation procedure with :

Code: Pascal  [Select][+][-]
  1.   Disassember:=TDisassembler6502.Create;
  2.  

I attempt to free it with :

Code: Pascal  [Select][+][-]
  1.   Disassember.Free;
  2.  
This is where I get the GPF.

Any idea what the problem might be? If I single step the debugger doesn't even make it to the Destroy methods of either of the classes.

I can post the entire code of the units if wanted just trying to not flood the forum :)

Cheers.

Phill.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11452
  • FPC developer.
Re: GPF on calling free.
« Reply #1 on: April 15, 2018, 10:18:21 pm »
    • the disassembler variable is overwritten/corrupted
    • the class has already been destroyed
    • something in the destructor of the tadisassembler class causes an exception/li]

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: GPF on calling free.
« Reply #2 on: April 15, 2018, 10:22:57 pm »
If Marco's hints are not sufficient to help you trace the error you'll need to share compilable code (or at least a compilable cut-down version) that shows the problem. The devil is in the detail, not in the overall design.

totya

  • Hero Member
  • *****
  • Posts: 720
Re: GPF on calling free.
« Reply #3 on: April 15, 2018, 10:31:50 pm »
Hi, in Lazarus: Project/publish project, then zip this result dir, and attach this zip file to your post.

It is createed in my initaliasation procedure with :

Code: Pascal  [Select][+][-]
  1.   Disassember:= TDisassembler6502.Create;
Code: Pascal  [Select][+][-]
  1.   Disassember.Free;

Try change for it:

Code: Pascal  [Select][+][-]
  1.   Disassember:= nil;
  2.   Disassember:= TDisassembler6502.Create;
Code: Pascal  [Select][+][-]
  1.   if Assigned(Disassember)
  2.     then FreeAndNil(Disassember)
  3.     else ShowMessage('variable is nil');

Prime

  • Jr. Member
  • **
  • Posts: 62
Re: GPF on calling free.
« Reply #4 on: April 15, 2018, 10:39:53 pm »
Bingo! I found the problem.

I was calling MemoryList.free in both TADissasembler and it's decendent class, needless to say the second call caused the problem :(

Thanks for the quick replies.

Cheers.

Phill.

 

TinyPortal © 2005-2018