GNU/Linux >> Linux Esercitazione >  >> Linux

Linux – In che modo Mono è magico?

Sto imparando C#, quindi ho creato un programmino C# che dice Hello, World! , quindi compilato con mono-csc ed eseguilo con mono :

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

L'ho notato quando ho premuto TAB in bash , Hello.exe è stato contrassegnato come eseguibile. In effetti, funziona solo con una shell che carica il nome del file!

Hello.exe è non un file ELF con un'estensione di file divertente:

$ 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 significa che è un eseguibile collegato staticamente di Microsoft Windows. Rilascialo su una finestra di Windows e (dovrebbe) funzionare.

Ho wine installato, ma wine , essendo un livello di compatibilità per le app di Windows, impiega circa 5 volte il tempo per eseguire Hello.exe come mono ed eseguirlo direttamente lo fa, quindi non è wine che lo esegue.

Presumo che ci sia del mono modulo del kernel installato con mono che intercetta il exec syscall/s, o cattura i binari che iniziano con 4D 5A , ma lsmod | grep mono e gli amici restituiscono un errore.

Cosa sta succedendo qui e come fa il kernel a sapere che questo eseguibile è speciale?

Solo per prova che non è mio shell che funziona con la magia, ho usato la Crap Shell (aka sh ) per eseguirlo e funziona ancora in modo nativo.

Ecco il programma per intero, visto che un commentatore era curioso:

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");
  }
}

Risposta accettata:

Questo è binfmt_misc in azione:permette di dire al kernel come eseguire binari di cui non è a conoscenza. Guarda il contenuto di /proc/sys/fs/binfmt_misc; tra i file che vedi lì, uno dovrebbe spiegare come eseguire i binari Mono:

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

(su un sistema Debian). Questo dice al kernel che i binari iniziano con MZ (4d5a ) deve essere assegnato a run-detectors . Quest'ultimo decide se utilizzare Mono o Wine per eseguire il binario.

I tipi binari possono essere aggiunti, rimossi, abilitati e disabilitati in qualsiasi momento; vedere la documentazione sopra per i dettagli (la semantica è sorprendente, il filesystem virtuale utilizzato qui non si comporta del tutto come un filesystem standard). /proc/sys/fs/binfmt_misc/status fornisce lo stato globale e ogni "descrittore" binario mostra il suo stato individuale. Un altro modo per disabilitare binfmt_misc è scaricare il suo modulo del kernel, se è compilato come modulo; questo significa anche che è possibile inserirlo nella blacklist per evitarlo del tutto.

Questa funzione consente di supportare nuovi tipi binari, come eseguibili MZ (che includono binari Windows PE e PE+, ma anche binari DOS e OS/2!), file Java JAR... Consente inoltre di supportare tipi binari noti su nuove architetture , tipicamente usando Qemu; quindi, con le librerie appropriate, puoi eseguire in modo trasparente i binari di ARM Linux su un processore Intel!

Relazionato:Cheat Sheet di Linux Things I Forget

La tua domanda derivava da una compilazione incrociata, anche se in senso .NET, e questo fa apparire un avvertimento con binfmt_misc :alcuni script di configurazione si comportano in modo anomalo quando si tenta di eseguire la compilazione incrociata su un sistema che può eseguire i binari della compilazione incrociata. In genere, il rilevamento della compilazione incrociata implica la creazione di un file binario e il tentativo di eseguirlo; se funziona, non stai compilando in modo incrociato, in caso contrario, lo sei (o il tuo compilatore è rotto). autoconf gli script di solito possono essere corretti in questo caso specificando esplicitamente la build e le architetture host, ma a volte dovrai disabilitare binfmt_misc temporaneamente...


Linux
  1. Come usare BusyBox su Linux

  2. Come installare Python su Linux

  3. Come uso cron in Linux

  4. Come installare Java su Linux

  5. Come partizionare un disco in Linux

Come installare Mono su Ubuntu 20.04

Come installare Mono su CentOS 8

Come installare Mono su Debian 10

Come installare FFmpeg su Linux

Come installare Mono o dotNET45 su Linux - Tutorial

Come installare Mono su Linux Mint 20