2013-11-07 2 views
6

Хорошо, это действительно волнует меня. У меня есть следующая функция, которая просто считывает ввод и возвращает строкуОшибка сегментации от функции, которая вообще не называется

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 в верхней части функции.

Я искренне не знаю, почему некорректная функция может вызвать ошибку ошибки сегментации.

Я использую gcc 4.6.3 на ubuntu.

Edit: Я знаю, что линия

if (fgets(text, 1024, stdin) != NULL) { 

это код обижая, потому что, как только я закомментировать, что условное, не происходит ошибка сегментации.

Я знаю, что функция NOT вызывается, потому что я не вижу вывода отладочного заявления printf, которое я поставил.

Редактировать 2: Я попытался изменить тип от 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, и на этот раз backtrace и рамки расскажут мне немного больше информации.

(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, но проблема исчезла, когда я прокомментирую нарушающую функцию, которая не вызывается.

+2

Вы попробовали 'make clean; make'? –

+0

И вы знаете, что это называется, потому что вы видите вывод из 'printf'? Вероятно, это поможет, если мы увидим больше соответствующего кода. –

+3

Постройте с помощью отладочной информации и запустите в отладчике. Он остановится при сбое, и вы сможете увидеть стек вызовов функций. И если стек вызовов выглядит «странным» (пожалуйста, отредактируйте свой вопрос, чтобы включить его), тогда, скорее всего, у вас есть проблема с разбивкой стека. –

ответ

10

Возможно, вам не хватает чего-то при инициализации libwebsockets.

Действительно, перекомпиляции libwebsockets с отладкой показывает, что:

GNU gdb (GDB) 7.6.1 (Debian 7.6.1-1) 
Copyright (C) 2013 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-linux-gnu". 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>... 
Reading symbols from /home/vili/x...done. 
(gdb) r 
Starting program: /home/vili/./x 
warning: Could not load shared library symbols for linux-vdso.so.1. 
Do you need "set solib-search-path" or "set sysroot"? 
Initializing Web Server 
[1384020141:5692] NOTICE: Initial logging level 7 
[1384020141:5692] NOTICE: Library version: 1.2 
[1384020141:5693] NOTICE: Started with daemon pid 0 
[1384020141:5693] NOTICE: static allocation: 5512 + (16 x 1024 fds) = 21896 bytes 
[1384020141:5693] NOTICE: canonical_hostname = x220 
[1384020141:5693] NOTICE: Compiled with OpenSSL support 
[1384020141:5693] NOTICE: Using non-SSL mode 
[1384020141:5693] NOTICE: per-conn mem: 248 + 1328 headers + protocol rx buf 
[1384020141:5713] NOTICE: Listening on port 8081 

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff7bc2080 in _IO_2_1_stderr_() from /lib/x86_64-linux-gnu/libc.so.6 
(gdb) bt 
#0 0x00007ffff7bc2080 in _IO_2_1_stderr_() from /lib/x86_64-linux-gnu/libc.so.6 
#1 0x00007ffff7bcd83c in libwebsocket_create_context (info=0x7fffffffe580) 
    at libwebsockets.c:2093 
#2 0x0000000000400918 in main() at x.c:66 
(gdb) up 
#1 0x00007ffff7bcd83c in libwebsocket_create_context (info=0x7fffffffe580) 
    at libwebsockets.c:2093 
2093     info->protocols[context->count_protocols].callback(context, 
(gdb) p context->count_protocols 
$1 = 1 
(gdb) p info->protocols[1] 
$2 = { 
    name = 0x7ffff7bc2240 <_IO_2_1_stdin_> "\210 \255", <incomplete sequence \373>, callback = 0x7ffff7bc2080 <_IO_2_1_stderr_>, 
    per_session_data_size = 140737349689696, rx_buffer_size = 0, 
    owning_server = 0x602010, protocol_index = 1} 
(gdb) 

Вполне вероятно, что вам нужно, чтобы закрыть массив libwebsocket_protocols с помощью специального входа (NULL), так что Lib будет знать, сколько записей он получил с помощью информации -> протоколы.

Edit: да, проверьте документы: http://jsk.pp.ua/knowledge/libwebsocket.html

Массив структур листинг поддерживаемых протоколов и обратного вызова от протокола специфические для каждого из них. Список заканчивается записью, в которой имеет указатель обратного вызова NULL.

+2

Абсолютно невероятно, я не могу поверить, что я укусил отвратительно, забыв что-то подобное! Угадайте, что это цена, которую вы платите за неточное чтение документации. Большое спасибо! – l46kok

+0

Случается со всеми ...В таких случаях не бойтесь погружаться в библиотеку, где проблема, похоже, происходит. – ldx

Смежные вопросы