# Android 应用调试日志抓取指南 ## 当前日志配置分析 ### ✅ 已有日志点 应用在关键位置使用 `android.util.Log` 记录日志: | 日志标签 | 位置 | 日志内容 | |---------|------|---------| | `MainViewModel` | 所有 ViewModel 操作 | 会话创建、参与者加入、TSS进度、异常 | | `TssRepository` | 所有 Repository 操作 | gRPC调用、TSS native调用、数据库操作 | | `GrpcClient` | 网络通信 | gRPC连接、请求/响应、错误 | | `TssNativeBridge` | TSS原生库 | 密钥生成、签名、错误 | ### 📋 关键日志内容 #### 1. 会话创建(创建2-of-3钱包) ``` MainViewModel: Creating new session: walletName=xxx, t=2, n=3 MainViewModel: Session created: sessionId=xxx, inviteCode=xxx MainViewModel: Session status fetched: X participants already joined MainViewModel: Participants: [partyId1, partyId2, ...] ``` #### 2. 密钥生成触发 ``` MainViewModel: Session started event for keygen initiator, triggering keygen MainViewModel: Starting keygen as initiator: sessionId=xxx, t=2, n=3 TssRepository: Starting keygen as initiator TssNativeBridge: keygenAsInitiator called ``` #### 3. 异常捕获(safeLaunch) ``` MainViewModel: Caught exception in safeLaunch [Stack trace...] ``` --- ## 🔍 日志抓取命令 ### 方案 1: 实时日志(推荐用于复现问题) ```bash # 清除旧日志 adb logcat -c # 实时查看所有应用日志(带时间戳) adb logcat -v time | grep -E "MainViewModel|TssRepository|GrpcClient|TssNativeBridge|AndroidRuntime" ``` ### 方案 2: 过滤关键标签(快速定位) ```bash # 只看应用相关日志 adb logcat MainViewModel:D TssRepository:D GrpcClient:D TssNativeBridge:D AndroidRuntime:E *:S ``` ### 方案 3: 保存完整日志到文件 ```bash # 清除旧日志 adb logcat -c # 重现问题(创建2-of-3钱包) # 保存日志到文件 adb logcat -d -v time > android_debug.log ``` --- ## 🎯 重点关注的日志 ### 创建 2-of-3 钱包失败时需要看到: #### ✅ 必须有的日志(正常流程) 1. **会话创建请求**: ``` MainViewModel: Creating new session: walletName=测试钱包, t=2, n=3, participantName=xxx ``` 2. **会话创建成功**: ``` MainViewModel: Session created successfully MainViewModel: sessionId: xxxxxxxx MainViewModel: inviteCode: ABCD1234 ``` 3. **获取会话状态**: ``` MainViewModel: Session status fetched: 2 participants already joined MainViewModel: Participants: [party-id-1, party-id-2] ``` 4. **收到 session_started 事件**: ``` MainViewModel: === MainViewModel received session event === MainViewModel: eventType: session_started MainViewModel: sessionId: xxxxxxxx ``` 5. **触发密钥生成**: ``` MainViewModel: Session started event for keygen initiator, triggering keygen MainViewModel: Starting keygen as initiator: sessionId=xxx, t=2, n=3 ``` 6. **TSS 原生库调用**: ``` TssNativeBridge: keygenAsInitiator called with sessionId=xxx TssNativeBridge: Keygen completed successfully ``` 7. **进度更新**: ``` MainViewModel: Progress update: 1 / 9 MainViewModel: Progress update: 2 / 9 ... MainViewModel: Progress update: 9 / 9 ``` #### ❌ 可能出现的错误日志 1. **safeLaunch 捕获的异常**: ``` MainViewModel: Caught exception in safeLaunch java.net.SocketTimeoutException: timeout at ... ``` 2. **gRPC 连接失败**: ``` GrpcClient: Failed to connect to server GrpcClient: Error: UNAVAILABLE: io exception ``` 3. **TSS 原生库错误**: ``` TssNativeBridge: keygenAsInitiator failed: [error message] ``` 4. **会话创建失败**: ``` MainViewModel: Service check failed TssRepository: Failed to create session: [error message] ``` --- ## 🚨 关键问题检查点 ### 1. 检查 safeLaunch 是否吞掉了异常 搜索日志中的: ``` "Caught exception in safeLaunch" ``` 如果有这行,说明异常被捕获了,查看后续的堆栈跟踪。 ### 2. 检查是否有 Result.failure 未处理 搜索: ``` "onFailure" "Failed to" "Error:" ``` ### 3. 检查 session_started 事件是否触发 搜索: ``` "Session started event for keygen initiator" ``` 如果**没有这行**,说明事件回调没有触发,密钥生成没有启动。 ### 4. 检查参与者计数 搜索: ``` "Session status fetched: X participants" ``` 如果参与者数量 < thresholdT(例如 2-of-3 需要至少2个参与者),会话不会启动。 --- ## 📊 日志分析流程图 ``` 启动应用 ↓ [搜索] "Service check" ├─ 成功 → 继续 └─ 失败 → 检查数据库/网络/原生库错误 ↓ 点击"创建钱包" ↓ [搜索] "Creating new session" ├─ 有 → 继续 └─ 无 → UI事件未触发(前端问题) ↓ [搜索] "Session created successfully" ├─ 有 → 继续 └─ 无 → 检查 gRPC 错误或 "onFailure" ↓ [搜索] "Session status fetched: X participants" ├─ 有 → 检查参与者数量是否 >= thresholdT └─ 无 → getSessionStatus 调用失败 ↓ [搜索] "Session started event" ├─ 有 → 继续 └─ 无 → WebSocket 事件未收到(服务器问题) ↓ [搜索] "Starting keygen as initiator" ├─ 有 → 继续 └─ 无 → safeLaunch 内部异常(搜索 "Caught exception") ↓ [搜索] "keygenAsInitiator called" ├─ 有 → 检查 "Keygen completed" 或 TSS错误 └─ 无 → 原生库调用未执行 ↓ [搜索] "Progress update" ├─ 有 → TSS 正在进行,检查是否完成 └─ 无 → TSS 未启动或卡住 ↓ [搜索] "Keygen completed successfully" ├─ 有 → 成功! └─ 无 → 检查 TSS 错误日志 ``` --- ## 🛠️ 调试建议 ### 如果看到 "Caught exception in safeLaunch" **原因**: safeLaunch 捕获了异常但可能没有正确显示给用户 **临时解决方案**: 查看异常堆栈,找到根本原因 **示例**: ``` MainViewModel: Caught exception in safeLaunch java.net.SocketTimeoutException: timeout at okhttp3.internal.connection.RealCall.execute at ... ``` → 说明 gRPC 连接超时 ### 如果没有 "Session started event" **原因**: WebSocket 事件回调未触发 **可能问题**: 1. service-party 服务器未运行 2. WebSocket 连接断开 3. 服务器未广播 session_started 事件 4. 参与者数量不足(< thresholdT) **检查**: ```bash # 检查服务器日志 tail -f /path/to/service-party/logs/server.log ``` ### 如果有 "Session started event" 但没有 "Starting keygen" **原因**: safeLaunch 内部的 startKeygenAsInitiator 调用失败 **检查**: - 搜索 "Caught exception in safeLaunch" - 查看异常类型和堆栈 --- ## 📝 日志模板(复制给我) 抓取日志后,请提供以下信息: ``` ### 1. 操作步骤 - [ ] 启动应用 - [ ] 点击"创建钱包" - [ ] 输入钱包名称: ___ - [ ] 选择 2-of-3 - [ ] 输入参与者名称: ___ - [ ] 点击"创建" - [ ] 【描述具体现象】: ___ ### 2. 关键日志片段 #### 会话创建 ``` [粘贴包含 "Creating new session" 的日志] ``` #### 会话状态 ``` [粘贴包含 "Session status fetched" 的日志] ``` #### 事件触发 ``` [粘贴包含 "Session started event" 的日志] ``` #### 异常(如果有) ``` [粘贴包含 "Caught exception" 的日志] ``` ### 3. 完整日志文件 [附件: android_debug.log] ``` --- ## 🔧 临时调试增强(如需更详细日志) 如果标准日志不够详细,可以临时添加更多日志: ### 在 MainViewModel.kt 的 safeLaunch 中: ```kotlin private fun safeLaunch( onError: ((Exception) -> Unit)? = null, block: suspend CoroutineScope.() -> Unit ) = viewModelScope.launch { try { android.util.Log.d("MainViewModel", "safeLaunch: Starting block") // 添加这行 block() android.util.Log.d("MainViewModel", "safeLaunch: Block completed successfully") // 添加这行 } catch (e: CancellationException) { android.util.Log.d("MainViewModel", "safeLaunch: CancellationException caught") // 添加这行 throw e } catch (e: Exception) { android.util.Log.e("MainViewModel", "safeLaunch: Caught exception: ${e.javaClass.simpleName}", e) // ... 现有代码 ... } } ``` --- ## ⚠️ 常见陷阱 ### 1. 异常被吞掉但 UI 不显示错误 **症状**: 操作无反应,没有错误提示 **原因**: safeLaunch 更新了 _uiState.error 但 UI 没有订阅 **检查**: 搜索日志中的 "Caught exception",看是否有异常但 UI 没反应 ### 2. Result.failure 未正确处理 **症状**: repository 返回 failure 但 ViewModel 没有处理 **检查**: 搜索 "onFailure" 和 "result.fold" ### 3. 协程被取消 **症状**: 操作执行到一半停止 **检查**: 搜索 "CancellationException" --- ## 📱 完整抓取命令(复制粘贴) ```bash # 1. 清除旧日志 adb logcat -c # 2. 开始记录(在另一个终端) adb logcat -v time > ~/Desktop/android_debug_$(date +%Y%m%d_%H%M%S).log # 3. 操作应用(重现问题) # 4. 停止记录(Ctrl+C) # 5. 发送日志文件给我 ``` 或者一步到位(操作完后手动停止): ```bash adb logcat -c && adb logcat -v time | tee android_debug.log | grep --color -E "MainViewModel|TssRepository|GrpcClient|TssNativeBridge|Exception|Error" ``` --- **准备好后,请执行上述命令,重现创建2-of-3失败的问题,然后把日志发给我!**