Seite 3 von 4
Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 09.10.2015 13:51
von RSBasic
ts-soft hat geschrieben:NicTheQuick hat geschrieben:Ja, ein Try-Catch wäre Bombe. Ich glaube ganz früher zu PB V2.x Zeiten hatte Rings mal eine Try-Catch-Funktion implementiert. Oder war es Danilo? Ich weiß nicht mehr genau. Das hätte ich jedenfalls auch gerne wieder. Alternativ kann man hier nur noch mit OnError arbeiten.
Die Try-Catch Lib war von Remi Meyer, in ASM geschrieben und die funktionierte wirklich gut. Es gibt noch weitere Try-Catch Routinen im engl. Forum, aber ich denke die Version von Danilo ist noch am ausgereiftesten, funktioniert leider nicht immer:
http://www.purebasic.fr/english/viewtop ... 39#p380239
Interessant, danke für den Link.
Aber für Kiffi ist es leider nicht brauchbar, da er lieber keine APIs verwenden möchte.
Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 09.10.2015 14:53
von Sicro
NicTheQuick hat geschrieben:Wenn mir jetzt noch jemand beibringt, wie ich das mit anonymen Labels machen kann, [...]
Code: Alles auswählen
Macro Try
OnErrorGoto(?label#MacroExpandedCount)
If #True
EndMacro
Macro Catch
Else
label#MacroExpandedCount:
EndMacro
Macro EndTry
EndIf
OnErrorDefault()
EndMacro
Procedure a()
EndProcedure
Procedure b(a.i)
EndProcedure
Procedure c(a.i, b.s)
EndProcedure
q.q = 123457698123
Try
CallFunctionFast(@a())
Debug "a() hat funktioniert."
Catch
Debug "a(): " + ErrorMessage() + "(@" + Str(ErrorAddress()) + ")"
EndTry
Try
CallFunctionFast(@b(), 1)
Debug "b(1) hat funktioniert."
Catch
Debug "b(1): " + ErrorMessage() + "(@" + Str(ErrorAddress()) + ")"
EndTry
Try
CallFunctionFast(@c(), 1, 2)
Debug "c(1, 2) hat funktioniert."
Catch
Debug "c(1, 2): " + ErrorMessage() + "(@" + Str(ErrorAddress()) + ")"
EndTry
Try
CallFunctionFast(@q)
Debug "q hat funktioniert."
Catch
Debug "q: " + ErrorMessage() + "(@" + Str(ErrorAddress()) + ")"
EndTry
Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 09.10.2015 16:52
von GPI
RSBasic hat geschrieben:Jemand aus diesem Forum hat mal nach einer Try-Catch-Funktion gefragt. Soweit ich weiß gab es auch eine Lösung, die gepostet wurde.
Könnte man nicht einfach mit Hilfe der eigenen Try-Funktion überprüfen, ob auf eine ungültige Speicheradresse zugegriffen wird?
Wenn beim Aufruf von CallFunctionFast() ein IMA-Fehler auftritt, dann weiß man, dass die übergebene Speicheradresse entweder nicht vorhanden ist oder dass der Pointer nicht auf eine Prozedur zeigt.
Leider kann ich den Thread nicht mehr finden und kann deshalb den Code nicht testen und hier verlinken. Vielleicht findet ihr den Thread.
Das kann aber imo auch keine Lösung sein. Da ist es eigentlich schon zu spät, ein Fehler ist passiert, wenn try auslöst. Und wenn es blöd läuft springt man in einen Code, der noch ein bischen was sinnvolles macht und wirrste Fehler verursacht. Sich auf sowas zu verlassen, halte ich für sehr Problematisch.
Imo sollte man nach Möglichkeit immer ohne Try/Catch auskommen. In der Regel kann man ja abfragen, was man macht - bspw. ob durch Null geteilt wird.
Genauso denke ich, dass eine "isProcedure"-Funktion für PB nicht gerade einfach zu programmieren sein würde. Wie will man sowas testen? Was wären dann die folgen und auch wichtig: Rentiert sich überhaupt Aufwand?
NicTheQuick hat geschrieben:Man kann Try-Catch schon simulieren mit OnError():
Funktioniert hier nicht 3.51 - zumindest nicht mit debugger.
Bei mir steigt das Programm bei CallFunctionFast(@c(), 1, 2) aus.
MacoExpandendCount ist hier übrigens dein Freund:
Edit: zu langsam.
__________________________________________________
Quote-Tag repariert
09.10.2015
RSBasic
Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 09.10.2015 19:25
von Sicro
GPI hat geschrieben:Imo sollte man nach Möglichkeit immer ohne Try/Catch auskommen. In der Regel kann man ja abfragen, was man macht - bspw. ob durch Null geteilt wird.
Als Programmierer sollte man eigentlich alle möglichen Fehler voraussehen, ja, aber wie wir Menschen nun mal sind, vergessen wir manchmal eine Fehlerbehandlung oder bauen sie nicht ein, weil wir gar nicht wissen, dass so ein Fehler auftreten kann. Von daher sind Try-Catch-Blocks kein schlechter Programmierstil, weil sie in der Regel alle Fehler abdecken.
Da wir bei einer Procedure-Adresse nur auf "ungleich 0" und "gleich 0" prüfen können, ist Try-Catch hier aktuell die einzigste Lösung.
Ich würde aber so ein Aufwand nicht machen. Wenn der Fremd-Entwickler sich nicht an die Doku hält und einen Unsinn als Callback-Adresse angibt, knallt es halt.
Code: Alles auswählen
Macro Try
OnErrorGoto(?label#MacroExpandedCount)
If #True
EndMacro
Macro Catch
Else
label#MacroExpandedCount:
EndMacro
Macro EndTry
EndIf
OnErrorDefault()
EndMacro
Try
CallFunctionFast(50)
Catch
MessageRequester("Fehler", "Funktion kann nicht aufgerufen werden!")
EndTry
funktioniert bei mir auch nicht. Ohne Debugger passiert nichts und mit Debugger meldet dieser, dass sich das Executable unerwartet beendete.
Setze ich anstatt des MessageRequesters wieder ein Debug ein, funktioniert es.
Also, sauber funktioniert die Sache noch nicht.
Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 09.10.2015 20:36
von GPI
Sicro hat geschrieben:GPI hat geschrieben:Imo sollte man nach Möglichkeit immer ohne Try/Catch auskommen. In der Regel kann man ja abfragen, was man macht - bspw. ob durch Null geteilt wird.
Als Programmierer sollte man eigentlich alle möglichen Fehler voraussehen, ja, aber wie wir Menschen nun mal sind, vergessen wir manchmal eine Fehlerbehandlung oder bauen sie nicht ein, weil wir gar nicht wissen, dass so ein Fehler auftreten kann. Von daher sind Try-Catch-Blocks kein schlechter Programmierstil, weil sie in der Regel alle Fehler abdecken.
Die große Gefahr ist halt, das man sich zu sehr auf Try-Catch verlässt und gar nicht mehr die Werte überprüft etc. Imo sollte man Minimum in der Log-Datei vermerken, das man hier was gründlich schief gelaufen ist.
Da wir bei einer Procedure-Adresse nur auf "ungleich 0" und "gleich 0" prüfen können, ist Try-Catch hier aktuell die einzigste Lösung.
Ich würde aber so ein Aufwand nicht machen. Wenn der Fremd-Entwickler sich nicht an die Doku hält und einen Unsinn als Callback-Adresse angibt, knallt es halt.
Zumal man eh davon ausgehen kann, wenn man was falsches übergibt, dass das definitiv nicht gewollt ist und man das Programm so oder so beenden sollte. Von daher kann man es ruhig krachen lassen

Außerdem ergibt sich das Problem, das OnError nicht mehr funktioniert. Dieser kann bspw. schon irgendwohin verbogen sein, bspw. damit in einen Texteditor noch versucht wird, ungesicherte Sachen temporär zu speichern. Mit Try-Catch würde man es aushebeln bzw. bei den Beispiel halt eiskalt ausschalten. Und dann geht die Fehlersuche los, warum das Ding abstürzt *UND* die OnError-Funktion nicht klappt.
Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 09.10.2015 20:51
von ts-soft
Es gibt schon sinnvolle Anwendungen für Try/Catch, z.B. eine unbekannte Datei, die man parst und die auf einmal unvorhersehbare Ergebnisse liefert, die zu einem IMA führen würden. Da wäre ein Try/Catch ganz praktisch, weil man kann die Datei nach dem unvorhersebaren Ergebnis, zu ende Parsen. Z.B. Object-/Libdateien wären Kandidaten dafür.
Aber abfangbare Fehler, sollte man schon selber abfangen

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 09.10.2015 21:34
von Sicro
Hinweis: Der Program-Stack wird nicht angepasst, bevor zu dieser Sprungmarke gesprungen wird. Daher sollte auf lokale Variablen nicht zugegriffen werden, da sie möglicherweise nicht mehr erreichbar sind. Es ist auch nicht sicher, die normale Programmausführung nach einem Fehler fortzusetzen, da Dinge wie die Return-Adresse einer Prozedur falsch sein können, wenn der Stack nicht länger korrekt ist. Die beste Vorgehensweise ist, einfach Informationen über den Fehler zu erfassen und anzuzeigen und dann das Programm zu beenden.
Quelle: PB-Hilfe => OnErrorGoto
Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 09.10.2015 23:18
von GPI
ts-soft hat geschrieben:Es gibt schon sinnvolle Anwendungen für Try/Catch, z.B. eine unbekannte Datei, die man parst und die auf einmal unvorhersehbare Ergebnisse liefert, die zu einem IMA führen würden. Da wäre ein Try/Catch ganz praktisch, weil man kann die Datei nach dem unvorhersebaren Ergebnis, zu ende Parsen. Z.B. Object-/Libdateien wären Kandidaten dafür.
Äh, wenn dein Parser so anpassen, das er auf Plausibilität überprüft? Er muss ja nicht gleich abstürzen, wenn er was entgegennimmt, was er nicht kennt. Unbekannte Lib-Dateien, die einfach mal so abstürzen würde ich eh nicht verwenden
Generell sollte man eigentlich bei allen Sachen, besonders wenn es ein Benutzer eingibt, überprüfen. Sehr viele Hacks beruhen auf sowas. Besonders wenn man Richtung Webserver(CGI) geht, sollte man lieber einmal zu viel überprüfen als zu wenig.
Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 10.10.2015 01:40
von NicTheQuick
Es gibt genug sinnvolle Anwendungen dafür. Abreißende IO-Streams, plötzlich ausgesteckte USB-Geräte. Eben alles, was in einer Multitasking-Umgebung so schief gehen kann.
An der Uni haben wir gelernt nur so mit Exceptions um uns zu schmeißen. Aber das war in Java und C++, also OOP. Und da macht es auch jede Menge Sinn, weil z. B. Konstruktoren keinen Rückgabewert besitzen. Exceptions kann man aber trotzdem immer werfen. In Python wird es auch gerne benutzt. Will man einen String in einen Integer casten und das geht schief, kriegt man eine Exception, die man mit excepts (catch) anfängt. Das ist einfacher als zwei Rückgabewerte auszuwerten. Einer, der das Ergebnis zurückgibt und einer, der einen Fehlercode darstellt.
Re: Prüfen, ob eine Adresse auf eine Procedure zeigt
Verfasst: 10.10.2015 16:11
von GPI
Blöde Frage, aber Exceptions sind nicht zwingen Try & Catch, oder? Also zumindest nicht so wie in den Beispiel bisher hier.