わかりました、これは本当に私を驚かせています。入力を読み取って文字列を返す次の関数があります
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 backtrace は以下を生成しました
#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 の新しいコピーを仮想 OS にインストールし、コードを再コンパイルしました。それでも同じ問題が発生します。 問題は、私のコードまたはライブラリ自体で行われているあいまいさのいずれかにあるようです。問題を示す最小限の例を作成しました。
#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 行目でセグメンテーション違反を引き起こしますが、呼び出されていない問題のある関数をコメントアウトすると、問題はなくなりました。