Wednesday, September 21, 2016

Unable to Run application via Terminal but application working fine in XCode

1 comment

I am working on lilgp which is a c language based tool for Genetic Programming. The problem that i am facing is that I am using XCode for the project and it is working fine and shows correct output via terminal. But when i try to run the same application in DerivedData of my project in XCode i get segmentation fault (11)

Then i have checked the console in Utilities for errors which shows error like this

    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  

However, when i checked app.m:614 it has if (strcmp(c, "regress_asim") != 0) { where c is a chracter array and this array is working fine from last couple of months and in XCode too. Can anybody tell me what am i missing?

UPDATE:

1) The Resolved Project settings for both Debug and Release are same (except for the binary paths for sure)

2) Code not only works in XCode but is also working in eclipse and creating a working binary.

3) The part of the code that crashes in that the array c is:

Declared as

char c[100]; 

Initillized as

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

The code block where it crashes

 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");     } 

3 Answers

Answers 1

Without seeing the code, this is like repairing a car in absolute darkness. Try it.

However, I'll give it a try.

In the stack dump, it shows that you are using fscanf to read data from a file. Later, strcmp crashes.

The obvious idea is that fscanf reads more characters than can fit in the char array, which leaves no space for the closing \0. strcmp (or any other code, doesn't really matter) the runs past the end of the string, until it hits something sensible, and then it crashes.

If this is the reason, making the buffer longer would fix it (temporarily). Set it something huge, like 4096, to verify the approach, and then find the real fix.

If you ask why the same program would work in one place, but not in the other - you are probably reading a different file, so the content of the file has different lengths; or you simple reading the file in a different directory, which has a longer name; any of those can be the reason for the char array overflow.

Second idea: The dump line VM Regions Near 0x68 shows the memory area where it dumped, and its content looks like a part of a ls result or a path/filename (/Users/USER/Library/Developer/Xcode/DerivedData/Theisis-gsze....), so potentially your variable for that path is too short. Make that one longer too and try.

Edit: c[100] is too small, the path shown there is 115 chars. Note that .\Thesis will be replaced by \Users\... by the OS, which then is longer than 100 chars.
Declare c[260] (or even larger) and you will be good.

Answers 2

According to these lines in the debug output:

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

What is causing the crash is the fscanf, not the strcmp. Check the return values from fopen, it must be NULL in your test case (most probably the file that is being read hasnt been found; when running the program from XCode, the working directory may not be the same as you were expecting).

In your case, this should suffice:

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" );     error( E_FATAL_ERROR, "Read Error" ); } 

Assuming that your error function jumps out of the function. If not, use some returns;

Answers 3

You need to check return values in 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 

From the looks at the rest of the posted code, it looks like error checking is an issue (MALLOC?) so the copying of the file path (not posted?) probably has the same issues and overflows the "c" buffer, causing fopen to return NULL and causing fscanf to fail. CHECK RETURN VALUES... if strncpy returns a string that doesn't have '\0' in c[sizeof(c)-1] - you cannot use it to open a file.

If You Enjoyed This, Take 5 Seconds To Share It

1 comment:

  1. In case you are looking into making money from your traffic with popunder advertisments, you should try one of the biggest companies: Propeller Ads.

    ReplyDelete