Skip to content

Commit a178380

Browse files
update Pthread config
1 parent a7473a9 commit a178380

File tree

5 files changed

+481
-109
lines changed

5 files changed

+481
-109
lines changed

Kconfig

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ menu "ESP32 SignalR Client Configuration"
1111

1212
config SIGNALR_WORKER_STACK_SIZE
1313
int "Worker task stack size (bytes)"
14-
default 3072
14+
default 6144
1515
range 2048 8192
1616
help
1717
Stack size for each worker task in bytes.
18-
Default: 3072 (3KB, optimized for ESP32)
19-
Recommended: 3KB for simple callbacks, 4KB for complex processing
18+
CRITICAL: C++ exception handling requires minimum 4-5KB stack!
19+
Default: 6144 (6KB) - required for safe exception unwinding
20+
Old default 3KB caused stack overflow during send() failures with exceptions.
21+
DO NOT reduce below 4096 unless you disable all exception throwing.
2022
Enable CONFIG_SIGNALR_ENABLE_STACK_MONITORING to measure actual usage.
2123

2224
config SIGNALR_SCHEDULER_STACK_SIZE

docs/PTHREAD_STACK_FIX.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# pthread栈溢出紧急修复指南
2+
3+
## ⚠️ CRITICAL: pthread任务栈太小!
4+
5+
### 崩溃信息
6+
```
7+
Guru Meditation Error: Core 0 panic'ed (Stack protection fault).
8+
Detected in task "pthread" at 0x403801da
9+
Stack bounds: 0x3fc97cb0 - 0x3fc982b0 (仅 2.6KB!)
10+
```
11+
12+
**根本原因**:ESP-IDF默认pthread栈只有**3KB**,C++异常需要4-5KB!
13+
14+
## 🔥 立即修复
15+
16+
### 方案1:增加pthread默认栈大小(推荐)
17+
18+
在项目根目录运行:
19+
```bash
20+
idf.py menuconfig
21+
```
22+
23+
导航到:
24+
```
25+
Component config →
26+
Pthread →
27+
Default task stack size (PTHREAD_TASK_STACK_SIZE_DEFAULT)
28+
```
29+
30+
**将默认值从 3072 改为 8192** (8KB)
31+
32+
或者直接在 `sdkconfig` 中添加/修改:
33+
```ini
34+
CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=8192
35+
```
36+
37+
### 方案2:禁用C++异常(极限优化)
38+
39+
如果内存极度紧张,可以禁用异常:
40+
```bash
41+
idf.py menuconfig
42+
```
43+
44+
导航到:
45+
```
46+
Compiler options →
47+
Enable C++ exceptions (COMPILER_CXX_EXCEPTIONS)
48+
[✗] 取消勾选
49+
```
50+
51+
或在 `sdkconfig` 中:
52+
```ini
53+
# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
54+
```
55+
56+
⚠️ **警告**:禁用异常会破坏SignalR SDK,需要大量代码重构!
57+
58+
## 🎯 推荐配置
59+
60+
### 最佳配置(稳定性优先)
61+
```ini
62+
# Pthread配置
63+
CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=8192
64+
65+
# SignalR配置
66+
CONFIG_SIGNALR_WORKER_STACK_SIZE=6144
67+
CONFIG_SIGNALR_CALLBACK_STACK_SIZE=6144
68+
CONFIG_SIGNALR_MAX_CALLBACK_TASKS=3
69+
```
70+
71+
### 平衡配置(内存有限)
72+
```ini
73+
# Pthread配置
74+
CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=6144
75+
76+
# SignalR配置
77+
CONFIG_SIGNALR_WORKER_STACK_SIZE=6144
78+
CONFIG_SIGNALR_CALLBACK_STACK_SIZE=4096
79+
CONFIG_SIGNALR_MAX_CALLBACK_TASKS=2
80+
```
81+
82+
### 极限配置(不推荐)
83+
```ini
84+
# Pthread配置
85+
CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=4096
86+
87+
# SignalR配置
88+
CONFIG_SIGNALR_WORKER_STACK_SIZE=4096
89+
CONFIG_SIGNALR_CALLBACK_STACK_SIZE=3072
90+
CONFIG_SIGNALR_MAX_CALLBACK_TASKS=1
91+
```
92+
93+
## 📊 内存成本对比
94+
95+
| 配置 | Pthread | Worker | 回调 | 总计 | 稳定性 |
96+
|------|---------|--------|------|------|--------|
97+
| **推荐** | 8KB | 6KB×2 | 6KB×3 | **38KB** | ⭐⭐⭐⭐⭐ |
98+
| 平衡 | 6KB | 6KB×2 | 4KB×2 | 26KB | ⭐⭐⭐⭐ |
99+
| 极限 | 4KB | 4KB×2 | 3KB×1 | 15KB | ⭐⭐ |
100+
| 当前(崩溃) | **3KB** | 6KB×2 | 6KB×3 | 33KB ||
101+
102+
## 🔍 诊断
103+
104+
### 检查当前配置
105+
```bash
106+
grep PTHREAD_TASK_STACK sdkconfig
107+
grep SIGNALR_ sdkconfig
108+
```
109+
110+
### 查看栈使用
111+
在日志中搜索:
112+
```
113+
Worker task exiting - stack: XXX bytes used, YYY bytes free
114+
Callback task final statistics: XXX bytes used, YYY bytes free
115+
```
116+
117+
如果"bytes free"低于512,**必须增加栈!**
118+
119+
## 🚀 验证修复
120+
121+
重新编译并测试:
122+
```bash
123+
idf.py build flash monitor
124+
```
125+
126+
观察日志:
127+
1. ✅ 不再出现"Stack protection fault"
128+
2. ✅ 栈使用统计显示有足够余量
129+
3. ✅ 网络断开重连不会崩溃
130+
131+
## 💡 为什么pthread会执行SignalR代码?
132+
133+
ESP-IDF的某些组件(如WebSocket客户端的事件处理)**可能在pthread上下文中执行**
134+
135+
```
136+
ESP WebSocket库内部事件
137+
138+
调用用户回调(在pthread中)
139+
140+
SignalR代码执行
141+
142+
C++异常展开
143+
144+
pthread栈溢出!💥
145+
```
146+
147+
## ✅ 已完成的优化
148+
149+
1.**预创建9个静态异常对象**
150+
- 启动时创建一次
151+
- 运行时零开销
152+
153+
2.**Worker栈增加到6KB**
154+
155+
3.**回调任务栈增加到6KB**
156+
157+
4.**WebSocket任务栈增加到8KB**
158+
159+
## ❌ 仍需手动配置
160+
161+
-**pthread栈** - 需要在`menuconfig``sdkconfig`中设置
162+
163+
## 📝 总结
164+
165+
### 立即行动
166+
```bash
167+
# 1. 配置pthread栈
168+
idf.py menuconfig
169+
# 设置 Pthread → Default task stack size = 8192
170+
171+
# 2. 重新编译
172+
idf.py build
173+
174+
# 3. 烧录测试
175+
idf.py flash monitor
176+
```
177+
178+
### 期望结果
179+
- ✅ pthread栈从3KB → 8KB
180+
- ✅ 完全消除栈溢出
181+
- ✅ 稳定运行不崩溃
182+
- ✅ 内存总开销:+5KB
183+
184+
---
185+
186+
**更新日期**: 2026-01-09
187+
**严重程度**: CRITICAL
188+
**状态**: ⚠️ 需要手动配置pthread栈

0 commit comments

Comments
 (0)