Gdb 디버깅 정보 및 디버깅 원리

    Linux에서 C ++ 프로그램 개발의 경우 makefile 및 cmake와 같은 컴파일 도구를 사용하더라도 컴파일러 도구 그룹 gcc가 궁극적으로 호출됩니다 . 여기 언급 된 도구 세트 는 C 프로그램을 컴파일하는 데 사용되는 컴파일러 도구와 C ++ 프로그램간에 약간의 차이가 있기 때문입니다. 일반적으로 C 프로그램 컴파일 하는 데 gcc 를 사용하고  C ++ 프로그램을 컴파일하는 데 g ++ 를 사용합니다  . (아래 설명의 편의를 위해 별도로 명시하지 않는 한 gcc와 g ++를 구분하지 않으며 gcc라는 용어를 균일하게 사용합니다.)

이 과정에서 사용하는 운영 체제는 CentOS 7.0으로 데모의 편의를위한 루트 계정 데모입니다. 판독기의 시스템에 gcc 및 gdb가 설치되어 있지 않은 경우 yum  명령을 사용하여  설치할 수 있습니다.

# 安装 gcc
yum install gcc
# 安装 g++
yum install gcc-c++
# 安装 gdb
yum install gdb

일반적으로 프로그램은 디버깅이 필요하며, 디버그되는 각 코드 라인의 정보 (스택 정보, 변수 이름 및 함수 이름)를 명확하게 보려면 디버거에 디버깅 기호 정보 가 포함되어야합니다 . gcc를  사용하여 프로그램 컴파일 할 때  -g  옵션 을 추가  하면 디버깅 기호 정보가 컴파일 된 프로그램에 유지 될 수 있습니다. 예를 들어, 다음 명령은 디버깅 정보와 함께 hello_server 프로그램을 생성합니다.

gcc -g -o hello_server hello_server.c

그렇다면 hello_server에 디버깅 정보가 포함되어 있는지 판단하는 방법은 무엇입니까? 이 프로그램을 디버그하기 위해 gdb를 사용하고, gdb는 올바르게 읽은 프로그램의 디버깅 정보를 표시하고, 열린 Linux Shell 터미널에 gdb hello_server 를 입력  하여 표시된 결과 를  확인합니다.

[root@localhost testclient]# gdb hello_server
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7_4.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/testclient/hello_server...done.
(gdb)

gdb가 성공적으로로드되면 다음 정보가 표시됩니다.

Reading symbols from /root/testclient/hello_server...done.

즉, 심볼 파일 읽기가 완료되면 프로그램에 디버깅 정보가 포함되어 있음을 나타냅니다. -g  옵션 없이 다시 시도해 봅시다  :

[root@localhost testclient]# gcc -o hello_server2 hello_server.c
[root@localhost testclient]# gdb hello_server2
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7_4.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/testclient/hello_server2...(no debugging symbols found)...done.
(gdb)

-g  옵션 없이 hello_server 2 프로그램을 디버깅하고 생성하기 위해 gdb를 사용 하는  경우, 디버깅 기호 정보를 읽을 때 다음 프롬프트가 수신됩니다.

Reading symbols from /root/testclient/hello_server2...(no debugging symbols found)...done.

그런데 -g 옵션을 추가하지 않는 것 외에도 Linux strip 명령을 사용하여 프로그램에서 디버깅 정보를 제거 할 수도 있습니다. hello_server에서 strip 명령을 시도해 봅시다.

[root@localhost testclient]# strip hello_server
##使用 strip 命令之前
-rwxr-xr-x. 1 root root 12416 Sep 8 09:45 hello_server
##使用 strip 命令之后
-rwxr-xr-x. 1 root root 6312 Sep 8 09:55 hello_server

hello_server에서 strip 명령을 사용한 후 프로그램이 훨씬 더 작다는 것을 알 수 있습니다 (12416 바이트에서 6312 바이트로 감소). 우리는 일반적으로 프로그램이 문제없이 테스트 된 후 프로덕션 환경 또는 공식 환경으로 프로그램을 릴리스하므로 프로그램의 크기를 줄이거 나 프로그램 실행의 효율성을 높이기 위해 심볼 정보를 디버깅하지 않는 프로그램을 생성합니다.

gdb를 사용하여이 프로그램의 디버깅 정보가 실제로 제거되었는지 확인합니다.

[root@localhost testclient]# gdb hello_server
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7_4.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/testclient/hello_server...(no debugging symbols found)...done.
(gdb)

두 가지 추가 설명 :

  • 이 과정에서는 gcc가 예제로 사용되었지만 -g 옵션은 실제로 makefile 및 cmake와 같은 도구로 컴파일 된 Linux 프로그램에도 적용 할 수 있습니다.
  • 실제로 디버거를 생성 할 때 일반적으로 -g 옵션을 추가해야 할뿐만 아니라 컴파일러의 프로그램 최적화 옵션을 끄는 것이 좋습니다. 컴파일러의 프로그램 최적화 옵션에는 일반적으로 O0에서 O4까지 5 개의 레벨이 있습니다 (첫 번째 O0은 문자 O에 숫자 0을 더한 것임), O0은 최적화가 없음을 의미하고, O1에서 O4까지 최적화 수준이 점점 높아지고 있으며, O4 최고입니다. 이것의 목적은 디버깅을위한 것이며, 심볼 파일에 표시되는 디버깅 변수는 소스 코드와 완전히 일치 할 수 있습니다. 예를 들어, 다음 코드를 가정하십시오.
  int func()
  {
      int a = 1;
      int b = a + 1;
      int c = a + b;
      return a + b + c;
  }

  int main()
  {
      int a = func();
      printf("%d\n", a);
  }

이 코드에서는 main () 함수에서 func () 함수가 호출되기 때문에 func () 함수의 값을 컴파일 중에 직접 계산할 수 있습니다. 최적화 옵션이 켜져 있으면이 함수의 로컬 변수는 실제로 디버그 됨. a, b, c는 직접 값으로 대체됩니다. (즉, 컴파일러가 계산 한 값, a는 1을 직접 사용하고, b는 2를 직접 사용하고, c는 3을 직접 사용하므로 a 및 c a 및 b 명령어), func () 함수도 최적화 될 수 있습니다. 이 경우 디버거가 표시하는 코드와 실제 코드가 다를 수있어 문제 해결에 어려움이있을 수 있습니다. 물론 위에서 언급 한 최적화 현상이 확실히 발생하는지 여부에 따라 컴파일러의 버전에 따라 동작이 다를 수 있습니다. 한마디로 디버그 파일을 생성 할 때 컴파일러 최적화 옵션을 끄는 것이 좋습니다 .

요약

이 강의에서는 주로 gdb와 같은 도구의 설치와 디버깅을위한 디버깅 심볼의 중요성을 소개하는 동시에 디버깅의 정확성에 대한 컴파일러 최적화 옵션의 영향에주의를 기울여야합니다.

추천

출처blog.csdn.net/weixin_38293850/article/details/107974741