初学Linux--编辑环境2(调试、库)

来源:互联网 发布:琉璃神社app备用域名 编辑:程序博客网 时间:2024/06/14 23:20

程序调试

错误处理

使用标准错误输出

标准错误输出就是用于向标准错误输出设备输出错误信息的,其文件描述符为2,在标准I/O库中,定义为stderr。默认状态下,标准错误输出的内容在屏幕上,利用这一特性,编程人员可以在程序的不同地方输出所需要的调试信息或者错误提示代码。

使用errno全局变量

linux编程下,系统预先定义了全局变量errno。每当调用函数或者系统调用失败,由系统内核将一个整形的错误代码保存至errno,errno变量的声明位于头文件errno.h中。为了更方便的查看错误的详细信息,linux系统提供了连个格式化错误信息的函数:perror和strerror。

#include<stdio.h>void perror(_const char*_s)

_s是一个指向字符串的指针。调用该函数后,将向标准输出设备输出“s:错误的详细信息”

#include<string.h>char*strerror(int_errnum)

_errnum是错误的值,可以直接使用errno。调用后将返回_errnum对应的详细错误信息。

使用错误信号处理

前两者都是在预知的情况下进行的,当编程人员不知道何时会出现异常,就可以使用错误信号处理。用户通过捕获错误信息进行处理

使用assert断言

断言是程序员编程时可以预知相应的状态,如某个表达式或某个变量的值,此时对该变量或者条件表达式使用断言。一旦该值与所预想的不符合则输出错误信息并结束运行。

#include<assert.h>void assert(int expression)

expression值为假,先向标准错误输出打印一条信息,然后通过abort来终止程序运行

内存泄漏的检查

1.通过ps命令查看内存消耗情况,看看内存是否动态持续增长。
2.通过代码分析工具对代码进行分析,根据分析报告判断是否存在内存泄漏

gdb介绍

gdb可以使用户在程序运行时观察程序的内部结构和内存的使用情况。要使用gdb,首先需要在编译过程中使用-g选项,生成gdb工作所必需的调试信息,另外要调试的可执行程序需要有源代码。
gdb启动的两种方法
1.运行gdb可执行文件名启动调试
2.先启动gdb,再执行file命令装入待调试的可执行程序
gdb的基本功能

file:装入想要调试的可执行文件kill:终止正在调试的程序list:列出一行源代码next:执行一行源代码,但不进入函数内部step:执行一行源代码,进入函数内部run:执行当前被调试的程序whatis:显示变量的数据类型print:显示数据,调用程序中的函数或者显示复杂的组合数据类型的值break:在代码里设置断点info break:显示当前断点的信息delete breakpoint:删除断点disable /enable breakpoint:临时禁用断点make:不退出gdb重新生成可执行文件shell:不退出gdb执行shell命令

执行run命令时,可以向被执行的程序传递参数。可以通过set args修改程序运行时的命令行参数,命令行参数使用后,如果run命令没有给参数,则使用上一次的参数。可以通过show args查看当前调试程序的命令行参数

创建与使用库

函数库介绍

1.系统函数库的使用
Linux系统提供的开发函数库位于/usr/bin和/bin目录下。使用系统函数库只需要在源程序中包含相应头文件即可。可以通过执行命令ar查询系统函数库的组成。查看函数的内容的过程如下ar tv libc.a.
如果需要查看某个目标问价中提供那些函数,可以先通过ar命令的x选项将目标文件从函数库中分离出来,再执行nm命令查看相应的目标文件中提供哪些函数,例如:ar x libc.a fprintf.o
nm fprintf.o

2.用户自定义函数库的创建和使用
(1)要形成用户自定义的函数库需要经过一下几个步骤:1.将功能整理成函数;2.将函数编译成目标文件;3.将目标文件打包成函数库,执行ar命令的c参数(新建)或r参数(附加)即可。
(2)函数库创建完成后,要在用户的程序中引用需要经过一下几个步骤:1.在源程序中包含相关头文件的信息;2.在源程序中调用函数库中相关的函数;3.在连接时通过-l选项指定要链接的函数库。

系统调用

linux系统下的编程过程中,还可以使用系统调用。系统调用是操作系统开放给用户的调用接口。实际上也是一种该函数,不过执行中需要由用户态切换到核心态。从可移植性来看,库函数更好;从执行效率来看,系统调用更高。

通常情况下,进程是不能访问内核的。它不能访问内核所占内存空间也不能调用内核函数。这是cpu的硬件保护措施决定的,也就是所谓“保护模式”。系统调用是一个例外,linux中处理系统调用类似中断,每个系统调用都有唯一的系统调用号作为标识,内核维护一张系统调用表,表中元素是系统调用函数的起始地址,而系统调用号就是系统调用在调用过程中的的偏移量。在进行系统调用时只要指定对应的系统调用号即可,系统调用的参数传递是通过寄存器完成的。Linux最多允许向系统调用传递6个参数,分别是%ebx、%ecx、%edx、%esi、%edi、%ebp,若寄存器已经被使用,需要在传参前把寄存器状态保存下来,系统调用后再恢复。

动态库的创建与使用

Linux系统下要创建动态链接库,需要经过以下步骤:1.编译时指定-fPIC选项。该选项通知gcc编译器产生可以重定位的与位置无关的目标代码;2.链接是指定-shared选项。通过者这个选项,使gcc生成动态链接库。
调用动态链接库有两种方式:
1.设置环境变量LD_LIBRARY_PATH
2.通过dlopen系列函数完成。

dlopen:打开动态链接库并且映射到当前进程的内存,返回句柄。声明在

#include<dlfcn.h>void*dlopen(_const char*_file,int _mode)

_file:动态链接库文件路径。
_mode:打开方式。一种是RTLD_LAZY只打开动态链接库文件,暂时不解析外部对动态库的应用,直到动态库函数被引用;一种是RTLD_NOW,打开文件在dlopen返回前解析所有的对动态库的引用

dlsym:返回一个指向被请求入口点的指针

void*dlsym(void*_restrict_handle,_const char*_restrict_name)

_handle:动态链接库的句柄,该句柄由dlopen返回
-name:要调用的动态链接库中的的函数名称

dlclose:用来关闭已经打开的动态链接库

int dlclose(void*_handle)

_handle:输入动态链接库句柄

dlerror:用于输出动态库操作过程中的错误信息。一般情况下在调用dlopen函数或者dlsym函数失败时调用

char*dlerror(void);

参考文献《Linux编程从入门到精通》