Integrierter und Stand-alone Debugger (console noch nicht getestet)
zwischen 10.000 - 20.000 Zeilen Code
Eine Prozedur wird endlos aufgerufen nachdem sie sich eigentlich mit ProcedureReturn verabschiedet. Ohne Debugger gibt es keine Endlosschleife.
Der Fehler ist möglicherweise schwer zu reproduzieren, und weil ich mit Fullscreen arbeite komme ich meistens nicht mehr wieder in die IDE/Debugger/Taskmanager um zu unterbrechen (dafür wäre wohl ein unerreichbarer flipbuffers() nötig). Ich habe die letzten Stunden "des Öfteren" den Reset Knopf betätigen müssen. Ich denke der Fehler sollte aber auch ohne Fullscreen reproduzierbar sein (das werde ich später testen).
Der Fehler tritt erst auf, nachdem ich eine Modifikation an einer Structure vorgenommen habe.
So funktioniert (grob) der Aufruf, über eine Lua 5.4 dll
Code: Alles auswählen
UseModule Lua
main()
=> lua_dofile() ; Lua::lua_dofile() is in Purebasic gewrapt und nicht aus der DLL, benutzt aber die lua_ Befehle aus der DLL
=> (lua script) shape:contains_point()
=> (PureBasic ProcedureC) tolua_contains_point(*L)
=> (PureBasic Procedure) point_in_poly(*P.Point2D,*segments.Segment2D,segment_count)
Die Aufrufende ProcedureC tolua_contains_point() (kaum bis gar nicht verändert) macht ihren Aufruf wie folgt:
Code: Alles auswählen
DeclareModule Lua
(...)
PrototypeC _lua_pushboolean(*L, value)
Global lua_pushboolean._lua_pushboolean ; <- wird bei init_lua_dll() gesetzt
(...)
EndDeclareModule
ProcedureC tolua_contains_point(*L)
;
Debug "tolua_contains_point" ; <-- wird nur 1x ausgegeben
(...)
*Segments=*poly\seg
count=*poly\s_count
result = point_in_poly(*P,*Segments,count) ; <------ Endlosschleife started wohl hier, wird ständig aufgerufen
;Debug "result: "+result ;
lua_pushboolean(*L, result) ;
ProcedureReturn 1 ;
(...)
EndProcedure
Erst seitdem ich folgende Veränderung vorgenommen habe, und die Proceduren angepasst habe tritt der Fehler auf:
Code: Alles auswählen
Structure Point2D ; <- unverändert
x.d
y.d
EndStructure
Structure Segment2D ; <- alt
x1.d
y1.d
x2.d
y2.d
EndStructure
Structure Segment2D ; neu
*A.Point2D
*B.Point2D
EndStructure
Beispiel
Code: Alles auswählen
Protected *SA.Segment2D , *SB.Segment2D
; alter segment vs segment test
segment_intersect_segment(*SA\x1,*SA\y1,*SA\x2,*SA\y2,*SA\x1,*SA\y1,*SA\x2,*SA\y2,*result.point2d)
; neu
segment_intersect_segment(*SA\A\x,*SA\A\y,*SA\b\x,*SA\b\y,*SB\A\x,*SB\A\y,*SB\b\x,*SB\B\y,*result.point2d)
Ich bedauere zutiefst daß aber genau in dieser point_in_poly Procedure diese Aufrufe eben nicht stattfinden, sondern erst nicht weit in einer benachbarten Procedure. Irgendwie kann es aber mit nichts Anderem als diese Verkomplizierung liegen, mit den Pointern. Es wird auch anscheinend nichts falsch verarbeitet.Außerdem benutze ich diese unfertige Procedure im test script ja nicht wenn der Fehler Auftritt, auch nicht an anderer stelle (liegt derzeit nur ungennutzt bei).
So hat sich die point_in_poly (auszugsweise)verändert:
Code: Alles auswählen
(...)
; alt:
If *S\x1>*S\x2
xmax=*S\x1
xmin=*S\x2
Else
xmax=*S\x2
xmin=*S\x1
EndIf
If *S\a\y1>*S\y2
ymax=*S\y1
ymin=*S\y2
Else
ymax=*S\y2
ymin=*S\y1
EndIf
(...)
xdiff = *S\x2-*S\x1
ydiff = *S\y2-*S\y1
(...)
; neu
If *S\a\x>*S\b\x
xmax=*S\a\x
xmin=*S\b\x
Else
xmax=*S\b\x
xmin=*S\a\x
EndIf
If *S\a\y>*S\b\y
ymax=*S\a\y
ymin=*S\b\y
Else
ymax=*S\b\y
ymin=*S\a\y
EndIf
(...)
xdiff = *S\b\x-*S\a\x
ydiff = *S\b\y-*S\a\y
(...)
Ich habe des Weiteren alle Proceduren nach folgenden Problemquellen durchforstet und umgeändert, weil sich mit sowas ebenso ähnliche "Heisenbugs" bemerkbar machen
Code: Alles auswählen
; alt
i+1
*P+SizeOf(Point2D)
*Structure\counter + 1 ; <- solche Sachen vermeide ich schon etwas Länger
; neu
i=i+1
*P=*P+SizeOf(Point2D)
*Structre\counter = *Structure\counter +1