已关闭
并发导致的闪退 #99
lvyandong创建于 8月14日关闭于 8月24日
程皖Orz
8月15日 评论:
8月15日 评论:
您好,您发的问题我们已接收到,看到您已经提供了解决方案,我们现在进行排查,如果明确是问题的话会有对应pr关联您的issue,如果是其他原因会在本issue下跟踪回复


8月20日 关联了pull request:ADD: 新增 Issue #99 pooled Unary 并发压测复现用例与 Demo
8月24日 关联了pull request:修复稳定性崩溃问题
8月24日 删除了关联的pull request:修复稳定性崩溃问题
8月24日 关联了pull request:修复稳定性崩溃问题
8月24日 删除了关联的pull request:修复稳定性崩溃问题
8月24日 关联了pull request:修复稳定性崩溃问题
程皖Orz
8月24日 评论:
8月24日 评论:
您好,针对这个堆栈,我们尝试进行了复现,并且已有demo复现成功,已经提了pr https://gitcode.com/CPF-ApplicationTPC/ohos_grpc_node/pull/99 ,按照正常流程,这个pr先进行关闭处理,您可以看下我们修改的内容,如果有疑问之类的欢迎再次提交issue


8月24日 关闭了 issue
9月22日 关联了pull request:fix: Fix the issue of UAF crash triggered by grpc probability.
0, std::__n1::allocator>)+136) [::2a1743f7315a5f32136a90327f5c5533]
#00 pc 000000000006bdbc /data/storage/el1/bundle/libs/arm64/libhttp2_napi.so [::2a1743f7315a5f32136a90327f5c5533]
1
#01 pc 0000000000052588 /data/storage/el1/bundle/libs/arm64/libhttp2_napi.so (OnStreamCloseCallback(nghttp2_session*, int, unsigned int, void*)+1620) [::2a1743f7315a5f32136a90327f5c5533]
2
#02 pc 0000000000018a88 /data/storage/el1/bundle/libs/arm64/libnghttp2.so.14 [::2d114b6e2fccab8f7e1090125d27feb4]
3
#03 pc 000000000001ed5c /data/storage/el1/bundle/libs/arm64/libnghttp2.so.14 (nghttp2_session_mem_recv2+7416) [::2d114b6e2fccab8f7e1090125d27feb4]
4
#04 pc 000000000001f5c4 /data/storage/el1/bundle/libs/arm64/libnghttp2.so.14 (nghttp2_session_recv+140) [::2d114b6e2fccab8f7e1090125d27feb4]
5
#05 pc 0000000000054a64 /data/storage/el1/bundle/libs/arm64/libhttp2_napi.so (HandleIo(Connection*, std::__n1::basic_string<char, std::__n1::char_traits
6
#06 pc 0000000000057304 /data/storage/el1/bundle/libs/arm64/libhttp2_napi.so (ReadWriteBuffer(pollfd*, int, Connection&, RequestTask*, bool&)+264) [::2a1743f7315a5f32136a90327f5c5533]
7
#07 pc 000000000003dec4 /data/storage/el1/bundle/libs/arm64/libhttp2_napi.so (HandleWritePooled(RequestTask*)+4804) [::2a1743f7315a5f32136a90327f5c5533]
8
#08 pc 0000000000067320 /system/lib64/platformsdk/libace_napi.z.so (NativeAsyncWork::AsyncWorkCallback(uv_work_s*)+304) [::450a6d44bdb4f26d59104e95c83ef40c]
14
#14 pc 00000000001e3ba8 /system/lib/ld-musl-aarch64.so.1 (start+240) [::9dfb43ddce39af2e816005522a86e123]
问题摘要
问题名称:HTTP/2 流关闭回调中的野指针访问
异常分析:
SIGSEGV 表示非法内存访问(段错误),发生在 libhttp2_napi.so 的 OnStreamCloseCallback 函数中(偏移量 1612)。
调用栈显示崩溃发生在 HTTP/2 会话处理流关闭时(nghttp2_session_mem_recv2 → OnStreamCloseCallback),最终由异步 I/O 线程触发(libuv/libffrt)。
场景日志表明崩溃发生在页面导航期间(如 SplashPage → AdPage 切换),可能与网络请求生命周期管理相关。
可能原因(按可能性排序)
分析依据:
OnStreamCloseCallback 是 HTTP/2 流关闭时的回调函数。崩溃发生在该函数内部(#01),可能因访问已释放的流对象(如 Connection 或 RequestTask)导致野指针。
佐证:
调用栈 #05 的 HandleIo 和 #07 的 HandleWrite 涉及 Connection 和 RequestTask,这些对象可能在流关闭前被意外释放。
分析依据:
调用栈 #09-#14 显示操作在异步线程(libuv/libffrt)执行,而 HTTP/2 会话可能被主线程或其他线程同时操作。
佐证:
nghttp2_session_recv(#04)和 OnStreamCloseCallback(#01)未同步访问共享数据,可能导致 session 或 stream 状态不一致。
分析依据:
SIGSEGV 可能因相邻内存越界写入破坏流对象指针(如 RequestTask* 在 #07 被传入)。
佐证:
调用栈 #06 的 ReadWriteBuffer 涉及缓冲区操作,若缓冲区大小计算错误可能引发越界。
解决方案
修改逻辑:在 OnStreamCloseCallback 中增加流对象有效性检查,使用弱引用或智能指针管理对象。
代码示例(伪代码):
// 修改 OnStreamCloseCallback 实现
void OnStreamCloseCallback(nghttp2_session* session, int stream_id, ...) {
// 从 session 获取流对象时检查有效性
StreamContext* ctx = static_cast<StreamContext*>(nghttp2_session_get_stream_user_data(session, stream_id));
if (!ctx || ctx->is_invalid) { // 增加有效性检查
return; // 跳过无效对象
}
// ...原有逻辑...
}
修改逻辑:为 HTTP/2 会话操作添加锁(如 std::mutex),确保回调期间对象不被释放。
代码示例:
// 在 Connection 类中添加互斥锁
class Connection {
std::mutex session_mutex;
nghttp2_session* session;
};
// 在操作 session 前加锁
void HandleIo(Connection* conn) {
std::lock_guardstd::mutex lock(conn->session_mutex);
nghttp2_session_recv(conn->session, ...);
}