Ingressi per migliorare il codice debuggability oltre a registri e codici di errore

StackOverflow https://stackoverflow.com/questions/2177597

  •  24-09-2019
  •  | 
  •  

Domanda

Oltre ai codici di errore, stringhe di errore e log, ci sono altre caratteristiche che possono essere incorporati nel codice per aumentare ottenere debug / informazioni di traccia durante l'esecuzione di codice che può aiutare i problemi di debug (o farci sapere cosa sta succedendo) in fase di esecuzione?

È stato utile?

Soluzione

Ecco un esempio di codice che invia uno stacktrace a un file su un errore di segmentazione

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>

static void signal_handler(int);
static void dumpstack(void);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);

struct sigaction sigact;
char *progname;

int main(int argc, char **argv){
    char *s;
    progname = *(argv);
    atexit(cleanup);
    init_signals();
    printf("About to seg fault by assigning zero to *s\n");
    *s = 0;
    sigemptyset(&sigact.sa_mask);
    return 0;
}

void init_signals(void){
    sigact.sa_handler = signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGINT, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGSEGV);
    sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGBUS);
    sigaction(SIGBUS, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGQUIT);
    sigaction(SIGQUIT, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGHUP);
    sigaction(SIGHUP, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGKILL);
    sigaction(SIGKILL, &sigact, (struct sigaction *)NULL);
}

static void signal_handler(int sig){
    if (sig == SIGHUP) panic("FATAL: Program hanged up\n");
    if (sig == SIGSEGV || sig == SIGBUS){
        dumpstack();
        panic("FATAL: %s Fault. Logged StackTrace\n", (sig == SIGSEGV) ? "Segmentation" : ((sig == SIGBUS) ? "Bus" : "Unknown"));
    }
    if (sig == SIGQUIT) panic("QUIT signal ended program\n");
    if (sig == SIGKILL) panic("KILL signal ended program\n");
    if (sig == SIGINT) ;
}

void panic(const char *fmt, ...){
    char buf[50];
    va_list argptr;
    va_start(argptr, fmt);
    vsprintf(buf, fmt, argptr);
    va_end(argptr);
    fprintf(stderr, buf);
    exit(-1);
}

static void dumpstack(void){
    /* Got this routine from http://www.whitefang.com/unix/faq_toc.html
    ** Section 6.5. Modified to redirect to file to prevent clutter
    */
    char dbx[160];
    sprintf(dbx, "echo 'where\ndetach' | dbx -a %d > %s.dump", getpid(), progname);
    system(dbx);
    return;
}

void cleanup(void){
    sigemptyset(&sigact.sa_mask);
    /* Do any cleaning up chores here */
}

Nella funzione dumpstack, dbx deve essere cambiato per soddisfare il vostro debugger, come ad esempio gdb per GNU Debugger, questo codice è stato utilizzato quando stavo programmando in AIX box a pochi anni fa. Notate come i segnali sono istituiti, e se si verifica un errore SIGSEGV, il gestore discariche lo stack in un file con estensione .dump. Il codice illustra l'errore di segmentazione e ne mostra lo stacktrace.

Questo è il mio codice preferito.

Spero che questo aiuti, I migliori saluti, Tom.

Altri suggerimenti

  • Costruire senza ottimizzazione, per preservare il maggior numero di "intenti" del codice il più possibile
  • Configurazione in modalità di debug, per aggiungere informazioni sui simboli
  • Non striscia l'eseguibile (su sistemi Linux / Unix), per mantenere le informazioni simbolo più possibile per i debugger di usare

Quando si costruisce per Linux, mi piace essere in grado di stampare un pila backtrace da un gestore di segnale. Questo aiuta a eseguire il debug di crash (SIGSEGV) oppure mi permette di inviare un segnale al programma di avviare una traccia dello stack in fase di esecuzione. core dump può anche essere utile per il debug crash (di nuovo in Linux).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top