分页: 1 / 1

GDB调试的信息怎么看?

发表于 : 2010-01-30 9:58
小锐同学
这个。。 :em06
让大家见笑了,我小菜鸟一只。

代码: 全选

lucifer@LovelyBaby:~/CC/MyJob$ cat copy1.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "apue.h"

#define BUFFSIZE 4096

int main(int argc, char *argv[])
{
	int fpw;//目标文件描述符
	int fpr;//源文件描述符
	int fpt;//临时文件描述符
	int n;//read()返回值
	char i;//临时变量
	FILE *fptF;//临时文件文件指针
	long int lseeko;//上次文件偏移量
	long int lseekc;//当前文件偏移量
	long int lseekn;//新的文件偏移量
	long int block;//需要复制的大小
	char buf[BUFFSIZE];//缓冲区

	if(argc != 5)
		printf("用法:源文件目录  目标文件目录  偏移量记录文件  要复制的数据大小(b)");
	if((fpr = open(argv[1],O_RDONLY)) < 0)
	{
		err_ret("%s: 文件打开失败", argv[1]);
		exit(1);
	}
	if((fpw = open(argv[2],O_CREAT | O_TRUNC)) < 0)
	{
		err_ret("%s: 文件打开失败", argv[2]);
		exit(1);
	}
	if((fpt = open(argv[3],O_RDWR)) < 0)
	{
		err_ret("%s: 文件打开失败", argv[3]);
		exit(1);
	}

	block = atol(argv[4]);//得到需要复制块的大小

	fptF = fdopen(fpt, "r+");//把文件描述符转换为文件指针
	if(fgets(buf, BUFFSIZE, fptF)==NULL)
		err_sys("读取偏移量记录文件出错");
	lseeko = atol(buf);//得到上次文件复制的偏移量
	
	close(fpt);
	remove(argv[3]);//删除偏移量记录文件

	if(lseeko != 0)//如果上次的偏移量不为零,设置偏移量
		while((n = lseek(fpw,lseeko,SEEK_SET)) == -1)
			err_sys("偏移量设置出错");

	while ((lseekn-lseeko) < block)
	{
		while ((n = read(fpr, buf, BUFFSIZE)) > 0)//读取数据到缓冲区
		{
			if(write(fpw, buf, n) != n)//从缓冲区写入数据
				err_sys("写入出错");
			lseekn = lseekn + BUFFSIZE;//得到当前文件偏移量
		}	
		if(n<0)
			err_sys("读取出错");
	}

	fpt = creat(argv[3],S_IRWXU);
	write(fpt, &lseekn, BUFFSIZE);

	exit(0);
}
lucifer@LovelyBaby:~/CC/MyJob$ gcc -g -rdynamic copy1.c
In file included from copy1.c:6:
apue.h: In function ‘err_doit’:
apue.h:107: warning: incompatible implicit declaration of built-in function ‘strlen’
apue.h:108: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘int’
apue.h:108: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘int’
apue.h:109: warning: incompatible implicit declaration of built-in function ‘strcat’
lucifer@LovelyBaby:~/CC/MyJob$ gdb ./a.out
GNU gdb (GDB) 7.0-ubuntu
Copyright (C) 2009 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".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/lucifer/CC/MyJob/a.out...done.
(gdb) r
Starting program: /home/lucifer/CC/MyJob/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ab8a87 in vfprintf () from /lib/libc.so.6
(gdb) q
A debugging session is active.

	Inferior 1 [process 5006] will be killed.

Quit anyway? (y or n) y
lucifer@LovelyBaby:~/CC/MyJob$ 
网上的教程GDB都会给出说哪句话错了,在第几行。

代码: 全选

xiaosuo@gentux test $ gcc -g -rdynamic d.c
xiaosuo@gentux test $ gdb ./a.out
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) r
Starting program: /home/xiaosuo/test/a.out

Program received signal SIGSEGV, Segmentation fault.
0x08048524 in dummy_function () at d.c:4
4               *ptr = 0x00;
(gdb)                      
哦?!好像不用一步步调试我们就找到了出错位置d.c文件的第4行,其实就是如此的简单。
而我的却不会说哪里错了,。但给出了这么两行 东西,怎么看这个东西呢?就是,怎么用这两行东西来找错呢?我知道内个SIGSEGV是试图访问不被允许的内存地址。

代码: 全选

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ab8a87 in vfprintf () from /lib/libc.so.6
还有个问题哦,就是用GDB调试的时候怎么让a.out带参数执行呢? :em06

Re: GDB调试的信息怎么看?

发表于 : 2010-01-30 10:11
小锐同学
这是doit的代码

代码: 全选

/*
 * Print a message and return to caller.
 * Caller specifies "errnoflag".
 */
static void
err_doit(int errnoflag, int error, const char *fmt, va_list ap)
{
    char    buf[MAXLINE];
   vsnprintf(buf, MAXLINE, fmt, ap);
   if (errnoflag)
       snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s\n",              107行
         strerror(error));                                                                                   108行
   strcat(buf, "");                                                                                            109行
   fflush(stdout);     /* in case stdout and stderr are the same */
   fputs(buf, stderr);
   fflush(NULL);       /* flushes all stdio output streams */
}

Re: GDB调试的信息怎么看?

发表于 : 2010-02-01 10:42
BigSnake.NET
用 bt 看回溯记录, 第一个应该是你调用 vfprintf 出了问题
第二个估计是你那个 ptr 出了问题,指向了非法地址

Re: GDB调试的信息怎么看?

发表于 : 2010-02-02 7:55
小锐同学
但是我的程序中并没有使用那个vfprinf()函数呀。 :em06

Re: GDB调试的信息怎么看?

发表于 : 2010-02-02 13:18
BigSnake.NET
13025700481 写了:但是我的程序中并没有使用那个vfprinf()函数呀。 :em06
那就是间接调用到了,都说了,看回溯记录

Re: GDB调试的信息怎么看?

发表于 : 2010-02-02 15:54
小锐同学
:em06

偶不认识回溯记录。

估计它也不认识我。

Re: GDB调试的信息怎么看?

发表于 : 2010-02-09 14:27
davyzhu
用valgrind来run一下吧。