Entrées pour améliorer debuggability de code en dehors des journaux et des codes d'erreur

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

  •  24-09-2019
  •  | 
  •  

Question

En dehors des codes d'erreur, les chaînes d'erreur et les journaux, sont-il d'autres caractéristiques qui peuvent être incorporés dans le code pour augmenter l'obtention debug / informations de suivi pendant l'exécution de code qui peut aider les problèmes de débogage (ou faites-nous savoir ce qui se passe) lors de l'exécution?

Était-ce utile?

La solution

Voici un exemple du code qui envoie un stacktrace à un fichier sur une erreur de segmentation

#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 */
}

Dans la fonction dumpstack, dbx doit être changé en fonction de votre débogueur, comme gdb pour GNU Debugger, ce code a été utilisé quand je programmation sur la boîte AIX il y a quelques années. Notez que les signaux sont mis en place, et si un défaut se produit SIGSEGV, le gestionnaire retourne la pile à un fichier d'extension .dump. Le code démontre la faute de segmentation et décharges du stacktrace.

C'est mon favori code.

Hope this helps, Meilleures salutations, Tom.

Autres conseils

  • Construire sans optimisation, pour préserver autant de « l'intention » du code que possible
  • Construire en mode débogage, d'ajouter des informations de symboles
  • Ne pas retirer l'exécutable (sur les systèmes Linux / Unix), de garder autant d'informations que possible pour symbole débogueurs à utiliser

Lors de la construction pour Linux, je voudrais être en mesure d'imprimer un pile trace à partir d'un gestionnaire de signaux. Cela aide les accidents de débogage (de SIGSEGV) ou me permet d'envoyer un signal au programme pour lancer une trace de la pile lors de l'exécution. décharges de base peut également être utile pour le débogage des accidents (encore une fois sous Linux).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top