好吧,这真的把我吓坏了。我有一个以下函数,它只读取输入并返回一个字符串
unsigned char* readFromIn() {
unsigned char* text = malloc(1024);
if (fgets(text, 1024, stdin) != NULL) { <--This is what's causing segmentation fault
int textLen = strlen(text);
if (textLen > 0 && text[textLen - 1] == '\n')
text[textLen - 1] = '\0'; // getting rid of newline character
return text;
}
else {
free(text);
return NULL;
}
}
问题是,这个函数在任何地方都没有被调用,只是为了确认,我把函数的名字改成了像 9rawiohawr90awrhiokawrioawr 这样疯狂的名字,并将 printf 语句放在函数的顶部。
我真的不确定为什么未调用的函数可能会导致分段错误错误。
我在 ubuntu 上使用 gcc 4.6.3。
编辑:我知道这条线
if (fgets(text, 1024, stdin) != NULL) {
是有问题的代码,因为一旦我注释掉该条件,就不会发生分段错误。
我知道该函数没有被调用,因为我没有看到我放置的 printf 调试语句的输出。
Edit2:我尝试将类型从 unsigned char 更改为 char。还是分段错误。我将尝试获取 gdb 输出。
Edit3:gdb 回溯产生以下
#0 0xb7fa5ac2 in _IO_2_1_stdin_ () from /lib/i386-linux-gnu/libc.so.6
#1 0xb7faf2fb in libwebsocket_create_context (info=0xbffff280) at libwebsockets.c:2125
#2 0x0804a5bb in main()
执行帧 0,1,2 不会输出任何特别有趣的东西。
Edit4:我已经尝试了评论中的所有建议,但无济于事,我仍然遇到相同的分段错误。
所以我在一个虚拟操作系统上安装了一个全新的 Ubuntu 副本并重新编译了我的代码。仍然会出现同样的问题。 在我看来,问题在于我的代码或库本身的一些晦涩难懂。我创建了一个演示问题的最小示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libwebsockets.h>
unsigned char* readFromIn() {
unsigned char* text = malloc(1024);
if (fgets(text, 1024, stdin) != NULL) { <--SEGMENTATION FAULT HERE
int textLen = strlen(text);
if (textLen > 0 && text[textLen - 1] == '\n')
text[textLen - 1] = '\0';
return text;
}
else {
free(text);
return NULL;
}
}
int callback_http(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len)
{
return 0;
}
static struct libwebsocket_protocols protocols[] = {
/* first protocol must always be HTTP handler */
{
"http-only", // name
callback_http, // callback
0 // per_session_data_size
}
};
int main(void) {
printf("Initializing Web Server\n");
// server url will be http://localhost:8081
int port = 8081;
const char *interface = NULL;
struct libwebsocket_context *context;
// we're not using ssl
const char *cert_path = NULL;
const char *key_path = NULL;
// no special options
int opts = 0;
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
info.port = port;
info.iface = interface;
info.protocols = protocols;
info.extensions = libwebsocket_get_internal_extensions();
info.ssl_cert_filepath = NULL;
info.ssl_private_key_filepath = NULL;
info.gid = -1;
info.uid = -1;
info.options = opts;
context = libwebsocket_create_context(&info);
if (context == NULL) {
fprintf(stderr, "libwebsocket init failed\n");
return 0;
}
printf("starting server...\n");
while (1) {
libwebsocket_service(context, 50);
}
printf("Shutting server down...\n");
libwebsocket_context_destroy(context);
return 0;
}
这就是我编译代码的方式
gcc -g testbug.c -o test -lwebsockets
这是我正在使用的库
http://git.libwebsockets.org/cgi-bin/cgit/libwebsockets/tag/?id=v1.23-chrome32-firefox24
您会看到我还没有调用函数 readFromIn(),一旦您尝试运行可执行文件,就会发生分段错误。
我重新运行了 gdb,这一次,回溯和框架告诉我更多信息。
(gdb) run
Starting program: /home/l46kok/Desktop/websocketserver/test
Initializing Web Server
[1384002761:2270] NOTICE: Initial logging level 7
[1384002761:2270] NOTICE: Library version: 1.3 unknown-build-hash
[1384002761:2271] NOTICE: Started with daemon pid 0
[1384002761:2271] NOTICE: static allocation: 4448 + (12 x 1024 fds) = 16736 bytes
[1384002761:2271] NOTICE: canonical_hostname = ubuntu
[1384002761:2271] NOTICE: Compiled with OpenSSL support
[1384002761:2271] NOTICE: Using non-SSL mode
[1384002761:2271] NOTICE: per-conn mem: 124 + 1360 headers + protocol rx buf
[1384002761:2294] NOTICE: Listening on port 8081
Program received signal SIGSEGV, Segmentation fault.
0xb7fb1ac0 in _IO_2_1_stdin_ () from /lib/i386-linux-gnu/libc.so.6
(gdb) backtrace
#0 0xb7fb1ac0 in _IO_2_1_stdin_ () from /lib/i386-linux-gnu/libc.so.6
#1 0xb7fcc2c6 in libwebsocket_create_context () from /usr/local/lib/libwebsockets.so.4.0.0
#2 0x080488c4 in main () at testbug.c:483
(gdb) frame 1
#1 0xb7fcc2c6 in libwebsocket_create_context () from /usr/local/lib/libwebsockets.so.4.0.0
(gdb) frame 2
#2 0x080488c4 in main () at testbug.c:483
483 context = libwebsocket_create_context(&info);
所以是的.. 我想我提供了手头的所有信息.. 但我真的不确定问题是什么。该程序在第 483 行导致分段错误,但是当我注释掉未调用的违规函数时,问题就消失了。