質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

Q&A

解決済

2回答

537閲覧

Cのwebsocketサーバにて、クライアントから受け取ったIDをグローバル変数に保持できない。

mememe

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

セグメンテーション違反

セグメンテーション違反とは、ソフトウェア実行時に発生するエラーのひとつであり、許可されていないメモリにアクセスしたときに起きます。しばしば、ポインタの不適切な使用、またはバッファオーバーフローによって起こります。

0グッド

0クリップ

投稿2023/06/03 05:25

編集2023/06/03 05:57

お世話になります。
以下の内容で困っておりまして、解決方法をご存じの方、
アドバイスやご教示を頂けますでしょうか。

実現したいこと

Cのlibwebsocketsにてwebsocketサーバを作成しています。
接続クライアントごとにクライアントから受け取ったユーザID(42バイト想定)を保持したいと考えています。

発生している問題・エラーメッセージ

下記のソースコードで実現しようとしています。
しかし、クライアントからユーザIDの登録済みかをリクエストすると、
「Segmentation fault (core dumped)」が表示され、
websocketサーバが強制終了してしまします。
※本ソースコードはクライアントID保持の機能を持たせる前は正常に機能していました。

#./wstest [2023/06/03 13:50:54:8713] N: lws_create_context: LWS: 4.3.99-v4.3.0-276-ge8eb7d6, NET CLI SRV H1 H2 WS SS-JSON-POL ConMon IPv6-absent [2023/06/03 13:50:54:8715] N: __lws_lc_tag: ++ [wsi|0|pipe] (1) [2023/06/03 13:50:54:8715] N: __lws_lc_tag: ++ [vh|0|netlink] (1) [2023/06/03 13:50:54:8716] N: __lws_lc_tag: ++ [vh|1|default||40000] (2) [2023/06/03 13:50:54:8716] N: [vh|1|default||40000]: lws_socket_bind: source ads 0.0.0.0 [2023/06/03 13:50:54:8716] N: __lws_lc_tag: ++ [wsi|1|listen|default||40000] (2) Starting server... [2023/06/03 13:51:09:2695] N: __lws_lc_tag: ++ [wsisrv|0|default|(null)] (1) Assigned Client Request message: SelReg,0xa7d206f33e6AaC9BD33d5EA943EE30fAaec9838F,5B11 Segmentation fault (core dumped)

ソースコード(抜粋)

※全てのソースコードは、「ソースコード(全て)」にに乗せています。

クライアントデータを保持する構造体はグローバルで定義しています。

// クライアントデータ構造体 struct ClientData { char userId[256]; };

クライアントデータ構造体はcallback_echoの引数userのメモリを使用して初期化しています。

static int callback_echo(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { char *methodName; char *userId; char *responseData = NULL; // userのポインタを使用 struct ClientData *client_data = (struct ClientData *)user; [省略] }

クライアントから対象のユーザIDがMySQLに登録済みかのリクエスト受けとり次第、
MySQLに問い合わせて、登録済の場合はユーザIDを保持しています。

static int callback_echo(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { [省略] switch (reason) { [省略] case LWS_CALLBACK_RECEIVE: { char *message = (char*)in; printf("Request message: %s\n", message); methodName = strtok(message, ","); // 登録済みか確認 if(strcmp(methodName, "SelReg") == 0) { userId = strtok(NULL, ","); // 42バイト文字列想定 char response[255]; int result = SelectRegist(userId, response); // MySQLに問い合わせ(スタブ) // 登録済みユーザ if(result == 0){ strncpy(client_data->userId, userId, sizeof(client_data->userId) - 1); // ユーザIDを保持 // エラー }else if (result == 1) { snprintf(response, sizeof(response), "1"); // 未登録ユーザ }else if (result == 2) { snprintf(response, sizeof(response), "2"); } printf("SelReg: %d\n", result); lws_write(wsi, (unsigned char*)response, strlen(response), LWS_WRITE_TEXT); } break; } [省略] } [省略] }

ソースコード(全て)

申し訳ありません。teratailの文字数制限超過の為下記URLでご確認ください。
http://160.251.81.206/teratail/20230603/wstest.c

試したこと

gdbでコアダンプのバックトレースを出力しました。
wstest.cの46行目でセグメンテーションフォルトが発生しているようですが、
その改修方法が分からない状態です。

(gdb) bt full #0 0x00007f59fbbc3e1b in __strncpy_sse2_unaligned () from /lib64/libc.so.6 No symbol table info available. #1 0x0000000000400a5e in callback_echo (wsi=0x8fdab0, reason=LWS_CALLBACK_RECEIVE, user=0x0, in=0x8f69f6, len=50) at wstest.c:46 response = '\000' <repeats 16 times>, "\200\221\033\375Y\177", '\000' <repeats 14 times>, "\b", '\000' <repeats 19 times>, "\300\302<\375Y\177\000\000\000\000\000\000\000\000\000\000 \324<\375Y\177\000\000\000\000\000\000\000\000\000\000\037\325<\375Y\177\000\000\354\363\032\375\000\000\000\000\300\302<\375Y\177\000\000\000\000\000\000\020", '\000' <repeats 11 times>, "\320\001_\361\374\177\000\000\tB\023\375Y\177\000\000\b\001_\361\374\177\000\000\000\000\000\000\000\000\000\000\200\221\033\375Y\177\000\000\000\000\000\000\b", '\000' <repeats 11 times>, "\020\000\000\000\060\000\000\000\340\001_\361\374\177\000\000"... result = 0 message = 0x8f69f6 "SelReg" methodName = 0x8f69f6 "SelReg" userId = 0x8f69fd "0xa7d206f33e6AaC9BD33d5EA943EE30fAaec9838F" responseData = 0x0 client_data = 0x0 #2 0x00007f59fd165253 in user_callback_handle_rxflow () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #3 0x00007f59fd194686 in lws_ws_frame_rest_is_payload () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #4 0x00007f59fd1947d0 in lws_parse_ws () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #5 0x00007f59fd1807c8 in lws_read_h1 () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #6 0x00007f59fd18f58b in rops_handle_POLLIN_ws () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #7 0x00007f59fd163967 in lws_service_fd_tsi () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #8 0x00007f59fd121522 in _lws_plat_service_forced_tsi () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #9 0x00007f59fd12192e in _lws_plat_service_tsi () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #10 0x00007f59fd121991 in lws_plat_service () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #11 0x00007f59fd163b2f in lws_service () from /usr/local/lib/libwebsockets.so.19 No symbol table info available. #12 0x0000000000400b73 in main () at wstest.c:107 info = {iface = 0x0, protocols = 0x6020a0 <protocols>, extensions = 0x0, token_limits = 0x0, http_proxy_address = 0x0, headers = 0x0, reject_service_keywords = 0x0, pvo = 0x0, log_filepath = 0x0, mounts = 0x0, server_string = 0x0, error_document_404 = 0x0, port = 40000, http_proxy_port = 0, max_http_header_data2 = 0, max_http_header_pool2 = 0, keepalive_timeout = 0, http2_settings = {0, 0, 0, 0, 0, 0, 0}, max_http_header_data = 0, max_http_header_pool = 0, ssl_private_key_password = 0x0, ssl_cert_filepath = 0x0, ssl_private_key_filepath = 0x0, ssl_ca_filepath = 0x0, ssl_cipher_list = 0x0, ecdh_curve = 0x0, tls1_3_plus_cipher_list = 0x0, server_ssl_cert_mem = 0x0, server_ssl_private_key_mem = 0x0, server_ssl_ca_mem = 0x0, ssl_options_set = 0, ssl_options_clear = 0, simultaneous_ssl_restriction = 0, simultaneous_ssl_handshake_restriction = 0, ssl_info_event_mask = 0, server_ssl_cert_mem_len = 0, server_ssl_private_key_mem_len = 0, server_ssl_ca_mem_len = 0, alpn = 0x0, client_ssl_private_key_password = 0x0, client_ssl_cert_filepath = 0x0, client_ssl_cert_mem = 0x0, client_ssl_cert_mem_len = 0, client_ssl_private_key_filepath = 0x0, client_ssl_key_mem = 0x0, client_ssl_ca_filepath = 0x0, client_ssl_ca_mem = 0x0, client_ssl_cipher_list = 0x0, client_tls_1_3_plus_cipher_list = 0x0, ssl_client_options_set = 0, ssl_client_options_clear = 0, client_ssl_ca_mem_len = 0, client_ssl_key_mem_len = 0, provided_client_ssl_ctx = 0x0, ka_time = 0, ka_probes = 0, ka_interval = 0, timeout_secs = 0, connect_timeout_secs = 0, bind_iface = 0, timeout_secs_ah_idle = 0, tls_session_timeout = 0, tls_session_cache_max = 0, gid = 0, uid = 0, options = 0, user = 0x0, count_threads = 0, fd_limit_per_thread = 0, vhost_name = 0x0, external_baggage_free_on_destroy = 0x0, pt_serv_buf_size = 0, fops = 0x0, foreign_loops = 0x0, signal_cb = 0x0, pcontext = 0x0, finalize = 0x0, finalize_arg = 0x0, listen_accept_role = 0x0, listen_accept_protocol = 0x0, pprotocols = 0x0, username = 0x0, groupname = 0x0, unix_socket_perms = 0x0, system_ops = 0x0, retry_and_idle_policy = 0x0, register_notifier_list = 0x0, pss_policies_json = 0x0, pss_plugins = 0x0, ss_proxy_bind = 0x0, ss_proxy_address = 0x0, ss_proxy_port = 0, txp_ops_ssproxy = 0x0, txp_ssproxy_info = 0x0, txp_ops_sspc = 0x0, rlimit_nofile = 0, early_smd_cb = 0x0, early_smd_opaque = 0x0, early_smd_class_filter = 0, smd_ttl_us = 0, smd_queue_depth = 0, fo_listen_queue = 0, event_lib_custom = 0x0, log_cx = 0x0, http_nsc_filepath = 0x0, http_nsc_heap_max_footprint = 0, http_nsc_heap_max_items = 0, http_nsc_heap_max_payload = 0, _unused = {0x0, 0x0}} context = 0x8f6010 n = 0 ret = 0 (gdb)

以上になります。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2023/06/03 06:16

ClientData 型のグローバル変数を用意して、そのアドレスを protocols に渡す必要があるのでは…。
mememe

2023/06/03 08:02

ありがとうございます。 おっしゃる通りでした。 該当箇所を修正した結果正常に動作しました。
guest

回答2

0

自己解決

皆様アドバイスをいただきありがとうございました。
hoshi-takanori様のコメントの通りで、ケアレスミスでした。
hoshi-takanori様が回答ではなくコメントでメッセージを送信されていましてベストアンサーに設定することができませんので、自己解決として処理させていただきます。

投稿2023/06/03 08:05

mememe

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

「Segmentation fault (core dumped)」が表示され、

どこかで不正アクセスが起こっているってことで、コードが間違っています
#コードの提示がないので、言えるのはここまで

投稿2023/06/03 06:06

y_waiwai

総合スコア87784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問