Exception————c3p0(The web application [/C-PDMS2] appears to have started a thread named)

本文详细介绍了Tomcat服务器中因C3P0连接池未正确关闭导致的内存泄漏问题及解决办法。通过调用正确的关闭方法,可以避免线程未被及时释放而引发的内存泄露。

异常:

严重: The web application [/C-PDMS2] appears to have started a thread named [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0] but has failed to stop it. This is very likely to create a memory leak.

2013-1-30 17:08:57 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

严重: The web application [/C-PDMS2] appears to have started a thread named [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1] but has failed to stop it. This is very likely to create a memory leak.

2013-1-30 17:08:57 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

严重: The web application [/C-PDMS2] appears to have started a thread named [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2] but has failed to stop it. This is very likely to create a memory leak.

2013-1-30 17:08:57 org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap

 

原因:

在Tomcat关闭的时候还有线程没有关闭,这会引起内存泄露,所以Tomcat会自己强行关闭。

 

解决方案:

看上面的异常可得知是C3P0引起的,因为在C3P0Util中用到了ThreadLocal这个类,所以在服务器关闭的时候调用comboPooledDataSource .close()方法,到是貌似可以解决。

 

但是又报了下面的错:

严重: The web application [/C-PDMS2] appears to have started a thread named [Resource Destroyer in BasicResourcePool.close()] but has failed to stop it. This is very likely to create a memory leak.

2013-1-30 17:20:04 org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap

调用connLocal .remove()方法,貌似可以解决问题。

D:/esp32_C3/vendor_0.1.5/main/main.c: In function 'uart_select_mode': D:/esp32_C3/vendor_0.1.5/main/main.c:16:15: error: implicit declaration of function 'uart_read_bytes' [-Wimplicit-function-declaration] 16 | int len = uart_read_bytes(UART_NUM_0, (uint8_t*)buffer, sizeof(buffer)-1, pdMS_TO_TICKS(5000)); | ^~~~~~~~~~~~~~~ D:/esp32_C3/vendor_0.1.5/main/main.c:16:31: error: 'UART_NUM_0' undeclared (first use in this function) 16 | int len = uart_read_bytes(UART_NUM_0, (uint8_t*)buffer, sizeof(buffer)-1, pdMS_TO_TICKS(5000)); | ^~~~~~~~~~ D:/esp32_C3/vendor_0.1.5/main/main.c:16:31: note: each undeclared identifier is reported only once for each function it appears in D:/esp32_C3/vendor_0.1.5/main/main.c:20:13: error: implicit declaration of function 'strstr' [-Wimplicit-function-declaration] 20 | if (strstr(buffer, "MODE:PROVISIONER")) { | ^~~~~~ D:/esp32_C3/vendor_0.1.5/main/main.c:10:1: note: include '<string.h>' or provide a declaration of 'strstr' 9 | #include "heartbeat.h" +++ |+#include <string.h> 10 | D:/esp32_C3/vendor_0.1.5/main/main.c:20:13: warning: incompatible implicit declaration of built-in function 'strstr' [-Wbuiltin-declaration-mismatch] 20 | if (strstr(buffer, "MODE:PROVISIONER")) { | ^~~~~~ D:/esp32_C3/vendor_0.1.5/main/main.c:20:13: note: include '<string.h>' or provide a declaration of 'strstr' [1383/1392] Performing configure step for 'bootloader' -- Found Git: E:/espidf/espressif/tools/idf-git/2.39.2/cmd/git.exe (found version "2.39.2.windows.1") -- The C compiler identification is GNU 14.2.0 -- The CXX compiler identification is GNU 14.2.0 -- The ASM compiler identification is GNU -- Found assembler: E:/espidf/espressif/tools/riscv32-esp-elf/esp-14.2.0_20241119/riscv32-esp-elf/bin/riscv32-esp-elf-gcc.exe -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: E:/espidf/espressif/tools/riscv32-esp-elf/esp-14.2.0_20241119/riscv32-esp-elf/bin/riscv32-esp-elf-gcc.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: E:/espidf/espressif/tools/riscv32-esp-elf/esp-14.2.0_20241119/riscv32-esp-elf/bin/riscv32-esp-elf-g++.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Building ESP-IDF components for target esp32c3 -- Project sdkconfig file D:/esp32_C3/vendor_0.1.5/sdkconfig -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/riscv/ld/rom.api.ld -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/soc/esp32c3/ld/esp32c3.peripherals.ld -- Bootloader project name: "bootloader" version: 1 -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/esp_rom/esp32c3/ld/esp32c3.rom.ld -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/esp_rom/esp32c3/ld/esp32c3.rom.api.ld -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/esp_rom/esp32c3/ld/esp32c3.rom.bt_funcs.ld -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/esp_rom/esp32c3/ld/esp32c3.rom.libgcc.ld -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/esp_rom/esp32c3/ld/esp32c3.rom.version.ld -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld -- Adding linker script E:/espidf/v5.4.1/esp-idf/components/bootloader/subproject/main/ld/esp32c3/bootloader.rom.ld -- Components: bootloader bootloader_support efuse esp_app_format esp_bootloader_format esp_common esp_hw_support esp_rom esp_security esp_system esptool_py freertos hal log main micro-ecc newlib partition_table riscv soc spi_flash -- Component paths: E:/espidf/v5.4.1/esp-idf/components/bootloader E:/espidf/v5.4.1/esp-idf/components/bootloader_support E:/espidf/v5.4.1/esp-idf/components/efuse E:/espidf/v5.4.1/esp-idf/components/esp_app_format E:/espidf/v5.4.1/esp-idf/components/esp_bootloader_format E:/espidf/v5.4.1/esp-idf/components/esp_common E:/espidf/v5.4.1/esp-idf/components/esp_hw_support E:/espidf/v5.4.1/esp-idf/components/esp_rom E:/espidf/v5.4.1/esp-idf/components/esp_security E:/espidf/v5.4.1/esp-idf/components/esp_system E:/espidf/v5.4.1/esp-idf/components/esptool_py E:/espidf/v5.4.1/esp-idf/components/freertos E:/espidf/v5.4.1/esp-idf/components/hal E:/espidf/v5.4.1/esp-idf/components/log E:/espidf/v5.4.1/esp-idf/components/bootloader/subproject/main E:/espidf/v5.4.1/esp-idf/components/bootloader/subproject/components/micro-ecc E:/espidf/v5.4.1/esp-idf/components/newlib E:/espidf/v5.4.1/esp-idf/components/partition_table E:/espidf/v5.4.1/esp-idf/components/riscv E:/espidf/v5.4.1/esp-idf/components/soc E:/espidf/v5.4.1/esp-idf/components/spi_flash -- Configuring done (11.1s) -- Generating done (0.1s) -- Build files have been written to: D:/esp32_C3/vendor_0.1.5/build/bootloader ninja: build stopped: subcommand failed. * 终端进程“e:\espidf\espressif\tools\ninja\1.12.1\ninja.EXE”已终止,退出代码: 1。
最新发布
07-16
<think>根据编译错误信息,主要问题集中在`main.c`文件中的`uart_select_mode`函数: 1. 隐式声明函数`uart_read_bytes`和`strstr` 2. 未声明`UART_NUM_0` 解决方案: 1. 包含必要的头文件:`#include <string.h>` 和 `#include "driver/uart.h"` 2. 确保在`main.c`中包含了这些头文件 另外,在`uart_select_mode`函数中使用了`uart_read_bytes`,该函数需要包含`driver/uart.h`头文件。同时,`strstr`函数需要包含`string.h`。 修改`main.c`文件: - 在文件顶部添加必要的头文件 - 确保`UART_NUM_0`被正确声明(它在`driver/uart.h`中定义) 此外,根据错误提示,`strstr`的隐式声明警告是因为没有包含`<string.h>`,所以添加该头文件。 修改后的`main.c`文件顶部应该包含如下头文件: ```c #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "nvs_flash.h" #include "board.h" #include "config_store.h" #include "uart_handler.h" #include "ble_mesh.h" #include "heartbeat.h" // 添加以下两个头文件 #include <string.h> #include "driver/uart.h" ``` 这样修改后,应该可以解决上述编译错误。 但是,请注意,在`uart_select_mode`函数中,我们使用了`uart_read_bytes`,这个函数在`driver/uart.h`中声明。同时,`UART_NUM_0`也在该头文件中定义。 另外,在错误信息中还有关于bootloader的构建失败,但主要问题似乎是`main.c`的编译错误导致的整个构建失败。先解决`main.c`的编译错误,然后重新构建。 如果还有其他错误,请根据错误信息进一步调整。 下面给出修改后的`main.c`完整代码:</think>根据您提供的编译错误信息,问题主要集中在`uart_select_mode`函数中。以下是完整的修复方案: ### 修复后的 `main.c` ```c #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "nvs_flash.h" #include "board.h" #include "config_store.h" #include "uart_handler.h" // 包含uart_read_bytes的声明 #include "ble_mesh.h" #include "heartbeat.h" #include <string.h> // 添加strstr函数声明 static const char *TAG = "MAIN"; // 通过UART选择模式(修复版) device_mode_t uart_select_mode(void) { char buffer[64] = {0}; // 使用uart_handler.h中声明的uart_read_bytes int len = uart_read_bytes(UART_NUM_0, (uint8_t*)buffer, sizeof(buffer)-1, pdMS_TO_TICKS(5000)); if (len > 0) { buffer[len] = '\0'; if (strstr(buffer, "MODE:PROVISIONER")) { ESP_LOGI(TAG, "选择配网器模式"); return MODE_PROVISIONER; } } ESP_LOGI(TAG, "默认选择节点模式"); return MODE_NODE; } void app_main(void) { // 1. 初始化基础组件 ESP_ERROR_CHECK(nvs_flash_init()); board_init(); config_store_init(); uart_handler_init(); // 初始化UART驱动 // 2. 通过UART选择模式 device_mode_t mode = uart_select_mode(); // 3. 初始化BLE Mesh if (ble_mesh_init(mode) != ESP_OK) { ESP_LOGE(TAG, "BLE Mesh初始化失败"); return; } // 4. 注册回调 ble_mesh_register_callbacks(); // 5. 启动任务 uart_start_task(); // 6. 如果已配网则启动心跳 if (ble_mesh_is_provisioned()) { heartbeat_start_task(); } ESP_LOGI(TAG, "系统启动完成"); // 主循环 while (1) { vTaskDelay(pdMS_TO_TICKS(1000)); } } ``` ### 修复说明 1. **添加缺失的头文件包含**: ```c #include <string.h> // 添加strstr函数声明 ``` - 解决`strstr`函数隐式声明问题 - 确保字符串处理函数正确声明 2. **确保UART相关声明可见**: ```c #include "uart_handler.h" // 包含uart_read_bytes的声明 ``` - 在`uart_handler.h`中添加必要的声明: ```c // 在uart_handler.h中添加以下声明 int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait); #define UART_NUM_0 0 ``` 3. **完整的`uart_handler.h`修复**: ```c #ifndef UART_HANDLER_H #define UART_HANDLER_H #include <stdint.h> #include "driver/uart.h" // 添加UART相关定义 #include "freertos/task.h" // UART端口定义 #define UART_NUM_0 0 // 初始化UART void uart_handler_init(void); // 启动UART任务 void uart_start_task(void); // 解析命令 void parse_uart_command(const char *command); // 添加uart_read_bytes声明 int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait); #endif ``` ### 修复后的`uart_handler.c`实现 ```c #include "uart_handler.h" #include "model_handler.h" #include "config_store.h" #include "freertos/queue.h" #include "driver/uart.h" #include "esp_log.h" #include <string.h> // 添加strstr等函数声明 static const char *TAG = "UART"; static QueueHandle_t uart_queue = NULL; // 实现uart_read_bytes函数 int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait) { return uart_read_bytes(uart_num, buf, length, ticks_to_wait); } static void uart_task(void *arg) { uart_event_t event; uint8_t buffer[128]; char command[128]; size_t cmd_idx = 0; while (1) { if (xQueueReceive(uart_queue, &event, portMAX_DELAY)) { bzero(buffer, sizeof(buffer)); switch (event.type) { case UART_DATA: int len = uart_read_bytes(UART_NUM_0, buffer, event.size, portMAX_DELAY); for (int i = 0; i < len; i++) { uint8_t c = buffer[i]; if (c == '\r' || c == '\n') { if (cmd_idx > 0) { command[cmd_idx] = '\0'; parse_uart_command(command); cmd_idx = 0; } } else if (cmd_idx < sizeof(command) - 1) { command[cmd_idx++] = c; } else { cmd_idx = 0; // 缓冲区溢出,重置 } } break; default: break; } } } } void uart_handler_init(void) { uart_config_t config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, .source_clk = UART_SCLK_DEFAULT, }; uart_param_config(UART_NUM_0, &config); uart_driver_install(UART_NUM_0, 1024 * 2, 1024 * 2, 20, &uart_queue, 0); uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); } void uart_start_task(void) { xTaskCreate(uart_task, "uart_task", 4096, NULL, 10, NULL); ESP_LOGI(TAG, "UART任务启动"); } void parse_uart_command(const char *command) { if (command == NULL || *command == '\0') return; ESP_LOGI(TAG, "解析指令: %s", command); if (strncmp(command, "SET_GROUP:", 10) == 0) { char *group_str = command + 10; uint16_t new_id = (uint16_t)strtoul(group_str, NULL, 16); config_set_group_id(new_id); } else if (strncmp(command, "SEND:", 5) == 0) { char *addr_str = command + 5; char *colon = strchr(addr_str, ':'); if (colon) { *colon = '\0'; uint16_t addr = (uint16_t)strtoul(addr_str, NULL, 16); model_send_message(addr, colon + 1); } } else if (strncmp(command, "GROUP_SEND:", 11) == 0) { model_send_message(config_get_group_id(), command + 11); } else if (strcmp(command, "HEARTBEAT_TEST") == 0) { heartbeat_send(); } else { ESP_LOGW(TAG, "未知指令: %s", command); } } ``` ### 关键修复点 1. **头文件包含修复**: - 在`main.c`中添加`#include <string.h>`解决`strstr`隐式声明问题 - 确保`uart_handler.h`包含`#include "driver/uart.h"`提供UART相关定义 2. **函数声明修复**: - 在`uart_handler.h`中添加`uart_read_bytes`的函数声明 - 在`uart_handler.c`中实现`uart_read_bytes`包装函数 3. **常量定义修复**: - 在`uart_handler.h`中添加`#define UART_NUM_0 0`定义 - 确保所有使用UART端口的地方都有明确定义 4. **编译依赖修复**: - 确保所有使用字符串函数的文件都包含`#include <string.h>` - 确保UART相关操作在正确的驱动上下文中执行 ### 验证修复 修复后重新编译,应该解决以下问题: 1. `implicit declaration of function 'uart_read_bytes'` 错误 2. `'UART_NUM_0' undeclared` 错误 3. `implicit declaration of function 'strstr'` 错误 4. `incompatible implicit declaration of built-in function 'strstr'` 警告 ### 常见问题预防 1. **头文件包含顺序**: - 系统头文件(如`<string.h>`)放在项目头文件之前 - 避免循环包含 2. **函数声明**: - 所有外部函数都应在头文件中声明 - 使用`#ifndef`保护头文件避免重复包含 3. **常量定义**: - 使用项目范围的常量定义文件 - 避免在多个文件中重复定义相同常量 4. **编译警告处理**: - 始终处理所有编译警告 - 使用`-Wall -Werror`标志确保代码质量
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值