backtrace(3)

الاسم
backtrace, backtrace_symbols, backtrace_symbols_fd - دعم لتصحيح التطبيق الذاتي

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <execinfo.h>

int backtrace(int size;
              void *buffer[size], int size);

char **backtrace_symbols(int size;
              void *const buffer[size], int size);
void backtrace_symbols_fd(int size;
              void *const buffer[size], int size, int fd);

الوصف
backtrace() تُرجع أثرًا رجعيًا للبرنامج المستدعي، في المصفوفة المشار إليها بواسطة buffer. الأثر الرجعي هو سلسلة استدعاءات الدوال النشطة حاليًا للبرنامج. كل عنصر في المصفوفة المشار إليها بواسطة buffer هو من النوع void *، وهو عنوان الإرجاع من إطار المكدس المقابل. تُحدد الوسيطة size الحد الأقصى لعدد العناوين التي يمكن تخزينها في buffer. إذا كان الأثر الرجعي أكبر من size، فسيتم إرجاع العناوين المقابلة لأحدث size استدعاءات دالة؛ للحصول على الأثر الرجعي الكامل، تأكد من أن buffer و size كبيران بما يكفي.

بالنظر إلى مجموعة العناوين التي أرجعتها backtrace() في buffer، تُترجم backtrace_symbols() العناوين إلى مصفوفة من السلاسل التي تصف العناوين رمزيًا. تُحدد الوسيطة size عدد العناوين في buffer. يتكون التمثيل الرمزي لكل عنوان من اسم الدالة (إذا كان يمكن تحديده)، وإزاحة سداسية عشرية داخل الدالة، وعنوان الإرجاع الفعلي (بالسداسي العشري). يُعاد عنوان مصفوفة مؤشرات السلاسل كنتيجة دالة لـ backtrace_symbols(). هذه المصفوفة مُخصصة بواسطة malloc(3) من قبل backtrace_symbols()، ويجب تحريرها بواسطة المستدعي. (السلاسل المشار إليها بواسطة مصفوفة المؤشرات لا تحتاج ولا ينبغي تحريرها.)

تأخذ backtrace_symbols_fd() نفس وسيطات buffer و size مثل backtrace_symbols()، ولكن بدلاً من إعادة مصفوفة من السلاسل إلى المستدعي، تكتب السلاسل، سطرًا واحدًا لكل سطر، إلى واصف الملف fd. لا تستدعي backtrace_symbols_fd() malloc(3)، وبالتالي يمكن استخدامها في المواقف التي قد تفشل فيها الدالة الأخيرة، ولكن انظر الملاحظات.

قيمة الإرجاع
تُرجع backtrace() عدد العناوين المُعادة في buffer، والذي لا يزيد عن size. إذا كانت القيمة المُعادة أقل من size، فقد خُزِن الأثر الرجعي الكامل؛ إذا كانت مساوية لـ size، فقد يكون قد قُطِع، وفي هذه الحالة، لا تُعاد عناوين أقدم إطارات المكدس.

عند النجاح، تُرجع backtrace_symbols() مؤشرًا إلى المصفوفة المُخصصة بواسطة malloc(3) من خلال الاستدعاء؛ عند الخطأ، يُعاد NULL.

السمات
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
الواجهة | السمة | القيمة
backtrace()، backtrace_symbols()، backtrace_symbols_fd() | سلامة الخيوط | MT-Safe

المعايير
GNU.

التاريخ
glibc 2.1.

ملاحظات
تفترض هذه الدوال بعض الافتراضات حول كيفية تخزين عنوان إرجاع الدالة على المكدس. لاحظ ما يلي:

•   قد يؤدي حذف مؤشرات الإطار (كما هو مُضمن في أي من مستويات التحسين غير الصفرية لـ gcc(1)) إلى انتهاك هذه الافتراضات.

•   لا تحتوي الدوال المُضمنة على إطارات مكدس.

•   يتسبب تحسين استدعاء الذيل في استبدال إطار مكدس بآخر.

•   لا تستدعي backtrace() و backtrace_symbols_fd() malloc() بشكل صريح، لكنهما جزء من libgcc، الذي يُحمّل ديناميكيًا عند أول استخدام. عادةً ما يؤدي التحميل الديناميكي إلى استدعاء malloc(3). إذا كنت بحاجة إلى أن لا تُخصص استدعاءات معينة لهاتين الدالتين ذاكرة (في معالجات الإشارات، على سبيل المثال)، فأنت بحاجة للتأكد من تحميل libgcc مسبقًا.

قد تكون أسماء الرموز غير متاحة دون استخدام خيارات رابط خاصة. بالنسبة للأنظمة التي تستخدم رابط GNU، من الضروري استخدام خيار الرابط -rdynamic. لاحظ أن أسماء الدوال "الثابتة" غير مكشوفة، ولن تكون متاحة في الأثر الرجعي.

أمثلة
يوضح البرنامج أدناه استخدام backtrace() و backtrace_symbols(). تُظهر جلسة الصدفة التالية ما قد نراه عند تشغيل البرنامج:

    $ cc -rdynamic prog.c -o prog
    $ ./prog 3
    backtrace() returned 8 addresses
    ./prog(myfunc3+0x5c) [0x80487f0]
    ./prog [0x8048871]
    ./prog(myfunc+0x21) [0x8048894]
    ./prog(myfunc+0x1a) [0x804888d]
    ./prog(myfunc+0x1a) [0x804888d]
    ./prog(main+0x65) [0x80488fb]
    /lib/libc.so.6(__libc_start_main+0xdc) [0xb7e38f9c]
    ./prog [0x8048711]

  مصدر البرنامج
    #include <execinfo.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    #define BT_BUF_SIZE 100

    void
    myfunc3(void)
    {
        int nptrs;
        void *buffer[BT_BUF_SIZE];
        char **strings;

        nptrs = backtrace(buffer, BT_BUF_SIZE);
        printf("backtrace() returned %d addresses\n", nptrs);

        /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
           would produce similar output to the following: */

        strings = backtrace_symbols(buffer, nptrs);
        if (strings == NULL) {
            perror("backtrace_symbols");
            exit(EXIT_FAILURE);
        }

        for (size_t j = 0; j < nptrs; j++)
            printf("%s\n", strings[j]);

        free(strings);
    }

    static void   /* "static" means don't export the symbol.  */
    myfunc2(void)
    {
        myfunc3();
    }

    void
    myfunc(int ncalls)
    {
        if (ncalls > 1)
            myfunc(ncalls - 1);
        else
            myfunc2();
    }

    int
    main(int argc, char *argv[])
    {
        if (argc != 2) {
            fprintf(stderr, "%s num-calls\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        myfunc(atoi(argv[1]));
        exit(EXIT_SUCCESS);
    }

انظر أيضًا
addr2line(1)، gcc(1)، gdb(1)، ld(1)، dlopen(3)، malloc(3)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.