OnError library in threaded program

Just starting out? Need help? Post your questions and find answers here.
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

OnError library in threaded program

Post by ozzie »

I have OnErrorCall(@generalErrorHandler()) near the start of my program, where the Procedure generalErrorHandler() is based on the ErrorHandler() in the PB documentation. This works well, catching mainly "Invalid memory access" conditions caused by array subscripts out of range - yes, my program is still in beta!

Sometimes, though, it seems that the values returned by ErrorFile() and Errorline() relate to a different thread to the one that caused the error. I include the thread number in the error message displayed. For example, I can get an Invalid memory access error reported on a source line that should not cause this condition, and the thread number in the message relates to a thread that doesn't even use that source line. In this situation I can accept that there is a memory problem occurring in the reported thread, but I can't easily find out line source code line on which the error occurs. I get the impression ErrorFile() and ErrorLine() may be returning the latest file and line executed, which may be by another thread.

My Compiler Options include:
Create threadsafe executable
Enable OnError lines support
Create unicode executable

Is there something else I should be doing to guarantee getting the correct ErrorFile() and ErrorLine() in the error handler?
Thorium
Addict
Addict
Posts: 1308
Joined: Sat Aug 15, 2009 6:59 pm

Re: OnError library in threaded program

Post by Thorium »

ozzie wrote: Sometimes, though, it seems that the values returned by ErrorFile() and Errorline() relate to a different thread to the one that caused the error.
It's a known problem. As far as i know you can't do anything about it. If you use threads ErrorFile() and Errorline() will not be reliable.
Hugo
New User
New User
Posts: 6
Joined: Fri Nov 25, 2005 8:46 am
Location: Germany

Re: OnError library in threaded program

Post by Hugo »

Hi,

any news about this?

I have the same problem to find the relevant line in my code in a threaded program. If the OnError lib will be unusable for this what else can I do to find the programline?

Hugo
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: OnError library in threaded program

Post by sec »

Fred, please help us !!

Thanks much.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: OnError library in threaded program

Post by ts-soft »

The OnError lib is not to found Bugs! For this is the Debugger, and it is not easy to find Bugs in Threaded programs.
You have to debug all threads separat, with disable/enable debugger.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: OnError library in threaded program

Post by sec »

ts-soft wrote:The OnError lib is not to found Bugs! For this is the Debugger, and it is not easy to find Bugs in Threaded programs.
You have to debug all threads separat, with disable/enable debugger.
The crash is only on customer's machine,.. I want get report bug, but dont know where to fix in source code??
Little John
Addict
Addict
Posts: 4802
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: OnError library in threaded program

Post by Little John »

sec wrote:The crash is only on customer's machine,.. I want get report bug, but dont know where to fix in source code??
I had a similar problem some time ago. I made good experiences with OnErrorCall().
Assigning some values to global variables and let the error handler show you these values can help a lot. My error handler looked like this:

Code: Select all

Procedure ErrorHandler()
   Protected msg$
   
   msg$ = "Error in packer plugin" + #LF$
   msg$ + #DQUOTE$ + g_TC_Packer_Plugin$ + #DQUOTE$ + #LF$
   msg$ + "calling CanYouHandleThisFile() for" + #LF$
   msg$ + #DQUOTE$ + g_TC_Packer_File$ + #DQUOTE$ + "." + #LF$
   msg$ + "Please report this error to the plugin author!" + #LF$
   msg$ + #LF$
   msg$ + "The reported error is: " + #DQUOTE$ + ErrorMessage() + #DQUOTE$ + "."
   MessageRequester("Fatal error", msg$)
   End
EndProcedure
I don't have experiences with threads, though. If your program uses threads, you probably should make some special preparations.

You can also write multiple error handlers, and then for any given context active the one you need:

Code: Select all

OnErrorCall(@ErrorHandler_1())
[...]
OnErrorCall(@ErrorHandler_2())
[...]
OnErrorCall(@ErrorHandler_3())
[...]
OnErrorCall(@ErrorHandler_1())
Regards, Little John
acreis
Enthusiast
Enthusiast
Posts: 232
Joined: Fri Jun 01, 2012 12:20 am

Re: OnError library in threaded program

Post by acreis »

I used to have the same problem in VB.NET, when using the "BackgroundWorker" (a sort of thread).

I think it is a Windows OS issue, and can only be solved by Microsoft (if possible).

My workaround is to code the software so that with a simple global flag, it works threaded or non threaded.

When the program is free of bugs, then "useThreads = #True".

In extreme circumnstances, this could even be an end-user option.

Regards, ACReis
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: OnError library in threaded program

Post by LiK137 »

I had the same problem with Errortraping in ThreadedApp.
OnErrorCalls was failing to call ErrorTraProcedure.
Program was crashing and Windows7ErReporting just myApp
is closing and no usefull info was given by Windows7 regarding cause of crash
My solution was inconvenient while being very accurate.
I Used logging each linenumber so after eachline was using ":linelog(realinum)"
and predictivly know where program crashed.
After I knew where to digg (bufferoverflow because of unicode) I fixed those errors and removed lineLogging.
Program runs smooth weeks and monthes untill manual shutdown.
PureBasic very powerfull and Forum is very quickresponsive.
Thanx FRED.
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: OnError library in threaded program

Post by Keya »

Perhaps you can check the current thread ID to detect which thread is triggering the error?

Code: Select all

CompilerSelect #PB_Compiler_OS   
  CompilerCase #PB_OS_MacOS, #PB_OS_Linux
    ImportC ""
      pthread_self.l()
    EndImport 
CompilerEndSelect

Procedure.l GetCurrentThreadId()
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows    
      ProcedureReturn GetCurrentThreadId_()
    CompilerCase #PB_OS_MacOS, #PB_OS_Linux
      ProcedureReturn pthread_self_()
  CompilerEndSelect  
EndProcedure
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: OnError library in threaded program

Post by RichAlgeni »

Agreed, it is very difficult to debug threads! Sometimes the stack is so corrupt, nothing at all is created by OnErrorCalls. This is especially so when writing Windows Services, of which I have many.

Once I realized this, there were a number of steps I took to track bugs down:
  1. 1. Make sure all dlls utilized are threadsafe.
  1. 2. Use Global, read-only switches to determine if a thread should be created, or the procedure called in the normal, non-threaded manner.
  1. 3. Create a procedure dedicated to logging, the create a standard for calling this procedure through Global and Local switches. At the beginning of each procedure I have, I assign a local base two number: 1, 2, 4, 8, 16, etc. I use an ini file to determine which procedures should be logged, for instance loggingLevel=18 means that the Procedure with 2 assigned and the Procedure with 16 assigned are logged, others are not.
  1. 4. I also have a Global logAllLevels switch, which makes it easy to turn on logging for all procedures.
  1. 5. I've found that most of the time, at least for myself, the problem is with memory reading or writing. Add extra logging calls to procedures that manipulate memory. Doublecheck allocating memory and their sizes. Try adding a small Delay after Poking and Peeking. Trying to write too much data into a memory area is a very common source of crashes that may not return any data from an OnErrorCall.
  1. 6. Try to never write Global variables from procedures, unless you add locking. Yes, there are times when you may need to do this! I've found SlimReaderWriter functions work great in Windows. Search for my user name, and you will see some posts about these.
  1. 7. If the crash is not duplicatable in non-threaded mode, most likely you are writing a Global variable without realizing it. In non-threaded mode, this isn't a problem.
  1. 8. Keep adding non-threaded logging calls, until you can consistently log just prior to when a failure occurs. If you are calling an external procedure, log just before the call, and just after.
Post Reply