[Lazarus] Lazarus application crash. Is PostMessage thread safe?
zeljko
zeljko at holobit.net
Wed Feb 10 08:44:26 CET 2016
On 02/09/2016 11:37 PM, Giuliano Colla wrote:
> Hi Lazarus guru's,
>
> I have stumbled into a problem with a Lazarus application. At random
> times, from 5 minutes to several hours, it crashes suddenly, and silently.
> The only way to get a clue has been to run it with gdb.
>
> It turns out that the crash occurs because of a Segmentation Fault in
> QTextEngine, triggered by a PostMessage, but apparently the cause was an
> endless loop in a previous PostMessage, which was executed some 1723
> times. Attached the gdb stack trace (with 1722 identical items suppressed).
>
> The scenario is a main thread using LCL, which is used, among other
> things not relevant here, to display information to the user, and
> another thread which communicates with a real-time process, and uses a
> PostMessage to wake up the main thread and make it show what required.
>
> It appears that in some circumstances, the Application.ProcessMessages
> invoked in the main thread restarts the handling of the same message,
> thus creating and endless loop.
>
> Is Application.ProcessMessages the vilain, or PostMessage or what?
>
> Snippet of auxiliary thread code:
>
>
>> procedure TSendRec.DoDisplayError;
>> var
>> Box: integer;
>> begin
>> ErrList[ErrPut] := ErrMsg;
>> inc(ErrPut);
>> if ErrPut > High(ErrList) then ErrPut := 0;
>> {$IFDEF USE_MESSAGES}
>> PostMessage(Form1.Handle,LM_ERROR,Integer(ErrPut),0);
>> {$ENDIF}
>> end;
> Snippet of main thread code:
>
>> procedure TForm1.HandleError(var Msg: TLMessage);
>> var
>> .....
>> begin
>> inc(ErrorCnt);
>> if ErrGet <> ErrPut then begin
>> ErrMsg := ErrList[ErrGet];
>> .......
>> AnswerString := Format('UNIT %XH device %s ERROR
>> %XH',[ErrMsg.yunit,Localize(NamUn[ErrMsg.device]),ErrMsg.ytype]);
>> ShowError(Self,Answerstring,BoxError[Box],Box);
>> inc(ErrGet);
>> if ErrGet > High(ErrList) then ErrGet := 0;
>> end;
>> end;
1.Your ErrList access does not look thread safe.
2.You are casting postMessage param as integer, IMO it's wrong,
shouldn't it be PtrInt or LPARAM ?
PostMessage(Form1.Handle,LM_ERROR, LPARAM(ErrPut),0);
3.Application.ProcessMessages probably recurse.
I'm using PostMessage() with QtLCL inside one app which heavily uses
threads for gui controls updates and it works w/o problems, atm, one of
our users have that app running, uptime is cca 90 days (since last
update). I don't use such lists, but creating record pointer and free it
in main thread message queue....
zeljko
More information about the Lazarus
mailing list