0

ここには本当に奇妙な問題があり、オンラインで答えを見つけることができませんでした。

errno を読み取ろうとしたときに segfault が発生したことは、printf ステートメントでデバッグした後に表示されます。問題のある行を 1 行ずつコメント アウトすると、segfault が発生するため、readdir() 呼び出しがディレクトリ ストリームの最後に到達して NULL を返した後、errno へのすべての参照をコメント アウトする必要がありました。

それでも、後で別の自動変数 file_count にアクセスしようとすると、コードはセグメンテーション違反を起こします。

何が起こっている?これはスタックオーバーフローですか?どうすれば止められますか?

必要に応じて、コードを以下に示します。問題のある errno への参照はすべて削除され、最後から 2 番目の行を正常に実行した後、プログラムは segfault しますprintf("printing file_count\n");

EDIT1: GDB バックトレースは次のとおりです。

#0  0xc95bf881 in strcpy () from /usr/lib/libc.so.1
#1  0x08051543 in dir_get_list (user=0x8047b88 "user1") at maildir.c:231
#2  0x08050f3e in main (argc=4, argv=0x80479f4) at maildir.c:43

END EDIT1

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>

#define MAX_FILENAME_LENGTH 255
#define MAX_USERNAME_LENGTH 40
#define MAX_PASSWORD_LENGTH 20


typedef int bool;

#define true 1
#define false 0


struct files_struct{
    /*The number of email messages in a maildir.*/
    int count; 

    /*A pointer to an array of pointers to the strings of the filenames. */
    char **FileNames;

    /*A pointer to an array of ints that give the corresponding size of the file.*/
    int  *FileSize;
};

typedef struct files_struct FilesStruct;


void dir_set_path(char* path);
bool check_user(char* username, char* pass);
FilesStruct* dir_get_list(char* user);
void delete_mail(char* user, char* filename);
char* get_file(char* user, char* filename);



FilesStruct* dir_get_list(char* user){
    char maildir_name[MAX_FILENAME_LENGTH];
    DIR * maildir_fd;
    struct dirent *maildir_p;

    strcpy(maildir_name,"./");
    strncat(maildir_name,user,MAX_USERNAME_LENGTH);
    strcat(maildir_name,"/");

    if((pthread_mutex_lock(&maildir_root_mutex))<0)
    perror("ERROR on locking maildir_root_mutex");
    printf("Opening directory ""%s""\n",maildir_name);
    if((maildir_fd = opendir(maildir_name))==NULL)
    perror("ERROR on opendir");

    int file_count = 0;

    /* scan over entire directory, counting number of files to that data can be properly malloced */
while(1){
    if((maildir_p = readdir(maildir_fd))==NULL){
        closedir(maildir_fd);
        printf("breaking loop\n");
        break;
    }
    char file[MAX_FILENAME_LENGTH+1];
    strcpy(file,maildir_p->d_name);

    printf("File %d: '%s'\n",file_count+1,maildir_p->d_name);
    /* if the file is a file other than an email */
    if(!strcmp(".",file)||!strcmp("..",file)||!strcmp("pass",file)||!strcmp(".svn",file)){
        printf("Continuing without incrementing file_count\n");
        continue;
    }
    file_count++;
}
printf("%u\n",maildir_fd);
printf("printing file_count\n");
printf("%d",file_count);
printf("file_count printed successfully");

/* 追加コード省略 */

4

1 に答える 1

0

最近これに出会いました。私の例では、別のモジュールが次のように宣言していました。

int errno = 0;

#include errno.h の代わりに、グローバルとして。「適切な」errno を使用するコードは、すぐにセグメンテーション違反になります。

于 2016-11-04T09:01:05.580 に答える