Python C-Modul - Malloc schlägt in einer bestimmten Version von Python fehl

9

Ich schreibe ein Python-Modul, um IO in einem O_DIRECT-Kontext auszuführen. Eine der Einschränkungen von O_DIRECT besteht darin, dass Sie in einen Puffer lesen müssen, der auf einer 4096-Byte-Grenze für 2.4- und 2.5-Kernel ausgerichtet ist, und 2.6 und höher ein beliebiges Vielfaches von 512 akzeptieren.

Der offensichtliche Speicherzuweisungskandidat dafür ist posix_memalign(void **memptr, size_t alignment, size_t size)

In meinem Code ordne ich einen Bereich wie folgt zu:

%Vor%

Wenn ich das Modul mit python3.2 kompiliere und importiere, funktioniert das (und der Rest des nicht gezeigten Moduls) gut.

Wenn ich dasselbe mit python2.7 versuche (ich möchte die Kompatibilität beibehalten), wird die PyErr_NoMemory-Ausnahme und mem_ret == ENOMEM ausgelöst, was bedeutet, dass sie nicht zugeordnet werden konnte.

Warum sollte die Version von Python, die ich kompiliere, beeinflussen, wie posix_memalign funktioniert?

Betriebssystem: Ubuntu 12.04 LTS

Compiler: Clang + GCC Zeigt dasselbe Verhalten

AKTUALISIEREN

Ich habe jetzt einen funktionierenden Code, dank user694733
Aber die Tatsache, dass es funktioniert, hat mich noch mehr verwirrt:

%Vor%

Kann jemand erklären, warum der inkorrekte erste Block unter Python3, aber nicht unter 2.7 funktioniert, und noch wichtiger, warum der korrekte zweite Block unter Python3 nicht funktioniert?

UPDATE 2

Die Handlung verdichtet sich, nachdem ich mich auf die korrekte Form des unten stehenden Codes festgelegt habe, habe ich vier verschiedene Versionen von Python getestet.

%Vor%

Unter Python 2.7 : Dieser Code funktioniert wie erwartet.
Unter Python 3.1 : Dieser Code funktioniert wie erwartet.
Unter Python 3.2 : Dieser Code generiert mem_ret == ENOMEM und gibt NULL für buffer
zurück Unter Python 3.3 : Dieser Code funktioniert wie erwartet.

Die Python-Versionen, die nicht in den Ubuntu-Repositories enthalten sind, wurden von der PPA in Ссылка

installiert

Wenn man an die Version denkt, die mit Python-Binärdateien versehen ist, sind die Versionen, die ich installiert habe:

%Vor%

Könnte die Verwendung des Wide-Unicode-Flags in der Python3-Standardverteilung diesen Fehler verursachen? Wenn ja, wie geschieht das?

Aus Gründen der Übersichtlichkeit wird die ENOMEM fehlgeschlagene Zuordnung bei jeder Variante von malloc() auftreten, sogar bei etwas so Einfachem wie malloc(512) .

    
Bradfirj 30.01.2014, 14:13
quelle

2 Antworten

1

Für eine schnelle Lösung bleiben Sie bei mmap anstelle von malloc+memalign

    
Dima Tisnek 02.04.2014 14:44
quelle
0

posix_memalign ist möglicherweise nicht derselbe Code in einer Kompilierungsumgebung wie ein anderer. Sie können sich leicht vorstellen, dass Python 3 einen anderen Funktionstest verwenden würde Makros zu Python 2. Das könnte bedeuten, dass es anderen Code laufen lässt.

Sie können sich die Symbole ansehen, die verwendet werden ... oft wird die Ausgabe von ldd oder nm einen Namen haben, der anzeigt, welche Version tatsächlich verwendet wird.

Zusätzlich, was ruft eine Strace-Show des Allokationssystems auf? Ich finde das ist eine gute Möglichkeit zu sehen, ob die übergebenen Argumente falsch sind, was ein Grund sein kann, ENOMEM zu bekommen.

    
Cameron Kerr 29.04.2014 11:08
quelle