gdb 로 c 언어 배우 기 (linux 환경 에서)
gdb 사용 안내
다음 C 프로그램 을 만 듭 니 다. minimal. c
int main()
{
int i =
1337;
return0;
}
printf 。 gdb C !
-g , gdb 。 。
$ gcc -g minimal.c -o minimal
$ gdb minimal
gdb prompt。 REPL,
(gdb) print 1 + 2
$1 = 3
!GDB print, C 。 GDB , GDB prompt help name-of-the-command。
:
(gbd) print (
int)
2147483648
$
2= -
2147483648
我们先忽略为什么2147483648 == -2147483648
。这里的重点是甚至一个计算在C中都可能会非常棘手,而GDB了解C的计算。
现在我们来在main函数中设置一个断点,然后开始运行程序:
(gdb)
breakmain
(gdb) run
이 프로그램 은 세 번 째 줄 에서 변수 i 가 초기 화 되 었 을 때 중단 되 었 습 니 다.i 가 초기 화 되 지 않 았 음 에 도 불구 하고 print 명령 으로 값 을 볼 수 있 습 니 다.
(gdb) print i
$3 = 32767
C 에서 초기 화 되 지 않 은 부분 변수의 값 이 정의 되 어 있 기 때문에 GDB 에서 다른 값 을 출력 할 수 있 습 니 다!
현재 줄 을 next 명령 으로 실행 할 수 있 습 니 다:
(gdb) next
(gdb) print i
$4 = 1337
x 명령 으로 메모리 보기
변 수 는 c 메모리 태그 연속 블록 입 니 다.하나의 변수의 메모리 블록 은 두 개의 숫자 로 결정 된다. 블록의 첫 번 째 byte 주소 와 블록의 크기 (bytes 단위).변수의 크기 는 변수의 유형 에 의 해 결정 된다.
C 의 특성 은 변수의 메모리 블록 에 직접 접근 해 야 한 다 는 것 입 니 다.연산 자 는 변수의 주 소 를 계산 할 수 있 고, sizeof 연산 자 는 변수 가 사용 하 는 메모리 크기 를 계산 할 수 있 습 니 다.
너 는 GDB 에서 이 두 개념 을 돌 릴 수 있다.
(gdb) print &i
$
5= (
int*)
0x7fff5fbff584
(gdb) print
sizeof(i)
$
6=
4
总而言之,i的内存块开始于0x7fff5fbff5b4,占用4个字节。我上面提到过一个变量的大小是由变量类型决定的。其实sizeof 操作可以直接作用在类型上:
(gdb) print
sizeof(
int)
$
7=
4
(gdb) print
sizeof(
double)
$
8=
8
这意味着,至少在你的机器上,int变量占用4个字节的空间,double占用8个。
使用GDB中的x命令,将会使它变成一个直接测试内存的强大的工具。X命令测量内存开始与一个特定的地址。它配备了一些格式化命令,提供精确的控制来实现你想检查多少字节,以及如何你想将它们打印出来。如果有疑问,在GDB prompt中执行help x。
&操作可以得到一个变量的地址,所以这意味着我们可以用x来执行&i并且来观察i值的原始字节。
(gdb) x/4xb &i
0x7fff5fbff584: 0x39 0x05 0x00 0x00
이 표 지 는 내 가 16 진수 4 개, 바이트 1 개 형식 으로 표시 하고 싶다 는 것 을 나타 낸다.나 는 i 의 메모리 크기 가 4 개의 바이트 이기 때문에 4 개의 바이트 를 보기 로 선택 했다.출력 정보 에서 바이트 마다 i 의 원본 주 소 를 표시 합 니 다.
마음 에 새 겨 야 할 디 테 일 은 intel 기기 에서 바이트 테스트 를 하면 바이트 가 'little - endian' 에 따라 정렬 된다 는 것 이다.
이 특성 을 더욱 잘 인식 할 수 있 는 방법 은 i 에 게 더 재 미 있 는 값 을 부여 한 다음 메모리 블록 을 다시 테스트 하 는 것 이다.
(gdb)
setvar i =
0x12345678
(gdb) x/
4xb &i
0x7fff5fbff584:
0x78
0x56
0x34
0x12
형식 을 ptype 명령 으로 보기
Ptype 은 아마 내 가 가장 좋아 하 는 명령 일 것 이다.C 표현 식 의 종 류 를 알려 줍 니 다:
(gdb) ptype i
type =
int
(gdb) ptype &i
type =
int*
(gdb) ptype main
type =
int(
void)
유형 은 C 에서 매우 복잡 할 수 있 지만, ptype 은 항상 볼 수 있 습 니 다.
포인터 와 배열
배열 은 C 에서 종 잡 을 수 없 는 개념 이다.이 장절 의 목적 은 간단 한 프로그램 을 작성 한 다음 에 GDB 에서 배열 을 이해 할 수 있 도록 실행 하고 테스트 하 는 것 이다.
Arrays. c 의 코드 는 다음 과 같 습 니 다.
int main()
{
int a[] = {
1,
2,
3};
return0;
}
-g , GDB , next :
$ gcc -g arrays.c -o arrays
$ gdb arrays
(gdb)
break main
(gdb) run
(gdb) next
a :
(gdb) print a
$
1 = {
1,
2,
3}
(gdb) ptype a
type =
int [
3]
gdb , x a :
(gdb) x/12xb &a
0x7fff5fbff56c: 0x01 0x00 0x00 0x00 0x02 0x00 0x00 0x00
0x7fff5fbff574: 0x03 0x00 0x00 0x00
x 0x7fff5fbff5dc 。a[0] , a[1] 。 a[2]。 sizeof a , 12 。
(gdb) print
sizeof(a)
$
2 =
12
, 。 , 。 , , ! , a :
(gdb) print a +
1
$
3= (
int*)
0x7fff5fbff570
a+1 int 0x7fff5fbff570
。 , x :
(gdb) x/4xb a + 1
0x7fff5fbff570: 0x02 0x00 0x00 0x00
주의 하 다 0x7fff5fbff 570 비 a 의 첫 번 째 바이트 주 소 는 0x7fff5fbff56c 대 4 입 니 다.int 가 4 개의 바이트 를 차지 하 는 것 을 감안 하면 a + 1 은 int 형 을 가리 키 는 지침 임 을 의미한다.
실제로 C 언어 에서 배열 색인 은 포인터 연산 의 문법 사탕 이다.a [i] 와 * (a + i) 등가.gdb 에서 해 보 세 요.
(gdb) print a[0]
$4 = 1
(gdb) print *(a + 0)
$5 = 1
(gdb) print a[1]
$6 = 2
(gdb) print *(a + 1)
$7 = 2
(gdb) print a[2]
$8 = 3
(gdb) print *(a + 2)
$9 = 3
, 。 ?
C , 。 : sizeof & 。
, & , : &a ?
, :
(gdb) x/4xb a
0x7fff5fbff56c: 0x01 0x00 0x00 0x00
(gdb) x/4xb &a
0x7fff5fbff56c: 0x01 0x00 0x00 0x00
하지만 이들 의 유형 은 다르다.우 리 는 a 의 퇴화 지침 이 머리 요 소 를 가리 키 는 것 을 보 았 기 때문에 하나의 유형 은 int * 일 것 이다.그리고 & a 에 대해 우 리 는 gdb 에 게 직접 물 어 볼 수 있다.
(gdb) ptype &a
type =
int(*)[
3]
& a 는 3 개의 정형 요 소 를 가 진 배열 지침 입 니 다.이것 은 a 가 & 작업 에서 퇴화 되 지 않 았 고 a 의 유형 은 int [3] 라 는 것 을 의미한다.
당신 은 지침 연산 을 통 해 a 의 퇴화 지침 과 & a 의 차 이 를 관찰 할 수 있 습 니 다.
(gdb) print a +
1
$
10= (
int*)
0x7fff5fbff570
(gdb) print &a +
1
$
11= (
int(*)[
3])
0x7fff5fbff578
注意到a加1的结果是向后加4个字节,相对的&a加1的结果是向后加12!
一个退化指针实际上是指向&a[0]的:
(gdb) print &a[
0]
$
11 = (
int *)
0x7fff5fbff56c 총결산
내 가 너 에 게 gdb 가 C 를 배 우 는 편리 한 도구 라 는 것 을 알 게 해 줄 수 있 기 를 바란다.표현 식 의 값 을 출력 할 수 있 습 니 다. 메모리 의 원본 바이트 도 볼 수 있 고, ptype 을 사용 하여 변수 형식 도 볼 수 있 습 니 다.
만약 당신 이 gdb 로 C 를 공부 하려 고 한다 면, 나 는 다음 과 같은 몇 가지 건의 가 있 습 니 다.
1. gdb 로 공부 하기 http://blog.csdn.net/physicsdandan/article/details/8076446 .
2. 탐색 구조 체 는 어떻게 메모리 에 저장 되 어 있 습 니까? 배열 과 무엇이 다 릅 니까?
3. gdb 의 disassemble 로 어 셈 블 리 언어 프로 그래 밍 을 배 웁 니 다!가장 재 미 있 는 연습 은 함수 호출 과정의 스 택 작업 방식 을 탐색 하 는 것 이다.
4. gdb 의 "tui" 모드 를 보십시오. 일반적인 gdb 에 있 는 ncurses 시도 층 을 제공 합 니 다.OS X 에 서 는 gdb 의 원본 코드 에서 설치 해 야 할 수도 있 습 니 다.
추가 (gdb 창 모드)
gdb 창 모드 로 들 어가 기: list 명령 이나 layot src 명령 또는 tui 명령
다른 코드 창 관련 명령:
info win 창 크기 layout next 를 다음 레이아웃 모드 layot prev 로 전환 하고 이전 레이아웃 모드 layot src 로 전환 합 니 다. 소스 코드 레이아웃 asm 만 표시 어 셈 블 리 코드 layout split 디 스 플레이 소스 코드 와 어 셈 블 리 코드 layout regs 만 표시 합 니 다. 레지스터 내용 추가 focus cmd / src / asm / regs / next / prev 현재 창 새로 고침 전환 모든 창 새로 고침 tui reg next 다음 레지스터 보이 기 tui reg system 디 스 플레이 시스템 레지스터 update 원본 코드 창 과 현재 실행 점 winheight name + / - line 을 업데이트 하여 name 창의 높이 tabset nchar 설정 tab 을 nchar 문자 로 설정 합 니 다.
info win 창 크기 보이 기
layot next 다음 레이아웃 모드 layot prev 에서 이전 레이아웃 모드 layot src 로 전환 소스 코드 레이아웃 asm 만 표시 어 셈 블 리 코드 layout split 디 스 플레이 소스 코드 와 어 셈 블 리 코드 layout regs 만 표시 합 니 다. 레지스터 내용 추가 focus cmd / src / asm / regs / next / prev 현재 창 새로 고침 전환 모든 창 새로 고침 tui reg next 다음 레지스터 보이 기 tui reg system 디 스 플레이 시스템 레지스터 update 원본 코드 창 과 현재 실행 점 winheight name + / - line 을 업데이트 하여 name 창의 높이 tabset nchar 설정 tab 을 nchar 문자 로 설정 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
용감한 바로 가기 및 우분투 응용 프로그램안녕하세요 여러분, 이 기사에서는 모든 사이트에서 pwa를 생성하고 실행기 응용 프로그램으로 추가하는 방법을 설명하고 싶습니다. 일부 웹사이트는 PWA로 설치를 허용하지 않지만 유사한 애플리케이션을 원합니다. 1. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.