GNU/Linux >> Tutoriels Linux >  >> Linux

Linux – En quoi Mono est-il magique ?

J'apprends le C#, alors j'ai créé un petit programme C# qui dit Hello, World! , puis compilé avec mono-csc et l'a exécuté avec mono :

$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!

J'ai remarqué que lorsque j'ai appuyé sur TAB dans bash , Hello.exe était marqué comme exécutable. En effet, il ne fonctionne que par un shell chargeant le nom du fichier !

Hello.exe n'est pas un fichier ELF avec une drôle d'extension :

$ readelf -a Hello.exe
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
$ xxd Hello.exe | head -n1
00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000  MZ..............

MZ signifie qu'il s'agit d'un exécutable Microsoft Windows lié statiquement. Déposez-le sur une boîte Windows, et il fonctionnera (devrait) fonctionner.

J'ai du wine installé, mais wine , étant une couche de compatibilité pour les applications Windows, prend environ 5 fois plus de temps pour exécuter Hello.exe comme mono et l'exécuter directement, donc ce n'est pas wine qui l'exécute.

Je suppose qu'il y a du mono module noyau installé avec mono qui intercepte le exec syscall/s, ou intercepte les binaires qui commencent par 4D 5A , mais lsmod | grep mono et les amis renvoient une erreur.

Que se passe-t-il ici, et comment le noyau sait-il que cela l'exécutable est spécial ?

Juste pour preuve, ce n'est pas mon la magie du shell, j'ai utilisé le Crap Shell (alias sh ) pour l'exécuter et il s'exécute toujours en mode natif.

Voici le programme complet, car un commentateur était curieux :

using System;

class Hello {
  /// <summary>
  ///   The main entry point for the application
  /// </summary>
  [STAThread]
  public static void Main(string[] args) {
    System.Console.Write("Hello, World!n");
  }
}

Réponse acceptée :

C'est binfmt_misc en action :il permet au noyau de savoir comment exécuter des binaires qu'il ne connaît pas. Regardez le contenu de /proc/sys/fs/binfmt_misc; parmi les fichiers que vous y voyez, un devrait expliquer comment exécuter les binaires Mono :

enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a

(sur un système Debian). Cela indique au noyau que les binaires commençant par MZ (4d5a ) doit être donné aux run-detectors . Ce dernier détermine s'il faut utiliser Mono ou Wine pour exécuter le binaire.

Les types binaires peuvent être ajoutés, supprimés, activés et désactivés à tout moment ; voir la documentation ci-dessus pour plus de détails (la sémantique est surprenante, le système de fichiers virtuel utilisé ici ne se comporte pas entièrement comme un système de fichiers standard). /proc/sys/fs/binfmt_misc/status donne le statut global, et chaque "descripteur" binaire montre son statut individuel. Une autre façon de désactiver binfmt_misc est de décharger son module noyau, s'il est construit en tant que module ; cela signifie également qu'il est possible de le mettre sur liste noire pour l'éviter complètement.

Cette fonctionnalité permet de supporter de nouveaux types binaires, comme les exécutables MZ (qui incluent les binaires Windows PE et PE+, mais aussi les binaires DOS et OS/2 !), les fichiers Java JAR… Elle permet également de supporter des types binaires connus sur de nouvelles architectures , utilisant généralement Qemu ; ainsi, avec les bibliothèques appropriées, vous pouvez exécuter en toute transparence des binaires ARM Linux sur un processeur Intel !

En relation:Feuille de triche des choses que j'oublie sous Linux

Votre question découlait d'une compilation croisée, bien que dans le sens .NET, et cela soulève une mise en garde avec binfmt_misc :certains scripts de configuration se comportent mal lorsque vous essayez de compiler de manière croisée sur un système qui peut exécuter les binaires compilés de manière croisée. En règle générale, la détection d'une compilation croisée implique la création d'un binaire et la tentative de l'exécuter ; s'il s'exécute, vous n'êtes pas en compilation croisée, si ce n'est pas le cas, vous l'êtes (ou votre compilateur est cassé). autoconf les scripts peuvent généralement être corrigés dans ce cas en spécifiant explicitement les architectures de construction et d'hôte, mais parfois vous devrez désactiver binfmt_misc temporairement…


Linux
  1. Comment utiliser BusyBox sous Linux

  2. Comment installer Python sur Linux

  3. Comment j'utilise cron sous Linux

  4. Comment installer Java sur Linux

  5. Comment partitionner un disque sous Linux

Comment installer Mono sur Ubuntu 20.04

Comment installer Mono sur CentOS 8

Comment installer Mono sur Debian 10

Comment installer FFmpeg sur Linux

Comment installer Mono ou dotNET45 sous Linux - Tutoriel

Comment installer Mono sur Linux Mint 20