Prüfen, ob eine Adresse auf eine Procedure zeigt

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag 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. :allright:
Aber für Kiffi ist es leider nicht brauchbar, da er lieber keine APIs verwenden möchte.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Sicro
Beiträge: 963
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag 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
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag 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
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
Sicro
Beiträge: 963
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag 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.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag 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.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag 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 :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Sicro
Beiträge: 963
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag 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
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag 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.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag 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.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Beitrag von GPI »

Blöde Frage, aber Exceptions sind nicht zwingen Try & Catch, oder? Also zumindest nicht so wie in den Beispiel bisher hier.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Antworten