【发布时间】:2017-01-18 16:55:30
【问题描述】:
我正在研究lilgp,这是一个基于 c 语言的遗传编程工具。我面临的问题是我正在为项目使用 XCode,它工作正常并通过终端显示正确的输出。但是当我尝试在我的 XCode 项目的DerivedData 中运行相同的应用程序时,我得到了分段错误 (11)
然后我检查了实用程序中的控制台是否有错误,显示类似这样的错误
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 是一个字符数组,并且该数组在过去几个月和 XCode 中都运行良好。谁能告诉我我错过了什么?
更新:
1) Debug 和 Release 的 Resolved Project 设置是相同的(除了二进制路径)
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");
}
【问题讨论】:
-
这个问题可能需要来自应用程序的更多代码来解决错误发生的位置。根据构建的调试和发布模式,它可能是某个 UB。
-
没有足够的代码给出一个连贯的答案。正如@Niall 提到的,程序中可能存在未定义的行为。有问题的行有一个 strcmp。如果'c'数组中没有空终止,它会在内存页面之间转换时读取溢出和可能的Seg Fault。如果 'c' 类似于 char c[10] 则输入 c[sizeof(c)-1] = '\0';在第 613 行,看看情况如何。在调试器下启动程序,使用不同的标志编译或只是运气可能会导致内存移位,即使使用 UB,程序也会成功。
-
一般情况下,尽可能使用
strncmp(需要最大长度)而不是strcmp,以避免在字符串中没有null时访问缓冲区之外。 -
与终端不同,Xcode 和 Eclipse 可能会将您的工作目录设置为
Equation_Default_data.csv可以设置为open(),但是在没有代码影响 @987654335 的情况下strcmp("Equation_Default_data.csv", "regress_asim")没有意义@介于两者之间。我建议使用“buf”或“c”以外的其他东西,这样就可以在不到处添加printf("%s",c);s 的情况下跟踪它……更好的是使用指向buf[] 的本地char*一个有用的名字 -
无论哪种方式,它可能是失败的
fscanf,而不是strcmp,因为您没有在使用之前检查您的fopen是否实际上为您提供了工作文件句柄而不是错误它在fscanf