Seite 1 von 1

[VC++ 2015] STL-abort() abfangen

Verfasst: 07.11.2017, 23:06
von Krishty
Ich habe eine Drittbibliothek, die unter sehr seltenen Umständen in ihrem Destruktor crasht (Zugriffsverletzung).

Ich muss irgendwie damit leben. Das Verhalten ist definitiv ein Bug, aber das Team sagt, dass sie ihn nicht beheben werden (zu selten & wir zahlen nicht genug). Eine andere Bibliothek ist keine Option, weil alle Alternativen bei den zehnfachen Lizenzkosten anfangen. Es ist auch nicht so, dass der Heap total geschrottet wäre – sie rufen wohl einfach an einer Stelle für eines ihrer Millionen Mikro-Objekte den falschen virtuellen Destruktor auf.

Destruktor vermeiden ist keine Option, weil dann Speicher im Gigabyte-Bereich leckt.

Bisher hatte ich das hier gemacht, und damit waren die Memory Leaks zumindest auf einige MiB runter:

  __try {
    delete lib;
  } __except(EXCEPTION_EXECUTE_HANDLER) {
    // well fuck it
  }



So weit, so gut. Jetzt das Problem:


Seit einem Update letztens (das wir natürlich brauchen, weil es andere Bugs behebt) funktioniert das nicht mehr. Statt mit einer Access Violation zu crashen, ruft die Bibliothek nun Visual C++’ vcruntime140.dll!_purecall() auf. Und das beendet das Programm via abort(). Ohne Widerrede. Und das darf nicht passieren.

Was soll ich jetzt tun?
  • Ich würde die Bibliothek gern in einen eigenen Prozess schieben, damit sie nicht unser ganzes Programm runterreißt, wenn sie abstürzt. Die Inter-Process Communication um die Daten hin und her zu kriegen ist aber ein zu großer Brocken für meinen Zeitrahmen.
  • Ich würde gern abort() ersetzen. Da die Bibliothek aber nicht aus einer einzigen DLL besteht, deren Import ich überschreiben müsste, sondern eher so aus 30, bin ich mir unsicher, wo der beste Ansatzpunkt wäre. Sie wird auch statisch geladen, das bedeutet: Ihre DLL-Initialisierung läuft, bevor eine einzige Zeile unseres Programms erreicht wird.
  • Irgendwelche Ideen?

Re: [VC++ 2015] STL-abort() abfangen

Verfasst: 07.11.2017, 23:29
von Krishty
Ich hab’s – man sollte nicht bei abort() ansetzen, sondern bei purecall(). Visual C++ bietet _set_purecall_handler().

Der MSDN-Artikel erwähnt’s nicht, aber man darf von seinem Handler nicht zurückkehren, weil dann automatisch abort() aufgerufen wird.

Ich löse jetzt, sobald die fehlende virtuelle Funktion aufgerufen wird, eine andere Ausnahme aus (Divide by Zero; Access Violation; blabla) und lande dann wieder, wie früher, im Exception Handler.

  void onPurecall() {
    RaiseException(EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_NONCONTINUABLE, 0, nullptr);
  }

  _set_purecall_handler(onPurecall);
  __try {
    delete lib;
  } __except(EXCEPTION_EXECUTE_HANDLER) {
    // well fuck it
  }
  _set_purecall_handler(nullptr);

Re: [VC++ 2015] STL-abort() abfangen

Verfasst: 08.11.2017, 09:26
von kimmi
Cooler böser Hack! Den merke ich mir. Die Inter-Prozess-Kommunikation ist aber charmant, da du den Prozess ( sofern der leakt ) auch wieder abschießen kann. UNd das sorgt für weniger Fragmentierungen, die meiner Erfahrung nach im Gig-Bereich gerade Probleme machen kann.

Re: [VC++ 2015] STL-abort() abfangen

Verfasst: 08.11.2017, 09:42
von Krishty
IPC wäre mein absoluter Favorit, aber ich kriege das gerade zeitlich nicht hin :( Mach mal Assimps IFC-Support besser, dann brauche ich den Hack vielleicht nicht mehr ;)

Re: [VC++ 2015] STL-abort() abfangen

Verfasst: 08.11.2017, 13:22
von kimmi
Bin dabei!