View Issue Details

IDProjectCategoryView StatusLast Update
0029759LazarusLCLpublic2020-03-06 19:43
Reporterbarlone Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
PlatformWinOSWindows 7 
Summary0029759: App stops with SIGSEGV if contain cmem unit (under Windows)
DescriptionExecution breaks in file astrings.inc - look to screenshot in attach. Unit heaptrc not used. Under Linux works fine.
Steps To ReproduceCreate new project, add cmem unit as first, run.
Additional InformationUnder Windows 7 x64 result is same. Under Win XP program starts but show exception on exit. Tried on several computers.
TagsNo tags attached.
Fixed in Revision
LazTarget
Widgetset
Attached Files

Activities

barlone

2016-02-29 19:44

reporter  

screenshot.png (39,384 bytes)   
screenshot.png (39,384 bytes)   

Thaddy de Koning

2016-02-29 22:19

reporter   ~0090498

Last edited: 2016-02-29 22:19

View 2 revisions

I can't reproduce that with a small test:
program cm;
{$APPTYPE CONSOLE}{$H+}
uses
  cmem;
var a:string;
begin
 a:='testme';
 writeln(a);
end.

Is it maybe XP specific? Tested r33135 32bit/64bit on windows 10

barlone

2016-03-01 11:05

reporter   ~0090512

Yes, simple console app works, try minimal LCL app:


program project1;

{$mode objfpc}{$H+}

uses
  cmem,
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, Unit1
  { you can add units after this };

{$R *.res}

begin
  RequireDerivedFormResource:=True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

barlone

2016-03-01 13:42

reporter   ~0090525

The shortest example that reproduces the problem:

program cm;
uses
  cmem, lclproc;
begin
end.

Cyrax

2016-03-01 15:34

reporter   ~0090526

cmem is only for unix/linux system. It is not for use under Windows.

barlone

2016-03-01 17:22

reporter   ~0090529

@Cyrax: I know, but my crossplatphorm project link big C library, that depend from C memory manager (staticaly) and without it project not linked.

Cyrax

2016-03-02 07:18

reporter   ~0090540

You can use conditional compilation directives {$IF DEFINED(UNIX) OR DEFINED(LINUX)} .. {$ENDIF UNIX} to control when compiler should add unit cmem in your program code. Thus when you debug under Windows, code from cmem unit isn't included in your program and when you do crosscompile to target system, it will be included into your program code.

Jonas Maebe

2016-03-02 09:58

manager   ~0090543

cmem also supported and works under Windows. What probably happens is that memory that was allocated using the default memory manager is getting freed after the cmem memory manager has been installed, e.g. because of a hack like what they want to do for WinCE in http://bugs.freepascal.org/view.php?id=29070

barlone

2016-03-02 11:22

reporter   ~0090549

@Jonas:
It is reasonable to create a separate feature request for extension of the syntax unit INITIALIZATION statmemt? For example:

initialization before <unit_name>
or
initialization first

It can resolve this and many other problems with unit initialization order.

Jonas Maebe

2016-03-02 11:34

manager   ~0090550

Last edited: 2016-03-02 11:34

View 2 revisions

1) that won't help here, since the cmem unit is the first unit in the uses clause of the main program and it still crashes apparently (according to your test in comment #c90525 above)
2) the compiler would have to perform a lot of additional checks for this, because such statements could result in cycles, and as soon as more than one unit has "initialization first" it would have to fail as well.

It would lot of complication for something that would still not work very well in practice, so I don't think that's a good idea.

barlone

2016-03-03 10:34

reporter   ~0090579

Defining DisableUTF8RTL (for LazUtils) solve problem and program correctly work under Windows. So it is not [only] RTL problem.

Jonas Maebe

2016-03-03 10:52

manager   ~0090581

It's probably caused by LCL conversion of the command line arguments to UTF-8. I.e., what they also want to do for WinCE as described in 0029070 (but which they can't). It's one more argument not to "fix" that for WinCE, and instead make it also impossible for other platforms (and fix that issue in a proper way).

The reason this causes problems is that the original memory for the command line arguments has been allocated by the system unit in its initialisation code, i.e. before the cmem unit has been initialised (the system unit must always initialise first). Then the LCL frees that memory after the cmem unit has been installed, causing the problem.

Bart Broersma

2016-03-03 12:35

developer   ~0090588

Is it possible to detect that cmem is used?

Bart Broersma

2016-03-03 12:50

developer   ~0090589

> Then the LCL frees that memory after the cmem unit has been installed,
> causing the problem.

AFAICS the LCL does not free that memory block.
Upon initialization the original pointer (argv) is saved.
Upon finilization the pointer argv is restored to its original value.

procedure SetupArgvAsUtf8;
var
  i: Integer;
begin
  SetLength(ArgsUTF8,length(ArgsW));
  OldArgV:=argv;
  GetMem(argv,SizeOf(Pointer)*length(ArgsW));
  for i:=0 to length(ArgsW)-1 do
  begin
    ArgsUTF8[i]:=ArgsW{%H-}[i];
    argv[i]:=PChar(ArgsUTF8[i]);
  end;
end;

procedure FinalizeLazUTF8;
{$IFDEF UTF8_RTL}
var
  p: PPChar;
{$ENDIF}
begin
  {$IF DEFINED(UTF8_RTL) AND NOT DEFINED(WINCE)}
  // restore argv and free memory
  if OldArgV<>nil then
  begin
    p:=argv;
    argv:=OldArgV;
    Freemem(p);
  end;
  {$IFEND}
end;

A simple program with the following uses clause
uses
  CMem, SysUtils, LazUtf8;
and heapTrace enabled (-gh) does not crash here (win32, fpc 3.0.0 on Win7-64)

Jonas Maebe

2016-03-03 13:01

manager   ~0090590

Then it's probably another, case where something is in fact freed. There is no (supported) way to detect whether another memory manager has been installed (cmem or otherwise).

barlone

2016-03-03 14:57

reporter   ~0090602

@Jonas:

> There is no (supported) way to detect whether another memory manager
> has been installed (cmem or otherwise).

function IsMemoryManagerSet:Boolean;

Bart Broersma

2016-03-03 16:19

developer   ~0090613

> function IsMemoryManagerSet:Boolean;
Also returns TRUE if HeapTrace is used, so not usefull for this particular problem.

barlone

2016-03-03 18:11

reporter   ~0090617

I propose add to TMemoryManager record member
ManagerName: pchar;
I can make patch set and test it.

Bart Broersma

2016-03-08 11:48

developer   ~0090763

I still cannot reproduce.
Lazarus 1.7 r51837 FPC 3.0.0 i386-win32-win32/win64

program cm;

{$mode objfpc}{$H+}
{$apptype console}

uses
  CMem, LCLProc;

var
  p: pointer;
begin
  {$ifdef cpu64}
  writeln('64-bit');
  {$else}
  writeln('32-bit');
  {$endif}
  {$ifdef disableutf8rtl}
  writeln('Utf8 in RTL is OFF');
  {$else}
  writeln('Utf8 in RTL is ON');
  {$endif}
  getmem(p,1024*1024);
end.

Testing for 32/64 bit and with/without DisableUtf8RTL:

C:\Users\Bart\LazarusProjecten\bugs\CMem>cm
32-bit
Utf8 in RTL is ON

C:\Users\Bart\LazarusProjecten\bugs\CMem>cm
32-bit
Utf8 in RTL is OFF

C:\Users\Bart\LazarusProjecten\bugs\CMem>cm
64-bit
Utf8 in RTL is ON

C:\Users\Bart\LazarusProjecten\bugs\CMem>cm
64-bit
Utf8 in RTL is OFF

Bart Broersma

2016-03-08 11:59

developer   ~0090764

I can also run a simple Lazarus GUI app with CMem, without crashes.
(It even does not crash when build with heaptrace (-gh))

barlone

2016-03-09 14:51

reporter   ~0090792

@bart:
I use FPC from trunk (3.1.1). Problem appear after updating FPC sources from trunk.

Bart Broersma

2016-03-10 17:13

developer   ~0090848

@barlone: can you disect which fpc revison broke it?
(I don't have fpc trunk)

BrunoK

2019-07-23 15:09

reporter   ~0117354

Last edited: 2019-07-23 15:11

View 2 revisions

I met with the same problem. I think it is an FPC bug or something in cmem that returns a nil pointer in astrings.inc pc_AnsiStr_SetLength that obtains a nil pointer.
The Pointer(S) there has a value of AnsiFirstOff (0C in 32 bit mode).
Haven't yet figured out what is the problem. It is on my list. I had thought that it occurred only to me because of some changes that I made in that unit.
EDIT : fpc 3.0.4

Bart Broersma

2020-03-01 15:28

developer   ~0121295

I can run full LCL programs with CMem on Windows with Lazarus 2.1.0 r62473 FPC 3.3.1 i386-win32-win32/win64, even with HeapTrace enabled.

BrunoK

2020-03-04 17:01

reporter   ~0121365

@Bart Broersma 2020-03-01 15:28

The following program compiled with FPC trunk doesn't report leaks when compiled with cmem or am I doing something wrong ?

program Project1;

{ compile with -gh }

uses
  cmem, { Comment out this line to use heap.inc }
  classes, SysUtils;

var
  vLogFileName : string;
begin
{$if declared(UseHeapTrace)}
  vLogFileName := ChangeFileExt(ParamStr(0), '_log.txt');
  if FileExists(vLogFileName) then
    DeleteFile(vLogFileName);
  SetHeapTraceOutput(vLogFileName);
  GlobalSkipIfNoLeaks := true; // supported as of debugger version 3.1.1
{$endif}
  TList.Create; // <- this will leak
  WriteLn('If leaks, they are written to : ', vLogFileName);
  Write('Press enter to quit > '); ReadLn;
end.

Akira1364

2020-03-06 19:43

reporter   ~0121419

@BrunoK:

HeapTrace is not actually supposed to do anything useful when combined with CMem (or at least it's never been implemented).

The `CGetHeapStatus` and `CGetFPCHeapStatus` functions that `cmem.pp` points the `GetHeapStatus` and `GetFPCHeapStatus` procvars of `CMemoryManager` at in the initialization section don't do anything at all: they just zero out the status records with `FillChar` and return them.

So if CMem is no longer crashing your app, then there's no longer a bug, HeapTrace or no HeapTrace.

Issue History

Date Modified Username Field Change
2016-02-29 19:44 barlone New Issue
2016-02-29 19:44 barlone File Added: screenshot.png
2016-02-29 22:19 Thaddy de Koning Note Added: 0090498
2016-02-29 22:19 Thaddy de Koning Note Edited: 0090498 View Revisions
2016-03-01 11:05 barlone Note Added: 0090512
2016-03-01 13:42 barlone Note Added: 0090525
2016-03-01 15:34 Cyrax Note Added: 0090526
2016-03-01 17:22 barlone Note Added: 0090529
2016-03-02 07:18 Cyrax Note Added: 0090540
2016-03-02 09:58 Jonas Maebe Note Added: 0090543
2016-03-02 11:22 barlone Note Added: 0090549
2016-03-02 11:34 Jonas Maebe Note Added: 0090550
2016-03-02 11:34 Jonas Maebe Note Edited: 0090550 View Revisions
2016-03-03 10:34 barlone Note Added: 0090579
2016-03-03 10:52 Jonas Maebe Note Added: 0090581
2016-03-03 10:52 Jonas Maebe Category RTL => LCL
2016-03-03 10:52 Jonas Maebe Project FPC => Lazarus
2016-03-03 12:35 Bart Broersma Note Added: 0090588
2016-03-03 12:50 Bart Broersma Note Added: 0090589
2016-03-03 13:01 Jonas Maebe Note Added: 0090590
2016-03-03 14:57 barlone Note Added: 0090602
2016-03-03 16:19 Bart Broersma Note Added: 0090613
2016-03-03 18:11 barlone Note Added: 0090617
2016-03-08 11:48 Bart Broersma Note Added: 0090763
2016-03-08 11:59 Bart Broersma Note Added: 0090764
2016-03-09 14:51 barlone Note Added: 0090792
2016-03-10 17:13 Bart Broersma Note Added: 0090848
2019-07-23 15:09 BrunoK Note Added: 0117354
2019-07-23 15:11 BrunoK Note Edited: 0117354 View Revisions
2020-03-01 15:28 Bart Broersma Note Added: 0121295
2020-03-04 17:01 BrunoK Note Added: 0121365
2020-03-06 19:43 Akira1364 Note Added: 0121419