Linux C++コードのデバッグをハンドルで教えます(静的ライブラリと動的ライブラリのデバッグを含む一歩手前)

17789 ワード

手でLinux C++コードのデバッグを教えます
ソフトウェアデバッグ自体は比較的複雑な活動であり、デバッグ者に明確な考え方を要求するだけでなく、デバッグ者自身のスキルにも高い要求がある.Windowsの下でVisual Studioは私たちのために多くの仕事をしてくれて、初心者が基本的に見ただけで得られるデバッグ体験を得ることができて、相対的に上手になりやすいです.しかしlinuxプラットフォームの下では、すべてが少し違っていて、GDBがどれだけ難しいかというわけではありませんが、visual studioに慣れた人にとっては最初は慣れていませんでした.しかし、Windowsプラットフォームの下でwindbgデバッグコードを使用する人にとっては、状況はずっと良いですが、考え方の転換とデバッグコマンドの再適応過程も必要です.GDBデバッグLinuxの下C/C++のドアを開けます.
Agenda
1.準備条件
2.GDBデバッグシート実行ファイル
3.GDB静的リンクライブラリのデバッグ
4.GDBデバッグ動的リンクライブラリ
 
1.準備条件
Linuxの下にvisual studioがないため、プログラムのコンパイルにはmakefileを借りる必要があります.次は簡単なmakefileを干しておきます.大きくなくて全部で、小さくて使えばいいです.
#makefile
CC=gcc CXX=g++ RM=rm -f CPPFLAGS=-g LDFLAGS=-g LDLIBS= AR=ar SRCS=main.cc functions.cc OBJS=$(subst .cc,.o,$(SRCS)) all: main main: $(OBJS) $(CXX) $(LDFLAGS) -o main $(OBJS) -L. $(LDLIBS) main.o: main.cc functions.h testobj.h functions.o: functions.h functions.cc clean: $(RM) $(OBJS) all-clean: clean $(RM) main

以下に関連する3つのファイルを直接copyで使用できます.
main.cc/functions.cc/functions.h
 1 #include<iostream>
 2 #include"functions.h"
 5 int main()
 6 {
 7 std::cout << "Enter two numbers:" << std::endl;
 8 int v1 = 0, v2 = 0;
 9 std::cin >> v1 >> v2;
10 std::cout << "The sum of " << v1 << " and " << v2
11 << " is " << v1 + v2 << std::endl;
12 
13 function();
14 
15 return 0;
16 }
1 #include<iostream>
2 int function(void)
3 {
4     std::cout << "I am in a function!" << std::endl;
5     return 0;
6 }
1 int function(void);

この4つのファイルを1つのディレクトリに入れると、このディレクトリの下でmakeを直接実行すると実行可能なファイルmainが生成されます.
2.GDBデバッグシート実行ファイル

solidmango@solidmango-pc:~/testmake/Test_L1$ gdb main GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7 Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> Reading symbols from main...done. (gdb) b 2 // Breakpoint 1 at 0x400a4a: file main.cc, line 2. (gdb) r // Starting program: /home/solidmango/testmake/Test_L1/main Breakpoint 1, main () at main.cc:7 7 std::cout << "Enter two numbers:" << std::endl;// (gdb) s Enter two numbers: 8 int v1 = 0, v2 = 0; (gdb) s // 9 std::cin >> v1 >> v2; (gdb) n 5 6 11 << " is " << v1 + v2 << std::endl; (gdb) s 10 std::cout << "The sum of " << v1 << " and " << v2 (gdb) s 11 << " is " << v1 + v2 << std::endl; (gdb) s The sum of 5 and 6 is 11 14 function(); (gdb)

 
3.GDB静的リンクライブラリのデバッグ
静的リンクライブラリのデバッグは、最終的なファイルがリンクされているため、単一の実行ファイルと似ています.静的リンクライブラリのデバッグには、2つの追加の2つの補助ファイルとmakefileとmainが必要です.ccは少し修正して、具体的に以下のように変更します:
#makefile
CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g
LDFLAGS=-g
LDLIBS=-ltest #changed
AR=ar

SRCS=main.cc functions.cc
OBJS=$(subst .cc,.o,$(SRCS))

all: main
main: $(OBJS) libtest.a #changed
$(CXX) $(LDFLAGS) -o main $(OBJS) -L. $(LDLIBS) 
main.o: main.cc functions.h testobj.h
functions.o: functions.h functions.cc

clean: $(RM) $(OBJS)

all
-clean: clean $(RM) main

main.cc/testobj.cc/testobj.h
#include<iostream>
#include"functions.h"
#include"testobj.h"

int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
std::cout << "The sum of " << v1 << " and " << v2
<< " is " << v1 + v2 << std::endl;

function();

TestObj();

return 0;
}

 
#include<iostream>
int TestObj(void)
{
    std::cout << "I am in TestObj!" << std::endl;
    return 0;
}
int TestObj(void);

実行結果は次のとおりです.
solidmango@solidmango-pc:~/testmake/Test_L1$ g++ -g -c -o testobj.o testobj.cc
solidmango@solidmango-pc:~/testmake/Test_L1$ ar rv libtest.a testobj.o
ar: creating libtest.a
a - testobj.o
solidmango@solidmango-pc:~/testmake/Test_L1$ make
g++  -g  -c -o main.o main.cc
g++  -g  -c -o functions.o functions.cc
g++ -g -o main main.o functions.o -L. -ltest 
solidmango@solidmango-pc:~/testmake/Test_L1$ ./main
Enter two numbers:
5
6
The sum of 5 and 6 is 11
I am in a function!
I am in TestObj!
solidmango@solidmango-pc:~/testmake/Test_L1$ 

 
4.GDBデバッグ動的リンクライブラリは動的リンクライブラリのデバッグと単一の実行ファイルの差が大きく、静的リンクライブラリのデバッグに対してmakefileのみを必要とする
少し修正して、具体的には以下のように変更します.
対応するダイナミックライブラリを生成し、copyをシステムディレクトリに
g++ -g -c -fPIC -o testobj.o testobj.cc
g++ -g  -shared -o libtest.so testobj.o
sudo cp libtest.so /lib/libtest.so

makefile
CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g
LDFLAGS=-g
LDLIBS=-ltest
AR=ar

SRCS=main.cc functions.cc
OBJS=$(subst .cc,.o,$(SRCS))

all: main
main: $(OBJS) libtest.so
    $(CXX) $(LDFLAGS) -o main $(OBJS) -L. $(LDLIBS) 
    
main.o: main.cc functions.h testobj.h

functions.o: functions.h functions.cc

clean:
    $(RM) $(OBJS)

all-clean: clean
    $(RM) main

solidmango@solidmango-pc:~/testmake/Test_L1$ gdb main GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7 Copyright (C) 2014 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-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from main...done. (gdb) b TestObj Breakpoint 1 at 0x400910 (gdb) r Starting program: /home/solidmango/testmake/Test_L1/main Enter two numbers: 7 8 The sum of 7 and 8 is 15 I am in a function! Breakpoint 1, 0x0000000000400910 in TestObj()@plt () (gdb) s Single stepping until exit from function _Z7TestObjv@plt, which has no line number information. TestObj () at testobj.cc:3 3 { (gdb) bt #0 TestObj () at testobj.cc:3 #1 0x0000000000400b05 in main () at main.cc:17 (gdb) info sharedlibrary From To Syms Read Shared Object Library 0x00007ffff7ddaae0 0x00007ffff7df54e0 Yes /lib64/ld-linux-x86-64.so.2 0x00007ffff7bd8850 0x00007ffff7bd89c5 Yes /lib/libtest.so 0x00007ffff792f5c0 0x00007ffff799299a Yes (*) /usr/lib/x86_64-linux-gnu/libstdc++.so.6 0x00007ffff752d4a0 0x00007ffff7673413 Yes /lib/x86_64-linux-gnu/libc.so.6 0x00007ffff720d610 0x00007ffff727c1b6 Yes /lib/x86_64-linux-gnu/libm.so.6 0x00007ffff6ff4ab0 0x00007ffff7004995 Yes (*) /lib/x86_64-linux-gnu/libgcc_s.so.1 (*): Shared library is missing debugging information. (gdb) list 1 #include<iostream> 2 int TestObj(void) 3 { 4 std::cout << "I am in TestObj!" << std::endl; 5 return 0; 6 } (gdb)

まとめ
本文はLinuxの下でGDBに基づく3種類の情況のデバッグ方式を総括して、その中に単一の実行可能なファイル、静的なリンク、動的なリンクを含んで、そして完全なmakefileを提供して、ソースのファイル、操作性はきわめて強くて、興味のある友达が自分で操作して練習することを提案して、みんなに役に立つことを望みます.