Programing

역추적()/backtrace_symbols() 기능 이름을 인쇄하는 방법?

c10106 2022. 5. 4. 21:15
반응형

역추적()/backtrace_symbols() 기능 이름을 인쇄하는 방법?

리눅스 관련backtrace()그리고backtrace_symbols()프로그램의 통화 추적을 생성할 수 있다.하지만 기능 주소만 출력하고 내 프로그램의 이름은 인쇄하지 않는다.어떻게 하면 그들이 함수 이름도 인쇄하게 할 수 있을까? 나는 프로그램을 컴파일해 보았다.-g게다가-ggdb. 아래 테스트 케이스는 다음과 같이 인쇄한다.


백트레이스 ------------./a.out³ [0x8048616]./a.out³ [0x8048623]/lib/libc.so.6(_libc_start_main+0xf3) [0x4a937413]./a.out³ [0x8048421]----------------------    

처음 두 개 항목에도 기능 이름을 표시했으면 좋겠는데foo그리고main

코드:

#include <execinfo.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>

static void full_write(int fd, const char *buf, size_t len)
{
        while (len > 0) {
                ssize_t ret = write(fd, buf, len);

                if ((ret == -1) && (errno != EINTR))
                        break;

                buf += (size_t) ret;
                len -= (size_t) ret;
        }
}

void print_backtrace(void)
{
        static const char start[] = "BACKTRACE ------------\n";
        static const char end[] = "----------------------\n";

        void *bt[1024];
        int bt_size;
        char **bt_syms;
        int i;

        bt_size = backtrace(bt, 1024);
        bt_syms = backtrace_symbols(bt, bt_size);
        full_write(STDERR_FILENO, start, strlen(start));
        for (i = 1; i < bt_size; i++) {
                size_t len = strlen(bt_syms[i]);
                full_write(STDERR_FILENO, bt_syms[i], len);
                full_write(STDERR_FILENO, "\n", 1);
        }
        full_write(STDERR_FILENO, end, strlen(end));
    free(bt_syms);
}
void foo()
{
    print_backtrace();
}

int main()
{
    foo();
    return 0;
}

기호는 동적 기호 표에서 가져왔으므로-rdynamic에 대한 선택권.gcc모든 기호가 테이블 안에 배치되도록 하는 깃발을 링커에 전달한다.

(GCC 매뉴얼링크 옵션 페이지 및/또는 glibc 매뉴얼백트레이스 페이지를 참조하십시오.)

이안 랜스 테일러의 뛰어난 리백트레이스가 이 문제를 해결한다.스택 언더블링을 처리하며 일반 ELF 기호와 DEMP 디버깅 기호를 모두 지원한다.

Libbacktrace는 못생길 수 있는 모든 기호를 내보낼 필요가 없으며, ASLR은 이를 깨지 않는다.

Libbacktrace는 원래 GCC 배포의 일부였다.이제 독립형 버전은 Github에서 찾을 수 있다.

https://github.com/ianlancetaylor/libbacktrace

실행 가능한 주소를 소스 코드 파일 이름+라인 번호에 매핑하려면 addr2line 명령을 사용하십시오.내놔!-f함수 이름도 가져오는 옵션.

또는 Libunwind를 사용해 보십시오.

부스트 역추적

다음 두 가지를 모두 인쇄하므로 매우 편리함:

  • Unmangled C++ 함수 이름
  • 줄넘기

널 위해 자동으로.

사용량 요약:

#define BOOST_STACKTRACE_USE_ADDR2LINE
#include <boost/stacktrace.hpp>

std::cout << boost::stacktrace::stacktrace() << std::endl;

나는 그것과 많은 다른 방법들에 최소한의 실행 가능한 예를 제공했다: C 또는 C++로 통화 스택을 인쇄

ret=== -1과 errno가 EINTER인 경우 위의 답변에는 버그가 있지만, ret를 복사한 것으로 계산해서는 안 된다(힘든 것이 싫으면 이것만으로 계정을 만들지 않을 것임

static void full_write(int fd, const char *buf, size_t len)
{
        while (len > 0) {
                ssize_t ret = write(fd, buf, len);

                if ((ret == -1) {
                        if (errno != EINTR))
                                break;
                        //else
                        continue;
                }
                buf += (size_t) ret;
                len -= (size_t) ret;
        }
}

참조URL: https://stackoverflow.com/questions/6934659/how-to-make-backtrace-backtrace-symbols-print-the-function-names

반응형