Share via


Addresssanitizer

Panoramica

I linguaggi C & C++ sono potenti, ma possono risentire di una classe di bug che influiscono sulla correttezza del programma e sulla sicurezza del programma. A partire da Visual Studio 2019 versione 16.9, il compilatore Microsoft C/C++ (MSVC) e l'IDE supportano il servizio di purificazione AddressSanitizer . AddressSanitizer (ASan) è una tecnologia del compilatore e del runtime che espone molti bug difficili da trovare con zero falsi positivi:

Usare AddressSanitizer per ridurre il tempo impiegato per:

  • Correttezza di base
  • Portabilità multipiattaforma
  • Sicurezza
  • Test di stress
  • Integrazione di nuovo codice

AddressSanitizer, originariamente introdotto da Google, fornisce tecnologie di ricerca di bug di runtime che usano direttamente i sistemi di compilazione esistenti e gli asset di test esistenti.

AddressSanitizer è integrato con il sistema di progetto di Visual Studio, il sistema di compilazione CMake e l'IDE. I progetti possono abilitare AddressSanitizer impostando una proprietà del progetto o usando un'opzione del compilatore aggiuntiva: /fsanitize=address. La nuova opzione è compatibile con tutti i livelli di ottimizzazione e configurazioni di x86 e x64. Tuttavia, non è compatibile con la modifica e continuazione, il collegamento incrementale e /RTC.

A partire da Visual Studio 2019 versione 16.9, la tecnologia AddressSanitizer di Microsoft abilita l'integrazione con l'IDE di Visual Studio. La funzionalità può facoltativamente creare un file di dump di arresto anomalo del sistema quando il servizio di purificazione rileva un bug in fase di esecuzione. Se si imposta la ASAN_SAVE_DUMPS=MyFileName.dmp variabile di ambiente prima di eseguire il programma, viene creato un file dump di arresto anomalo del sistema con metadati aggiuntivi per un debug post-mortem efficiente dei bug diagnosticati con precisione. Questi file di dump semplificano l'uso esteso di AddressSanitizer per:

  • Test del computer locale
  • Test distribuiti locali
  • Flussi di lavoro basati sul cloud per i test

Installare AddressSanitizer

Per impostazione predefinita, i carichi di lavoro C++ nella Programma di installazione di Visual Studio installano le librerie AddressSanitizer e l'integrazione dell'IDE. Tuttavia, se si esegue l'aggiornamento da una versione precedente di Visual Studio 2019, usare il programma di installazione per abilitare il supporto di ASan dopo l'aggiornamento. È possibile aprire il programma di installazione dal menu principale di Visual Studio tramite Strumenti Ottieni strumenti>e funzionalità... Scegliere Modifica nell'installazione esistente di Visual Studio dalla Programma di installazione di Visual Studio per passare alla schermata seguente.

Screenshot of the Visual Studio Installer. The C++ AddressSanitizer component, under the Optional section, is highlighted.

Nota

Se si esegue Visual Studio nel nuovo aggiornamento ma non è stato installato ASan, viene visualizzato un errore quando si esegue il codice:

LNK1356: impossibile trovare la libreria 'clang_rt.asan_dynamic-i386.lib'

Usare AddressSanitizer

Iniziare a compilare i file eseguibili con l'opzione del /fsanitize=address compilatore usando uno di questi metodi di sviluppo comuni:

  • Compilazioni della riga di comando
  • Sistema del progetto di Visual Studio
  • Integrazione di Visual Studio CMake

Ricompilare, quindi eseguire il programma normalmente. Questa generazione di codice espone molti tipi di bug diagnosticati con precisione. Questi errori vengono segnalati in tre modi: nell'IDE del debugger, nella riga di comando o archiviati in un nuovo tipo di file di dump per un'elaborazione off-line precisa.

Microsoft consiglia di usare AddressSanitizer in questi tre flussi di lavoro standard:

Questo articolo illustra le informazioni necessarie per abilitare i tre flussi di lavoro elencati in precedenza. Le informazioni sono specifiche dell'implementazione di Windows 10 dipendente dalla piattaforma di AddressSanitizer. Questa documentazione integra la documentazione eccellente di Google, Apple e GCC già pubblicata.

Nota

Il supporto corrente è limitato a x86 e x64 in Windows 10. Inviare commenti e suggerimenti su ciò che si vuole visualizzare nelle versioni future. I commenti e suggerimenti ci aiutano a classificare in ordine di priorità altri sanificatori per il futuro, ad esempio /fsanitize=thread, /fsanitize=leak/fsanitize=memory, /fsanitize=undefined, o /fsanitize=hwaddress. Se si verificano problemi, è possibile segnalare bug qui .

Usare AddressSanitizer da un prompt dei comandi per sviluppatori

Usare l'opzione /fsanitize=address del compilatore in un prompt dei comandi per sviluppatori per abilitare la compilazione per il runtime AddressSanitizer. L'opzione /fsanitize=address è compatibile con tutti i livelli di ottimizzazione C++ o C esistenti (ad esempio, /Od, /O1/O2, /O2 /GL, e PGO). L'opzione funziona con CRT statici e dinamici , ad esempio , /MD/MDd, /MTe /MTd. Funziona se si crea un file EXE o una DLL. Le informazioni di debug sono necessarie per una formattazione ottimale degli stack di chiamate. Nell'esempio seguente viene cl /fsanitize=address /Zi passato alla riga di comando.

Le librerie AddressSanitizer (file con estensione lib) vengono collegate automaticamente. Per altre informazioni, vedere Riferimento al linguaggio AddressSanitizer, alla compilazione e al debug.

Esempio: overflow del buffer globale di base

// basic-global-overflow.cpp
#include <stdio.h>
int x[100];
int main() {
    printf("Hello!\n");
    x[100] = 5; // Boom!
    return 0;
}

Uso di un prompt dei comandi per gli sviluppatori per Visual Studio 2019, compilare main.cpp con /fsanitize=address /Zi

Screenshot of a command prompt showing the command to compile with AddressSanitizer options. The command is: `cl main.cpp -faanitize-address /Zi`.

Quando si esegue il risultato main.exe nella riga di comando, viene creato il report degli errori formattato che segue.

Si considerino le caselle rosse sovrapposte che evidenziano sette informazioni chiave:

Screenshot of the debugger showing a basic global overflow error.

Sono presenti sette evidenziazioni rosse che identificano le informazioni chiave nel report degli errori. Eseguono il mapping all'elenco numerato che segue questo screenshot. Le caselle numerate evidenziano il testo seguente: 1) global-buffer-overflow 2) WRITE di dimensioni 4 3) basic-global-overflow.cpp 7 4) a destra della variabile globale 'x' definita in 'basic-global-over-overflow.cpp:3:8' 5) di dimensioni 400 6) 00 00[f9]f9 f9 7) Box si trova nell'area della legenda dei byte shadow e contiene redzone globale: f9

Evidenziazioni rosse, dall'alto verso il basso

  1. Il bug di sicurezza della memoria è un overflow globale del buffer.
  2. Sono stati archiviati 4 byte (32 bit) all'esterno di qualsiasi variabile definita dall'utente.
  3. L'archivio ha avuto luogo nella funzione main() definita nel file basic-global-overflow.cpp alla riga 7.
  4. La variabile denominata x viene definita in basic-global-overflow.cpp alla riga 3, a partire dalla colonna 8
  5. Questa variabile x globale è di dimensioni pari a 400 byte
  6. Il byte di ombreggiatura esatto che descrive l'indirizzo di destinazione dell'archivio ha un valore0xf9
  7. La legenda dei byte ombreggiatura dice 0xf9 che è un'area di riempimento a destra di int x[100]

Nota

I nomi delle funzioni nello stack di chiamate vengono generati tramite il simbolizzatore LLVM richiamato dal runtime in caso di errore.

Usare AddressSanitizer in Visual Studio

AddressSanitizer è integrato con l'IDE di Visual Studio. Per attivare AddressSanitizer per un progetto MSBuild, fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni e scegliere Proprietà. Nella finestra di dialogo Pagine delle proprietà selezionare Proprietà>di configurazione C/C++>Generale, quindi modificare la proprietà Enable AddressSanitizer. Scegli OK per salvare le modifiche.

Screenshot of the Property Pages dialog showing the Enable AddressSanitizer property.

Per eseguire la compilazione dall'IDE, rifiutare esplicitamente eventuali opzioni incompatibili. Per un progetto esistente compilato tramite /Od (o modalità debug), potrebbe essere necessario disattivare queste opzioni:

Per compilare ed eseguire il debugger, premere F5. In Visual Studio viene visualizzata una finestra Eccezione generata :

Screenshot of the debugger showing a global buffer overflow error.

Usare AddressSanitizer da Visual Studio: CMake

Per abilitare AddressSanitizer per un progetto CMake creato in Windows di destinazione, seguire questa procedura:

  1. Aprire l'elenco a discesa Configurazioni nella barra degli strumenti nella parte superiore dell'IDE e selezionare Gestisci configurazioni.

    Screenshot of the CMake configuration dropdown. It displays options like x64 Debug, x64 Release, and so on. At the bottom of the list, Manage Configurations... is highlighted.

    Verrà aperto l'editor di Impostazioni progetto CMake, che riflette il contenuto del file del CMakeSettings.json progetto.

  2. Scegliere il collegamento Modifica JSON nell'editor. Questa selezione consente di passare alla visualizzazione json non elaborato.

  3. Aggiungere il frammento di codice seguente al "windows-base" set di impostazioni, all'interno "configurePresets": per attivare Address Sanitizer:

    "environment": {
      "CFLAGS": "/fsanitize=address",
      "CXXFLAGS": "/fsanitize=address"
    }
    

    "configurePresets" ha un aspetto simile al seguente:

        "configurePresets": [
          {
            "name": "windows-base",
            "hidden": true,
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/out/build/${presetName}",
            "installDir": "${sourceDir}/out/install/${presetName}",
            "cacheVariables": {
              "CMAKE_C_COMPILER": "cl.exe",
              "CMAKE_CXX_COMPILER": "cl.exe"
            },
            "condition": {
              "type": "equals",
              "lhs": "${hostSystemName}",
              "rhs": "Windows"
            },
            "environment": {
              "CFLAGS": "/fsanitize=address",
              "CXXFLAGS": "/fsanitize=address"
            }
          },
    
  4. Il servizio di purificazione degli indirizzi non funziona se è specificato edit-and-continue (/ZI), che è abilitato per impostazione predefinita per i nuovi progetti CMake. In CMakeLists.txtimpostare come commento (prefisso con #) la riga che inizia con set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT". La riga è simile alla seguente:

    # set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
    
  5. Premere CTRL+S per salvare il file JSON

  6. Cancellare la directory della cache CMake e riconfigurarsi scegliendo dal menu di Visual Studio: Project Delete cache and Reconfigure (Elimina>cache e riconfigura). Scegliere quando viene visualizzata la richiesta di cancellare la directory della cache e riconfigurarla.

  7. Sostituire il contenuto del file di origine (ad esempio, CMakeProject1.cpp) con quanto segue:

    // CMakeProject1.cpp : Defines the entry point for the application
    
    #include <stdio.h>
    
    int x[100];
    
    int main()
    {
        printf("Hello!\n");
        x[100] = 5; // Boom!
        return 0;
    }
    
  8. Scegliere F5 per ricompilare ed eseguire nel debugger.

    Questo screenshot acquisisce l'errore dalla compilazione CMake.

    Screenshot of an exception that says: Address Sanitizer Error: Global buffer overflow. In the background, address sanitizer output is visible in command window.

Dump di arresto anomalo di AddressSanitizer

Sono state introdotte nuove funzionalità in AddressSanitizer per l'uso con flussi di lavoro cloud e distribuiti. Questa funzionalità consente la visualizzazione offline di un errore AddressSanitizer nell'IDE. L'errore viene sovrapposto all'origine, proprio come si farebbe in una sessione di debug in tempo reale.

Questi nuovi file di dump possono causare efficienza durante l'analisi di un bug. Non è necessario rieseguire o trovare dati remoti o cercare un computer che è andato fuori linea.

Per produrre un nuovo tipo di file di dump che può essere visualizzato in Visual Studio in un altro computer in un secondo momento:

set ASAN_SAVE_DUMPS=MyFileName.dmp

A partire da Visual Studio 16.9 è possibile visualizzare un errore diagnosticato con precisione, archiviato nel *.dmp file, sopra il codice sorgente.

Questa nuova funzionalità di dump di arresto anomalo del sistema consente flussi di lavoro basati sul cloud o test distribuiti. Può anche essere usato per archiviare un bug dettagliato e praticabile in qualsiasi scenario.

Esempi di errori

AddressSanitizer può rilevare diversi tipi di errori di uso improprio della memoria. Di seguito sono riportati molti degli errori di runtime segnalati quando si eseguono i file binari compilati usando l'opzione del compilatore AddressSanitizer (/fsanitize=address):

Per altre informazioni sugli esempi, vedere Esempi di errore AddressSanitizer.

Differenze con Clang 12.0

MSVC è attualmente diverso da Clang 12.0 in due aree funzionali:

  • stack-use-after-scope : questa impostazione è attivata per impostazione predefinita e non può essere disattivata.
  • stack-use-after-return : questa funzionalità richiede un'opzione aggiuntiva del compilatore e non è disponibile solo impostando ASAN_OPTIONS.

Queste decisioni sono state prese per ridurre la matrice di test necessaria per distribuire questa prima versione.

Le funzionalità che potrebbero causare falsi positivi in Visual Studio 2019 16.9 non sono state incluse. Tale disciplina imponeva l'integrità dei test efficace necessaria quando si considera l'interoperabilità con decenni di codice esistente. Altre funzionalità possono essere considerate nelle versioni successive:

Per altre informazioni, vedere Compilazione per AddressSanitizer con MSVC.

Documentazione del settore esistente

Documentazione completa già esistente per queste implementazioni di linguaggio e dipendenti dalla piattaforma della tecnologia AddressSanitizer.

Questo documento fondamentale su AddressSanitizer descrive l'implementazione.

Vedi anche

Problemi noti di AddressSanitizer
Riferimento alla compilazione e al linguaggio AddressSanitizer
Informazioni di riferimento sul runtime AddressSanitizer
Byte ombreggiatura AddressSanitizer
AddressSanitizer cloud o test distribuiti
Integrazione del debugger AddressSanitizer
Esempi di errore addressSanitizer