[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