Forum: PC-Programmierung Python ctypes Access violation bei Einbindung logging Modul


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Thomas W. (thomas_v2)


Lesenswert?

Hallo,

ich verwende Python 3.7 und binde mit ctypes unter Windows eine dll ein, 
deren Funktionen ich dann aufrufe. Das funktioniert auch alles soweit.

Jetzt wollte ich zur Verfeinerung das logging Modul von Python 
verwenden, und stelle nun fest, dass alleine durch das Einbinden des 
Moduls mit "import logging" mein erster Aufruf einer Funktion der dll 
mit "OSError: exception: access violation writing 0x0000004C". Die 
Adresse ist dabei immer die gleiche.

Die erste Funktion die ich dort aufrufe bekommt ein Callback zu einer 
Python Funktion übergeben, was ich verwende und was auch funktioniert. 
Die Funktion unterstützt es aber auch ohne Callbacks wenn ich dort Null 
übergebe. Aber auch wenn ich das ändere bekomme ich eine Access 
violation.

Also sobald ich "import logging" im Code stehen habe, bekomme ich den 
Fehler. Auch wenn ich daraus überhaupt nichts verwende.

Zur Information: Wenn ich den Callback verwende, dann bekomme ich direkt 
bei Aufruf der ersten Funktion einen Aufruf des Callbacks zur 
Bestätigung.

Ich habe von dem Programm was ich dort anspreche in weiteren Python 
Funktionen andere dlls mit ctypes eingebunden die auch Callbacks 
verwenden, da funktioniert alles auch mit dem logging Modul.

Hat jemand eine Idee was da schieflaufen könnte? Komme ich mit der 
Adressangabe 0x4c dahinter?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas W. schrieb:
> Hat jemand eine Idee was da schieflaufen könnte?

Ich würde erst einmal versuchen, das Auftreten des Fehlers einzugrenzen,
bspw. durch Debug-Ausgaben und/oder schrittweises Weglassen von Teilen
deiner DLL-Funktion. Vielleicht entdeckst du damit eine uninitialisierte
Variable, einen falsch berechneten Pointer, ein überlaufendes Array oder
was auch immer die Ursache für den Segfault sein mag.

> Komme ich mit der Adressangabe 0x4c dahinter?

Kaum, es sei denn, du erkennst die Zahl 0x4C (dezimal 76) wieder, bspw.
als Integer-Wert, der irgendwohin (bspw. in ein Array) geschrieben
wird, wo er später fälschlicherweise als Pointer interpretiert wird.

von Thomas W. (thomas_v2)


Lesenswert?

Yalu X. schrieb:
> Ich würde erst einmal versuchen, das Auftreten des Fehlers einzugrenzen,
> bspw. durch Debug-Ausgaben und/oder schrittweises Weglassen von Teilen
> deiner DLL-Funktion. Vielleicht entdeckst du damit eine uninitialisierte
> Variable, einen falsch berechneten Pointer, ein überlaufendes Array oder
> was auch immer die Ursache für den Segfault sein mag.

Das ist leider die erste Funktion die ich aufrufe, mit der ich mich bei 
den Diensten der Anwendung anmelden muss. Dort bekomme ich dann eine 
Dienst ID zurück mit der ich die anderen Funktionen aufrufen kann.

Wie ich jetzt aber festgestellt habe, bekomme ich die Access violation 
mit der gleichen Adresse auch ohne das logging Modul, allerdings 
sporadisch einmal alle 60-100 Aufrufe, d.h. wenn ich mein Python Skript 
diese Anzahl von der Kommandozeile aus starte.

Aber mit import logging geht nie etwas, wenn ich die Importzeile 
auskommentiere funktioniert es.
Die 0x4c scheint zumindest keine Offset-Adresse des Parameterstacks zu 
sein, der ist nur 24 Bytes groß.

Vielleicht schreibe ich nochmal kurz eine Testanwendung in C, nicht dass 
das Verhalten sich auch von dort aus zeigt und der Fehler in der 
angesprochenen Anwendung liegt.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Thomas W. schrieb:
> Das ist leider die erste Funktion die ich aufrufe, mit der ich mich bei
> den Diensten der Anwendung anmelden muss. Dort bekomme ich dann eine
> Dienst ID zurück mit der ich die anderen Funktionen aufrufen kann.

Ich meinte damit, den Fehler innerhalb der aufgerufenen Funktion
einzugrenzen, da ja – wenn ich dich richtig verstanden habe – dort der
Fehler auftritt.

Oder hast du diese Funktion gar nicht selber geschrieben und auch keinen
Quellcode davon? Dann geht das natürlich nicht so ohne weiteres.

Das Importieren des Logging-Moduls ist ziemlich sicher nicht die
Ursache, sondern höchstens der Auslöser des Problems. Der eigentliche
Fehler steckt vermutlich in der DLL-Funktion, deswegen würde ich dort
mit der Suche beginnen.

von Thomas W. (thomas_v2)


Lesenswert?

Yalu X. schrieb:
> Oder hast du diese Funktion gar nicht selber geschrieben und auch keinen
> Quellcode davon? Dann geht das natürlich nicht so ohne weiteres.

Nein, die Funktionen in der DLL habe ich nicht geschrieben. Das ist die 
offizielle Schnittstelle zum Ansprechen der Anwendung. Ich habe davon 
die Header-Dateien mit den Funktions- und Strukturdefinitionen.

von Thomas W. (thomas_v2)


Lesenswert?

Ich konnte das Problem so wie es aussieht beheben.
Als erstes habe ich ein Update in der Zielsoftware aufgespielt, dann 
funktionierte es zumindest teilweise ohne Zugriffsverletzung, aber es 
kam dann sporadisch nach n Aufrufen der Fehler wie ohne die Verwendung 
des logging Moduls.

Dann habe ich in meinem Python Programm nach Beendigung mit Aufruf von 
FreeLibrary aus der kernel32.dll die geladene dll noch einmal explizit 
entladen, und das hat dann den eigentlichen Erfolg gebracht. Eigentlich 
sollte das wohl der GC von Python übernehmen, aber der scheint nicht 
immer das zu machen was man von ihm erwartet.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.