Recent

Author Topic: Runtime(0) Error  (Read 5136 times)

JimKueneman

  • Full Member
  • ***
  • Posts: 220
Runtime(0) Error
« on: July 02, 2020, 02:56:11 pm »
I am at my wits end on this one....  My application does this on Mac and Windows so it seems like the compiler should be eliminated as the problem.... 

After about 3-8 calls to this function the app stops and throws a "raised exception class 'RunError(0)'" then it throws an "unknown" exception at the entrance to a method call.  It did the same thing on a previous method call within the same object but I refactored and pulled that code into this method but it now fails on NEW method call that use to be in the previous method that I eliminated...   I don't know what to do.  If I break it just sits at the method, looking at that stack tells me nothing as it stops at this place it is.  Looking at the CPU it just shows a bunch of question marks. 

Code: Pascal  [Select][+][-]
  1. procedure TFormTrainCommander.OnNodeIdentifyProducers(Sender: TObject;
  2.   LccSourceNode: TLccNode; LccMessage: TLccMessage; var DoDefault: Boolean);
  3. var
  4.   NMRA_SpeedStep: TLccDccSpeedStep;
  5.   NMRA_ForceLongAddress: Boolean;
  6.   SearchStr: string;
  7.   SearchDccAddress: LongInt;
  8.   ForceLongAddress: Boolean;
  9.   Train: TLccTrain;
  10.   SpeedStep: TLccDccSpeedStep;
  11.   ListIndex: Integer;
  12.   AnEvent: TEventID;
  13.   CanNode: TLccCanNode;
  14. begin
  15.  
  16.   // Only the CommandStation replies to this Event
  17.   if LccSourceNode = CommandStationNode then
  18.   begin
  19.     if LccMessage.TractionSearchIsEvent then
  20.     begin
  21.       NMRA_ForceLongAddress := False;
  22.       NMRA_SpeedStep := ldssDefault;
  23.  
  24.       SearchStr := LccMessage.TractionSearchDecodeSearchString;
  25.  
  26.       if TryStrToInt(SearchStr, SearchDccAddress) then                       // Gaurd against an empty string
  27.       begin
  28.         ForceLongAddress := False;                          // Setup up what we call defaults
  29.         SpeedStep := ldss14;                                // Setup up what we call defaults
  30.  
  31.         if LccMessage.TractionSearchIsProtocolAny then
  32.         begin
  33.  
  34.         end else
  35.         if LccMessage.TractionSearchIsProtocolDCC(NMRA_ForceLongAddress, NMRA_SpeedStep) then
  36.         begin
  37.           // Was a NMRA DCC message so look for the DCC specific information that overrides our defaults
  38.           LccMessage.TractionSearchIsProtocolDCC(ForceLongAddress, SpeedStep);
  39.           // Look for an existing Train
  40.           ListIndex := -1;
  41.           Train := TrainDatabase.FindByDccAddress(SearchDccAddress, ForceLongAddress, ListIndex);
  42.  
  43.           if (Train = nil) and LccMessage.TractionSearchIsForceAllocate then
  44.           begin
  45.             CanNode := CreateTrainNode;
  46.  
  47. // Dies on this call and yes TrainDatabase is created, also the previous code the function call WAS WITHIN THIS SAME OBJECT and it did the same thing.
  48.           Train := TrainDatabase.AddTrain('New Train', SearchStr, SearchDccAddress, ForceLongAddress, SpeedStep, CanNode);
  49.  
  50.  
  51.             ListViewTrains.AddItem(CanNode.NodeIDStr + ' : ' + CanNode.AliasIDStr, nil);
  52.                                                                                      
  53.  

The method is nothing fancy in parameter passing:

Code: Pascal  [Select][+][-]
  1. function TLccTrainDatabase.AddTrain(ARoadName, ARoadNumber: string;
  2.   ADccAddress: Word; ALongAddress: Boolean; ASpeedStep: TLccDccSpeedStep;
  3.   ALccNode: TLccNode): TLccTrain;
  4. var
  5.   ATrain: TLccTrain;
  6. begin
  7.   Result := TLccTrain.Create;
  8.   Result.DccAddress := ADccAddress;
  9.   Result.RoadName := ARoadName;
  10.   Result.RoadNumber := ARoadNumber;
  11.   Result.FLongAddress := ALongAddress;
  12.   Result.FSpeedSteps := ASpeedStep;
  13.   Result.LccNode := ALccNode;
  14.   TrainList.Add(Result);
  15. end;
  16.  

I am at a loss to even understand what to look for since I don't know what that error code means "0".  I have the "Verify Method Calls" -CR option on but it does it with it off as well and the SEEMS like it acts up more with it on but it could just be coincidence.   

How do I debug this?

Thanks
Jim 
« Last Edit: July 02, 2020, 03:24:52 pm by JimKueneman »

rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: Runtime(0) Error
« Reply #1 on: July 02, 2020, 03:39:36 pm »
Can you view the Call Stack when you get this exception.

View > Debug Windows > Call Stack
(or CTRL + ALT + S)

What linenumber does it say for the unit containing TLccTrainDatabase.AddTrain()

(You can also right click there and choose copy all and post it)

JimKueneman

  • Full Member
  • ***
  • Posts: 220
Re: Runtime(0) Error
« Reply #2 on: July 02, 2020, 03:48:18 pm »
#0 fpc_raiseexception at :0
#1 SYSUTILS_$$_RUNERRORTOEXCEPT$LONGINT$POINTER$POINTER at :0

// Green arrow points here to line #2

#2 ONNODEIDENTIFYPRODUCERS(0x2819e04, 0xd21624, 0xd15e24, 0x20e7404, true) at traincommanderunit.pas:486
#3 DOPRODUCERIDENTIFY(0xd21624, 0xd15e24, 0x20e7404, true) at ../../Target-Common/lcc_node_manager.pas:428
#4 PROCESSMESSAGE(0xd15e24, 0x20e7404) at ../../Target-Common/lcc_node.pas:1137
#5 PROCESSMESSAGE(0xd15e24, 0x20e7404) at ../../Target-Common/lcc_node.pas:662
#6 PROCESSMESSAGE(0xd21624, 0x20e7404) at ../../Target-Common/lcc_node_manager.pas:616
#7 DORECEIVEMESSAGE(0xf669b4) at ../../Target-PC/HardwareConnection/lcc_ethernet_server.pas:940
#8 CLASSES_$$_EXECUTETHREADQUEUEENTRY$TThread.PTHREADQUEUEENTRY at :0
#9 CARBONAPP_LAZWAKE(0xbfffeb70, 0xd191d0, 0x0) at carbonobject.inc:375
#10 _InvokeEventHandlerUPP at :0
#11 DispatchEventToHandlers at :0
#12 SendEventToEventTargetInternal at :0
#13 SendEventToEventTargetWithOptions at :0
#14 ToolboxEventDispatcherHandler at :0
#15 DispatchEventToHandlers at :0
#16 SendEventToEventTargetInternal at :0
#17 SendEventToEventTarget at :0
#18 APPPROCESSMESSAGES(0xe04274) at carbonobject.inc:693
#19 HANDLEMESSAGE(0x2009c04) at application.inc:1282
#20 RUNLOOP(0x2009c04) at application.inc:1419
#21 EVENTLOOPEVENTHANDLER(0xbffff510, 0xd21930, 0xe04274) at carbonobject.inc:173
#22 _InvokeEventHandlerUPP at :0
#23 DispatchEventToHandlers at :0
#24 SendEventToEventTargetInternal at :0
#25 SendEventToEventTargetWithOptions at :0
#26 ToolboxEventDispatcherHandler at :0
#27 DispatchEventToHandlers at :0
#28 SendEventToEventTargetInternal at :0
#29 SendEventToEventTarget at :0
#30 ToolboxEventDispatcher at :0
#31 RunApplicationEventLoop at :0
#32 APPRUN(0xe04274, {n  Proc = {procedure (POINTER)} 0xbffffa8c, n  Self = 0x2009c04n}) at carbonobject.inc:635
#33 RUN(0x2009c04) at application.inc:1407
#34 PASCALMAIN at TrainCommander.lpr:20
#35 SYSTEM_$$_FPC_SYSTEMMAIN$LONGINT$PPCHAR$PPCHAR at :0
#36 _start at :0
#37 start at :0
« Last Edit: July 02, 2020, 03:55:40 pm by JimKueneman »

jamie

  • Hero Member
  • *****
  • Posts: 6128
Re: Runtime(0) Error
« Reply #3 on: July 02, 2020, 04:05:15 pm »
An error like that is usually related to the STACK being unrolled early..

That can happen if you flood the local stack within a procedure and this is usually caused over memory overwrites.

 Also looking at your report here, it could also be you are processing some items during a Onxxxxxx event that could be getting triggered at the wrong time and there by disrupting your algorithm .

 I don't know your structure of your classes but if you are using property fields instead of directly assigning the fields, you could have a setter method doing something to early..

 Just a guess really.
The only true wisdom is knowing you know nothing

rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: Runtime(0) Error
« Reply #4 on: July 02, 2020, 04:10:21 pm »
You could put a breakpoint on that line (with F5), run it again (with debugging F9), and examine the variables when it breaks on that breakpoint. Including if TrainDatabase itself is still valid. But it indeed doesn't seem like a classical runtime error.

After examining you could try F7 (to step into the procedure).

JimKueneman

  • Full Member
  • ***
  • Posts: 220
Re: Runtime(0) Error
« Reply #5 on: July 02, 2020, 04:29:31 pm »
You could put a breakpoint on that line (with F5), run it again (with debugging F9), and examine the variables when it breaks on that breakpoint. Including if TrainDatabase itself is still valid. But it indeed doesn't seem like a classical runtime error.

After examining you could try F7 (to step into the procedure).

Thanks, I have done that numerous times and all the variables are exactly what I expect them to be and if I try ti single step into the procedure it just throws the error.

JimKueneman

  • Full Member
  • ***
  • Posts: 220
Re: Runtime(0) Error
« Reply #6 on: July 02, 2020, 04:32:49 pm »
An error like that is usually related to the STACK being unrolled early..

That can happen if you flood the local stack within a procedure and this is usually caused over memory overwrites.

 Also looking at your report here, it could also be you are processing some items during a Onxxxxxx event that could be getting triggered at the wrong time and there by disrupting your algorithm .

 I don't know your structure of your classes but if you are using property fields instead of directly assigning the fields, you could have a setter method doing something to early.. 

Line #8 appears to be where it moves from the context of the Ethernet thread to the main thread.

 Just a guess really.

So one thing to note here this could be significant is this is an app that implements an Ethernet messaging protocol.  So I have a Synapse running in a thread receiving messages.  This is called through a Synchronize call from within that thread processing the message that was received.
« Last Edit: July 02, 2020, 04:34:50 pm by JimKueneman »

rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: Runtime(0) Error
« Reply #7 on: July 02, 2020, 04:39:00 pm »
This is called through a Synchronize call from within that thread processing the message that was received.
If this is done correctly it shouldn't be a problem (but that's a big if) :)

JimKueneman

  • Full Member
  • ***
  • Posts: 220
Re: Runtime(0) Error
« Reply #8 on: July 02, 2020, 04:56:08 pm »
So on its journey it passes through this object that acts as the dispatcher of the messages...  this does not create a reference counted object correct?  I would need to decend from one of the TInterfacedxxxx objects for that to occur since I have not implemented IUnknown.   

Code: Pascal  [Select][+][-]
  1.   TLccNodeManager = class(TComponent, INodeManagerCallbacks)
  2.   private
  3.     FOnLccNodeAliasIDChanged: TOnLccNodeMessage;  

Aidex

  • Jr. Member
  • **
  • Posts: 82
Re: Runtime(0) Error
« Reply #9 on: July 02, 2020, 05:14:50 pm »
Just one more thing about the stack:
If it is a stack problem, you could try to define all parameters of the function as "const".
And what is the local ATrain variable for?

JimKueneman

  • Full Member
  • ***
  • Posts: 220
Re: Runtime(0) Error
« Reply #10 on: July 02, 2020, 05:56:13 pm »
So I moved the local variables out of the function into the global variable space and the same problem occurs...

I use it later in the method to send a reply through the ethernet link.

Code: Pascal  [Select][+][-]
  1.         if (Train <> nil) then
  2.           begin
  3.             AnEvent := LccMessage.ExtractDataBytesAsEventID(0);
  4.             if Train.LccNode is TLccCanNode then
  5.               WorkerMsg.LoadProducerIdentified(Train.LccNode.NodeID, (Train.LccNode as TLccCanNode).AliasID, AnEvent, evs_Valid )
  6.             else
  7.               WorkerMsg.LoadProducerIdentified(Train.LccNode.NodeID, 0, AnEvent, evs_Valid );
  8.  
  9.             NodeManager.SendMessage(WorkerMsg);              
  10.  

rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: Runtime(0) Error
« Reply #11 on: July 02, 2020, 06:09:05 pm »
What happens if you remove the Train := TrainDatabase.AddTrain() line and create a Train := TLccTrain.Create; yourself there.
If that works you know it's either the TrainDatabase instance which is corrupt or one of its variables or one of the passes parameters.


jamie

  • Hero Member
  • *****
  • Posts: 6128
Re: Runtime(0) Error
« Reply #12 on: July 02, 2020, 06:16:50 pm »
you said you send a reply when ever you receive a ethernet message?

Are you doing this while in the synchronized called ?

If so there could be some issue there.

can you cancel the reply send or use a cached delay method of doing it?
The only true wisdom is knowing you know nothing

JimKueneman

  • Full Member
  • ***
  • Posts: 220
Re: Runtime(0) Error
« Reply #13 on: July 02, 2020, 06:38:24 pm »
you said you send a reply when ever you receive a ethernet message?

Are you doing this while in the synchronized called ?

If so there could be some issue there.

can you cancel the reply send or use a cached delay method of doing it?

It never makes it to the code where I send the reply message.  Also the reply message does buffer the reply in a thread safe list and returns.  The thread picks up the messages from that list later.


jamie

  • Hero Member
  • *****
  • Posts: 6128
Re: Runtime(0) Error
« Reply #14 on: July 02, 2020, 06:46:57 pm »
ok, for testing purposes, kill the ethernet traffic and simulate a message to the same code in the same manner.. Use a Timer or something...
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018