lseek unter cygwin

By dose | September 6, 2007
Under: technical stuff, Uncategorized

Unlängst musste ich in der Firma unsere Unix-Programme mittels Cygwin teilweise auf WIN32 portieren.
Nachdem ich es geschafft hatte, dass die Programme kompilieren versuchte ich ein Programm zu starten.
Boom: malloc() fehler, zu wenig SPeicherplatz.
Eine Analyse des MAskenhandlercodes ergab allerdings, dass die Fehlermeldung ein Folgefehler von einem misslungenen lseek() Aufruf war.
Der Maskenhandler wurde vor 20 Jahren unter Unix programmiert. Es wurde für den Seek-Modus nicht eine der Konstanten aus unistd.h verwendet, sondern der numerische Wert direkt angegeben.
Ansich kein Fehler. Daher wurde die unistd.h auch nicht #includet, der Compiler bindet lseek() dann implizit.
Allerdings lieferte unter Cygwin das lseek() dann immer EINVAL.
Der Parameterwert stimmte aber. Schließlich habe ich dann folgendes Experiment gemacht:

Einmal ein Programm, in welchem lseek() implizit gebunden wird und einmal habe ich die
unistd.hinkludiert. Siehe da, mit unistd.h funktioniert das Kommando, ohne die include-Datei nicht. Ein weiterer Versuch zeigte, dass bereits die Deklaration der Funktion ausreicht, damit es funktioniert, nur beim implizit binden trat immer EINVAL auf.
Das machte mich natürlich etwas stutzig, sodass ich dann den Assember-Code der beiden Funktionsaufrufe verglichen habe:


Mit Deklaration (unistd.h)
0040108E |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX ; EAX = Handle von open
00401091 |. C74424 0C 0200>MOV DWORD PTR SS:[ESP+C],2
00401099 |. C74424 04 0000>MOV DWORD PTR SS:[ESP+4],0
004010A1 |. C74424 08 0000>MOV DWORD PTR SS:[ESP+8],0
004010A9 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004010AC |. 890424 MOV DWORD PTR SS:[ESP],EAX
004010AF |. E8 1C010000 CALL

Ohne Deklartaion (unistd.h):
0040108E |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX ; EAX = Handle von open
00401091 |. C74424 08 0200>MOV DWORD PTR SS:[ESP+8],2
00401099 |. C74424 04 0000>MOV DWORD PTR SS:[ESP+4],0
004010A1 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004010A4 |. 890424 MOV DWORD PTR SS:[ESP],EAX
004010A7 |. E8 14010000 CALL

Bei impliziter Bindung wird also offensichtlich lseek64 der Cygwin-DLL mit einem Parameter zu wenig aufgerufen:
Implizite Bindung: lseek64(hFile, 0, 2);
Mit Deklaration: lseek64(hFile, 0, 0, 2);

Daher also der Fehler. Ob das nun ein Compilerbug ist oder böse Absicht kann ich nicht sagen. Auf der Cygwin-Mailingliste habe ich nur bei einem ähnlichen Fall den lapidaren Kommentar gefunden, dass es unsauber ist, die Header-Datei nicht zu inkludieren. Das mag schon stimmen, allerdings sehe ich die fehlerhafte implizite Bindung trotzdem als Bug an.

One comment | Add One

Comments

  1. some random geek - 07/28/2009 at 00:38

    get a life!

    (still, nice info.)

Trackbacks

Leave a Comment

Name:

E-Mail :

Subscribe :
Website :

Comments :