9.4 KiB
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: 实时日志(推荐用于复现问题)
# 清除旧日志
adb logcat -c
# 实时查看所有应用日志(带时间戳)
adb logcat -v time | grep -E "MainViewModel|TssRepository|GrpcClient|TssNativeBridge|AndroidRuntime"
方案 2: 过滤关键标签(快速定位)
# 只看应用相关日志
adb logcat MainViewModel:D TssRepository:D GrpcClient:D TssNativeBridge:D AndroidRuntime:E *:S
方案 3: 保存完整日志到文件
# 清除旧日志
adb logcat -c
# 重现问题(创建2-of-3钱包)
# 保存日志到文件
adb logcat -d -v time > android_debug.log
🎯 重点关注的日志
创建 2-of-3 钱包失败时需要看到:
✅ 必须有的日志(正常流程)
-
会话创建请求:
MainViewModel: Creating new session: walletName=测试钱包, t=2, n=3, participantName=xxx -
会话创建成功:
MainViewModel: Session created successfully MainViewModel: sessionId: xxxxxxxx MainViewModel: inviteCode: ABCD1234 -
获取会话状态:
MainViewModel: Session status fetched: 2 participants already joined MainViewModel: Participants: [party-id-1, party-id-2] -
收到 session_started 事件:
MainViewModel: === MainViewModel received session event === MainViewModel: eventType: session_started MainViewModel: sessionId: xxxxxxxx -
触发密钥生成:
MainViewModel: Session started event for keygen initiator, triggering keygen MainViewModel: Starting keygen as initiator: sessionId=xxx, t=2, n=3 -
TSS 原生库调用:
TssNativeBridge: keygenAsInitiator called with sessionId=xxx TssNativeBridge: Keygen completed successfully -
进度更新:
MainViewModel: Progress update: 1 / 9 MainViewModel: Progress update: 2 / 9 ... MainViewModel: Progress update: 9 / 9
❌ 可能出现的错误日志
-
safeLaunch 捕获的异常:
MainViewModel: Caught exception in safeLaunch java.net.SocketTimeoutException: timeout at ... -
gRPC 连接失败:
GrpcClient: Failed to connect to server GrpcClient: Error: UNAVAILABLE: io exception -
TSS 原生库错误:
TssNativeBridge: keygenAsInitiator failed: [error message] -
会话创建失败:
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 事件回调未触发
可能问题:
- service-party 服务器未运行
- WebSocket 连接断开
- 服务器未广播 session_started 事件
- 参与者数量不足(< thresholdT)
检查:
# 检查服务器日志
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 中:
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"
📱 完整抓取命令(复制粘贴)
# 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. 发送日志文件给我
或者一步到位(操作完后手动停止):
adb logcat -c && adb logcat -v time | tee android_debug.log | grep --color -E "MainViewModel|TssRepository|GrpcClient|TssNativeBridge|Exception|Error"
准备好后,请执行上述命令,重现创建2-of-3失败的问题,然后把日志发给我!