other tools

其他工具

       精通调试代码并不是说学会使用GDB这样的调试器就行了这只是开端。

       为了增强调试技能,初学者程序员最好学会其中的集中调试工具,了解那种工具适合于调试那种程序错误,并识别发生程序错误时使用其中那个工具可以节省时间和精力。

充分利用文本编辑器

       最好的调试方法是一开始就不要有编程错误,而简单地充分利用一种支持编程的编辑器就可以达到这个效果。因为:

l  精通强大的编辑器可以缩短编写代码所需的时就爱你,具有自动缩排、单词补充和全文代码查询等特殊功能的编辑器对程序员是非常有利的;

l  优秀的编辑器确实可以帮到编码者在编写代码时捕获某些类型的程序错误。

 

MarkMakefile中可以使用patsubst关键字来进行文本查找和替换命令。

 

       vim中调用make非常方便,不需要退出编辑器,直接:make 即可,同时vim可以捕获编译器发出的所有消息,编辑器理解GCC输出内容的语法,知道何时发生编辑器警告或错误。发生错误时可以直接定位到第一个错误,然后使用:cnext或者:cprevious来显示下一个或上一个错误或者警告。

       Vim中可以使用K来查询man页面中的函数

充分利用编译器

       如果说编辑器是对抗程序错误的第一个武器,那么编译器就是第二个武器了,所有编译器都有能力扫描代码并查找常见错误,但是通常必须通过调用适当的选项来启用这种错误检查。

       对于GCC而言,如果不适用-Wall,就几乎没有必要使用GCC了,所以任何编译最好都加上-Wall选项。

C语言中的错误报告

       C语言中的错误报告是使用名为errno的老式机制完成的。系统与库调用的失败通常是由于设置了名为errno的全局定义整数变量,在大多数GNU/Linux系统上,error是在/usr/include/errno.h上声明的,因此,只要包含了这个头文件,就不必在源代码中声明extern int errno

       当一个系统或库调用失败时,它将errno设置为一个指示失败类型的值。检查errno的值,并采取适当的动作可以判断错误类型。比如可以使用函数perror或者strerror

       errno可以通过任何库函数或系统调用设置,无论它是成功还是失败。因为即便成功的函数调用能够设置errno,让人不能依赖errno告诉你是否发生了错误。因此使用errno最安全的方式为:

l  执行对库或者系统函数的调用;

l  使用函数的返回值判断时候发生了某个错误;

l  如果发生了某个错误,使用errno确定为什么发生这个错误。

库函数和系统调用的区别

       库函数是更高级别的,完全在用户空间里运行,并未程序员提供了更方便的做实际工作的函数接口。

       系统调用代表用户以内核模式工作,由操作系统本身的内核提供。

       库函数printf看上去类似于一般输出函数,但是它实际上只是格式化你提供给字符串的数据,并用低级系统调用write编写字符串数据,然后将数据发送到一个与终端的标准输出关联的文件中。

更好地使用straceltrace

       strace跟踪系统调用而ltrace跟踪库调用,这两个使用程序,有时比深度调试代码还快。

静态代码检查器:lint与其衍生

       静态代码检查器:扫描代码的工具,不编译代码,仅仅警告错误、可能的错误和与严格C语言编码标准的差距。

       衍生版本为splint:该软件的目标是帮助编写大部分有防御性、安全和尽可能少出错的程序,当然,改程序对组成有效代码的内容非常挑剔。

       很多程序员将splint没有报告警告看做一种极大的荣誉。当出现这种情况是,代码被声明为无lint的。

调试动态分配的内存

       动态分配的内存(Dynamically Allocated Memory, DAM)是程序用malloccalloc这样的函数从堆中请求的内存。

       查找DAM问题分麻烦,分为以下几类:

l  没有释放动态分配的内存;内存泄漏

l  malloc的调用失败;

l  DAM段之外的地址执行读写操作;访问错误

l  释放DAM段之后对DAM区域中的内存进行读写操作;访问错误

l  对动态内存的同一段调用两次free重复释放double free

Electric Fence

       Bruce Perens1988年写的,当EFence链接到代码中时,导致程序在发生下列情况之一时立即发生段错误并转出核心:

l  DAM边界之外执行读写操作;

l  对已经释放的DAM执行读写操作;

l  对没有指向malloc分配的DAM的指针执行free,包括重复释放的特殊情况。

比如,

gcc –g3 –Wall –std=c99 test.c –o test_with_efence outOfBound_with_efence  –lefence

gcc –g3 –Wall –std=c99 test.c –o test_with_efence outOfBound_without_efence  -lefence

可以对一个内存泄露但是没有编译失败的程序做测试。

GNU C库工具调试DAM问题

l  在调用任何与堆有关的函数钱调用函数mcheck

l  使用mtrace函数捕获内存泄露和重复释放;

fedora自动化编译autotools的使用

fedora自动化编译autotools的使用

具体操作步骤

l  准备好源码文件helloworld.c Makefile.am文件。

l  执行autoscan生成configure.scan,将configure.scan改为configure.in并修改configure.in

l  然后执行:

n  aclocal;

n  autoheader;

n  touch README NEWS AUTHORS ChangeLog

n  autoconf;

n  automake –add-missing;

n  ./configure;

n  make;

n  ./helloworld ;         运行程序

n  make dist            制作发布的包

n  make dist            制作发布的包并对其进行测试检查

n  make clean        清除make命令产生的目标文件及可执行文件

automake autoconf 自动化编译说明

利用autotools自动生成makefile文件,自动化编译自己的工程,autotools工具只需要用户输入简单的目标文件、依赖文件、文件目录就可以轻松地生成Makefile了。

首先安装autotools系列工具,包括aclocalautoscanautomakeautoheaderautoconf等。

可以通过rpm –qa | grep auto来查看各个应用程序,如果没有

yum install automake即可安装。

详细步骤:

1.建立自己的工程,编写源文件并创建Makefile.am

1)最顶层目录名为模块名 helloworld

源文件放在模块下面的src子目录,例如helloworld/src

2) src 下面,创建源文件main.c

3) helloworld目录下面创建Makefile.am文件(为Makefile.in的模板文件,.am扩展名是automake的缩写),内容如下:

SUBDIRS=src SUBDIRS=src

4) helloworld/src 目录下创建Makefile.am文件 内容如下:

bin_PROGRAMS=helloworld

helloworld_SOURCES=main.c

  bin_PROGRAMS=helloworld

  helloworld_SOURCES=main.c

其中,PROGRAMS表示要产生的是可执行文件,有多个可执行文件文件时,可用空格分开,而bin表示可执行文件的安装目录SOURCES表示生成可执行文件需要的源文件,有多个源文件时,也用空格分开。比如想生成两个可执行程序helloworld1helloworld2,那么就需要写成:

bin_PROGRAMS=helloworld1 helloworld2

helloworld1_SOURCES=main1.c

helloworld2_SOURCES=main2.c

2.运行 autoscan —创建autoconf的模板

autoscan      将生成configure.scanautoscan.log文件,它会在给定目录及其子目录树中检查源文件,若没有给定目录,就在当前目录及其子目录树中进行检查。它会搜索源文件以寻找一般的移植性问题并且创建一个文件configure.scan,通过这个文件我们可以创建autoconf需要的模版文件。

 autoscan

1).目录下面生成了configure.scan 文件,利用命令

mv configure.scan configure.in  将生成的configure.scan更改为autoconf需要的文件模版configure.in

mv configure.scan configure.in

configure.in 文件为autoconf 的模板文件,内容如下所示,其中#行为注释行:

# -*- Autoconf -*-

# Process this file with autoconf to produce a configure script.

 

 

AC_PREREQ([2.68])

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

AC_CONFIG_SRCDIR([src/main.c])

AC_CONFIG_HEADERS([config.h])

 

 

# Checks for programs.

AC_PROG_CC

 

 

# Checks for libraries.

 

 

# Checks for header files.

 

 

# Checks for typedefs, structures, and compiler characteristics.

 

 

# Checks for library functions.

 

 

AC_CONFIG_FILES([Makefile

src/Makefile])

AC_OUTPUT

#                                               -*- Autoconf -*-

# Process this file with autoconf to produce a configure script.

 

 

AC_PREREQ([2.68])

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

AC_CONFIG_SRCDIR([src/main.c])

AC_CONFIG_HEADERS([config.h])

 

 

# Checks for programs.

AC_PROG_CC

 

 

# Checks for libraries.

 

 

# Checks for header files.

 

 

# Checks for typedefs, structures, and compiler characteristics.

 

 

# Checks for library functions.

 

 

AC_CONFIG_FILES([Makefile

                 src/Makefile])

AC_OUTPUT

2). 修改configure.in文件

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

修改为:

AC_INIT(helloworld, 0.1, shaoguangleo@gmail.com)     =–初始化autoconf

AC_INIT(helloworld, 0.1, wang@gmail.com)   ==>初始化autoconf

并添加

AM_INIT_AUTOMAKE(helloworld, 0.1)         =–初始化automake 必须的宏,这个如果不添加就会导致在autoconf时出错,信息大概为configure.in:no proper invocation of AM_INIT_AUTOMAKE was found

AM_INIT_AUTOMAKE(helloworld, 0.1)  ==>初始化automake

3.运行 aclocal — 复制所有的宏命令

aclocal

aclocal

备注:configure.in 里面包含了一系列的宏命令,运行aclocal的目的是把工程需要的宏命令展开。(aclocal.m4 就是configure.in中用到的宏定义)会生成autom4te.cache文件夹和aclocal.m4文件。

4.运行autoheader —生成配置头文件的模板config.h.in并创建4个必要的文件

autoheader autoheader

 

备注:此时再创建4个必要的文件

touch README NEWS AUTHORS ChangeLog

README :描述模块的功能,用法和注意事项
NEWS :
描述模块最新的动态
AUTHORS :
模块的作者及联系方式
ChangeLog :
记录模块的修改历史

上述几个文件可以暂时为空。

5. automake –add-missing   生成Makefiel.in和所需要的脚本

automake –add-missing   其中add-missing选项会让automake自动添加一些必须的脚本文件。

automake -a

6. autoconf — 生成configure脚本

autoconf     autoconf

生成configure脚本

7. ./configure — 生成最终的Makefile文件

./configure

./configure

configure 通常有两个参数

1) –prefix 用来制定安装目录 linux默认/usr/local

2) –host 用于交叉编译

8 make =– 编译

make

make

9.make install 安装

make install

make install

 

10.make dist或者make distcheck =–发布软件包

make dist或者make distcheck

make dist或者make distcheck 

生成helloworld-0.1.tar.gz

autotools生成Makefile流程图

clip_image002

fedora automatic compile autotools usage

fedora自动化编译autotools的使用

具体操作步骤

l  准备好源码文件helloworld.c Makefile.am文件。

l  执行autoscan生成configure.scan,将configure.scan改为configure.in并修改configure.in

l  然后执行:

n  aclocal;

n  autoheader;

n  touch README NEWS AUTHORS ChangeLog

n  autoconf;

n  automake –add-missing;

n  ./configure;

n  make;

n  ./helloworld ;         运行程序

n  make dist            制作发布的包

n  make dist            制作发布的包并对其进行测试检查

n  make clean        清除make命令产生的目标文件及可执行文件

automake autoconf 自动化编译说明

利用autotools自动生成makefile文件,自动化编译自己的工程,autotools工具只需要用户输入简单的目标文件、依赖文件、文件目录就可以轻松地生成Makefile了。

首先安装autotools系列工具,包括aclocalautoscanautomakeautoheaderautoconf等。

可以通过rpm –qa | grep auto来查看各个应用程序,如果没有

yum install automake即可安装。

详细步骤:

1.建立自己的工程,编写源文件并创建Makefile.am

1)最顶层目录名为模块名 helloworld

源文件放在模块下面的src子目录,例如helloworld/src

2) src 下面,创建源文件main.c

3) helloworld目录下面创建Makefile.am文件(为Makefile.in的模板文件,.am扩展名是automake的缩写),内容如下:

SUBDIRS=src SUBDIRS=src

4) helloworld/src 目录下创建Makefile.am文件 内容如下:

bin_PROGRAMS=helloworld

helloworld_SOURCES=main.c

  bin_PROGRAMS=helloworld

  helloworld_SOURCES=main.c

其中,PROGRAMS表示要产生的是可执行文件,有多个可执行文件文件时,可用空格分开,而bin表示可执行文件的安装目录SOURCES表示生成可执行文件需要的源文件,有多个源文件时,也用空格分开。比如想生成两个可执行程序helloworld1helloworld2,那么就需要写成:

bin_PROGRAMS=helloworld1 helloworld2

helloworld1_SOURCES=main1.c

helloworld2_SOURCES=main2.c

2.运行 autoscan —创建autoconf的模板

autoscan      将生成configure.scanautoscan.log文件,它会在给定目录及其子目录树中检查源文件,若没有给定目录,就在当前目录及其子目录树中进行检查。它会搜索源文件以寻找一般的移植性问题并且创建一个文件configure.scan,通过这个文件我们可以创建autoconf需要的模版文件。

 autoscan

1).目录下面生成了configure.scan 文件,利用命令

mv configure.scan configure.in  将生成的configure.scan更改为autoconf需要的文件模版configure.in

mv configure.scan configure.in

configure.in 文件为autoconf 的模板文件,内容如下所示,其中#行为注释行:

# -*- Autoconf -*-

# Process this file with autoconf to produce a configure script.

 

 

AC_PREREQ([2.68])

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

AC_CONFIG_SRCDIR([src/main.c])

AC_CONFIG_HEADERS([config.h])

 

 

# Checks for programs.

AC_PROG_CC

 

 

# Checks for libraries.

 

 

# Checks for header files.

 

 

# Checks for typedefs, structures, and compiler characteristics.

 

 

# Checks for library functions.

 

 

AC_CONFIG_FILES([Makefile

src/Makefile])

AC_OUTPUT

#                                               -*- Autoconf -*-

# Process this file with autoconf to produce a configure script.

 

 

AC_PREREQ([2.68])

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

AC_CONFIG_SRCDIR([src/main.c])

AC_CONFIG_HEADERS([config.h])

 

 

# Checks for programs.

AC_PROG_CC

 

 

# Checks for libraries.

 

 

# Checks for header files.

 

 

# Checks for typedefs, structures, and compiler characteristics.

 

 

# Checks for library functions.

 

 

AC_CONFIG_FILES([Makefile

                 src/Makefile])

AC_OUTPUT

2). 修改configure.in文件

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

修改为:

AC_INIT(helloworld, 0.1, shaoguangleo@gmail.com)     =–初始化autoconf

AC_INIT(helloworld, 0.1, wang@gmail.com)   ==>初始化autoconf

并添加

AM_INIT_AUTOMAKE(helloworld, 0.1)         =–初始化automake 必须的宏,这个如果不添加就会导致在autoconf时出错,信息大概为configure.in:no proper invocation of AM_INIT_AUTOMAKE was found

AM_INIT_AUTOMAKE(helloworld, 0.1)  ==>初始化automake

3.运行 aclocal — 复制所有的宏命令

aclocal

aclocal

备注:configure.in 里面包含了一系列的宏命令,运行aclocal的目的是把工程需要的宏命令展开。(aclocal.m4 就是configure.in中用到的宏定义)会生成autom4te.cache文件夹和aclocal.m4文件。

4.运行autoheader —生成配置头文件的模板config.h.in并创建4个必要的文件

autoheader autoheader

 

备注:此时再创建4个必要的文件

touch README NEWS AUTHORS ChangeLog

README :描述模块的功能,用法和注意事项
NEWS :
描述模块最新的动态
AUTHORS :
模块的作者及联系方式
ChangeLog :
记录模块的修改历史

上述几个文件可以暂时为空。

5. automake –add-missing   生成Makefiel.in和所需要的脚本

automake –add-missing   其中add-missing选项会让automake自动添加一些必须的脚本文件。

automake -a

6. autoconf — 生成configure脚本

autoconf     autoconf

生成configure脚本

7. ./configure — 生成最终的Makefile文件

./configure

./configure

configure 通常有两个参数

1) –prefix 用来制定安装目录 linux默认/usr/local

2) –host 用于交叉编译

8 make =– 编译

make

make

9.make install 安装

make install

make install

 

10.make dist或者make distcheck =–发布软件包

make dist或者make distcheck

make dist或者make distcheck 

生成helloworld-0.1.tar.gz

autotools生成Makefile流程图

clip_image002