Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-16 Thread Giuliano Colla

Il 16/02/2016 10:04, Michael Schnell ha scritto:

a (potential) bug (in "Glib2" whatever this exactly means)


Glib2 means version 2 of GTK Glib, which is used by Qt (and by GTK) to 
implement the main event loop.

libglib-2.0.so.0

The full picture (from stack trace) is as follows:

1. The main loop of Lazarus (under Qt WS) calls AppWaitMessage in
   qtobject.inc
2. qtobject calls QCoreApplication::processEvents in qcoreapplication_c.cpp
3. qcoreapplication_c.cpp calls QEventDispatcherGlib in libQtGui.so.4
4. QEventDispatcherGlib calls g_main_context_iteration in
   libglib-2.0.s0.0 (the Glib2)
5. if g_main_context_iteration has pending messages, it calls
   g_main_context_dispatch
6. g_main_context_dispatch calls QCoreApplicationPrivate::sendPostedEvents

When the user code calls Application.ProcessMessages the same sequence 
occurs:
AppProcessMessages in QtObjects.inc is called, which then calls 
QCoreApplication::processEvents, and all the steps from 2 on are identical.


My feeling is that the bug is sort of this: if the call to 
Application.ProcessMessages causes a recursion, and a new different 
message has arrived in the meantime, g_main_context_iteration() 
understands rightly that there is a pending message to dispatch, but it 
decides wrongly to dispatch again the old one, instead of the new one.
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-16 Thread Giuliano Colla

Il 16/02/2016 10:04, Michael Schnell ha scritto:
Anyway, IMHO it's not a good idea to fight a (potential) bug (in 
"Glib2" whatever this exactly means) by implementing a completely 
queer behavior in Application.ProcessMessage. 


I fully agree with you. Seeing a unexpected recursion, I had started 
believing that somehow Application.ProcessMessages could be the 
responsible. But if the problem is elsewhere, it should be fixed 
elsewhere, by someone knowing what he's doing.


Giuliano


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-16 Thread Michael Schnell

On 02/15/2016 07:23 PM, Giuliano Colla wrote:






The result is to make Application.ProcessMessage not 100% reentrant, 
because of a Glib2 bug.
Would you suggest not to handle "the same" event ? How should you 
detect that its the event already in the works or the next occurrence  ?


In the case I've stumbled into, when next message eventually comes 
(after 1722 iterations over the previous one) the program crashes for 
a  SEGFAULT, most likely generated by a stack overflow.
Anyway, IMHO it's not a good idea to fight a (potential) bug (in "Glib2" 
whatever this exactly means) by implementing a completely queer behavior 
in Application.ProcessMessage.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-15 Thread Giuliano Colla

Il 15/02/2016 11:54, Michael Schnell ha scritto:

On 02/13/2016 12:27 PM, Giuliano Colla wrote:


At least under Qt widgetset, it may happen that calling 
Application.ProcessMessages from within a Message Handler will cause 
the same message which was being processed to be processed again, the 
handler called again and Application.ProcessMessages being called 
again, thus originating an endless loop and a consequent stack overflow.


When calling Application.ProcessMessages from within a Message Handler 
the *next* event in the event  queue should be handled. If 
*the*event*already*being*handled* pops up again, that would be a bug. 
But of course "the same" message might have pushed by some thread and 
also needs handling. Here the same handler might be called 
recursively. This of course does need additional stack space, but not 
infinitely .


I'm positively sure that the message being handled is *the same* for a 
number of reasons.
It is identified by an "errorstring" which from the stack dump is always 
the same.
It cannot be sent more than once, because where it originates it waits 
for a user error reset, before sending the next. Moreover, the error 
messages originate in a real-time part, which has a pool of just 40 
messages, therefore it can't possibly send 1722 messages.
The same code has been field tested in hundreds of application which 
have been running for many years (since 2005), with the only difference 
that the messages were handled in the OnIdle Handler, waking up the main 
thread periodically with a timer event, instead of waking up the main 
thread with a PostMessage.







The result is to make Application.ProcessMessage not 100% reentrant, 
because of a Glib2 bug.
Would you suggest not to handle "the same" event ? How should you 
detect that its the event already in the works or the next occurrence  ?




In the case I've stumbled into, when next message eventually comes 
(after 1722 iterations over the previous one) the program crashes for a  
SEGFAULT, most likely generated by a stack overflow.


Giuliano




--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-15 Thread Michael Schnell

On 02/13/2016 12:27 PM, Giuliano Colla wrote:


At least under Qt widgetset, it may happen that calling 
Application.ProcessMessages from within a Message Handler will cause 
the same message which was being processed to be processed again, the 
handler called again and Application.ProcessMessages being called 
again, thus originating an endless loop and a consequent stack overflow.


When calling Application.ProcessMessages from within a Message Handler 
the *next* event in the event  queue should be handled. If 
*the*event*already*being*handled* pops up again, that would be a bug. 
But of course "the same" message might have pushed by some thread and 
also needs handling. Here the same handler might be called recursively. 
This of course does need additional stack space, but not infinitely .




The result is to make Application.ProcessMessage not 100% reentrant, 
because of a Glib2 bug.
Would you suggest not to handle "the same" event ? How should you detect 
that its the event already in the works or the next occurrence  ?


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-13 Thread Giuliano Colla

Il 12/02/2016 15:35, Michael Schnell ha scritto:

On 02/12/2016 03:17 PM, Mattias Gaertner wrote:
IMHO, Michael, you should not redefine words. It confuses people. 
Reentrant means it can be called again, while it is still running. It 
does not need to be thread-safe. 


Sorry that was not me. The subject here is " thread save " ,so 
I tried to explain exactly the difference you mention.




It was possibly me causing the confusion.

I was experiencing random crashes triggered from a PostMessage executed 
in a different thread.


My first assumption was that possibly PostMessage wasn't thread safe, 
and this is the reason of the subject of my first post.


Further analysis has shown that this was not the case. It was not a 
matter of thread-safe, but a matter of recursion.


At least under Qt widgetset, it may happen that calling 
Application.ProcessMessages from within a Message Handler will cause the 
same message which was being processed to be processed again, the 
handler called again and Application.ProcessMessages being called again, 
thus originating an endless loop and a consequent stack overflow.


All of that apparently originates in the g_main_context_iteration() 
procedure of Glib2, which, in some cases, doesn't properly terminate a 
dispatch operation, and in case of recursion will execute again a 
g_main_context_dispatch() for a message already dispatched. As it is 
g_main_context_iteration() responsibility to decide which procedures to 
call and when terminate, it is its responsibility to provide appropriate 
protection from recursion.


Looking into the code of gmain.c of Glib2, and in different versions, it 
can be seen that attempts have been made to avoid the problem, but 
apparently there's still a hole left.


The result is to make Application.ProcessMessage not 100% reentrant, 
because of a Glib2 bug.


Giuliano


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-12 Thread Michael Schnell

On 02/12/2016 03:17 PM, Mattias Gaertner wrote:
IMHO, Michael, you should not redefine words. It confuses people. 
Reentrant means it can be called again, while it is still running. It 
does not need to be thread-safe. 


Sorry that was not me. The subject here is " thread save " ,so I 
tried to explain exactly the difference you mention.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-12 Thread Michael Schnell

On 02/10/2016 10:12 PM, C Western wrote:


My understanding is Application.ProcessMessages has to be reentrant ...


As calling Application.ProcessMessages is only allowed from the main 
thread it does not need to be reentrant = thread-save.


Of course it can be called recursively and it hence is reentrant in that 
meaning.


-Michael


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-12 Thread Mattias Gaertner
On Fri, 12 Feb 2016 14:53:29 +0100
Michael Schnell  wrote:

> On 02/10/2016 10:12 PM, C Western wrote:
> >
> > My understanding is Application.ProcessMessages has to be reentrant ...
> 
> As calling Application.ProcessMessages is only allowed from the main 
> thread it does not need to be reentrant = thread-save.

IMHO, Michael, you should not redefine words. It confuses people.
Reentrant means it can be called again, while it is still running. It
does not need to be thread-safe. And a thread-safe function does not
need to be reentrant.
Application.ProcessMessages itself is reentrant, but it is not
thread-safe. In fact, as already noted by Michael, it must only be
called by the main thread.
But Application.ProcessMessages can call almost any event
handler, which might not support changing certain properties while
executing.

 
> Of course it can be called recursively and it hence is reentrant in that 
> meaning.

True.

Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-11 Thread Giuliano Colla

Il 10/02/2016 21:13, Giuliano Colla ha scritto:
I don't believe that there's an easy way to protect 
Application.ProcessMessages from recursion unless someone is willing 
to debug and patch Glib (which is used not only by Qt, but also from 
GTK, if I'm not wrong).


A snippet from gmain.c:

#if 0
  /* If recursing, finish up current dispatch, before starting over */
  if (context->pending_dispatches)
{
  if (dispatch)
g_main_dispatch (context, _time);

  UNLOCK_CONTEXT (context);
  return TRUE;
}
#endif



It would appear that they realized the dispatch recursion problems but 
where unable to find a clean solution!
This code appears both in glib-2.28.8 (the one coming with CentOs 6, 
which I've been using) and in the current version i.e. glib-2.47.5.
My feeling is that it's been left there as a reminder that the matter is 
still pending.

I'm afraid we must live with it.

Giuliano



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-10 Thread Giuliano Colla

Il 10/02/2016 13:48, zeljko ha scritto:

I believe
that Application.ProcessMessages should protect itself too, avoiding to
handle more than once the same message.


But where ? In LCL or per widgetset ? 


I skimmed through the backtrace. It would appear that the recursion 
originates in g_main_context_iteration() which calls 
g_main_context_dispatch(), which will continue to dispatch the same 
message. I don't believe that there's an easy way to protect 
Application.ProcessMessages from recursion unless someone is willing to 
debug and patch Glib (which is used not only by Qt, but also from GTK, 
if I'm not wrong). Personally I  give up.


Giuliano


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-10 Thread C Western

On 10/02/16 20:13, Giuliano Colla wrote:

Il 10/02/2016 13:48, zeljko ha scritto:

I believe
that Application.ProcessMessages should protect itself too, avoiding to
handle more than once the same message.


But where ? In LCL or per widgetset ?


I skimmed through the backtrace. It would appear that the recursion
originates in g_main_context_iteration() which calls
g_main_context_dispatch(), which will continue to dispatch the same
message. I don't believe that there's an easy way to protect
Application.ProcessMessages from recursion unless someone is willing to
debug and patch Glib (which is used not only by Qt, but also from GTK,
if I'm not wrong). Personally I  give up.

Giuliano



My understanding is Application.ProcessMessages has to be reentrant for 
the clipboard to work, at least under X, as clipboard content is 
retrieved by receiving messages. See 
http://bugs.freepascal.org/view.php?id=26242 for a (fixed) bug that 
showed this up. The sequence is something along the lines of (for 
example) ProcessMessages -> Handle paste button -> clipboard -> 
ProcessMessages.


Colin


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-10 Thread Giuliano Colla

Il 10/02/2016 00:18, Denis Kozlov ha scritto:
Is your LM_ERROR larger than LM_USER? 


Yes :

const
LM_ANSWER= LM_USER + 100;
LM_MESSAGE   = LM_USER + 101;
LM_ERROR = LM_USER + 102;

Giuliano


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-10 Thread Giuliano Colla

Il 10/02/2016 00:22, Denis Kozlov ha scritto:
You create a recursive scenario yourself by calling 
Application.ProcessMessages inside of ShowError inside of HandleError 
- which is the message handling procedure itself, which is triggered 
by Application.ProcessMessages. 


That's what I had guessed, but having it confirmed makes me feel better.

Moreover my ShowError is not protected from recursion, because 
Application.ProcessMessages is called before incrementing ErrGet. 
Therefore in case of recursion, it will attempt to process again the 
same message.


I would appear that also Application.ProcessMessages is not protected 
against recursion, which is possibly a bug.


Thanks a lot,

Giuliano


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-10 Thread Giuliano Colla

Il 10/02/2016 08:44, zeljko ha scritto:

1.Your ErrList access does not look thread safe.


It's a poor man's thread safe queue, implemented as a ring buffer, with 
two indexes, ErrGet and ErrPut. It's fully safe, provided the buffer is 
guaranteed not to overflow, and that ErrPut is updated only after the 
buffer has been written. Only the sending thread writes the buffer and 
ErrPut, while the receiving thread only writes ErrGet, and reads just 
once ErrPut.
This mechanism has been tested by some billion messages passing in the 
years through it, by Kylix applications running 7/7 24h/24h in several 
hundreds locations.


It's not that there have been billions if errors:-) , but an identical 
setup is used to update informations at a rate of 8/10 per second. Only, 
in Kylix I couldn't use PostMessage, and it was processed in an OnIdle 
handler.



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);

PostMessage param is not actually used.

3.Application.ProcessMessages probably recurse.


This I believe to be the problem. From the observations from Denis I 
realized that my code isn't protected against recursion, but I believe 
that Application.ProcessMessages should protect itself too, avoiding to 
handle more than once the same message.


However thanks a lot,

Giuliano


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-10 Thread zeljko

On 02/10/2016 11:19 AM, Giuliano Colla wrote:


This I believe to be the problem. From the observations from Denis I
realized that my code isn't protected against recursion, but I believe
that Application.ProcessMessages should protect itself too, avoiding to
handle more than once the same message.


But where ? In LCL or per widgetset ?

zeljko

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-10 Thread Giuliano Colla

Il 10/02/2016 12:31, zeljko ha scritto:

On 02/10/2016 11:19 AM, Giuliano Colla wrote:


This I believe to be the problem. From the observations from Denis I
realized that my code isn't protected against recursion, but I believe
that Application.ProcessMessages should protect itself too, avoiding to
handle more than once the same message.


But where ? In LCL or per widgetset ?



I don't know. I did look into the code a long time ago, and I seem to 
remember that the main loop is handled differently: some widgetsets do 
rely on LCL, some on their main loop. I was hoping that someone more 
knowledgeable than me would say "oh yes, the right spot is just here!".
If such is not the case, I'll try, as soon as I have some time (which I 
don't have at the moment), to look again into the matter, and possibly 
suggest a patch.


Giuliano


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-10 Thread zeljko

On 02/10/2016 12:48 PM, Giuliano Colla wrote:

Il 10/02/2016 12:31, zeljko ha scritto:

On 02/10/2016 11:19 AM, Giuliano Colla wrote:


This I believe to be the problem. From the observations from Denis I
realized that my code isn't protected against recursion, but I believe
that Application.ProcessMessages should protect itself too, avoiding to
handle more than once the same message.


But where ? In LCL or per widgetset ?



I don't know. I did look into the code a long time ago, and I seem to
remember that the main loop is handled differently: some widgetsets do
rely on LCL, some on their main loop. I was hoping that someone more
knowledgeable than me would say "oh yes, the right spot is just here!".
If such is not the case, I'll try, as soon as I have some time (which I
don't have at the moment), to look again into the matter, and possibly
suggest a patch.


Qt relies on LCL main loop.

zeljko


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-10 Thread Giuliano Colla

Il 10/02/2016 22:12, C Western ha scritto:
My understanding is Application.ProcessMessages has to be reentrant 
for the clipboard to work, at least under X, as clipboard content is 
retrieved by receiving messages. See 
http://bugs.freepascal.org/view.php?id=26242 for a (fixed) bug that 
showed this up. The sequence is something along the lines of (for 
example) ProcessMessages -> Handle paste button -> clipboard -> 
ProcessMessages.


Well, in general it appears to behave, otherwise a lot of code would fail.
I just stumbled in a special case, when Application.ProcessMessages is 
called from within the handler of a message posted by a PostMessage from 
a different thread. It would appear that, under some circumstances 
(because the error appears randomly), there's a bug which causes it to 
pass again the same message, thus causing and endless loop. It's the 
recursion in this specific case which appears to be buggy.


Giuliano


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


[Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-09 Thread Giuliano Colla

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;

procedure TForm1.ShowError(Sender: TObject; errorstring: string;
Berror: TBoxerror; ErrBox: Integer);
var
...
begin
. (code to fill up Panel4)
  Panel4.Show;
  Panel4.BringToFront;
  Application.ProcessMessages;
  ResetBtn.SetFocus;
end;


Thanks for any help

Giuliano


[Thread debugging using libthread_db enabled]
[New Thread 0x7fffe7a90700 (LWP 4310)]

Program received signal SIGSEGV, Segmentation fault.
0x003d6a7dc904 in QTextEngine::itemize() const () from /usr/lib64/libQtGui.so.4
#0  0x003d6a7dc904 in QTextEngine::itemize() const () from /usr/lib64/libQtGui.so.4
#1  0x003d6a6f1fc9 in QPainter::drawText(QPointF const&, QString const&, int, int) () from /usr/lib64/libQtGui.so.4
#2  0x77d297db in drawText (handle=0x1729710, x=10, y=33, s=0x7f805578) at /usr/include/QtGui/qpainter.h:916
#3  QPainter_drawText3 (handle=0x1729710, x=10, y=33, s=0x7f805578) at src/qpainter_c.cpp:865
#4  0x00751061 in DRAWTEXT (this=0x7fffe9ca2300, X=10, Y=33, S=0x7f805578) at qt/qtobjects.pas:2832
#5  0x006d190d in EXTTEXTOUT (this=0x748d5730, DC=140737115726592, X=10, Y=20, OPTIONS=0, RECT=0x0, STR=0x7fffe9ca7990 '1 Â'#150, COUNT=4, DX=0x0) at qt/qtwinapi.inc:2291
#6  0x00595551 in EXTUTF8OUT (this=0x748d5730, DC=140737115726592, X=10, Y=20, OPTIONS=0, RECT=0x0, STR=0x7fffe9ca7990 '1 Â'#150, COUNT=4, DX=0x0) at include/intfbaselcl.inc:214
#7  0x0057e41c in EXTUTF8OUT (DC=140737115726592, X=10, Y=20, OPTIONS=0, RECT=0x0, STR=0x7fffe9ca7990 '1 Â'#150, COUNT=4, DX=0x0) at include/lclintf.inc:147
#8  0x005c2890 in TEXTOUT (this=0x7fffea0eed80, X=10, Y=20, TEXT=0x7fffe9ca7990 '1 Â'#150) at include/canvas.inc:1360
#9  0x004e6fec in POSWRT (PIMAGE=33286, SYM=144 #144, BGCOL=0, FGCOL=65280, CANVAS=0x7fffea0eed80, POS=...) at USequen.pas:547
#10 0x004e7b8b in DISPLCOD (DEVICE=FEEDER1_DEV, DISPLCORR=false, B=...) at USequen.pas:761
#11 0x004fca93 in HANDLEMESSAGE (this=0x748d7790, MSG=...) at USequen.pas:5779
#12 0x004b47a1 in SYSTEM_TOBJECT_$__DISPATCH$formal ()
#13 0x004fc128 in ?? ()
#14 0x748d7790 in ?? ()
#15 0x0003 in ?? ()
#16 0x0465 in ?? ()
#17 0x7f8062e8 in ?? ()
#18 0x748d7790 in ?? ()
#19 0x0001 in ?? ()
#20 0x7fffe009ac60 in ?? ()
#21 0x7fffe009ac60 in ?? ()
#22 0x00d645d4 in ?? ()
#23 0x00e5ad10 in ?? ()
---
The following section repeated 1723 times:
#24 0x00602c6f in WNDPROC (this=0x748d7790, THEMESSAGE=...) at include/control.inc:2112
#25 0x005f3dc4 in WNDPROC (this=0x748d7790, MESSAGE=...) at include/wincontrol.inc:5341
#26 0x004d1afe in WNDPROC (this=0x748d7790, THEMESSAGE=...) at include/customform.inc:1443
#27 0x0072918d in DELIVERMESSAGE (this=0x7fffec014630, MSG=0, AISINPUTEVENT=false) at qt/qtwidgets.pas:5549
#28 0x00726cfc in SLOTLCLMESSAGE (this=0x7fffec014630, SENDER=0xe5ad10, EVENT=0x7fffe009ac60) at qt/qtwidgets.pas:4353
#29 0x007232c8 in EVENTFILTER (this=0x7fffec014630, SENDER=0xe5ad10, EVENT=0x7fffe009ac60) at qt/qtwidgets.pas:2678
#30 0x0072d364 in EVENTFILTER 

Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-09 Thread Denis Kozlov

On 09/02/2016 22:37, Giuliano Colla wrote:

PostMessage(Form1.Handle,LM_ERROR,Integer(ErrPut),0);


Is your LM_ERROR larger than LM_USER?

PostMessage is thread safe.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-09 Thread Denis Kozlov


You create a recursive scenario yourself by calling 
Application.ProcessMessages inside of ShowError inside of HandleError - 
which is the message handling procedure itself, which is triggered by 
Application.ProcessMessages.



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Lazarus application crash. Is PostMessage thread safe?

2016-02-09 Thread zeljko

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

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus