为什么 __stack_chk_fail 在来自 ipa 的 运行 时发生,而不是在 Xcode 中的设备上 运行 时发生?
Why does __stack_chk_fail happen when running from ipa, but not when running on device in Xcode?
这是具体的堆栈跟踪,请参阅下面的代码...
Thread 8 Crashed:
0 libsystem_kernel.dylib 0x00000001969bb270 __pthread_kill + 8
1 libsystem_pthread.dylib 0x0000000196a5916c pthread_kill + 108
2 libsystem_c.dylib 0x0000000196932b94 __abort + 112
3 libsystem_c.dylib 0x00000001969333f8 __stack_chk_fail + 208
只有在我为企业部署导出 ipa 并尝试在我的设备上 运行 之后才会出现这种情况。同样的设备,在 Xcode 中调试时 运行 就可以了。有什么想法吗?我在做什么破坏了堆栈?
// MACROS USED
#define BUFFER_SIZE_MAX 20480 // 20KB max payload for URL requests
#define BUFFER_SIZE_READ 4096 // 4KB
#define BUFFER_SIZE 4100 // 4KB w padding
#define NUL '[=15=]'
... relavent code ...
char readBuffer[BUFFER_SIZE] = {};
long bytesRead = 0;
char *buff = NULL;
while (((bytesRead = read(sck, readBuffer, BUFFER_SIZE_READ)) > 0)) {
if (!stop || *stop) { // volatile bool* passed to method
break;
}
if (bytesRead > 0) {
readBuffer[bytesRead] = NUL; // add NUL terminator
}
long len = bytesRead;
if (buff) {
len += strlen(buff);
buff = (char *)realloc(buff, len * sizeof(char));
} else {
buff = (char *)malloc(len * sizeof(char));
buff[0] = NUL;
}
strcat(buff, readBuffer);
if (strlen(buff) >= BUFFER_SIZE_MAX) {
// payload shouldn't be bigger than 20K in most use-cases
// adjust BUFFER_SIZE_MAX as needed
break;
}
}
if (buff) {
response = strdup(buff);
free(buff);
}
LOGV("\n\n<<<<<============\nHTTP payload:\n<<<<<============>>>>>>");
LOGV("\n\nREQUEST:\n----------->\n%s", request);
LOGV("\n\nRESPONSE:\n----------->\n%s\n\n", response);
close(sck);
return response; /// must call free
这里有一些问题,其中任何一个都可能导致您的问题:
1) readBuffer 的大小为 4100 字节。
但是当你 "readBuffer[bytesRead] = NUL;" 你 可以 写入 readBuffer[4100] 即超过缓冲区的末尾。
char readBuffer[BUFFER_SIZE] 应该是 char readBuffer[BUFFER_SIZE+1].
2) buff = (char *)malloc(len * sizeof(char));
您分配了收到的数据量,但不允许在调用 strcat() 时添加空终止符。你应该分配 (len + 1).
3) buff = (char *)realloc(buff, len * sizeof(char));
您再次分配时不考虑空终止符。
应该是 buff = (char *)realloc(buff, (len+1) * sizeof(char));
当您写入不属于您的内存时,行为就会变得不确定。所以有些时候它可能是个问题,其他时候你可能会侥幸逃脱。这取决于您要覆盖的内存中存在的内容。所以你总是在这里做坏事,但只是有时看到它的后果。
这是具体的堆栈跟踪,请参阅下面的代码...
Thread 8 Crashed:
0 libsystem_kernel.dylib 0x00000001969bb270 __pthread_kill + 8
1 libsystem_pthread.dylib 0x0000000196a5916c pthread_kill + 108
2 libsystem_c.dylib 0x0000000196932b94 __abort + 112
3 libsystem_c.dylib 0x00000001969333f8 __stack_chk_fail + 208
只有在我为企业部署导出 ipa 并尝试在我的设备上 运行 之后才会出现这种情况。同样的设备,在 Xcode 中调试时 运行 就可以了。有什么想法吗?我在做什么破坏了堆栈?
// MACROS USED
#define BUFFER_SIZE_MAX 20480 // 20KB max payload for URL requests
#define BUFFER_SIZE_READ 4096 // 4KB
#define BUFFER_SIZE 4100 // 4KB w padding
#define NUL '[=15=]'
... relavent code ...
char readBuffer[BUFFER_SIZE] = {};
long bytesRead = 0;
char *buff = NULL;
while (((bytesRead = read(sck, readBuffer, BUFFER_SIZE_READ)) > 0)) {
if (!stop || *stop) { // volatile bool* passed to method
break;
}
if (bytesRead > 0) {
readBuffer[bytesRead] = NUL; // add NUL terminator
}
long len = bytesRead;
if (buff) {
len += strlen(buff);
buff = (char *)realloc(buff, len * sizeof(char));
} else {
buff = (char *)malloc(len * sizeof(char));
buff[0] = NUL;
}
strcat(buff, readBuffer);
if (strlen(buff) >= BUFFER_SIZE_MAX) {
// payload shouldn't be bigger than 20K in most use-cases
// adjust BUFFER_SIZE_MAX as needed
break;
}
}
if (buff) {
response = strdup(buff);
free(buff);
}
LOGV("\n\n<<<<<============\nHTTP payload:\n<<<<<============>>>>>>");
LOGV("\n\nREQUEST:\n----------->\n%s", request);
LOGV("\n\nRESPONSE:\n----------->\n%s\n\n", response);
close(sck);
return response; /// must call free
这里有一些问题,其中任何一个都可能导致您的问题:
1) readBuffer 的大小为 4100 字节。 但是当你 "readBuffer[bytesRead] = NUL;" 你 可以 写入 readBuffer[4100] 即超过缓冲区的末尾。 char readBuffer[BUFFER_SIZE] 应该是 char readBuffer[BUFFER_SIZE+1].
2) buff = (char *)malloc(len * sizeof(char)); 您分配了收到的数据量,但不允许在调用 strcat() 时添加空终止符。你应该分配 (len + 1).
3) buff = (char *)realloc(buff, len * sizeof(char)); 您再次分配时不考虑空终止符。 应该是 buff = (char *)realloc(buff, (len+1) * sizeof(char));
当您写入不属于您的内存时,行为就会变得不确定。所以有些时候它可能是个问题,其他时候你可能会侥幸逃脱。这取决于您要覆盖的内存中存在的内容。所以你总是在这里做坏事,但只是有时看到它的后果。