c编写linux+cd,Linux c/c++编程和调试

main.c/main.cpp

#include

int main(int argc, char *argv[])

{

printf("Hello world!\n");

return 0;

}

gcc -o hello main.c

./hello

g++ -o hello main.cpp

./hello

main.c->main.obj(lib文件)->hello

gcc/g++ 编译选项

gcc -o -O3 Wall hello main.c -l/homelzyrinc/ -L/home/zyr/ibs/ -lmath /home/zyr/ibs/ibmath.so

gcc- > .c,g++> .cpp

-o outile输出到指定的文件

-E 仅作预处理(code.i,不进行编译、汇编和链接。)

-S 仅编译到汇编语言(code.s),不进行汇编和链接。

-c 编译、汇编到目标代码(code.o),不进行链接含

-shared 生成共享目标文件。通常用在建立共享库时。我”

-static 禁止使用共享连接的

-llibrary 进行链接时搜索名为library的库-ldir把dir加入到搜索头文件的路径列表中。

-Ldir 把dir加入到搜索库文件的路径列表中。

例子: $ gcc -I/home/foo -L/home/foo -Itest test.c -o test

-Dname 预定义一个名为name的宏,

例子: $ gcc -DTEST_ CONFIG test.c -o test

-Dname =definition 预定义名为name,值为definition的宏。

-ggdb -ggdblevel

为调试器gdb生成调试信息。level 可以为1,2,3,默认值为2

-g -glevel

生成操作系统本地格式的调试信息。-g和-ggdb并不太相同,-g会生成gdb之外的信息。level取值同上。

-Wall 会打开-一些很有用的警告选项,建议编译时加此选项。

-w 禁止显示所有警告信息。

Optimization

-O0 禁正编译器进行优化。默认为此项。

-O -O1 尝试优化编译时间和可执行文件大小。

-O2 更多的优化,会尝试几乎全部的优化功能,但不会进行“空间换时间”的优化方法。

-O3 在-O2的基础上再打开一些优化选项:-finline-functions, -funswitch-loops 和-fgcse-after-reload。

-Os 对生成文件大小进行优化。它会打开-O2开的全部选项,除了会那些增加文伴大小的。

Makefile的编写

hello:main.o

g++ -o hello main.o

main.o:main.cpp

g++ -c main.cpp -o main.o

clean:

rm -f *.o hello

注意:代码第2,4, 6行都是以一个tab字符

了解Scons :跨平台的gnu make替代工具分其集成功能类似

autoconf/automake scons是一一个更简便,更可靠,更高效的编译软件。

Scons help doc :http://blog.sina.Com.cn/s/blog 5eb8ebcb0100sjlb.html

http://www.ibm.com/ developerworks/cn/linux/l-cn-sconsl

使用示例

func.h

#ifndef _FUNC_H_

#define _FUNC_H_

#include

void my_print();

#endif

func.cpp

#include "func.h"

void my_print()

{

printf("Hello world!\n");

return;

}

main.cpp

#include "func.h"

int main(int argc,char *argv[])

{

int i = 10;

my_print();

printf("i=%d\n", i);

return 0;

}

Makefile编写

hello:main.o func.o

g++ -g -o hello main.o func.o

func.o:func.cpp

g++ -g -c func.cpp -o func.o

main.o:main.cpp

g++ -g -c main.cpp -o main.o

clean:

rm -f main *.o

==================

Makefile的规则

目标:需要的条件(依赖)

命令(注意前面用tab键开头)

解释:

1目标可以是一个或多个,可以是Object File, 也可以是执行文件,甚至可以是一个标签。

2需要的条件就是生成目标所需要的文件或目标

3命令就是生成目标所需要执行的脚本,比如gcc,g++,rm等

上面的Makefile.针对的是一个源文件。那么假如一一个程 序项目里有多个源文件,应该怎么写Makefile呢?

Makefile

ovempass:main.o http.o httppost.o

g++ -g -o overpass :main.o http.o httppost.o -L. -lhiredis -lpthread

main.o:main.cpp

g++ -g -o main.cpp -o main.o

http.o:http.cpp

g++ -g -c http.cpp -o http.o

httpost.o:httppost.cpp

g++ -g -c httppost.cpp -o httppost.o

clean:

rm -f *.o overpass

其中,第2,4,6,8,10 行后面都是一个tab字符,这一点要特别注意,否则在执行make的时候,GCC会报错。

make -f 指定makefile名

Makefile的变量

OBJS = file1. o file2.o

CC = gcc

CFLAGS = -Wall -O -g

INC = /root/includes/

LIBS= /root/libs/

helloworld : $(OBJS)

$(CC) $(OBJS) -o helloworld

file1.o: file1.c

$(CC) $(CFLAGS) -C -I$(INC) file1.c -o file1.o -L$(LIBS) -lmath

file2.o : file2.c

$(CC) $(CFLAGS) -c -I$(INC) file2.c -o file2.o -L$(LIBS)-Imath

clean:

rm -rf' *o helloworld

.c.o规则

hello:file1.o file2.o

gcc -o hello file1.o file2.o

file1.o:file1.c

gcc -c file1.c -o file1.o

file2.o:file2.c

gcc -c file2.c -o file2.o

clean:

rm -f *.o hello

.c.o规则表示所有的.o文件都是依赖与相应的c文件的(暂时无法加上调试信息-g和-|等标志)

hello:file1.o fiel2.o

gcc -o $@ $^

.C.O:

gcc -c $< -o $@

clean:

rm -f *o hello

f544d0f15106?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image.png

Makefile .c.o

OBJS = file1.o file2. o

CC = gcc

CFLAGS = -Wall -O -g

INC= /root/includes/

LIBS = /root/libs/

helloworld : $(OBJS)

$(CC) -o $@ $^

.c.o:

$(CC) $(CFLAGS) -c -I$(INC)$< -o $@ -L$(LIBS) -lmath

clean:

rm -rf *.o helloworld

GDB 调试命令

gdb hello

List

b-break for func,line

r-run

c-continue

s-step, into

n-step over

p-print

q-quit

多线程:

gdb -p pid .

set scheduler-locking on

info threads

thread2

b functionname

c/s/n

objdump S hello//查看汇编代码

1简介

GDB(GNU Debugger)是GCC的调试工具。其功能强大,现描述如下:

GDB主要帮忙你完成下面四个方面的功能:

1.启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。

2.可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)

3.当程序被停住时,可以检查此时你的程序中所发生的事。

4.动态的改变你程序的执行环境。

2 生成调试信息

一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如:

gcc -g hello.c -o hello

g++ -g hello.cpp -o hello

如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用-g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他。

3 启动GDB的方法

gdb program

program 也就是你的执行文件,一般在当前目录下。

4 程序运行上下文

4.1 程序运行参数

set args 可指定运行时参数。(如:set args 10 20 30 40 50 )

show args 命令可以查看设置好的运行参数。

run 启动程序

4.2 工作目录

cd 相当于shell的cd命令。

pwd 显示当前的所在目录。

5 设置断点

5.1 简单断点

break 设置断点,可以简写为b

b 10 设置断点,在源程序第10行

b func 设置断点,在func函数入口处

5.2 多文件设置断点

在进入指定函数时停住:

C++中可以使用class::function或function(type,type)格式来指定函数名。如果有名称空间,可以使用namespace::class::function或者function(type,type)格式来指定函数名。

break filename:linenum -- 在源文件filename的linenum行处停住

break filename:function -- 在源文件filename的function函数的入口处停住

break class::function或function(type,type) -- 在类class的function函数的入口处停住

break namespace::class::function -- 在名称空间为namespace的类class的function函数的入口处停住

5.3 查询所有断点

info b

6条件断点

一般来说,为断点设置一个条件,我们使用if关键词,后面跟其断点条件。

设置一个条件断点

b test.c:8 if intValue == 5

7 维护停止点

delete [range...] 删除指定的断点,如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d。

比删除更好的一种方法是disable停止点,disable了的停止点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。

disable [range...]

disable所指定的停止点,如果什么都不指定,表示disable所有的停止点。简写命令是dis.

enable [range...]

enable所指定的停止点,如果什么都不指定,表示enable所有的停止点。简写命令是ena.

8 调试代码

run 运行程序,可简写为r

next 单步跟踪,函数调用当作一条简单语句执行,可简写为n

step 单步跟踪,函数调进入被调用函数体内,可简写为s

finish 退出进入的函数

until 在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体,可简写为u。

continue 继续运行程序,可简写为c

9 查看运行时数据

print 打印变量、字符串、表达式等的值,可简写为p

p count 打印count的值

10 自动显示

你可以设置一些自动显示的变量,当程序停住时,或是在你单步跟踪时,这些变量会自动显示。相关的GDB命令是display。

display 变量名

info display -- 查看display设置的自动显示的信息。

undisplay num(info display时显示的编号)

delete display dnums… -- 删除自动显示,dnums意为所设置好了的自动显式的编号。如果要同时删除几个,编号可以用空格分隔,如果要删除一个范围内的编号,可以用减号表示(如:2-5)

disable display dnums…

enable display dnums…

disable和enalbe不删除自动显示的设置,而只是让其失效和恢复。

11查看修改变量的值

(gdb) ptype width -- 查看变量width的类型

type = double

(gdb) p width -- 打印变量width 的值

$4 = 13

你可以使用set var命令来告诉GDB,width不是你GDB的参数,而是程序的变量名,如:

(gdb) set var width=47

在你改变程序变量取值时,最好都使用set var格式的GDB命令。

12 显示源代码

GDB 可以打印出所调试程序的源代码,当然,在程序编译时一定要加上 –g 的参数,把源程序信息编译到执行文件中。不然就看不到源程序了。当程序停下来以后,

GDB会报告程序停在了那个文件的第几行上。你可以用list命令来打印程序的源代码。默认打印10行,还是来看一看查看源代码的GDB命令吧。

list linenum

Print lines centered around line number linenum in the current source file.

list function

显示函数名为function的函数的源程序。

list

显示当前行后面的源程序。

list -

显示当前行前面的源程序。

一般是打印当前行的上5行和下5行,如果显示函数是是上2行下8行,默认是10行,当然,你也可以定制显示的范围,使用下面命令可以设置一次显示源程序的行数。

set listsize count

设置一次显示源代码的行数。(unless the list argument explicitly specifies some other number)

show listsize

查看当前listsize的设置。

core文件调试

生成CORE文件并调试CORE文件:

查看系统CORE文件设置:ulimit -a

打开CORE文件: ulimit -c unlimited 或者 ulimit -c 1000

禁用: ulimit -c 0

调试CORE文件:

gdb programbin corefile

where/bt

如果持久打开CORE,需要设置

/etc/profiles 中的:

No core files by default

ulimit -c unlimited

ulimit -S -c 0 > /dev/nuI 2>&1

使之生效:

source /etc/profile

linux下可以使用eclipse或Code::Blocks等工具编写c/c++程序

静态库的编写

firstlib.h

/*firstlib.h*/

void Print();

firstlib.c

/*firstlib.c*/

#include

#include "firstlib.h"

void Print()

{

printf("hello first static lib\n");

}

Makefile:

libfirstlib.a:firstlib.c

gcc -c firstlib.c

ar -rsv libfirstlib.a firstlib.o

clean:

rm -f *.o *.a

静态库的使用

firstlib.h

/*firstlib.h*/

void Print();

main.c

#include "firstlib.h"

void main(void)

{

Print();

}

Makefile:

testlib:main.o

gcc -o testlib main.c -L. -lfirstlib

clean:

rm -f *.o testlib

动态库的编写

firstlib.h

/*firstlib.h*/

void Print();

firstlib.c

/*firstlib.c*/

#include

#include "firstlib.h"

void Print()

{

printf("hello first so lib\n");

}

Makefile:

libfirstlib.so:firstlib.c

gcc -shared -fPIC -o libfirstlib.so firstlib.c

clean:

rm -f *.so *.o

动态库的使用

firstlib.h

/*firstlib.h*/

void Print();

main.c

#include "firstlib.h"

void main(void)

{

Print();

}

Makefile:

main:main.c

gcc -o main -I. main.c -L. -lfirstlib

clean:

rm -f main *.o

注意:

将动态库拷贝到/lib或/usr/lib或/usr/lib64/中去如: sudo cp libfirstlib.so usr/ib64

linux中查看程序使用了哪些动态库:

ldd helloworld.

objdump -tT xxx.so 查看xxx.so的符号表

nm -D xxx.so 列出动态库的符号清单

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值