Sign in Join

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

Mailing lists / fpc-pascal / 2010-10

Disk Full

7 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Bernd Kreuss

The following code (Msg is just outputting to the debug monitor) will produce something strange:

// replace all line endings with space
for Pos1 := 1 to Len do begin
  try
    Msg(2, 'GetVector', Format('  %d %d',[Pos1, Len]));
    if Line[Pos1] = #13 then Line[Pos1] := ' ';
    if Line[Pos1] = #10 then Line[Pos1] := ' ';
  except
    on e: Exception do
      Msg(2, 'GetVector', Format('e %d %d %s',[Pos1, Len, e.message]));
  end;
end;
Show quoted text 23 lines
[1428] <2> TRConsole.GetVector: 1 84 [1428] <2> TRConsole.GetVector: 2 84 [1428] <2> TRConsole.GetVector: 3 84 [1428] <2> TRConsole.GetVector: e 3 84 Disk Full [1428] <2> TRConsole.GetVector: 4 84 [1428] <2> TRConsole.GetVector: 5 84 [1428] <2> TRConsole.GetVector: 6 84 [1428] <2> TRConsole.GetVector: 7 84 [1428] <2> TRConsole.GetVector: 8 84 [1428] <2> TRConsole.GetVector: 9 84 [1428] <2> TRConsole.GetVector: e 9 84 Disk Full [1428] <2> TRConsole.GetVector: 10 84 [1428] <2> TRConsole.GetVector: 11 84 [1428] <2> TRConsole.GetVector: 12 84 [1428] <2> TRConsole.GetVector: 13 84 [1428] <2> TRConsole.GetVector: 14 84 [1428] <2> TRConsole.GetVector: 15 84 [1428] <2> TRConsole.GetVector: e 15 84 Disk Full [1428] <2> TRConsole.GetVector: 16 84 [1428] <2> TRConsole.GetVector: 17 84 [1428] <2> TRConsole.GetVector: 18 84 [1428] <2> TRConsole.GetVector: 19 84 [1428] <2> TRConsole.GetVector: 20 84

and so on.

This is not the only code that fails in strange ways! I wondered all the time why I got random non-deterministic crashes all the time and only when I inserted these debug message outputs into this loop the nature of the problem became more clear.

The code in question is running in a dll that is loaded by a the proprietary software Metatrader 4 (through their proprietary scripting language) and it does not much more than having a TProcess in which Rterm.exe (the R-Project) is running (and idle) and there are two pipes for the stdio of this process but they are empty and idle when this happens. I have no other threads started when this happens (of course Metatrader has a few) but not my dll and nothing calls into my dll when this happens.

FPC is 2.5.1 trunk.

There are no OS exceptions happening because I have another dll with an exception handler hooked into AddVectoredExceptionHandler() as the very forst handler that does reliable log all these windows exceptions (AV, FPU, etc).

What could cause this strange effect? What kind of outside force can make this thread raise an FPC native exception although it does not come anywhere near a raise statement? Maybe there is something wrong in the DLLMain when the attach_thread event happens? does it mess up this thread ID (or however the raise mechanism works) with something else?

Maybe something else is permanently calling raise and random other threads are catching it?

confused,
Bernd

Reply by email

Bernd Kreuss
to Bernd Kreuss
Bernd Kreuss wrote 11 lines
> [1428] <2> TRConsole.GetVector: 1 84 > [1428] <2> TRConsole.GetVector: 2 84 > [1428] <2> TRConsole.GetVector: 3 84 > [1428] <2> TRConsole.GetVector: e 3 84 Disk Full > [1428] <2> TRConsole.GetVector: 4 84 > [1428] <2> TRConsole.GetVector: 5 84 > [1428] <2> TRConsole.GetVector: 6 84 > [1428] <2> TRConsole.GetVector: 7 84 > [1428] <2> TRConsole.GetVector: 8 84 > [1428] <2> TRConsole.GetVector: 9 84 > [1428] <2> TRConsole.GetVector: e 9 84 Disk Full

What do you suggest I could try to narrow down the reason for this?

PS: Is there any possibility to make a DLL that has a completely empty DLLMain or one that I can entirely write myself without having to patch the RTL?

Reply by email

Bernd Kreuss
to Bernd Kreuss

from rtl/win/syswin.inc:

Show quoted text 20 lines
DLL_THREAD_ATTACH : begin inclocked(Thread_count); WinEnterCriticalSection(AttachingThread); if Win32GetCurrentThreadId MainThreadIdWin32 then begin { Allocate Threadvars } SysAllocateThreadVars; { NS : no idea what is correct to pass here - pass dummy value for now } { passing a dummy is ok, the correct value is read from the coff header of SysInstance (FK) } InitThread($1000000); { Assume everything is idempotent there, as the thread could have been created with BeginThread... } end; if assigned(Dll_Thread_Attach_Hook) then Dll_Thread_Attach_Hook(DllParam); Dll_entry:=true; { return value is ignored } WinLeaveCriticalSection(AttachingThread); end;

will this also work when some object in my own dll is starting a thread with TThread that is already properly initialized or will it then try to initialize it twice?

Reply by email

Bernd Kreuss
to Bernd Kreuss: The following code (Msg is just outputting to the debug monitor) will produce something…
Bernd Kreuss wrote
"Disk full"

Please ignore this thread and don't waste any more time thinking about it.

It was my own stupidity. My über-cool debug log function had a stupid writeln in it that should not have been used when running on windows and no stdout is available. This writeln did cause the "disk full".

All problems seem to be gone now.

Bernd

Reply by email

Sven Barth
to Bernd Kreuss: from rtl/win/syswin.inc: will this also work when some object in my own dll is starting a…
Bernd Kreuss wrote 26 lines
from rtl/win/syswin.inc: > DLL_THREAD_ATTACH : > begin > inclocked(Thread_count); > > WinEnterCriticalSection(AttachingThread); > if Win32GetCurrentThreadId MainThreadIdWin32 then > begin > { Allocate Threadvars } > SysAllocateThreadVars; > > { NS : no idea what is correct to pass here - pass dummy value for now } > { passing a dummy is ok, the correct value is read from the coff header of SysInstance (FK) } > InitThread($1000000); { Assume everything is idempotent there, as the thread could have been created with BeginThread... } > end; > > if assigned(Dll_Thread_Attach_Hook) then > Dll_Thread_Attach_Hook(DllParam); > Dll_entry:=true; { return value is ignored } > WinLeaveCriticalSection(AttachingThread); > end; will this also work when some object in my own dll is starting a thread with TThread that is already properly initialized or will it then try to initialize it twice?

Although you've said that you've found the problem: yes, that is a concern that occured to me as well after I reported the problem of the AttachingThread critical section. I'll need to look into it what problems there really could arise and how it might be fixed.

Regards,
Sven

Reply by email

Sven Barth
to Bernd Kreuss: from rtl/win/syswin.inc: will this also work when some object in my own dll is starting a…
Bernd Kreuss wrote 26 lines
from rtl/win/syswin.inc: > DLL_THREAD_ATTACH : > begin > inclocked(Thread_count); > > WinEnterCriticalSection(AttachingThread); > if Win32GetCurrentThreadId MainThreadIdWin32 then > begin > { Allocate Threadvars } > SysAllocateThreadVars; > > { NS : no idea what is correct to pass here - pass dummy value for now } > { passing a dummy is ok, the correct value is read from the coff header of SysInstance (FK) } > InitThread($1000000); { Assume everything is idempotent there, as the thread could have been created with BeginThread... } > end; > > if assigned(Dll_Thread_Attach_Hook) then > Dll_Thread_Attach_Hook(DllParam); > Dll_entry:=true; { return value is ignored } > WinLeaveCriticalSection(AttachingThread); > end; will this also work when some object in my own dll is starting a thread with TThread that is already properly initialized or will it then try to initialize it twice?

Although you've said that you've found the problem: yes, that is a concern that occured to me as well after I reported the problem of the AttachingThread critical section. I'll need to look into it what problems there really could arise and how it might be fixed.

Regards,
Sven

Reply by email

Sven Barth

Am 12.10.2010 09:51, schrieb Sven Barth:
[4 times the same mail]

Sorry for the spam, but Thunderbird reported an error which wasn't one. *blush*

Regards,
Sven

Reply by email