关于fopen电话的SIGABRT

时间:2013-09-27 21:57:50

标签: c linux gcc file-io gdb

我正在编写一段代码来检查文件是否存在。当用户传入一个只带有名称(没有斜杠)的文件参数时,我将使用PATH环境变量中的路径检查文件是否存在。我正在使用gcc编译Ubuntu并且一直在使用gdb。我发现导致SIGABRT的那条线但不确定信息告诉我什么。这是我第一次使用gdb。这是我的片段:

char* PATH = NULL;
PATH = (char*)getenv( "PATH" );
char* pathtoken = strtok( PATH, ":" );
int index = 0;

while ( pathtoken != NULL )
{
    index++;
    printf( "%s\n", pathtoken );
    char* pathdir = (char*)malloc( sizeof(pathtoken) );
    strcpy( pathdir, pathtoken );
    GetFullPath( pathdir, filename );
    inputstream = fopen( pathdir, "r" );

    if ( inputstream != NULL)
    {
        free( pathdir );
        break;
        }

        free( pathdir );
        pathtoken = strtok( NULL, ":" );
    }

char* GetFullPath( char* dirpath, char* filename )
{
    //Append back slash
    int len = strlen(dirpath);
    dirpath[len] = '/';
    dirpath[len+1] = '\0';

    return strcat( dirpath, filename );
}

它发生在fopen行的第一次迭代中。这是我的gdb输出

  

启动程序:/home/seapoe/Documents/OsClass/CodePractice/a.out text1   / usr / lib中/ lightdm / lightdm

     

断点1,main(argc = 2,argv = 0xbffff3a4)位于xssh.c:87

     

87 GetFullPath(pathdir,filename);

     

(gdb)next

     

89 inputstream = fopen(pathdir,“r”);

     

(gdb)print pathdir

     

$ 5 = 0x804c008“/ usr / lib / lightdm / lightdm / text1”

     

(gdb)print pathdir [strlen(pathdir)]

     

$ 6 = 0'\ 000'

     

(gdb)print pathdir [strlen(pathdir)+1]

     

$ 7 = 0'\ 000'

     

(gdb)print pathdir [strlen(pathdir)+2]

     

$ 8 = 0'\ 000'

     

(gdb)print pathdir [strlen(pathdir)-1]

     

$ 9 = 49'1'

     

(gdb)next

     

*检测到glibc /home/seapoe/Documents/OsClass/CodePractice/a.out:free():无效   下一个尺寸(正常):0x0804c018 * *

     

======= Backtrace:=========

     

/lib/i386-linux-gnu/libc.so.6(+ 0x75ee2)[0xb7e97ee2]

     

/lib/i386-linux-gnu/libc.so.6(+ 0x65db5)[0xb7e87db5]

     

/lib/i386-linux-gnu/libc.so.6(+的fopen 0x2B访问)[0xb7e87deb]

     

/home/seapoe/Documents/OsClass/CodePractice/a.out [0x8048a77]

     

/lib/i386-linux-gnu/libc.so.6(__ libc_start_main + 0xf3)[0xb7e3b4d3]

     

/home/seapoe/Documents/OsClass/CodePractice/a.out [0x8048771]

     

=======记忆图:========

     

08048000-0804a000 r-xp 00000000 08:01 536263 / home / seapoe / Documents / OsClass   /CodePractice/a.out

     

0804a000-0804b000 r - p 00001000 08:01 536263 /home/seapoe/Documents/OsClass/CodePractice/a.out

     

0804b000-0804c000 rw-p 00002000 08:01 536263 /home/seapoe/Documents/OsClass/CodePractice/a.out

     

0804c000-0806d000 rw-p 00000000 00:00 0 [heap]

     

b7df3000-b7e0f000 r-xp 00000000 08:01 394136 /lib/i386-linux-gnu/libgcc_s.so.1

     

b7e0f000-b7e10000 r - p 0001b000 08:01 394136 /lib/i386-linux-gnu/libgcc_s.so.1

     

b7e10000-b7e11000 rw-p 0001c000 08:01 394136 /lib/i386-linux-gnu/libgcc_s.so.1

     

b7e21000-b7e22000 rw-p 00000000 00:00 0

     

b7e22000-b7fc5000 r-xp 00000000 08:01 394115 /lib/i386-linux-gnu/libc-2.15.so

     

b7fc5000-b7fc7000 r - p 001a3000 08:01 394115 /lib/i386-linux-gnu/libc-2.15.so

     

b7fc7000-b7fc8000 rw-p 001a5000 08:01 394115 /lib/i386-linux-gnu/libc-2.15.so

     

b7fc8000-b7fcb000 rw-p 00000000 00:00 0

     

b7fd9000-b7fdd000 rw-p 00000000 00:00 0

     

b7fdd000-b7fde000 r-xp 00000000 00:00 0 [vdso]

     

b7fde000-b7ffe000 r-xp 00000000 08:01 394095 /lib/i386-linux-gnu/ld-2.15.so

     

b7ffe000-b7fff000 r - p 0001f000 08:01 394095 /lib/i386-linux-gnu/ld-2.15.so

     

b7fff000-b8000000 rw-p 00020000 08:01 394095 /lib/i386-linux-gnu/ld-2.15.so

     

bffdf000-c0000000 rw-p 00000000 00:00 0 [stack]

     

编程接收信号SIGABRT,已中止。

     __kernel_vsyscall()

中的

0xb7fdd424

调用GetFullPath后,您可以看到在fopen调用之前返回有效路径

2 个答案:

答案 0 :(得分:5)

char* pathdir = (char*)malloc( sizeof(pathtoken) );

错了。 sizeof(pathtoken)将为您提供系统上指针的大小(4或8)。 你想要

pathdir = strdup(pathtoken)

这也是错误的,因为你试图追加它。只需使pathdir成为MAX_PATH(或PATH_MAX,取决于您的操作系统)长度的char数组。

答案 1 :(得分:2)

问题在于:

sizeof(pathtoken)

sizeof运算符不起作用,它只是给你一个指针变量的大小,并没有提供足够的空间。你真正想要的是:

char* pathdir = malloc( strlen(pathtoken) + 1 );

或者,作为MK。状态,如果你在GetFullPath()期间没有尝试填充更多角色,这就是你想要的。为了补偿,要么按照他的建议设置足够大的静态数组,要么执行以下操作:

pathdir = GetFullPath( pathdir, filename );

....

char* GetFullPath( char* dirpath, char* filename )
{
    char * temp_path = malloc(strlen(dirpath) + strlen(filename) + 2);
    if ( temp_path == NULL ) {
        fprintf(stderr, "No memory!\n");
        exit(EXIT_FAILURE);
    }

    sprintf(temp_path, "%s/%s", dirpath, filename);
    free(dirpath);
    return temp_path;
}

请勿在{。

中转换malloc()的回报。