Невозможно запустить приложение через терминал, но приложение отлично работает в XCode

Я работаю над lilgp, который является инструментом на языке C для генетического программирования. Проблема, с которой я сталкиваюсь, заключается в том, что я использую XCode для проекта, и он работает нормально и показывает правильный вывод через терминал. Но когда я пытаюсь запустить то же приложение в DerivedData моего проекта в XCode, я получаю ошибку сегментации (11)

Затем я проверил консоль в Utilities для ошибок, которые показывают ошибку, подобную этой

    Process:               Theisis [9325]
Path:                  /Users/USER/Library/Developer/Xcode/DerivedData/Theisis-gszeehddtmnlkqdbicpeffygvkcw/Build/Products/Release/Theisis
Identifier:            Theisis
Version:               0
Code Type:             X86-64 (Native)
Parent Process:        bash [8987]
Responsible:           Terminal [299]
User ID:               501

Date/Time:             2016-09-11 01:05:25.158 +0500
OS Version:            Mac OS X 10.11.6 (15G31)
Report Version:        11
Anonymous UUID:        4063B9C3-F525-D9BD-EF5E-358810571673

Sleep/Wake UUID:       CA5341A7-C252-4C76-B694-7F2DAE196F79

Time Awake Since Boot: 57000 seconds
Time Since Wake:       1600 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000068

VM Regions Near 0x68:
--> 
    __TEXT                 0000000100c4e000-0000000100c6a000 [  112K] r-x/rwx SM=COW  /Users/USER/Library/Developer/Xcode/DerivedData/Theisis-gszeehddtmnlkqdbicpeffygvkcw/Build/Products/Release/Theisis

 Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_c.dylib               0x00007fff93a8b09e flockfile + 4
1   libsystem_c.dylib               0x00007fff93a8d463 fscanf + 156
2   Theisis                         0x0000000100c57853 app_initialize + 195 (app.m:614)
3   Theisis                         0x0000000100c4f245 main + 453 (main.m:205)
4   libdyld.dylib                   0x00007fff8e0575ad start + 1

Thread 0 crashed with X86 Thread State (64-bit): 
  rax: 0x00007fff5efb1970  rbx: 0x0000000000000000  rcx: 0x00000b0000000000  rdx: 0x0000000100c6aa8c
  rdi: 0x0000000000000000  rsi: 0x0000000100c675d4  rbp: 0x00007fff5efb1860  rsp: 0x00007fff5efb1860
   r8: 0x00000000fffffffc   r9: 0x00007fff740b1c10  r10: 0x00007fff97709e01  r11: 0x00007fff93a8d3c7
  r12: 0x450022575a4d98d4  r13: 0x0000000000000000  r14: 0x0000000100c675d4  r15: 0x0000000000000000
  rip: 0x00007fff93a8b09e  rfl: 0x0000000000010246  cr2: 0x0000000000000068

Logical CPU:     4
Error Code:      0x00000004
Trap Number:     14

VM Region Summary:
ReadOnly portion of Libraries: Total=176.1M resident=0K(0%) swapped_out_or_unallocated=176.1M(100%)
Writable regions: Total=19.6M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=19.6M(100%)

                                VIRTUAL   REGION 
REGION TYPE                        SIZE    COUNT (non-coalesced) 
===========                     =======  ======= 
Activity Tracing                  2048K        2 
Kernel Alloc Once                    4K        2 
MALLOC                            9604K       17 
Stack                             64.0M        3 
VM_ALLOCATE                          4K        2 
__DATA                            8300K      141 
__LINKEDIT                        91.4M        4 
__TEXT                            84.7M      146 
__UNICODE                          552K        2 
shared memory                        8K        3 
===========                     =======  ======= 
TOTAL                            260.2M      312 

Однако, когда я проверил app.m: 614, он имеет if (strcmp(c, "regress_asim") != 0) { , где c - массив chracter, и этот массив работает отлично с последних нескольких месяцев и в XCode. Может ли кто-нибудь сказать мне, что мне не хватает?

UPDATE:

1) Параметры Resolved Project для Debug и Release одинаковы (за исключением двоичных путей)

2) Код работает не только в XCode, но также работает в eclipse и создает рабочий двоичный файл.

3) Часть кода, сбой в том, что массив c:

Объявлено как

char c[100];

Инициализировано как

 strncpy(c, "Equation_Default_data.csv", sizeof(c));

Блок кода, в котором он сбой

 if (!startfromcheckpoint) {
        oprintf( OUT_PRG, 50, "not starting from checkpoint file.\n");

        param = get_parameter("app.fitness_cases");
        if (param == NULL)
            fitness_cases = 200;
        else {
            fitness_cases = atoi(param);
            if (fitness_cases < 0)
                error( E_FATAL_ERROR,
                      "invalid value for \"app.fitness_cases\".");
        }
        FILE *in_file = fopen(c, "r");
        fscanf(in_file, "%d", &fitness_cases);
        if (strcmp(c, "regress_asim") != 0) {  //Line 614
            app_y_desired = (double *) MALLOC(fitness_cases * sizeof(double));
            app_fitness_cases[0] = (double *) MALLOC(
                                                     fitness_cases * sizeof(double));
            app_fitness_cases[1] = (double *) MALLOC(
                                                     fitness_cases * sizeof(double));
            app_fitness_cases[2] = (double *) MALLOC(
                                                     fitness_cases * sizeof(double));
            app_fitness_cases[3] = (double *) MALLOC(
                                                     fitness_cases * sizeof(double));

            memset(app_fitness_cases[2], 0, fitness_cases * sizeof(double));
            memset(app_fitness_cases[3], 0, fitness_cases * sizeof(double));
            memset(app_y_desired, 0, fitness_cases * sizeof(double));

        }
        app_fitness_importance = (int *) MALLOC(fitness_cases * sizeof(int));
        //Asim Code
        double x, y;
        for (i = 0; i < fitness_cases; ++i) {
            fscanf(in_file, "%lf", &x);
            fscanf(in_file, "%lf", &y);
            app_fitness_cases[0][i] = x;
            app_fitness_cases[1][i] = y;
            if (strcmp(c, "regress_asim") != 0) {
                app_y_desired[i] = y;
            }
            app_fitness_importance[i] = checkImportance(x);
        }
        fclose(in_file);
        datapointsPerImportance = (int*) MALLOC((max_datapoint_importance+1)*sizeof(int));
        memset(datapointsPerImportance, 0, (max_datapoint_importance+1)*sizeof(int));
        for (i = 0; i < fitness_cases; ++i) {
          // printf("%d : %d\n",i,checkImportance(app_fitness_cases[0][i]));
            datapointsPerImportance[checkImportance(app_fitness_cases[0][i])]=datapointsPerImportance[checkImportance(app_fitness_cases[0][i])]+1;

        }
        for(int i=0;i<=max_datapoint_importance;i++)
        {
            printf("Importance %d =%d\n",i,datapointsPerImportance[i]);
        }
        /*oprintf( OUT_PRG, 50, "%d fitness cases:\n", fitness_cases);
         for (i = 0; i < fitness_cases; ++i) {
         x = (random_double() * 2.0) - 1.0;

         // change this line to modify the goal function.
         y = x * x * x * x + x * x * x + x * x + x;

         app_fitness_cases[0][i] = x;
         app_fitness_cases[1][i] = y;

         // oprintf( OUT_PRG, 50, "    x = %12.5lf, y = %12.5lf\n", x, y);
         }*/
    } else {
        oprintf( OUT_PRG, 50, "started from checkpoint file.\n");
    }

Ответы

Ответ 1

Не видя кода, это похоже на ремонт автомобиля в абсолютной темноте. Попробуйте.

Однако я попробую.

В дампе стека он показывает, что вы используете fscanf для чтения данных из файла. Позже сбой strcmp.

Очевидная идея состоит в том, что fscanf читает больше символов, чем может помещаться в массив char, что не оставляет места для закрытия \0. strcmp (или любой другой код, на самом деле не имеет значения) пробегает конец строки, пока он не попадет в нечто разумное, а затем он сработает.

Если это причина, сделав буфер длиннее, он исправит его (временно). Установите для него что-то огромное, например 4096, чтобы проверить подход, а затем найти реальное исправление.

Если вы спросите, почему одна и та же программа будет работать в одном месте, но не в другой, вы, вероятно, читаете другой файл, поэтому содержимое файла имеет разную длину; или вы просто читаете файл в другом каталоге, который имеет более длинное имя; любой из них может быть причиной переполнения массива char.

Вторая идея: строка дампа VM Regions Near 0x68 показывает область памяти, в которой она сбрасывается, и ее содержимое выглядит как часть результата ls или путь/имя файла (/Users/USER/Library/Developer/Xcode/DerivedData/Theisis-gsze....), поэтому потенциально ваша переменная для этого пути слишком короткий. Сделайте это еще и попробуйте.

Изменить: c[100] слишком мало, путь показывает 115 символов. Обратите внимание, что .\Thesis будет заменено на \Users\... OS, которое тогда длиннее 100 символов.
Объявите c[260] (или даже больше), и вы будете хорошо.

Ответ 2

В соответствии с этими строками в выводе отладки:

 Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_c.dylib               0x00007fff93a8b09e flockfile + 4
1   libsystem_c.dylib               0x00007fff93a8d463 fscanf + 156

Что вызывает сбой - это fscanf, а не strcmp. Проверьте возвращаемые значения из fopen, он должен быть NULL в вашем тестовом примере (скорее всего, файл, который читается, не найден, при запуске программы из XCode рабочий каталог может быть не таким, каким вы ожидали).

В вашем случае этого должно быть достаточно:

FILE *in_file = fopen(c, "r");
if (in_file == NULL) {
    perror( "The following IO error occurred" );
    error( E_FATAL_ERROR, "IO error" );
}
int r = fscanf(in_file, "%d", &fitness_cases);
if (r != 1) {
    perror( "The following IO error occurred" );
    fclose( in_file );
    error( E_FATAL_ERROR, "Read Error" );
}

Предполагая, что ваша функция ошибки выпрыгивает из функции. Если нет, используйте несколько return s;

Ответ 3

Вам нужно проверить возвращаемые значения в C

    FILE *in_file = fopen(c, "r");
    /* insert error checking code here */
    fscanf(in_file, "%d", &fitness_cases);
    /* otherwise it fails here when fscanf tries to read from NULL */
    if (strcmp(c, "regress_asim") != 0) {  //Line 614

От взгляда на остальную часть опубликованного кода, похоже, что проверка ошибок является проблемой (MALLOC?), поэтому копирование пути к файлу (не опубликовано?), вероятно, имеет те же проблемы и переполняет буфер "c", заставляя fopen возвращать NULL и вызывая потерю fscanf. CHECK RETURN VALUES... если strncpy возвращает строку, которая не имеет "\ 0" в c [sizeof (c) -1], вы не можете использовать ее для открытия файла.