Anti-Jammer-Thread

Hier kann über allgemeine Themen diskutiert werden, die sonst in kein Forum passen.
Insbesondere über Szene, Games, Kultur, Weltgeschehen, Persönliches, Recht, Hard- und Software.
Alexander Kornrumpf
Moderator
Beiträge: 2112
Registriert: 25.02.2009, 13:37

Re: Anti-Jammer-Thread

Beitrag von Alexander Kornrumpf »

MasterQ32 hat geschrieben: Das ist so nicht ganz richtig. Bison/Yacc sind beides Tools, welche selbst nur eine Bison-Grammatik verstehen. Diese lesen sie ein, wandeln sie in einen Automaten um und erzeugen für diesen Automaten C-Code, welcher die vom Automaten erkannte Grammatik erkennt. Von dem Code, der in Bison werkelt ist nacher keine einzige Zeile mehr vorhanden.
Das ist mir bekannt. Und ungefähr so "sollte" das hier diskutierte Tool meiner Meinung nach auch funktionieren. Was ich geschildert habe ist ein fiktives bison/yacc, das so funktioniert, wie ich glaube dass DerAlbi will das sein Tool funktioniert, mit dem Ziel per Analogie aufzuzeigen, dass das vielleicht nicht ideal ist.

Habe es per EDIT eindeutiger gemacht.
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

Ich habe meine komplette Fehlerbehandlung auf was eigenes Callback-basiertes umgestellt, und es war wohl die beste Entscheidung meiner Programmierlaufbahn.

Im Grund nimmt jetzt jede Funktion dieses struct entgegen:

  struct Supervisor {
    void * context;
    intptr_t (__stdcall * onEvent)(void * context, int event, void const * more, char * callStack);
  };


Passiert irgendwas, das nicht lokal behandelt werden kann, wird das onEvent-Callback aufgerufen. Erfordert das irgendeine Entscheidung des Users, wird der Rückgabewert ausgewertet. Braucht man zusätzliche Details (bei nicht vorhandener Datei z.B. den Pfad), wird das in dem Zusatzzeiger übergeben. Und alle Funktionen geben nun nur noch ein bool zurück, ob ein kritischer Abbruch vorliegt (Grund egal, wurde ja vorher an Ort und Stelle ausdiskutiert).

Die Event-Codes dürfen nicht doppelt vorkommen. Das ist eine globale Liste, die man warten muss, und davor hat es mir immer gegraust. Aber nach einem Jahr kann ich sagen: Sie ist es total wert, und 2³² Werte sind VIEL Platz.

Fortschrittsbalken mit Abbruchfunktion? Der Algorithmus muss einfach regelmäßig

  if(0 == report(supervisor, current_percentage, 0, 0)) {
    break;
  }


aufrufen. Und BUMM, sind alle UI-Probleme, die ich je hatte, gelöst:
  • Lokalisierung? Lächerlich einfach. In der Logik kommen nur noch Codes vor, die irgendwo im Callback zu Text umgewandelt werden. Von minimal-C-Konsolenanwendungen über „ich schreib alles in log.txt und lass es dann crashen“ bis zu High-End-C#-Programmen mit lokalisierter Grafik-UI, kein Problem mehr. Wenn ich meine Logik in einer Shell Extension verwenden will, darf sie nur noch den ersten Fehler als 4-B-COM-HRESULT zurückgeben? Ist in 30 Sekunden erledigt – ohne Logikänderungen.
  • Sprachbarrieren? struct + Callback kann jede Sprache. In 20 Zeilen hat man einen C#-Wrapper mit hübschen onError(), onResume, onD3D11Error(HResult)-Methoden.
  • Fortschrittsbalken & Abbruchfunktion hatten wir ja gerade. Und das optional beim Einbinden der Logik. Jeder Logik, sogar verschachtelt (Callbacks verketten).
  • Bei Fehlern erneut versuchen (Login abgelaufen, erneut einloggen! WLAN abgerissen; wiederholen, sobald die Verbindung wieder steht! Datenträger X einlegen!)? Geradezu lächerlich einfach, weil die UI einfach 1 oder 0 zurückgeben muss. Versucht das mal mit Codebases, die auf Exceptions aufbauen – wegschmeißen, neu machen; wegschmeißen, …
  • Welche Fehler kritisch sind, bestimmt jetzt die UI. Microsoft musste für IntelliSense einen neuen Compiler bauen, weil der Alte dafür entworfen war, jeden Fehler als kritisch zu behandeln? lol, Amateure! Wenn jetzt ein INI_PARSE_ERROR_EXPECTED_NEWLINE ankommt, kann ich mir aussuchen, ob ich den Text im Editor rot unterkringle oder das direkt das ganze System crashe!
  • Meine Fresse, erzeugt das geilen Code. Ein einfaches if(nullptr in die Logik, und der Compiler schmeißt jeden Code, der entfernt mit Fehlerbehandlung/Fortschrittsbehandlung/Userfragen zu tun hat aus der EXE raus, bis aufs letzte Byte.
Bleibt noch der callStack-Parameter:
  • Leute schreiben gern __FILE__, __LINE__, __FUNCTION__ in ihre Return Values/Exceptions/andere primitive Fehlerreflexe
  • das System freut sich über die Unmenge Strings
  • Angreifer freuen sich über die Funktionsnamen, den sie im Code wiederfinden
  • Programmierer freuen sich über die Erkenntnis, dass custom_memcpy() einen Nullzeiger hat, sind aber total ratlos, was denn kopiert werden sollte und was das Programm gerade macht
  • Call Stacks sind 1337 – kompakter und aussagekräftiger
  • dummerweise funktionieren die nicht über Sprachgrenzen hinweg – wenn sich die C#-UI oder die Python-Testfälle im der C#-/Python-Callback befinden, haben sie keinen Zugriff auf den Call Stack, der den Fehler eskaliert hat
  • also Call Stack einfach als ASCII-Text mitliefern
  • natürlich nicht bei trivialen Dingen wie Fortschrittsinformationen
Nächster Schritt? Die ganze Umgebung durch Callbacks virtualisieren.
  • Dateisystem, damit meine ganze Dateiverarbeitung sowohl mit der Platte als auch in Netzwerkstreams als auch in den PAK-Archiven von Spielen funzt (klingt wie Standard-C-Streams – nur, dass ich mit denen über Persönliches zerstritten bin)
  • Threads & Locks, damit ich meine geometrischen Algorithmen mit einer Zeile zwischen seriell/Thread Pool’d/Threaded portieren kann (OHNE TEMPLATES, weil bei mir noch immer alles in unter einer Sekunde kompiliert)
  • Speicheranforderungen, damit ich Systeme über verschiedene Anforderungen hinweg portieren kann (bei Servern immer ordentlich aufräumen vs. bei kleinen Apps einfach den Speicher zukleistern und alle Jubeljahre die Pools löschen, war bei Assimp ein Hauptproblem)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4256
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Anti-Jammer-Thread

Beitrag von Chromanoid »

Klingt ziemlich cool. Außer die Event-IDs... Das läuft aus meiner Sicht schnell auf unangenehme Connascence of meaning hinaus. Kannst Du nicht statt einer Event-ID ein eigenes Objekt übergeben, dass typisiert wie ein eigener Exception-Typ/Event-Typ alle wichtigen Daten enthält? Der Lebenszyklus des Events könnte doch auf den Aufruf des Callbacks begrenzt sein. Im Grunde willst Du mit den Event-Codes doch eine Art Reflection machen, würde da nicht dieser typeid-Operator passen? Vielleicht könnte man außerdem noch ein Cause-Event hinzufügen, damit Du Events schachteln kannst, sonst hast Du entweder leaky Abstractions oder man kann die Fehler nur schlecht analysieren.

Mich würde noch interessieren, wie Du mit Prozessen umgehst, die nicht "graceful" weiterbearbeitet werden können, egal was der User sagt. Also ein Fall wo man normalerweise eine Exception bis zum User durchreicht. So wie ich Deine Ausführungen verstehe, würdest Du anhand der Event-ID interpretieren, dass der Prozess sowieso nicht weitergeht und dann nur eine Fehlermeldung anzeigen? Da fände ich dann wirklich ein Objekt schöner das über die Hierarchie oder so abbildet, ob es sich um was kritisches handelt. Wie würdest Du mit Fällen umgehen, in denen man als Aufrufer gerne weitere Fehlerbehandlung durchführen möchte, einen Supervisor davor schalten, der nur bestimmte Events weiter propagiert? Bei der generischen Fehlerbehandlung vermisst man Reflection mal tatsächlich oder?
Alexander Kornrumpf
Moderator
Beiträge: 2112
Registriert: 25.02.2009, 13:37

Re: Anti-Jammer-Thread

Beitrag von Alexander Kornrumpf »

Krishty hat geschrieben:Ich habe meine komplette Fehlerbehandlung auf was eigenes Callback-basiertes umgestellt, und es war wohl die beste Entscheidung meiner Programmierlaufbahn.

Im Grund nimmt jetzt jede Funktion dieses struct entgegen:

  struct Supervisor {
    void * context;
    intptr_t (__stdcall * onEvent)(void * context, int event, void const * more, char * callStack);
  };
Ist geil oder? Moderne Programmiersprachen und ihre Idiome sind das Ergebnis von ich weiß nicht wievielen Mannstunden klunger Menschen, aber was man eigentlich will ist ein simples Paar aus Daten und tuWasMitDenDaten.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von dot »

Krishty hat geschrieben:Passiert irgendwas, das nicht lokal behandelt werden kann, [...]
Gibt's dafür nicht Exceptions? :P
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

Chromanoid hat geschrieben:Außer die Event-IDs... Das läuft aus meiner Sicht schnell auf unangenehme Connascence of meaning hinaus. Kannst Du nicht statt einer Event-ID ein eigenes Objekt übergeben, dass typisiert wie ein eigener Exception-Typ/Event-Typ alle wichtigen Daten enthält? Der Lebenszyklus des Events könnte doch auf den Aufruf des Callbacks begrenzt sein. Im Grunde willst Du mit den Event-Codes doch eine Art Reflection machen, würde da nicht dieser typeid-Operator passen?
Ich übergebe für Events, bei denen eine Event-ID nicht ausreicht, durchaus den Rest über den Zeiger in more! Aktuell z.B. bei Zugriffsfehlern auf Registry-Schlüssel den Hive, Pfad, und Win32-Fehlercode. Da müssen sich natürlich wieder beide Programmteile einigen, aber sowas ändert sich nicht gerade häufig.
Mich würde noch interessieren, wie Du mit Prozessen umgehst, die nicht "graceful" weiterbearbeitet werden können, egal was der User sagt. Also ein Fall wo man normalerweise eine Exception bis zum User durchreicht. So wie ich Deine Ausführungen verstehe, würdest Du anhand der Event-ID interpretieren, dass der Prozess sowieso nicht weitergeht und dann nur eine Fehlermeldung anzeigen? Da fände ich dann wirklich ein Objekt schöner das über die Hierarchie oder so abbildet, ob es sich um was kritisches handelt. Wie würdest Du mit Fällen umgehen, in denen man als Aufrufer gerne weitere Fehlerbehandlung durchführen möchte, einen Supervisor davor schalten, der nur bestimmte Events weiter propagiert? Bei der generischen Fehlerbehandlung vermisst man Reflection mal tatsächlich oder?
Habe ich das mti der vorherigen Antwort abgehakt? Also bei Dateizugriffsfehler z.B. kann sich die UI dann aussuchen, ob sie einfach via int 3 in den Debugger crasht oder mit den Win32-Error-Codes und dem Pfad Pathologie betreibt und ein hübsches „die Datei ist noch in Bearbeitung durch XYZ“ anzeigt.
dot hat geschrieben:Gibt's dafür nicht Exceptions? :P
Wenn mein Datei-Parser normalerweise bei kaputten Thumbnails abbricht, ich aber für die Forensik einen kompatiblen Modus brauche, der so viele Daten wie möglich weiter birgt – dann schreibe ich

  catch(BrokenThumbnailException const & e) {
    log("broken Thumbnail @%p", e.offsetInFile);
    resume;
  }


? Wenn ich das könnte, würde ich mir tatsächlich Arbeit sparen. Geht aber leider nur mit SEH, und darauf will ich nicht aufbauen müssen …
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: Anti-Jammer-Thread

Beitrag von Spiele Programmierer »

Ich bin ehrlich gesagt etwas skeptisch. Wie zum Beispiel allokierst du Speicher so dass beim Fehlschlagen so ein Callback aufgerufen wird? Brauchen dann nicht unglaublich viele Funktionen so ein Callback? String-Funktionen stelle ich mir extrem anstrengend zu verwenden vor.

Die Error-IDs sind für meinen Geschmack auch zu zentralistisch verwaltet. Warum übergibst du nicht zB. einen Pointer zu einer kleinen statischen konstanten Struktur die dann am besten auch gleich einen String mit der Fehlerbeschreibung enthält (+ ggf. weitere Informationen). Das hätte in meinen Augen viele Vorteile: Es ist Typsicher, es kann beliebig erweitert werden, man muss keine IDs mehr zuweiten, alle weiteren Informationen sind dann ganz lokal bei der Fehlerdefinition.

Meine Erfahrung in C++ ohne Exceptions sind sehr negativ. Und das, obwohl ich eigentlich alles andere als ein Freund der Exceptions bin, aber in C++ fehlen einach alternative Sprachmittel. Das geht damit schon los, dass RAII praktisch unbrauchbar wird, weil man im Konstruktor keine Fehlercodes zurückgeben kann. Falls im Konstruktor mehrere Objekte konstruiert werden die jeweils Fehler auslösen können, wird das Konzept der Initialisierungsliste zum Problem.
Überhaupt ist es ausgesprochen mühselig, auf alle Rückgabewerte zu reagieren:

Code: Alles auswählen

std::unique_ptr<GameObj> GameObj(a, b, c, d, e);

//Stattdessen....

std::unique_ptr<GameObj> GameObj;
{
    ErrorCodeT ErrorCode;
    if (!(GameObj = std::make_unique<GameObj>(a, b, c, d, e, ErrorCode)))
         return ErrorCodeT::OutOfMemory;
    if (ErrorCode != ErrorCodeT::Success)
         return ErrorCode;
}
Aber das Schlimmste ist, dass man das nichtmal in ein Makro packen kann, weil die notwendigen "returns" keine Expressions sind!
Ich habe begonnen, mich wirklich nach GCCs Expression Statements oder insgesamt Rusts System zur Fehlerrückgabe zu sehnen.

EDIT:
Wenn mein Datei-Parser normalerweise bei kaputten Thumbnails abbricht, ich aber für die Forensik einen kompatiblen Modus brauche, der so viele Daten wie möglich weiter birgt – dann schreibe ich ...
Nun, dafür müsstest du die Methode in mehrere Schritte unterteilen und dann im User Code über alle Thumbnails iterieren, so dass du jeden einzelnen Aufruf abfangen kannst und mit dem nächsten Thumbnail fortfahren.
Evt. könnten dabei Coroutines in C++17 weiterhelfen, allerdings weiß ich darüber zu wenig.

Ansonsten spricht in dem Fall nichts gegen ein ganz lokales Callbacksystem ohne globale IDs etc.?
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

Spiele Programmierer hat geschrieben:Ich bin ehrlich gesagt etwas skeptisch. Wie zum Beispiel allokierst du Speicher so dass beim Fehlschlagen so ein Callback aufgerufen wird?
Ich verstehe gerade nicht ganz – wofür Speicher? Um Stack Overflows zu vermeiden?
Spiele Programmierer hat geschrieben:Warum übergibst du nicht zB. einen Pointer zu einer kleinen statischen konstanten Struktur die dann am besten auch gleich einen String mit der Fehlerbeschreibung enthält (+ ggf. weitere Informationen). Das hätte in meinen Augen viele Vorteile: Es ist Typsicher, es kann beliebig erweitert werden, man muss keine IDs mehr zuweiten, alle weiteren Informationen sind dann ganz lokal bei der Fehlerdefinition.
Wie identifiziere ich denn von Python aus, dass es sich bei diesem Zeiger um eine FileAccessException handelt? Durch den String, der da drin ist? Dann habe ich statt int-IDs nun char *-IDs, das ist keine Verbesserung sondern nur viel Bloat. Oder ist der String nur zur Convenience da, wie std::exception::what()? In dem Fall ist er nutzlos weil die UI ihn erst ins Chinesische übersetzen muss um ihn anzuzeigen, und darum alle Strings im Voraus bekannt sein müssen.
Meine Erfahrung in C++ ohne Exceptions sind sehr negativ. Und das, obwohl ich eigentlich alles andere als ein Freund der Exceptions bin, aber in C++ fehlen einach alternative Sprachmittel. Das geht damit schon los, dass RAII praktisch unbrauchbar wird, weil man im Konstruktor keine Fehlercodes zurückgeben kann. Falls im Konstruktor mehrere Objekte konstruiert werden die jeweils Fehler auslösen können, wird das Konzept der Initialisierungsliste zum Problem.
Überhaupt ist es ausgesprochen mühselig, auf alle Rückgabewerte zu reagieren:
Weißt du, was das Schöne am zweiten Quelltext ist? Dass ihn jeder sofort versteht. Ich kann den Praktikanten mit C#-Erfahrung draufgucken lassen und der weiß sofort, ob Fehler behandelt werden oder nicht. Im ersten Beispiel muss ich ihn erstmal eine Woche in C++-Idiome einarbeiten, dann die Eigenheiten der verschiedenen Smart Pointers erklären, und dann C++-Wrapper für zwei C-Fremdbibliotheken schreiben, weil sie Parameter für a und b sind.
Ich habe begonnen, mich wirklich nach GCCs Expression Statements oder insgesamt Rusts System zur Fehlerrückgabe zu sehnen.
Danke für den Link! Wäre Rust ein, zwei Jahre früher gekommen … ach wer weiß :(
Nun, dafür müsstest du die Methode in mehrere Schritte unterteilen und dann im User Code über alle Thumbnails iterieren, so dass du jeden einzelnen Aufruf abfangen kannst und mit dem nächsten Thumbnail fortfahren.
Evt. könnten dabei Coroutines in C++17 weiterhelfen, allerdings weiß ich darüber zu wenig.
Jetzt hat mein C++-zu-C#-Interface statt einer Funktion und einem Callback
  • 30 verstreute Funktionen
  • eine Iteratorklasse
  • einen Wrapper auf C++-Seite, der alle C++-Exceptions fängt und in was .NET-kompatibles übersetzt, weil man Exceptions nicht in andere Sprachen schmeißen darf und wenn doch, dann schlecht auswerten kann
  • die Coroutines crashen erstmal die Common Language Runtime weil da irgendwas nicht Fiber-Safe war
Und jeder, der da jemals einen Bug beheben soll, muss sich erstmal in alles einarbeiten. Nein. Einfach nein.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von dot »

Sehr guter Talk zum Thema:

[youtube]fOV7I-nmVXw[/youtube]

;)
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

Hmm … ist doch C++-spezifisch, oder? Wie lösen dispatcher() und transmogrify() das Problem einer globalen Fehlerliste, wenn eine andere Sprache Fehler behandeln soll?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: Anti-Jammer-Thread

Beitrag von Spiele Programmierer »

Ich verstehe gerade nicht ganz – wofür Speicher? Um Stack Overflows zu vermeiden?
:?: Naja, wenn man zum Beispiel ein paar Strings beliebiger Länge in einer Datenstruktur braucht.
Die Allokation kann schließlich jederzeit fehlschlagen. (malloc gibt 0 zurück, std::bad_alloc fliegt)
Meine Erfahrung ist, dass es sehr kompliziert ist, derartige Fehler ohne Exceptions richtig abzufangen.
Wie identifiziere ich denn von Python aus, dass es sich bei diesem Zeiger um eine FileAccessException handelt?
Ich habe keine Erfahrung mit Python. In C# ist das auf jeden Fall kein Problem. Du vergleichst einfach ob der IntPtr gleich dem IntPtr zu dem "FileAccessException" Speicherblock ist.
In dem Fall ist er nutzlos weil die UI ihn erst ins Chinesische übersetzen muss um ihn anzuzeigen, und darum alle Strings im Voraus bekannt sein müssen.
Sehe ich anders. Ein solcher Fehler sollte ja auch idR. nicht direkt im Benutzerinterface erscheinen. Es ist eine Information für die Techniker.

Was ich noch viel schrecklicher finde: Lokalisierte Fehlermeldungen! Die einzige Person die viele Fehler beheben könnte, versteht ihn dann nicht mehr und "der gebildete Nutzer" ist nicht mehr in der Lage im Internet nach der Fehlermeldung zu suchen.
Weißt du, was das Schöne am zweiten Quelltext ist? Dass ihn jeder sofort versteht. Ich kann den Praktikanten mit C#-Erfahrung draufgucken lassen und der weiß sofort, ob Fehler behandelt werden oder nicht.
Ich glaube, da stimme ich nicht ganz zu. Wenn der Praktikant nur die Funktionsweise des Codes verstehen will, ist die erste Variante ganz offensichtlich prägnanter bezüglich der High Level Funktionsweise. Wenn der Praktikant den Code schreibt und mit der ersten Variante verwirrt ist, dann würde er bestimmt nicht alle Fehler in der zweiten Variante richtig behandeln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

Spiele Programmierer hat geschrieben:
Ich verstehe gerade nicht ganz – wofür Speicher? Um Stack Overflows zu vermeiden?
:?: Naja, wenn man zum Beispiel ein paar Strings beliebiger Länge in einer Datenstruktur braucht.
Die Allokation kann schließlich jederzeit fehlschlagen. (malloc gibt 0 zurück, std::bad_alloc fliegt)
Meine Erfahrung ist, dass es sehr kompliziert ist, derartige Fehler ohne Exceptions richtig abzufangen.
Achso – bisher hatte ich noch nichts mit dynamischer Länge. Dateinamen etc. liegen ja an dem Punkt, an dem man sie braucht, sowieso schon fertig vor.
Spiele Programmierer hat geschrieben:
Wie identifiziere ich denn von Python aus, dass es sich bei diesem Zeiger um eine FileAccessException handelt?
Ich habe keine Erfahrung mit Python. In C# ist das auf jeden Fall kein Problem. Du vergleichst einfach ob der IntPtr gleich dem IntPtr zu dem "FileAccessException" Speicherblock ist.
Und wo kriege ich den her? #include FileAccessException.hpp wird ja schlecht gehen … alle möglichen Probleme als DLL-Export definieren und die Definitionen nach C# übersetzen und synchron halten?
Spiele Programmierer hat geschrieben:
In dem Fall ist er nutzlos weil die UI ihn erst ins Chinesische übersetzen muss um ihn anzuzeigen, und darum alle Strings im Voraus bekannt sein müssen.
Sehe ich anders. Ein solcher Fehler sollte ja auch idR. nicht direkt im Benutzerinterface erscheinen. Es ist eine Information für die Techniker.

Was ich noch viel schrecklicher finde: Lokalisierte Fehlermeldungen! Die einzige Person die viele Fehler beheben könnte, versteht ihn dann nicht mehr und "der gebildete Nutzer" ist nicht mehr in der Lage im Internet nach der Fehlermeldung zu suchen.
Bis zu welchem Grad die Fehlermeldungen angezeigt und lokalisiert werden sollen, da scheiden sich die Geister und die Anwendungsfälle sowieso (eine Management-Konsole auf einem Server hat andere Anforderungen als eine internationalisierte App), aber wenn diese Datenstrukturen erst garnicht den Benutzer erreichen sollen, kann man sich den String-Bloat auch sparen und einfach eine ID reinschreiben. Damit wären wir … wieder bei dem, was ich mache.
Spiele Programmierer hat geschrieben:
Weißt du, was das Schöne am zweiten Quelltext ist? Dass ihn jeder sofort versteht. Ich kann den Praktikanten mit C#-Erfahrung draufgucken lassen und der weiß sofort, ob Fehler behandelt werden oder nicht.
Ich glaube, da stimme ich nicht ganz zu. Wenn der Praktikant nur die Funktionsweise des Codes verstehen will, ist die erste Variante ganz offensichtlich prägnanter bezüglich der High Level Funktionsweise.
Auch das ist wohl Geschmackssache – ich jedenfalls bevorzuge viel dummen Code, an dem man sofort erkennen kann was das Programm macht, gegenüber wenig tiefgründigem Code, bei dem man erstmal zehn Klassen analysieren muss um zu verstehen, was er unter Speicherdruck macht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: Anti-Jammer-Thread

Beitrag von Spiele Programmierer »

aber wenn diese Datenstrukturen erst garnicht den Benutzer erreichen sollen, kann man sich den String-Bloat auch sparen und einfach eine ID reinschreiben.
Ich denke es gibt auch noch eine Zwischenstuffe. Als Entwickler hat man dann den Vorteil, dass man nicht immer die Fehler-IDs nachschlagen muss. Was ist wenn man mal eine ID ändert oder entfernt? Was ist wenn ein technisch versierter Nutzer das Problem verstehen will?

Die Windowsfehlercodes (Oder noch schlimmer: errno) sind diesbezüglich zum Beispiel ein Negativbeispiel. Man kriegt entweder eine kryptische ID von der man nichtmal entfernt das Problem ablesen kann oder mit ein paar komplizierten WinAPIs bekommt man eine lokalisierte Fehlermeldung ohne genauere Details.
Und wo kriege ich den her? #include FileAccessException.hpp wird ja schlecht gehen … alle möglichen Probleme als DLL-Export definieren und die Definitionen nach C# übersetzen und synchron halten?
Nun, du musst dann halt die IDs nach C# übersetzen. Scheint mir etwa auf das selbe rauszukommen.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4256
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Anti-Jammer-Thread

Beitrag von Chromanoid »

Könnte man nicht sonst pro Event-ID eine Methode anlegen, die auch per DLL exportiert wird? Die ID-Methoden würden eine Event-ID auf Basis der Basisadresse der DLL (oder sowas) und eines DLL-lokalen Zählers raus geben (oder vielleicht UUIDs?). Die IDs sind damit über Modulgrenzen hinweg eindeutig und die Entwickler würden mitbekommen, wenn ein Event entfernt wird, da die Methode in der DLL nicht mehr vorliegt. Man könnte dann noch mit ein bisschen Metaprogrammierung eine Auflösefunktion von IDs zu Methodenname in die Module/DLLs mit Supervisor-Funktion packen, so dass man einen technischen Kürzel aus der Event-ID erzeugen kann. Wenn man dann mal ein Event grundlegend überarbeitet, so dass die Verarbeitung bestehender Routinen kaputt geht, kann man das Event bzw. die Event-ID-Rückgabemethode einfach umbenennen und schon gibt's ordentliche Compile/Laufzeit-Fehler bei allen Beteiligten.
Zuletzt geändert von Chromanoid am 02.09.2016, 22:30, insgesamt 1-mal geändert.
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

Spiele Programmierer hat geschrieben:Nun, du musst dann halt die IDs nach C# übersetzen. Scheint mir etwa auf das selbe rauszukommen.
Naja … ein enum mit 200 Einträgen und ein Dutzend structs ist was anderes als 200 Klassen :)
Chromanoid hat geschrieben:Könnte man nicht sonst pro Event-ID eine Methode anlegen, die auch per DLL exportiert wird? Die ID-Methoden würden eine Event-ID auf Basis der Basisadresse der DLL (oder sowas) und eines DLL-lokalen Zählers raus geben (oder vielleicht UUIDs?). Die IDs sind damit über Modulgrenzen hinweg eindeutig und die Entwickler würden mitbekommen, wenn ein Event entfernt wird, da die Methode in der DLL nicht mehr vorliegt.
Alles, was mit DLL-Export zu tun hat, kann vom Compiler nicht mehr wegoptimiert werden, wenn es nicht benutzt wird. Da ist man dann wieder beim Bloat-Problem.

Das mit den UUIDs ist aber eine gute Idee. Ich hatte mir mal vorgenommen, die Error-IDs aus MAC und Datum/Uhrzeit zu hashen. Mit 32 Bits würde man schon auf kollisionsfreie IDs kommen, selbst wenn mehr als vier Leute mit meinem Kram arbeiten würden.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: Anti-Jammer-Thread

Beitrag von Spiele Programmierer »

Ich glaube du stellt dir da gerade etwas anderes vor?
Ich dachte an soetwas:

Code: Alles auswählen

struct ErrorType
{
    char const* Description; 
    //Weitere Fehlerinformationen falls sinnvoll.
    //Oder ein Callback für die Description anstatt die Description selbst. Dann kann man die Meldung an der Callsite dynamisch mit mehr Informationen versehen. (Dein "more")
};
extern const ErrorType ErrorOutOfMemory = { "The process is unable to allocate the required memory" }; 
extern const ErrorType ErrorOutOfBoundsAccess = { "An access occured outside the bounds of a datastructur" }; 
...
Ein großer Vorteil ist, dass der Linker den Fehlermeldungen "IDs" zuweist. (In Form der Adressen zu den Variablen)
Außerdem kann man weitere Informationen mitgeben.
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

Sorry – ich dachte an ein Klasse pro Fehler. (Aktuell haben 90 % der Fehler keinen Typ, und für den Rest eigene Strukturen.)

Ich bin immernoch strikt dagegen, irgendwelche Beschreibungen (oder Callbacks dafür) in der Logik zu parken. Die Logik sollte keine Ahnung von String-Repräsentation (nutzt die UI Unicode, ANSI, oder ASCII?) oder Lokalisierung (du willst alles auf Englisch, ich will halt auch Chinesisch) oder Informationsumfang (einfach nur Fehlermeldung ausgeben, oder dem User erklären, was passiert sein könnte?) haben. Da wir jetzt einen Funktionszeiger exportieren, landet die Formatierungsfunktion selbst dann im Logikmodul, wenn der Client keine Fehler ausgibt und sofort abbricht, meine Shell Extensions sind nun also alle viermal so groß (zusätzlich dazu, dass wir Lokalisierung und Kontrolle über Character Sets verloren haben).

Machen wir weiter und nehmen an, dass die IDs nun immer synchron sind. Wie genau fange ich nun im C#-Code eine FileAccessDenied-Exception und sage (nach Aufforderung an den User, die Datei zu schließen), dass der Client es erneut versuchen soll?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4854
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Schrompf »

Ziemlich gemischte Gefühle, aber doch mehr zu freuen als zu jammern: Meine Tochter, Lilja Ziegenhagen, geboren am 4.9.2016. Es gab einige hässliche Komplikationen, aber wir sind alle noch am Leben. Und das war scheiße knapp.

Wird noch ne Weile dauern, ehe ich wieder an den heimischen Rechner oder gar zu was Produktivem kommen werde, aber egal: wir sind alle noch am Leben.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

Schwierig, darauf zu antworten, aber die Freude überwiegt ja, also … Beste Glückwünsche!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Tiles
Establishment
Beiträge: 1990
Registriert: 11.01.2003, 13:21
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Tiles »

Auch von mir beste Glückwünsche. Ich hoffe mal der Rest ist inzwischen auch wieder wohl auf.
Free Gamegraphics, Freeware Games https://www.reinerstilesets.de
Die deutsche 3D Community: https://www.3d-ring.de
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4256
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Anti-Jammer-Thread

Beitrag von Chromanoid »

Ich wünsche Euch viel Kraft für die nächste Zeit und Alles Gute!
Matthias Gubisch
Establishment
Beiträge: 470
Registriert: 01.03.2009, 19:09

Re: Anti-Jammer-Thread

Beitrag von Matthias Gubisch »

Herzlichen Glückwunsch Thomas
Bevor man den Kopf schüttelt, sollte man sich vergewissern einen zu haben
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: Anti-Jammer-Thread

Beitrag von antisteo »

Glückwunsch Schrompf.

Bei uns gibt's auch Neuigkeiten: Eigenheim gekauft

[youtube]zv7c5EmZMBc[/youtube]
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von xq »

Glückwunsch Schrompf und antisteo! Ist das Haus jetzt das Haus, das ihr mitgefunded haben wolltet? Sieht auf jeden Fall alt, aber schön aus.
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
GameDevR
Beiträge: 63
Registriert: 27.06.2014, 10:16
Wohnort: Wien

Re: Anti-Jammer-Thread

Beitrag von GameDevR »

Auch von mir herzlichen Glückwunsch Schrompf und antisteo! :)
Auch zu finden auf: Pewn.de | itch.to | Game Jolt | Twitter | YouTube
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4256
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Anti-Jammer-Thread

Beitrag von Chromanoid »

Für alle, die daran interessiert sind: httpS://zfx.info geht jetzt auch. Demnächst erfolgt evt. noch eine automatische Umleitung.

Danke Seraph!
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

geilgeilgeilgeilgeil
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von xq »

GEIL!
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

Übrigens an dieser Stelle auch noch vielen Dank dafür, dass ihr das Forum nicht irgendwo in die Cloud geschoben habt. CloudFlare z.B. ist mit Tor eine katastrophale Captcha-Orgie. Auf vielen Seiten laden die Bilder nur Schrittweise, und ich muss ca. zehn Mal aktualisieren bis von einem Bild mehr als der obere Rand da ist.

ZFX und fefe sind so ziemlich die einzigen nichtkommerziellen Seiten, die ich problemlos ansurfen kann.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4256
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Anti-Jammer-Thread

Beitrag von Chromanoid »

Krishty hat geschrieben:ZFX und fefe sind so ziemlich die einzigen nichtkommerziellen Seiten, die ich problemlos ansurfen kann.
Ach deswegen hängst Du hier rum :D
Antworten