مدخلات لتحسين قابلية تصريف الكود بصرف النظر عن السجلات ورموز الخطأ

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

  •  24-09-2019
  •  | 
  •  

سؤال

بصرف النظر عن رموز الأخطاء ، وسلاسل الأخطاء والسجلات ، هل هناك أي ميزات أخرى يمكن دمجها في الكود لزيادة الحصول على معلومات التصحيح / التتبع أثناء وقت تشغيل الكود والتي يمكن أن تساعد في تصحيح مشكلات (أو إخبارنا بما يجري) في وقت التشغيل؟

هل كانت مفيدة؟

المحلول

إليك مثال على الرمز الذي يرسل stacktrace إلى ملف على خطأ تجزئة

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

في الوظيفة dumpstack, dbx يجب تغييرها لتناسب تصحيح الأخطاء الخاص بك ، مثل gdb بالنسبة إلى GNU Debugger ، تم استخدام هذا الرمز عندما كنت أقوم برمجة على AIX Box قبل بضع سنوات. لاحظ كيف يتم إعداد الإشارات ، وإذا حدث خطأ في SIGSEGV ، فإن المعالج يتفصل المكدس إلى ملف مع ملحق .dump. يوضح الكود خطأ التجزئة ويتفصل stacktrace.

هذا هو الكود المفضل لدي.

أتمنى أن يساعد هذا ، مع أطيب التحيات ، توم.

نصائح أخرى

  • بناء بدون تحسين ، للحفاظ على أكبر قدر ممكن من "نية" الكود
  • بناء في وضع التصحيح ، لإضافة معلومات الرمز
  • لا تقم بتجريد القابل للتنفيذ (على أنظمة Linux/UNIX) ، للحفاظ على أكبر قدر ممكن من معلومات الرموز لاستخدامها

عند بناء Linux ، أود أن أكون قادرًا على طباعة أ مكدس الخلفية من معالج الإشارة. هذا يساعد على تصحيح حوادث التصحيح (SIGSEGV) أو يسمح لي بإرسال إشارة إلى البرنامج لبدء مكدس الخلفي في وقت التشغيل. مقالب أساسية يمكن أن تكون مفيدة أيضًا في حوادث تصحيح الأخطاء (مرة أخرى في Linux).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top