修改TCP client例程时产生严重错误

jinkai
Posts: 11
Joined: Fri Jun 16, 2023 2:24 am

修改TCP client例程时产生严重错误

Postby jinkai » Tue Sep 12, 2023 6:24 am

idf版本:V5.0.2
开发板:esp-32
问题描述:
重复连接WiFi时,会无法创建socket,因此,我使用 SO_LINGER 参数,希望tcp断开时立马释放socket;同时,我希望发送tcp的等待超时时间为5秒,为此使用 SO_SNDTIMEO 参数,这里我遇到了两个问题:
问题1:
SO_SNDTIMEO 似乎未正常生效,我设置connect超时时间为5秒,超过五秒connect并没有结束,是我使用方法出现问题了吗?
menuconfig已做如下设置:LWIP_SO_LINGER(=y) "Enable SO_LINGER processing"
问题2:
在反复开关wifi后,产生如下log的错误:

Code: Select all

#######################################rxBytes:14, buffer data:126 0 11 18 8 49 50 51 52 53 54 55 56 18

I (1710426) wifi:state: run -> init (0)
I (1710426) wifi:pm stop, total sleep time: 4238202 us / 4972342 us

I (1710426) wifi:new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
saveWifiConfigInNvs(91) Updating wifi config in NVS ...
I (1710476) wifi:new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (1710486) wifi:state: init -> auth (b0)
I (1710486) wifi:state: auth -> assoc (0)
I (1710486) wifi:state: assoc -> run (10)
I (1710506) wifi:connected with 111111, aid = 1, channel 6, BW20, bssid = 94:a6:7e:41:be:c1
I (1710506) wifi:security: WPA2-PSK, phy: bg, rssi: -51
I (1710506) wifi:pm start, type: 1

I (1710516) esp_netif_handlers: sta ip: 192.168.142.18, mask: 255.255.255.0, gw: 192.168.142.254
wifiEventHandler(211) got ip:192.168.142.18

I (1710526) esp_netif_handlers: sta ip: 192.168.142.18, mask: 255.255.255.0, gw: 192.168.142.254
wifiEventHandler(211) got ip:192.168.142.18

I (1710546) wifi:AP's beacon interval = 102400 us, DTIM period = 2
#######################################rxBytes:30, buffer data:126 0 27 65 13 49 57 50 46 49 54 56 46 49 52 50 46 51 0 9 1 2 3 4 5 6 7 8 9 107

I (1715436) TCP client: Socket created, connecting to 192.168.142.3:3333
Guru Meditation Error: Core  0 panic'ed (StoreProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x40013fdb  PS      : 0x00060a34  A0      : 0x80010464  A1      : 0x3ffc208c
A2      : 0x3ffcc9e0  A3      : 0x3ffcca20  A4      : 0x04000000  A5      : 0x00000002
A6      : 0x0000000a  A7      : 0x00000012  A8      : 0x00000000  A9      : 0x00000001
A10     : 0x00000000  A11     : 0x00000261  A12     : 0x00000069  A13     : 0x3ffd4270
A14     : 0x3ffb9a20  A15     : 0x00000084  SAR     : 0x0000001d  EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff


Backtrace: 0x40013fd8:0x3ffc208c |<-CORRUPTED
似乎是connect函数出错,文档上说此时程序正尝试解引用一个 NULL 指针,是时序出现问题了吗?


代码如下:

Code: Select all

/**
 * @brief       发送 wifi 数据, wifi 发送数据指令格式:
 *              |-- 目的地址长度(1 byte) --|-- 目的地址(n bytes) --|-- 信息长度(2 bytes) --|-- 目的地址长度(n bytes) --|
 * @param[in]   data - 发送数据内容
 * @param[in]   len - 发送数据内容的长度
 */
int tcpClientSendDataToRemote(uint8_t *data, const uint16_t len)
{
    char host_ip[17] = {0};
    int addr_family = 0;
    int ip_protocol = 0;
    int sendDataLen = 0;
    int toWrite = len;
    int written = 0;
    int sock = 0;
    int err = 0;

    if (NULL == data || len < 11 || WifiStation.status != WIFI_STATUS_CONNECTED)
    {
        return -1;
    }

    memcpy((uint8_t *)host_ip, (uint8_t *)(data + 1), data[0]);

    struct sockaddr_in dest_addr;
    dest_addr.sin_addr.s_addr = inet_addr(host_ip);
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(PORT);
    addr_family = AF_INET;
    ip_protocol = IPPROTO_IP;

    sock =  socket(addr_family, SOCK_STREAM, ip_protocol);
    if (sock < 0)
    {
        ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
        goto failed;
    }
    ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, PORT);

    struct timeval timeout;
    timeout.tv_sec = 3;
    timeout.tv_usec = 0;
    err = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
    if (err != 0)
    {
        goto failed;
    }

    struct linger link;
    link.l_onoff = 1;
    link.l_linger = 0;
    err = setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*)&link, sizeof(link));
    if (err != 0)
    {
        goto failed;
    }

    err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6));
    if (err != 0)
    {
        ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
        goto failed;
    }
    ESP_LOGI(TAG, "Successfully connected");

    while (toWrite > 0)
    {
        written = send(sock, (data + len - toWrite), toWrite, 0);
        if (written < 0) {
            ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
            goto failed;
        }
        toWrite -= written;
    }

    if (sock != -1)
    {
        ESP_LOGW(TAG, "Shutting down socket");
        shutdown(sock, 0);
        close(sock);
    }
    return 0;

failed:
    if (sock != -1)
    {
        shutdown(sock, 0);
        close(sock);
    }

    return -1;
}
问题2时操作为:打开wifi ——> 设置静态IP ——> 输入ssid和密码 ——> 发送数据 ——> 关闭wifi,重复以上步骤。

jinkai
Posts: 11
Joined: Fri Jun 16, 2023 2:24 am

Re: 修改TCP client例程时产生严重错误

Postby jinkai » Tue Sep 12, 2023 9:35 am

再补充一个问题:
问题3:
添加SO_LINGER相关代码后。出现以下log:

Code: Select all

I (661399) wifi:bcn_timeout,ap_probe_send_start
I (663899) wifi:ap_probe_send over, resett wifi status to disassoc
I (663899) wifi:state: run -> init (c800)
I (663899) wifi:pm stop, total sleep time: 592585542 us / 653377789 us

I (663909) wifi:new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1

assert failed: tcp_abandon /IDF/components/lwip/lwip/src/core/tcp.c:582 (don't call tcp_abort/tcp_abandon for listen-pcbs)


Backtrace: 0x40081fe2:0x3ffd62e0 0x40092dd5:0x3ffd6300 0x40099a45:0x3ffd6320 0x4012193a:0x3ffd6440 0x40121a01:0x3ffd6480 0x40130220:0x3ffd64a0 0x4013092d:0x3ffd64d0 0x4011e669:0x3ffd64f0 0x4011e714:0x3ffd6510 0x40095fc5:0x3ffd6540
0x40081fe2: panic_abort at D:/Espressif/frameworks/esp-idf-v5.0.2/components/esp_system/panic.c:423

0x40092dd5: esp_system_abort at D:/Espressif/frameworks/esp-idf-v5.0.2/components/esp_system/esp_system.c:153

0x40099a45: __assert_func at D:/Espressif/frameworks/esp-idf-v5.0.2/components/newlib/assert.c:78

0x4012193a: tcp_abandon at D:/Espressif/frameworks/esp-idf-v5.0.2/components/lwip/lwip/src/core/tcp.c:582 (discriminator 1)

0x40121a01: tcp_abort at D:/Espressif/frameworks/esp-idf-v5.0.2/components/lwip/lwip/src/core/tcp.c:646

0x40130220: lwip_netconn_do_close_internal at D:/Espressif/frameworks/esp-idf-v5.0.2/components/lwip/lwip/src/api/api_msg.c:1032

0x4013092d: lwip_netconn_do_delconn at D:/Espressif/frameworks/esp-idf-v5.0.2/components/lwip/lwip/src/api/api_msg.c:1245 (discriminator 2)

0x4011e669: tcpip_thread_handle_msg at D:/Espressif/frameworks/esp-idf-v5.0.2/components/lwip/lwip/src/api/tcpip.c:162

0x4011e714: tcpip_thread at D:/Espressif/frameworks/esp-idf-v5.0.2/components/lwip/lwip/src/api/tcpip.c:148

0x40095fc5: vPortTaskWrapper at D:/Espressif/frameworks/esp-idf-v5.0.2/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:154
请问有什么解决方法吗?

ESP_YJM
Posts: 300
Joined: Fri Feb 26, 2021 10:30 am

Re: 修改TCP client例程时产生严重错误

Postby ESP_YJM » Wed Sep 13, 2023 2:33 am

问题1:SO_SNDTIMEO 只能用于 connect 之后调用 send/write 才有效,如果你想进行 connect 的连接超时设置的话,你需要先将 socket 设置为非阻塞的,然后通过 select 进行超时处理,具体细节你可以参考 https://github.com/espressif/esp-idf/bl ... tls.c#L332

问题2:这个是必现的吗?你反汇编看下 PC 地址是哪个函数,加点日志定位下。

问题3:你把 SO_LINGER 的设置放到 connect 之后。

jinkai
Posts: 11
Joined: Fri Jun 16, 2023 2:24 am

Re: 修改TCP client例程时产生严重错误

Postby jinkai » Wed Sep 13, 2023 8:16 am

ESP_YJM wrote:
Wed Sep 13, 2023 2:33 am
问题1:SO_SNDTIMEO 只能用于 connect 之后调用 send/write 才有效,如果你想进行 connect 的连接超时设置的话,你需要先将 socket 设置为非阻塞的,然后通过 select 进行超时处理,具体细节你可以参考 https://github.com/espressif/esp-idf/bl ... tls.c#L332

问题2:这个是必现的吗?你反汇编看下 PC 地址是哪个函数,加点日志定位下。

问题3:你把 SO_LINGER 的设置放到 connect 之后。
感谢您的回复,关于问题2,我把SO_LINGER放在connect之后send之前后,出现如下报错,麻烦您看一下:

Code: Select all

I (33001) wifi:state: run -> init (0)
I (33001) wifi:pm stop, total sleep time: 9752299 us / 10851411 us

I (33011) wifi:<ba-del>idx
I (33011) wifi:new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x40095f9f  PS      : 0x00060533  A0      : 0x80094d71  A1      : 0x3ffdb780
0x40095f9f: uxListRemove at C:/Espressif/frameworks/esp-idf-v5.0.1/components/freertos/FreeRTOS-Kernel/list.c:197

A2      : 0xa174a1ce  A3      : 0x3ffc3324  A4      : 0x00000004  A5      : 0x00060523
A6      : 0x00000006  A7      : 0x0000abab  A8      : 0x80096174  A9      : 0x3ffdb750
A10     : 0x00000001  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x80000000
A14     : 0xffffffff  A15     : 0x00000000  SAR     : 0x00000018  EXCCAUSE: 0x0000001c
EXCVADDR: 0xa174a1de  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff


Backtrace: 0x40095f9c:0x3ffdb780 0x40094d6e:0x3ffdb7a0 0x40093d3c:0x3ffdb7c0 0x40093e70:0x3ffdb800 0x40083959:0x3ffdb820 0x40193ff9:0x3ffdb840 0x401941fb:0x3ffdb860 0x4018aa4f:0x3ffdb890 0x40179a9f:0x3ffdb8b0 0x4016e599:0x3ffdb8d0 0x4016f9a4:0x3ffdb8f0 0x4016e0ec:0x3ffdb910 0x4009b2ed:0x3ffdb930 0x40095ff5:0x3ffdb960
0x40095f9c: uxListRemove at C:/Espressif/frameworks/esp-idf-v5.0.1/components/freertos/FreeRTOS-Kernel/list.c:194

0x40094d6e: xTaskRemoveFromEventList at C:/Espressif/frameworks/esp-idf-v5.0.1/components/freertos/FreeRTOS-Kernel/tasks.c:3800

0x40093d3c: xQueueSemaphoreTake at C:/Espressif/frameworks/esp-idf-v5.0.1/components/freertos/FreeRTOS-Kernel/queue.c:1605

0x40093e70: xQueueTakeMutexRecursive at C:/Espressif/frameworks/esp-idf-v5.0.1/components/freertos/FreeRTOS-Kernel/queue.c:738

0x40083959: mutex_lock_wrapper at C:/Espressif/frameworks/esp-idf-v5.0.1/components/esp_wifi/esp32/esp_adapter.c:393

0x40193ff9: wpa2_api_lock at C:/Espressif/frameworks/esp-idf-v5.0.1/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c:83

Who is online

Users browsing this forum: No registered users and 120 guests