# 2019q1 Homework5 (daemon) contributed by < `F74021200` > 在 clone 給定的[程式碼](https://github.com/sysprog21/kecho)後,執行 make ,在 make 的過程中會出現以下的錯誤訊息: ```shell echo >&2 " ERROR: Kernel configuration is invalid."; \ ``` 但是仍有產生 .ko 檔,並可載入 kernel 。 make 結束後,執行: ```shell sudo insmod fastecho.ko ``` 將 module 載入 kernel 。 成功載入後,執行: ```shell telnet localhost 12345 ``` 透過 telnet 連線至 echo server , fastecho ,預期會有以下畫面: ```shell Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. ``` 接著於鍵盤輸入: ```shell 1 ``` 會有以下畫面: ```shell Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 1 1 :P�& ``` 會有一行亂碼。 開啟另一 Terminal ,使用 dmesg 查看 printk 輸出的資訊如下: ```shell [233191.127281] fastecho: socket create ok.... [233191.127294] fastecho: setsockopt ok.... [233191.127301] fastecho: socket bind ok.... [233191.127308] fastecho: socket listen ok.... [233207.182909] fastechostrlen when malloc:14 [233207.182920] fastecho: start get response [233340.704296] fastecho: get request = 1 :P\xe1&V \xa97 [233340.704309] fastecho: start send request. [233340.704369] fastecho: send request = 1 :P\xe1&V \xa97 [233340.704375] fastecho: start get response ``` 關閉 telnet ,並卸載 fastecho module 。 查看 get_request() 的使用,發現 get_request() 在 echo_server_worker() 中被使用,傳入的參數, buf ,在 echo_server_worker() 中被宣告並配置空間,如下所示: ```click= static int echo_server_worker(void *arg) { struct socket *sock; unsigned char *buf; int res; sock = (struct socket *) arg; allow_signal(SIGKILL); allow_signal(SIGTERM); buf = kmalloc(BUF_SIZE, GFP_KERNEL); if (!buf) { printk(KERN_ERR MODULE_NAME ": kmalloc error....\n"); return -1; } while (!kthread_should_stop()) { res = get_request(sock, buf, BUF_SIZE - 1); if (res <= 0) { if (res) { printk(KERN_ERR MODULE_NAME ": get request error = %d\n", res); } break; } res = send_request(sock, buf, strlen(buf)); if (res < 0) { printk(KERN_ERR MODULE_NAME ": send request error = %d\n", res); break; } } res = get_request(sock, buf, BUF_SIZE - 1); res = send_request(sock, buf, strlen(buf)); kernel_sock_shutdown(sock, SHUT_RDWR); sock_release(sock); kfree(buf); return 0; } ``` 但使用前未將 buf 所指向的空間初始化;在 get_request() 中,若取得的字串沒覆蓋掉已存在亂碼的空間,這些亂碼將會於輸出時顯現,導致非預期結果;因此,於 echo_server.c 中,進入 get_request() 前,都先以 memset() 將 buf 初始化,如下第 20 行: ```click= static int echo_server_worker(void *arg) { struct socket *sock; unsigned char *buf; int res; sock = (struct socket *) arg; allow_signal(SIGKILL); allow_signal(SIGTERM); buf = kmalloc(BUF_SIZE, GFP_KERNEL); if (!buf) { printk(KERN_ERR MODULE_NAME ": kmalloc error....\n"); return -1; } printk(MODULE_NAME "strlen when malloc:%ld\n", strlen(buf)); while (!kthread_should_stop()) { memset(buf, '\0', BUF_SIZE); res = get_request(sock, buf, BUF_SIZE - 1); if (res <= 0) { if (res) { printk(KERN_ERR MODULE_NAME ": get request error = %d\n", res); } break; } res = send_request(sock, buf, strlen(buf)); if (res < 0) { printk(KERN_ERR MODULE_NAME ": send request error = %d\n", res); break; } } res = get_request(sock, buf, BUF_SIZE - 1); res = send_request(sock, buf, strlen(buf)); kernel_sock_shutdown(sock, SHUT_RDWR); sock_release(sock); kfree(buf); return 0; } ``` 重新 make 並載入 fastecho.ko ,執行 telnet 後,不再有亂碼產生,但是游標會停在上個輸出的第一個字元,導致在 Terminal 畫面中,這次輸入的字元會覆蓋掉上次輸出的字元,導致這些字元混在一起。 發現將 send_request() 中,第 14 行與第 18 行的 strlen(buf) 改成 BUF_SIZE 後,上述問題便解決,但不知為什麼,目前仍在尋找原因。 ```click= static int send_request(struct socket *sock, unsigned char *buf, size_t size) { int length; struct kvec vec; struct msghdr msg; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; vec.iov_base = buf; vec.iov_len = strlen(buf); printk(MODULE_NAME ": start send request.\n"); length = kernel_sendmsg(sock, &msg, &vec, 1, strlen(buf) - 1); printk(MODULE_NAME ": send request = %s\n", buf); return length; } ```