Ich habe ein paar Probleme festgestellt, wenn ich ELF Executables in WSL ausführe. Einige C Standardfunktionen scheinen unterschiedliche Wertebereiche bzw. unterschiedliche Auflösungen zurückzugeben. Ich vermute sie kompilieren zu Prozessorinstruktionen die halt bereits unterschiedliche Werte erzeugen, je nachdem für welches OS der Prozessor ausgelegt ist. Und im Fall von WSL ist das nun mal Windows.
Zwei Beispiele:
-
Auf Windows is CLOCKS_PER_SEC mit 10.000 definiert. Auf Linux mit 1.000.000 (POSIX Anforderung soweit ich gelesen habe). Alle Programme die für Linux compiliert sind, CLOCKS_PER_SEC im Code haben und unter WSL laufen, werden Mist produzieren. Unter WSL ist die Auflösung 10.000 ¯\_(ツ)_/¯
-
RAND_MAX ist 32.767 auf Windows und 2.147.483.647 auf Linux. Allerdings gibt rand() auch auf WSL nur Werte 0..32.767 zurück. Das geht fürchterlich in die Hose.
Nein, ich will hier keine Diskussion über die Sinnhaftigkeit der Verwendung von clock() und rand() anzetteln. Mir geht es darum, dass sich ELF Executables in WSL eben offenbar nicht "nativ" verhalten. WSL verspricht das aber. Das wiederum bedeutet, dass man Programme eben nicht für WSL compilieren sollte. Was aber dann? Das einzige was mir bislang dazu einfällt, ist eine Prüfung zur Laufzeit à la ...
... mit 10000 als Magic Number, da so etwas wie ein CLOCKS_PER_SEC_ON_WSL logischerweise in keiner Implementierung definiert ist.
Aber alle ursprünglich für Linux compilierten Programme die so eine Prüfung nicht beinhalten, können potenziell an irgendeiner Stelle unerwartetes Verhalten zeigen wenn sie im WSL ausgeführt werden.
Und an dem Punkt würde ich gern irgendwo einen Bugreport aufmachen. Aber wo?
Zwei Beispiele:
-
clock()
Auf Windows is CLOCKS_PER_SEC mit 10.000 definiert. Auf Linux mit 1.000.000 (POSIX Anforderung soweit ich gelesen habe). Alle Programme die für Linux compiliert sind, CLOCKS_PER_SEC im Code haben und unter WSL laufen, werden Mist produzieren. Unter WSL ist die Auflösung 10.000 ¯\_(ツ)_/¯
-
rand()
RAND_MAX ist 32.767 auf Windows und 2.147.483.647 auf Linux. Allerdings gibt rand() auch auf WSL nur Werte 0..32.767 zurück. Das geht fürchterlich in die Hose.
Nein, ich will hier keine Diskussion über die Sinnhaftigkeit der Verwendung von clock() und rand() anzetteln. Mir geht es darum, dass sich ELF Executables in WSL eben offenbar nicht "nativ" verhalten. WSL verspricht das aber. Das wiederum bedeutet, dass man Programme eben nicht für WSL compilieren sollte. Was aber dann? Das einzige was mir bislang dazu einfällt, ist eine Prüfung zur Laufzeit à la ...
C:
#ifdef _WIN32
const int clocks_per_sec = CLOCKS_PER_SEC;
#else // ! _WIN32
#include <string.h>
#include <sys/utsname.h>
struct utsname sys_inf_buf = {0};
uname(&sys_inf_buf);
const int clocks_per_sec = strstr(sys_inf_buf.release, "microsoft") ? 10000 : CLOCKS_PER_SEC;
#endif // ! _WIN32
Aber alle ursprünglich für Linux compilierten Programme die so eine Prüfung nicht beinhalten, können potenziell an irgendeiner Stelle unerwartetes Verhalten zeigen wenn sie im WSL ausgeführt werden.
Und an dem Punkt würde ich gern irgendwo einen Bugreport aufmachen. Aber wo?
- Den Compilerbauern würde ich keinen Vorwurf machen. Wie oben zu sehen, wäre eine Prüfung zur Laufzeit erforderlich.
- Das WSL Team behauptet, dass ELF Programme nativ ausführbar sind. Scheinbar aber nicht ohne Einschränkung. Ich hab aber keine Ahnung inwiefern sie tatsächlich was ändern könnten (nach dem Motto "wenn Prozessorinstruktion xyz gelesen wird, gehe in ein Workaround") oder inwiefern sogar am Linux Kernel geschraubt werden müsste, den WSL2 nutzt.
- Am Ende vielleicht sogar in Richtung Prozessorentwickler?
Zuletzt bearbeitet: