文件/目录复制程序在Xcode上运行,但是使用相同的编译器从命令行给出分段错误11(clang)

时间:2018-02-27 14:49:41

标签: c c99 c11

编辑2:这个问题似乎根植于被复制的文件总大小。我拿了我正在复制的源目录并从中删除了一些文件以减少存储空间,现在程序只能打印10份副本,再次总计大约150 mb,其中第11位将它带到165。减少或者在合理范围内(2-25个字符)增加文件名本身中的字符数似乎没有任何影响,所以我猜这个问题与目录路径缓冲区没有关系(无论如何,Xcode在这种情况下可能会得到相同的错误。)

这是否与bash脚本可以使用的堆栈内存上的硬帽有关?因为如果Xcode程序没有相同的限制,那么为什么它可以完美地运行超过6 gb的数据,但只能通过命令行(完全)运行大约150-160 mb。

如果它与命令行的限制或bash脚本可以使用多少内存有关,那么我的问题是如何才能正确地优化它以避免这种错误?

我正在编写一个程序,该程序接收给定目录的用户输入,并从参数创建一个副本及其内容在另一个目录中特定次数。当我使用clang从Xcode运行它时,它编译并运行完美,所有副本都没有问题,就我所见。当我尝试使用clang从命令行运行完全相同的程序时,它会产生大约4-5个副本,然后给出"分段错误11 :(核心转储)"。

编辑:它在Xcode上运行得很好,任意数量的副本(我已经尝试了总计大约6gb的150),当我从命令行运行它时可以运行4个副本(总共约160 mb),在第五天,它开始变得混乱。

当我使用lldb(backtrack)进行调试时,我得到了以下内容:

    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x68)
    * frame #0: 0x00007fffc32ce6a0 libsystem_c.dylib`flockfile + 4
      frame #1: 0x00007fffc32d183c libsystem_c.dylib`fwrite + 72
      frame #2: 0x0000000100001550 copy`fcopy(s_dir="/temp/", s_name="mov1 copy 7.mov", d_dir="/Users/Ziad/Downloads/temp 5/", d_name="mov1 copy 7.mov") at main.c:69
      frame #3: 0x0000000100001818 copy`copy_contents(source_dir="/temp", dest_dir="/Users/Ziad/Downloads/temp 5") at main.c:100
      frame #4: 0x0000000100001abc copy`dir_copy(search_d="/", copy_d="temp", dest_d="/Users/Ziad/Downloads/", count=25) at main.c:133
      frame #5: 0x0000000100001bbf copy`distribute(search_d="/", copy_d="temp", username="Ziad", c_each=25) at main.c:153
      frame #6: 0x0000000100001db7 copy`main(argc=1, argv=0x00007fff5fbffa80) at main.c:179
      frame #7: 0x00007fffc325c235 libdyld.dylib`start + 1

请求的大部分代码:

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

enum {
    FOUND = 0,
    NFOUND = 1,
    RERROR = 3,
    OERROR = 4,
    DUPLIC = 5,
} ErrorCodes;

typedef struct dirent   dirent;
typedef DIR             dir;
typedef FILE            file;

int dir_copy(char* search_d, char* copy_d, char* dest_d, size_t count);

int dir_check(char* search_d, char* find_d) {
    dir*    dirp = opendir(search_d);
    dirent* dp;
    while (dirp) {
        if ((dp = readdir(dirp)) != NULL) {
            if (strcmp(dp->d_name, find_d) == 0) {
                closedir(dirp);
                return FOUND;
            }
        }
        else {
            closedir(dirp);
            return NFOUND;
        }
    }
    return OERROR;
}

int dir_test(char* dir_t) {
    dir*    dirp = opendir(dir_t);
    if (dirp) {
        closedir(dirp);
        return FOUND;
    }
    else {
        return OERROR;
    }
}

int fcopy(char* s_dir, char* s_name, char* d_dir, char* d_name) {
    char    buf[BUFSIZ], sbuf[BUFSIZ], dbuf[BUFSIZ];
    size_t  n;
    sprintf(sbuf, "%s%s", s_dir, s_name);
    sprintf(dbuf, "%s%s", d_dir, d_name);
    file*   file_s = fopen(sbuf, "r");
    file*   file_d = fopen(dbuf, "w");

    while ((n = fread(buf, sizeof(char), sizeof(buf), file_s)) > 0) {
        if (fwrite(buf, sizeof(char), n, file_d) != n) {
            return -1;
        }
    }
    return 0;
}

void    copy_contents(char* source_dir, char* dest_dir) {
    dir*    dirp_s = opendir(source_dir);
    dir*    dirp_d = opendir(dest_dir);
    dirent* dp_s;
    dirent* dp_d;
    char    sbuf[BUFSIZ], dbuf[BUFSIZ], cbuf[BUFSIZ];
    char    sdbuf[BUFSIZ], ddbuf[BUFSIZ];
    sprintf(sdbuf, "%s", source_dir);
    sprintf(ddbuf, "%s", dest_dir);
    while (dirp_s && dirp_d) {
        errno = 0;
        if ((dp_s = readdir(dirp_s)) != NULL) {
            sprintf(sbuf, "%s/", sdbuf);
            sprintf(dbuf, "%s/", ddbuf);
            sprintf(cbuf, "%s%s", sbuf, dp_s->d_name);
            if (dir_test(cbuf) == FOUND) {
                if (strcmp(dp_s->d_name, ".") == 0 || strcmp(dp_s->d_name, "..") == 0) {
                    ;
                }
                else {
                    dir_copy(sbuf, dp_s->d_name, dbuf, 1);
                }
            }
            else {
                fcopy(sbuf, dp_s->d_name, dbuf, dp_s->d_name);
            }
        }
        else {
            closedir(dirp_s);
            closedir(dirp_d);
            break;

        }
    }
}

int dir_copy(char* search_d, char* copy_d, char* dest_d, size_t count) {
    int     dcount;
    char    sbuf[BUFSIZ], cbuf[BUFSIZ], dbuf[BUFSIZ];
    char    sdbuf[BUFSIZ], cdbuf[BUFSIZ], ddbuf[BUFSIZ];
    sprintf(sdbuf, "%s", search_d);
    sprintf(cdbuf, "%s", copy_d);
    sprintf(ddbuf, "%s", dest_d);
    if (dir_check(sdbuf, cdbuf) == FOUND) {
        for (dcount = 0; dcount < count; dcount++) {
            sprintf(sbuf, "%s%s", sdbuf, cdbuf);
            if (dcount > 0) {
                sprintf(dbuf, "%s%s %d", ddbuf, cdbuf, dcount);
            }
            else {
                sprintf(dbuf, "%s%s", ddbuf, cdbuf);
            }
            sprintf(cbuf, "%s %d", cdbuf, dcount);
            if (dir_check(search_d, cbuf) == FOUND) {
                return DUPLIC;
            }
            mkdir(dbuf, ACCESSPERMS);
            copy_contents(sbuf, dbuf);
        }
        return FOUND;
    }
    return NFOUND;
}

char* read_in(char* str, int buflen, FILE* stream)
{
    if (fgets(str, buflen, stream) != 0)
    {
        size_t len = strlen(str);
        if (len > 0 && str[len - 1] == '\n')
            str[len - 1] = '\0';
        return str;
    }
    return 0;
}

int main(int argc, char* argv[]) {
    dir_copy("/", "temp", "/Users/", 7);

    return 0;
}

dir_copy()获取要搜索的目录的第一个参数(search_d),即要复制的目录的第二个参数(copy_d),目标目录的参数({ {1}}),以字符串形式传入。最后一个参数是dest_d,它是应在size_t count中生成的copy_d的副本数。

0 个答案:

没有答案