linux যবহ কিভাবে একটি বিভাজন ত্রুটিতে লিনাক্সে একটি কোর ডাম্প তৈরি করবেন?




লিনাক্স সার্ভার (10)

সিস্টেম কল setrlimit ব্যবহার করে প্রোগ্রাম ডাম্প চালু কোর ভাল।

উদাহরণ:

#include <sys/resource.h>

bool enable_core_dump(){    
    struct rlimit corelim;

    corelim.rlim_cur = RLIM_INFINITY;
    corelim.rlim_max = RLIM_INFINITY;

    return (0 == setrlimit(RLIMIT_CORE, &corelim));
}

আমার লিনাক্সে একটি প্রক্রিয়া আছে যা একটি সেগমেন্টেশন ফল্ট পেয়েছে। এটি ব্যর্থ হলে কোর ডাম্প তৈরি করতে আমি কীভাবে বলতে পারি?


এটি উল্লেখযোগ্য যে আপনার যদি একটি systemd সেটআপ থাকে, তবে কিছুটা ভিন্ন। core_pattern systemd-coredump(8) মাধ্যমে কোর- core_pattern sysctl মানের মাধ্যমে কোর সেটগুলি সাধারণত পাইপ করা হবে। কোর ফাইলের আকারের রlimিটটি সাধারণত "সীমাহীন" হিসাবে কনফিগার করা হবে।

এটি coredumpctl(1) ব্যবহার করে কোর ডাম্প পুনরুদ্ধার করা সম্ভব হয়।

কোর ডাম্প, ইত্যাদির সংগ্রহস্থল coredump.conf(5) দ্বারা কনফিগার করা হয় coredump.conf(5) । Coredumpctl ম্যান পৃষ্ঠাতে কোর ফাইলগুলি কীভাবে পেতে হয় তা উদাহরণস্বরূপ আছে, তবে সংক্ষেপে, এটি এমন দেখতে হবে:

কোর ফাইল খুঁজুন:

[[email protected]]~$ coredumpctl list test_me | tail -1
Sun 2019-01-20 11:17:33 CET   16163  1224  1224  11 present /home/vps/test_me

কোর ফাইল পান:

[[email protected]]~$ coredumpctl -o test_me.core dump 16163

অপেক্ষা করুন। এটা স্বয়ংক্রিয়ভাবে করে। এটা করতে কোন প্রয়োজন


শেষ পর্যন্ত আমি যা করেছি তা gdb কে ক্র্যাশ করার আগে প্রক্রিয়াটিতে সংযুক্ত করেছিল, এবং তারপর সেটি সিগফ্টটি পেয়ে আমি generate-core-file কমান্ডটি কার্যকর করেছিলাম। একটি কোর ডাম্প যে বাধ্য প্রজন্মের।


একটি কোর ডাম্প প্রজন্মের প্রভাবিত হতে পারে যে আরো কিছু জিনিস আছে। আমি এই সম্মুখীন:

  • ডাম্পের জন্য ডিরেক্টরি লিখতে হবে। ডিফল্টরূপে এটি প্রক্রিয়াটির বর্তমান ডিরেক্টরি, তবে এটি /proc/sys/kernel/core_pattern নির্ধারণ করে পরিবর্তিত হতে পারে।
  • কিছু পরিস্থিতিতে, /proc/sys/fs/suid_dumpable মধ্যে কার্নেল মানটি কোর উত্পন্ন করা প্রতিরোধ করতে পারে।

এমন অনেক পরিস্থিতিতে রয়েছে যা মানব পৃষ্ঠাতে বর্ণিত প্রজন্মকে প্রতিরোধ করতে পারে - man core চেষ্টা করুন।


এটি আপনি কোন শেল ব্যবহার করছেন তা নির্ভর করে। আপনি bash ব্যবহার করছেন, তাহলে ulimit কমান্ডটি প্রোগ্রাম এক্সিকিউশন সম্পর্কিত বিভিন্ন সেটিংস নিয়ন্ত্রণ করে, যেমন আপনি কোর ডাম্প করতে চান কিনা। আপনি টাইপ করুন

ulimit -c unlimited

তারপরে তার প্রোগ্রামগুলি যে কোনও আকারের কোরকে ডাম্প করতে পারে। আপনি যদি চান তবে সীমাহীনতার পরিবর্তে 52M এর মতো একটি আকার নির্দিষ্ট করতে পারেন, তবে কার্যক্রমে এটির প্রয়োজন হতে পারে না কারণ কোর ফাইলের আকার সম্ভবত আপনার জন্য কোন সমস্যা হবে না।

Tcsh, আপনি টাইপ করতে চাই

limit coredumpsize unlimited

ডিফল্টরূপে আপনি একটি কোর ফাইল পাবেন। এই প্রক্রিয়াটির বর্তমান ডিরেক্টরিটি লেখার যোগ্য কিনা তা পরীক্ষা করুন, না কোনও কোর ফাইল তৈরি করা হবে না।


কোর ডাম্প সক্রিয় করার জন্য নিম্নলিখিত কাজ করুন:

  1. ইন /etc/profile ইন লাইন মন্তব্য:

    # ulimit -S -c 0 > /dev/null 2>&1
  2. /etc/security/limits.conf লাইনে মন্তব্য করুন:

    *               soft    core            0
  3. cmd limit coredumpsize unlimited কার্যকর করুন এবং cmd limit coredumpsize unlimited দিয়ে এটি পরীক্ষা করুন:

    # limit coredumpsize unlimited
    # limit
    cputime      unlimited
    filesize     unlimited
    datasize     unlimited
    stacksize    10240 kbytes
    coredumpsize unlimited
    memoryuse    unlimited
    vmemoryuse   unlimited
    descriptors  1024
    memorylocked 32 kbytes
    maxproc      528383
    #
  4. কোরফিল লিখিত কিনা তা পরীক্ষা করার জন্য আপনি cmd kill -s SEGV <PID> সহ সম্পর্কিত প্রক্রিয়াটি খুন করতে পারেন (প্রয়োজনে, কোন মূল ফাইল লিখিত না হলে এটি চেক হিসাবে ব্যবহার করা যেতে পারে):

    # kill -s SEGV <PID>

কোরফিলটি একবার লেখা হয়ে গেলে সংশ্লিষ্ট ফাইলগুলিতে আবার coredump সেটিংস নিষ্ক্রিয় করতে ভুলবেন না (1./2./3।)!


কোর ডাম্পগুলি কোথায় উৎপন্ন হয় তা পরীক্ষা করার জন্য, চালান:

sysctl kernel.core_pattern

বা:

cat /proc/sys/kernel/core_pattern

যেখানে %e প্রক্রিয়া নাম এবং %t সিস্টেম সময়। আপনি এটি /etc/sysctl.conf পরিবর্তন করতে পারেন এবং sysctl -p দ্বারা পুনরায় লোড করতে পারেন।

যদি মূল ফাইলগুলি তৈরি হয় না (এটি পরীক্ষা করে দেখুন: sleep 10 & killall -SIGSEGV sleep ), killall -SIGSEGV sleep চেক করুন: ulimit -a

আপনার কোর ফাইলের আকার সীমিত থাকলে চালান:

ulimit -c unlimited

এটা সীমাহীন করতে।

তারপরে আবার পরীক্ষা করুন, যদি কোর ডাম্পিং সফল হয় তবে আপনি নিম্নরূপ সেগমেন্টেশন ফল্ট ইঙ্গিতটি পরে "(ডাম্প ডাম্প)" দেখতে পাবেন:

বিভাজন ত্রুটি: 11 (কোর ডাম্প)

আরও দেখুন: কোর ডাম্প করা হয়েছে - কিন্তু কোর ফাইল বর্তমান ডিরেক্টরি নয়?

উবুন্টু

উবুন্টুতে কোর ডাম্পগুলি Apport দ্বারা পরিচালিত হয় এবং /var/crash/ অবস্থিত থাকতে পারে। যাইহোক, এটি স্থিতিশীল রিলিজে ডিফল্টরূপে নিষ্ক্রিয় করা হয়।

বিস্তারিত জানার জন্য, দয়া করে চেক করুন: উবুন্টুতে কোর ডাম্প কোথায় পাওয়া যায়?

ম্যাক অপারেটিং সিস্টেম

MacOS এর জন্য, দেখুন: কিভাবে Mac OS X এ কোর ডাম্প তৈরি করবেন?


সম্ভবত আপনি এইভাবে এটি করতে পারেন, এই প্রোগ্রামটি ডিবাগারে একটি সেগমেন্টেশন ফল্ট এবং শেলগুলি আটকাতে কিভাবে একটি বিক্ষোভ প্রদর্শন করা হয় (এটি AIX অধীনে ব্যবহৃত মূল কোড) এবং সেগমেন্টেশন ফল্টের বিন্দু পর্যন্ত স্ট্যাক ট্রেস প্রিন্ট করে। লিনাক্সের ক্ষেত্রে gdb ব্যবহার করার জন্য আপনাকে sprintf variable পরিবর্তন করতে হবে।

#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
    */
    /* This needs to be changed... */
    char dbx[160];

    sprintf(dbx, "echo 'where\ndetach' | dbx -a %d > %s.dump", getpid(), progname);
    /* Change the dbx to gdb */

    system(dbx);
    return;
}

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

এখানে আপনি এই ব্লগে here দেখানো হিসাবে কোর ডাম্প করতে gdb পেতে একটি প্যারামিটার যোগ করতে হতে পারে।





tcsh