@gracker/smartperfetto 1.0.14 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +16 -8
- package/dist/agent/agents/base/baseAgent.d.ts.map +1 -1
- package/dist/agent/agents/base/baseAgent.js +5 -1
- package/dist/agent/agents/base/baseAgent.js.map +1 -1
- package/dist/agent/context/enhancedSessionContext.d.ts +5 -0
- package/dist/agent/context/enhancedSessionContext.d.ts.map +1 -1
- package/dist/agent/context/enhancedSessionContext.js +13 -0
- package/dist/agent/context/enhancedSessionContext.js.map +1 -1
- package/dist/agent/core/conclusionContract.d.ts +16 -1
- package/dist/agent/core/conclusionContract.d.ts.map +1 -1
- package/dist/agent/core/conclusionGenerator.d.ts.map +1 -1
- package/dist/agent/core/conclusionGenerator.js +90 -7
- package/dist/agent/core/conclusionGenerator.js.map +1 -1
- package/dist/agent/core/executors/directSkillExecutor.d.ts.map +1 -1
- package/dist/agent/core/executors/directSkillExecutor.js +6 -12
- package/dist/agent/core/executors/directSkillExecutor.js.map +1 -1
- package/dist/agent/core/orchestratorTypes.d.ts +16 -0
- package/dist/agent/core/orchestratorTypes.d.ts.map +1 -1
- package/dist/agent/core/orchestratorTypes.js.map +1 -1
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.d.ts.map +1 -1
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.js +4 -1
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.js.map +1 -1
- package/dist/agent/scene/sceneStage1Runner.d.ts +1 -1
- package/dist/agent/scene/sceneStage1Runner.d.ts.map +1 -1
- package/dist/agent/scene/sceneStage1Runner.js +1 -1
- package/dist/agent/scene/sceneStage1Runner.js.map +1 -1
- package/dist/agent/scene/sceneStoryService.d.ts +1 -1
- package/dist/agent/scene/sceneStoryService.d.ts.map +1 -1
- package/dist/agent/scene/sceneStoryService.js +4 -1
- package/dist/agent/scene/sceneStoryService.js.map +1 -1
- package/dist/agent/types/agentProtocol.d.ts.map +1 -1
- package/dist/agent/types/agentProtocol.js +4 -1
- package/dist/agent/types/agentProtocol.js.map +1 -1
- package/dist/agent/types.d.ts +7 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/agentOpenAI/openAiRuntime.d.ts.map +1 -1
- package/dist/agentOpenAI/openAiRuntime.js +11 -1
- package/dist/agentOpenAI/openAiRuntime.js.map +1 -1
- package/dist/agentOpenAI/openAiToolAdapter.d.ts.map +1 -1
- package/dist/agentOpenAI/openAiToolAdapter.js +27 -2
- package/dist/agentOpenAI/openAiToolAdapter.js.map +1 -1
- package/dist/agentv3/artifactStore.d.ts +5 -0
- package/dist/agentv3/artifactStore.d.ts.map +1 -1
- package/dist/agentv3/artifactStore.js +3 -0
- package/dist/agentv3/artifactStore.js.map +1 -1
- package/dist/agentv3/claudeMcpServer.d.ts +15 -1
- package/dist/agentv3/claudeMcpServer.d.ts.map +1 -1
- package/dist/agentv3/claudeMcpServer.js +436 -91
- package/dist/agentv3/claudeMcpServer.js.map +1 -1
- package/dist/agentv3/claudeRuntime.d.ts.map +1 -1
- package/dist/agentv3/claudeRuntime.js +17 -0
- package/dist/agentv3/claudeRuntime.js.map +1 -1
- package/dist/agentv3/claudeSystemPrompt.d.ts.map +1 -1
- package/dist/agentv3/claudeSystemPrompt.js +9 -0
- package/dist/agentv3/claudeSystemPrompt.js.map +1 -1
- package/dist/agentv3/mcpToolRegistry.d.ts +14 -2
- package/dist/agentv3/mcpToolRegistry.d.ts.map +1 -1
- package/dist/agentv3/mcpToolRegistry.js +25 -6
- package/dist/agentv3/mcpToolRegistry.js.map +1 -1
- package/dist/agentv3/sessionStateSnapshot.d.ts +41 -0
- package/dist/agentv3/sessionStateSnapshot.d.ts.map +1 -1
- package/dist/agentv3/types.d.ts +5 -0
- package/dist/agentv3/types.d.ts.map +1 -1
- package/dist/agentv3/types.js.map +1 -1
- package/dist/assistant/application/agentAnalyzeSessionService.d.ts +6 -0
- package/dist/assistant/application/agentAnalyzeSessionService.d.ts.map +1 -1
- package/dist/assistant/application/agentAnalyzeSessionService.js +9 -3
- package/dist/assistant/application/agentAnalyzeSessionService.js.map +1 -1
- package/dist/assistant/application/assistantApplicationService.d.ts.map +1 -1
- package/dist/assistant/application/assistantApplicationService.js +3 -1
- package/dist/assistant/application/assistantApplicationService.js.map +1 -1
- package/dist/cli-user/bin.js +99 -1
- package/dist/cli-user/bin.js.map +1 -1
- package/dist/cli-user/commands/analyze.d.ts +3 -0
- package/dist/cli-user/commands/analyze.d.ts.map +1 -1
- package/dist/cli-user/commands/analyze.js +2 -0
- package/dist/cli-user/commands/analyze.js.map +1 -1
- package/dist/cli-user/commands/codebase.d.ts +29 -0
- package/dist/cli-user/commands/codebase.d.ts.map +1 -0
- package/dist/cli-user/commands/codebase.js +152 -0
- package/dist/cli-user/commands/codebase.js.map +1 -0
- package/dist/cli-user/commands/config.d.ts.map +1 -1
- package/dist/cli-user/commands/config.js +4 -1
- package/dist/cli-user/commands/config.js.map +1 -1
- package/dist/cli-user/commands/report.js +64 -0
- package/dist/cli-user/commands/report.js.map +1 -1
- package/dist/cli-user/io/paths.d.ts +3 -0
- package/dist/cli-user/io/paths.d.ts.map +1 -1
- package/dist/cli-user/io/paths.js +6 -0
- package/dist/cli-user/io/paths.js.map +1 -1
- package/dist/cli-user/io/sessionStore.d.ts +1 -0
- package/dist/cli-user/io/sessionStore.d.ts.map +1 -1
- package/dist/cli-user/io/sessionStore.js +5 -0
- package/dist/cli-user/io/sessionStore.js.map +1 -1
- package/dist/cli-user/repl/renderer.d.ts +8 -0
- package/dist/cli-user/repl/renderer.d.ts.map +1 -1
- package/dist/cli-user/repl/renderer.js.map +1 -1
- package/dist/cli-user/services/cliAnalyzeService.d.ts +6 -0
- package/dist/cli-user/services/cliAnalyzeService.d.ts.map +1 -1
- package/dist/cli-user/services/cliAnalyzeService.js +183 -29
- package/dist/cli-user/services/cliAnalyzeService.js.map +1 -1
- package/dist/cli-user/services/turnPersistence.d.ts +0 -10
- package/dist/cli-user/services/turnPersistence.d.ts.map +1 -1
- package/dist/cli-user/services/turnPersistence.js +62 -0
- package/dist/cli-user/services/turnPersistence.js.map +1 -1
- package/dist/cli-user/services/turnRunner.d.ts +3 -0
- package/dist/cli-user/services/turnRunner.d.ts.map +1 -1
- package/dist/cli-user/services/turnRunner.js +6 -0
- package/dist/cli-user/services/turnRunner.js.map +1 -1
- package/dist/cli-user/types.d.ts +5 -0
- package/dist/cli-user/types.d.ts.map +1 -1
- package/dist/routes/agentReportRoutes.d.ts +1 -0
- package/dist/routes/agentReportRoutes.d.ts.map +1 -1
- package/dist/routes/agentReportRoutes.js +13 -2
- package/dist/routes/agentReportRoutes.js.map +1 -1
- package/dist/routes/agentResumeRoutes.d.ts.map +1 -1
- package/dist/routes/agentResumeRoutes.js +29 -5
- package/dist/routes/agentResumeRoutes.js.map +1 -1
- package/dist/routes/agentRoutes.d.ts.map +1 -1
- package/dist/routes/agentRoutes.js +297 -91
- package/dist/routes/agentRoutes.js.map +1 -1
- package/dist/routes/ragAdminRoutes.d.ts +13 -24
- package/dist/routes/ragAdminRoutes.d.ts.map +1 -1
- package/dist/routes/ragAdminRoutes.js +266 -11
- package/dist/routes/ragAdminRoutes.js.map +1 -1
- package/dist/scripts/verifyAgentSseScrolling.js +119 -3
- package/dist/scripts/verifyAgentSseScrolling.js.map +1 -1
- package/dist/services/agentEventStore.d.ts.map +1 -1
- package/dist/services/agentEventStore.js +13 -3
- package/dist/services/agentEventStore.js.map +1 -1
- package/dist/services/agentReportData.d.ts +3 -0
- package/dist/services/agentReportData.d.ts.map +1 -1
- package/dist/services/agentReportData.js.map +1 -1
- package/dist/services/analysisResultSnapshotPipeline.d.ts +3 -0
- package/dist/services/analysisResultSnapshotPipeline.d.ts.map +1 -1
- package/dist/services/analysisResultSnapshotPipeline.js +3 -0
- package/dist/services/analysisResultSnapshotPipeline.js.map +1 -1
- package/dist/services/analysisResultSnapshotStore.d.ts.map +1 -1
- package/dist/services/analysisResultSnapshotStore.js +34 -2
- package/dist/services/analysisResultSnapshotStore.js.map +1 -1
- package/dist/services/aospKnowledgeIngester.d.ts +7 -0
- package/dist/services/aospKnowledgeIngester.d.ts.map +1 -1
- package/dist/services/aospKnowledgeIngester.js +19 -7
- package/dist/services/aospKnowledgeIngester.js.map +1 -1
- package/dist/services/auth/codebaseScopes.d.ts +6 -0
- package/dist/services/auth/codebaseScopes.d.ts.map +1 -0
- package/dist/services/auth/codebaseScopes.js +23 -0
- package/dist/services/auth/codebaseScopes.js.map +1 -0
- package/dist/services/codebase/codeAwareFeature.d.ts +4 -0
- package/dist/services/codebase/codeAwareFeature.d.ts.map +1 -0
- package/dist/services/codebase/codeAwareFeature.js +18 -0
- package/dist/services/codebase/codeAwareFeature.js.map +1 -0
- package/dist/services/codebase/codeLookupLedger.d.ts +37 -0
- package/dist/services/codebase/codeLookupLedger.d.ts.map +1 -0
- package/dist/services/codebase/codeLookupLedger.js +126 -0
- package/dist/services/codebase/codeLookupLedger.js.map +1 -0
- package/dist/services/codebase/codebaseRegistry.d.ts +76 -0
- package/dist/services/codebase/codebaseRegistry.d.ts.map +1 -0
- package/dist/services/codebase/codebaseRegistry.js +164 -0
- package/dist/services/codebase/codebaseRegistry.js.map +1 -0
- package/dist/services/codebase/defaultCodebaseServices.d.ts +5 -0
- package/dist/services/codebase/defaultCodebaseServices.d.ts.map +1 -0
- package/dist/services/codebase/defaultCodebaseServices.js +21 -0
- package/dist/services/codebase/defaultCodebaseServices.js.map +1 -0
- package/dist/services/codebase/patchProposer.d.ts +44 -0
- package/dist/services/codebase/patchProposer.d.ts.map +1 -0
- package/dist/services/codebase/patchProposer.js +163 -0
- package/dist/services/codebase/patchProposer.js.map +1 -0
- package/dist/services/codebase/pathSecurityGate.d.ts +33 -0
- package/dist/services/codebase/pathSecurityGate.d.ts.map +1 -0
- package/dist/services/codebase/pathSecurityGate.js +214 -0
- package/dist/services/codebase/pathSecurityGate.js.map +1 -0
- package/dist/services/enterpriseSchema.d.ts.map +1 -1
- package/dist/services/enterpriseSchema.js +11 -0
- package/dist/services/enterpriseSchema.js.map +1 -1
- package/dist/services/evidence/evidenceContractBuilder.d.ts +11 -0
- package/dist/services/evidence/evidenceContractBuilder.d.ts.map +1 -0
- package/dist/services/evidence/evidenceContractBuilder.js +530 -0
- package/dist/services/evidence/evidenceContractBuilder.js.map +1 -0
- package/dist/services/htmlReportGenerator.d.ts +9 -0
- package/dist/services/htmlReportGenerator.d.ts.map +1 -1
- package/dist/services/htmlReportGenerator.js +133 -0
- package/dist/services/htmlReportGenerator.js.map +1 -1
- package/dist/services/persistAgentSession.d.ts.map +1 -1
- package/dist/services/persistAgentSession.js +24 -0
- package/dist/services/persistAgentSession.js.map +1 -1
- package/dist/services/processIdentity/identityContractMapper.d.ts +14 -0
- package/dist/services/processIdentity/identityContractMapper.d.ts.map +1 -0
- package/dist/services/processIdentity/identityContractMapper.js +135 -0
- package/dist/services/processIdentity/identityContractMapper.js.map +1 -0
- package/dist/services/processIdentity/types.d.ts +5 -0
- package/dist/services/processIdentity/types.d.ts.map +1 -1
- package/dist/services/processIdentity/types.js.map +1 -1
- package/dist/services/rag/aospSourceIngester.d.ts +26 -0
- package/dist/services/rag/aospSourceIngester.d.ts.map +1 -0
- package/dist/services/rag/aospSourceIngester.js +143 -0
- package/dist/services/rag/aospSourceIngester.js.map +1 -0
- package/dist/services/rag/appSourceIngester.d.ts +37 -0
- package/dist/services/rag/appSourceIngester.d.ts.map +1 -0
- package/dist/services/rag/appSourceIngester.js +165 -0
- package/dist/services/rag/appSourceIngester.js.map +1 -0
- package/dist/services/rag/baseIngester.d.ts +18 -0
- package/dist/services/rag/baseIngester.d.ts.map +1 -0
- package/dist/services/rag/baseIngester.js +197 -0
- package/dist/services/rag/baseIngester.js.map +1 -0
- package/dist/services/rag/kernelSourceIngester.d.ts +35 -0
- package/dist/services/rag/kernelSourceIngester.d.ts.map +1 -0
- package/dist/services/rag/kernelSourceIngester.js +170 -0
- package/dist/services/rag/kernelSourceIngester.js.map +1 -0
- package/dist/services/rag/lookupResponseFilter.d.ts +42 -0
- package/dist/services/rag/lookupResponseFilter.d.ts.map +1 -0
- package/dist/services/rag/lookupResponseFilter.js +192 -0
- package/dist/services/rag/lookupResponseFilter.js.map +1 -0
- package/dist/services/rag/sessionToolResultRegistry.d.ts +25 -0
- package/dist/services/rag/sessionToolResultRegistry.d.ts.map +1 -0
- package/dist/services/rag/sessionToolResultRegistry.js +57 -0
- package/dist/services/rag/sessionToolResultRegistry.js.map +1 -0
- package/dist/services/rag/toolResultProjectionFilter.d.ts +18 -0
- package/dist/services/rag/toolResultProjectionFilter.d.ts.map +1 -0
- package/dist/services/rag/toolResultProjectionFilter.js +33 -0
- package/dist/services/rag/toolResultProjectionFilter.js.map +1 -0
- package/dist/services/ragStore.d.ts +8 -0
- package/dist/services/ragStore.d.ts.map +1 -1
- package/dist/services/ragStore.js +77 -8
- package/dist/services/ragStore.js.map +1 -1
- package/dist/services/rbac.d.ts +1 -1
- package/dist/services/rbac.d.ts.map +1 -1
- package/dist/services/rbac.js +6 -0
- package/dist/services/rbac.js.map +1 -1
- package/dist/services/security/codeAwareOutputRegistry.d.ts +6 -0
- package/dist/services/security/codeAwareOutputRegistry.d.ts.map +1 -0
- package/dist/services/security/codeAwareOutputRegistry.js +55 -0
- package/dist/services/security/codeAwareOutputRegistry.js.map +1 -0
- package/dist/services/security/llmEchoOutputFilter.d.ts +49 -0
- package/dist/services/security/llmEchoOutputFilter.d.ts.map +1 -0
- package/dist/services/security/llmEchoOutputFilter.js +133 -0
- package/dist/services/security/llmEchoOutputFilter.js.map +1 -0
- package/dist/services/security/secretPatterns.d.ts +6 -0
- package/dist/services/security/secretPatterns.d.ts.map +1 -0
- package/dist/services/security/secretPatterns.js +23 -0
- package/dist/services/security/secretPatterns.js.map +1 -0
- package/dist/services/skillEngine/skillExecutor.d.ts +14 -2
- package/dist/services/skillEngine/skillExecutor.d.ts.map +1 -1
- package/dist/services/skillEngine/skillExecutor.js +133 -13
- package/dist/services/skillEngine/skillExecutor.js.map +1 -1
- package/dist/services/skillEngine/types.d.ts +2 -0
- package/dist/services/skillEngine/types.d.ts.map +1 -1
- package/dist/services/symbol/breakpadSymParser.d.ts +19 -0
- package/dist/services/symbol/breakpadSymParser.d.ts.map +1 -0
- package/dist/services/symbol/breakpadSymParser.js +40 -0
- package/dist/services/symbol/breakpadSymParser.js.map +1 -0
- package/dist/services/symbol/kallsymsParser.d.ts +12 -0
- package/dist/services/symbol/kallsymsParser.d.ts.map +1 -0
- package/dist/services/symbol/kallsymsParser.js +41 -0
- package/dist/services/symbol/kallsymsParser.js.map +1 -0
- package/dist/services/symbol/r8MappingParser.d.ts +40 -0
- package/dist/services/symbol/r8MappingParser.d.ts.map +1 -0
- package/dist/services/symbol/r8MappingParser.js +99 -0
- package/dist/services/symbol/r8MappingParser.js.map +1 -0
- package/dist/services/symbol/symbolResolver.d.ts +59 -0
- package/dist/services/symbol/symbolResolver.d.ts.map +1 -0
- package/dist/services/symbol/symbolResolver.js +147 -0
- package/dist/services/symbol/symbolResolver.js.map +1 -0
- package/dist/services/symbol/traceSymbolContext.d.ts +14 -0
- package/dist/services/symbol/traceSymbolContext.d.ts.map +1 -0
- package/dist/services/symbol/traceSymbolContext.js +45 -0
- package/dist/services/symbol/traceSymbolContext.js.map +1 -0
- package/dist/services/verifier/claimVerificationRunner.d.ts +20 -0
- package/dist/services/verifier/claimVerificationRunner.d.ts.map +1 -0
- package/dist/services/verifier/claimVerificationRunner.js +88 -0
- package/dist/services/verifier/claimVerificationRunner.js.map +1 -0
- package/dist/services/verifier/deterministicClaimVerifier.d.ts +8 -0
- package/dist/services/verifier/deterministicClaimVerifier.d.ts.map +1 -0
- package/dist/services/verifier/deterministicClaimVerifier.js +178 -0
- package/dist/services/verifier/deterministicClaimVerifier.js.map +1 -0
- package/dist/types/claimVerification.d.ts +38 -0
- package/dist/types/claimVerification.d.ts.map +1 -0
- package/dist/types/claimVerification.js +6 -0
- package/dist/types/claimVerification.js.map +1 -0
- package/dist/types/dataContract.d.ts +30 -0
- package/dist/types/dataContract.d.ts.map +1 -1
- package/dist/types/dataContract.js +7 -0
- package/dist/types/dataContract.js.map +1 -1
- package/dist/types/evidenceContract.d.ts +100 -0
- package/dist/types/evidenceContract.d.ts.map +1 -0
- package/dist/types/evidenceContract.js +6 -0
- package/dist/types/evidenceContract.js.map +1 -0
- package/dist/types/identityContract.d.ts +57 -0
- package/dist/types/identityContract.d.ts.map +1 -0
- package/dist/types/identityContract.js +6 -0
- package/dist/types/identityContract.js.map +1 -0
- package/dist/types/multiTraceComparison.d.ts +3 -0
- package/dist/types/multiTraceComparison.d.ts.map +1 -1
- package/dist/types/sparkContracts.d.ts +31 -3
- package/dist/types/sparkContracts.d.ts.map +1 -1
- package/dist/types/sparkContracts.js.map +1 -1
- package/package.json +8 -1
- package/skills/atomic/process_identity_resolver.skill.yaml +130 -1
- package/skills/atomic/process_slice_cpu_hotspots.skill.yaml +321 -0
- package/skills/composite/code_pinpoint.skill.yaml +111 -0
- package/strategies/anr.strategy.md +2 -2
- package/strategies/code-aware.template.md +37 -0
- package/strategies/game.strategy.md +1 -1
- package/strategies/general.strategy.md +1 -1
- package/strategies/prompt-methodology.template.md +2 -0
- package/strategies/scrolling.strategy.md +1 -0
|
@@ -144,6 +144,22 @@ display:
|
|
|
144
144
|
label: "关键线程"
|
|
145
145
|
type: string
|
|
146
146
|
format: truncate
|
|
147
|
+
- name: thread_utid
|
|
148
|
+
label: "命中线程 UTID"
|
|
149
|
+
type: number
|
|
150
|
+
- name: thread_tid
|
|
151
|
+
label: "命中线程 TID"
|
|
152
|
+
type: number
|
|
153
|
+
- name: thread_name
|
|
154
|
+
label: "命中线程"
|
|
155
|
+
type: string
|
|
156
|
+
format: truncate
|
|
157
|
+
- name: thread_role
|
|
158
|
+
label: "线程角色"
|
|
159
|
+
type: string
|
|
160
|
+
- name: thread_target_matched
|
|
161
|
+
label: "命中目标线程"
|
|
162
|
+
type: boolean
|
|
147
163
|
- name: layer_packages
|
|
148
164
|
label: "Layer 包名"
|
|
149
165
|
type: string
|
|
@@ -233,6 +249,17 @@ sql: |
|
|
|
233
249
|
MAX(CASE
|
|
234
250
|
WHEN input.target_thread IS NOT NULL
|
|
235
251
|
AND COALESCE(t.name, '') GLOB '*' || input.target_thread || '*'
|
|
252
|
+
THEN 1
|
|
253
|
+
WHEN LOWER(COALESCE(input.target_thread, '')) IN ('main', 'ui', 'app_main')
|
|
254
|
+
AND (t.is_main_thread = 1 OR t.tid = p.pid)
|
|
255
|
+
THEN 1
|
|
256
|
+
WHEN LOWER(COALESCE(input.target_thread, '')) IN ('renderthread', 'render_thread', 'render')
|
|
257
|
+
AND (
|
|
258
|
+
t.name IN ('RenderThread', 'GPU completion', 'hwuiTask0', 'hwuiTask1')
|
|
259
|
+
OR t.name GLOB '[0-9]*.ui'
|
|
260
|
+
OR t.name GLOB '[0-9]*.raster'
|
|
261
|
+
OR t.name GLOB 'Cr*Main'
|
|
262
|
+
)
|
|
236
263
|
THEN 1 ELSE 0 END) AS target_thread_match,
|
|
237
264
|
GROUP_CONCAT(DISTINCT CASE
|
|
238
265
|
WHEN t.is_main_thread = 1 OR t.tid = p.pid
|
|
@@ -247,6 +274,96 @@ sql: |
|
|
|
247
274
|
CROSS JOIN input
|
|
248
275
|
GROUP BY t.upid
|
|
249
276
|
),
|
|
277
|
+
thread_identity_candidates AS (
|
|
278
|
+
SELECT
|
|
279
|
+
t.upid,
|
|
280
|
+
t.utid,
|
|
281
|
+
t.tid,
|
|
282
|
+
COALESCE(t.name, '<unnamed>') AS thread_name,
|
|
283
|
+
CASE
|
|
284
|
+
WHEN t.is_main_thread = 1 OR t.tid = p.pid THEN 'app_main'
|
|
285
|
+
WHEN t.name IN ('RenderThread', 'GPU completion', 'hwuiTask0', 'hwuiTask1')
|
|
286
|
+
OR t.name GLOB '[0-9]*.ui'
|
|
287
|
+
OR t.name GLOB '[0-9]*.raster'
|
|
288
|
+
OR t.name GLOB 'Cr*Main'
|
|
289
|
+
THEN 'render_thread'
|
|
290
|
+
ELSE 'unknown'
|
|
291
|
+
END AS thread_role,
|
|
292
|
+
CASE
|
|
293
|
+
WHEN input.target_thread IS NOT NULL
|
|
294
|
+
AND COALESCE(t.name, '') GLOB '*' || input.target_thread || '*'
|
|
295
|
+
THEN 1
|
|
296
|
+
WHEN LOWER(COALESCE(input.target_thread, '')) IN ('main', 'ui', 'app_main')
|
|
297
|
+
AND (t.is_main_thread = 1 OR t.tid = p.pid)
|
|
298
|
+
THEN 1
|
|
299
|
+
WHEN LOWER(COALESCE(input.target_thread, '')) IN ('renderthread', 'render_thread', 'render')
|
|
300
|
+
AND (
|
|
301
|
+
t.name IN ('RenderThread', 'GPU completion', 'hwuiTask0', 'hwuiTask1')
|
|
302
|
+
OR t.name GLOB '[0-9]*.ui'
|
|
303
|
+
OR t.name GLOB '[0-9]*.raster'
|
|
304
|
+
OR t.name GLOB 'Cr*Main'
|
|
305
|
+
)
|
|
306
|
+
THEN 1 ELSE 0
|
|
307
|
+
END AS thread_target_matched,
|
|
308
|
+
ROW_NUMBER() OVER (
|
|
309
|
+
PARTITION BY t.upid
|
|
310
|
+
ORDER BY
|
|
311
|
+
CASE
|
|
312
|
+
WHEN input.target_thread IS NOT NULL
|
|
313
|
+
AND COALESCE(t.name, '') GLOB '*' || input.target_thread || '*'
|
|
314
|
+
THEN 0
|
|
315
|
+
WHEN LOWER(COALESCE(input.target_thread, '')) IN ('main', 'ui', 'app_main')
|
|
316
|
+
AND (t.is_main_thread = 1 OR t.tid = p.pid)
|
|
317
|
+
THEN 0
|
|
318
|
+
WHEN LOWER(COALESCE(input.target_thread, '')) IN ('renderthread', 'render_thread', 'render')
|
|
319
|
+
AND (
|
|
320
|
+
t.name IN ('RenderThread', 'GPU completion', 'hwuiTask0', 'hwuiTask1')
|
|
321
|
+
OR t.name GLOB '[0-9]*.ui'
|
|
322
|
+
OR t.name GLOB '[0-9]*.raster'
|
|
323
|
+
OR t.name GLOB 'Cr*Main'
|
|
324
|
+
)
|
|
325
|
+
THEN 0 ELSE 1
|
|
326
|
+
END,
|
|
327
|
+
CASE WHEN t.is_main_thread = 1 OR t.tid = p.pid THEN 0 ELSE 1 END,
|
|
328
|
+
CASE
|
|
329
|
+
WHEN t.name IN ('RenderThread', 'GPU completion', 'hwuiTask0', 'hwuiTask1')
|
|
330
|
+
OR t.name GLOB '[0-9]*.ui'
|
|
331
|
+
OR t.name GLOB '[0-9]*.raster'
|
|
332
|
+
OR t.name GLOB 'Cr*Main'
|
|
333
|
+
THEN 0 ELSE 1
|
|
334
|
+
END,
|
|
335
|
+
t.utid
|
|
336
|
+
) AS thread_rank
|
|
337
|
+
FROM thread t
|
|
338
|
+
JOIN process p USING (upid)
|
|
339
|
+
CROSS JOIN input
|
|
340
|
+
WHERE
|
|
341
|
+
(input.target_thread IS NOT NULL AND COALESCE(t.name, '') GLOB '*' || input.target_thread || '*')
|
|
342
|
+
OR (LOWER(COALESCE(input.target_thread, '')) IN ('main', 'ui', 'app_main') AND (t.is_main_thread = 1 OR t.tid = p.pid))
|
|
343
|
+
OR (LOWER(COALESCE(input.target_thread, '')) IN ('renderthread', 'render_thread', 'render') AND (
|
|
344
|
+
t.name IN ('RenderThread', 'GPU completion', 'hwuiTask0', 'hwuiTask1')
|
|
345
|
+
OR t.name GLOB '[0-9]*.ui'
|
|
346
|
+
OR t.name GLOB '[0-9]*.raster'
|
|
347
|
+
OR t.name GLOB 'Cr*Main'
|
|
348
|
+
))
|
|
349
|
+
OR t.is_main_thread = 1
|
|
350
|
+
OR t.tid = p.pid
|
|
351
|
+
OR t.name IN ('RenderThread', 'GPU completion', 'hwuiTask0', 'hwuiTask1')
|
|
352
|
+
OR t.name GLOB '[0-9]*.ui'
|
|
353
|
+
OR t.name GLOB '[0-9]*.raster'
|
|
354
|
+
OR t.name GLOB 'Cr*Main'
|
|
355
|
+
),
|
|
356
|
+
thread_identity AS (
|
|
357
|
+
SELECT
|
|
358
|
+
upid,
|
|
359
|
+
utid AS thread_utid,
|
|
360
|
+
tid AS thread_tid,
|
|
361
|
+
thread_name,
|
|
362
|
+
thread_role,
|
|
363
|
+
thread_target_matched
|
|
364
|
+
FROM thread_identity_candidates
|
|
365
|
+
WHERE thread_rank = 1
|
|
366
|
+
),
|
|
250
367
|
frame_rows AS (
|
|
251
368
|
SELECT
|
|
252
369
|
a.upid,
|
|
@@ -326,6 +443,11 @@ sql: |
|
|
|
326
443
|
COALESCE(ts.has_rendering_thread, 0) AS has_rendering_thread,
|
|
327
444
|
COALESCE(ts.target_thread_match, 0) AS target_thread_match,
|
|
328
445
|
ts.key_thread_names,
|
|
446
|
+
ti.thread_utid,
|
|
447
|
+
ti.thread_tid,
|
|
448
|
+
ti.thread_name,
|
|
449
|
+
ti.thread_role,
|
|
450
|
+
COALESCE(ti.thread_target_matched, 0) AS thread_target_matched,
|
|
329
451
|
COALESCE(fs.frame_rows, 0) AS frame_rows,
|
|
330
452
|
COALESCE(fs.jank_rows, 0) AS jank_rows,
|
|
331
453
|
COALESCE(fs.layer_target_match, 0) AS layer_target_match,
|
|
@@ -342,6 +464,7 @@ sql: |
|
|
|
342
464
|
FROM process_base pb
|
|
343
465
|
CROSS JOIN input
|
|
344
466
|
LEFT JOIN thread_summary ts USING (upid)
|
|
467
|
+
LEFT JOIN thread_identity ti USING (upid)
|
|
345
468
|
LEFT JOIN frame_summary fs USING (upid)
|
|
346
469
|
LEFT JOIN oom_summary os USING (upid)
|
|
347
470
|
LEFT JOIN battery_top bt
|
|
@@ -367,7 +490,8 @@ sql: |
|
|
|
367
490
|
CASE WHEN target_name IS NOT NULL AND COALESCE(process_name, '') GLOB target_name || '*' THEN 20 ELSE 0 END +
|
|
368
491
|
CASE WHEN target_name IS NOT NULL AND COALESCE(cmdline, '') GLOB target_name || '*' THEN 20 ELSE 0 END +
|
|
369
492
|
CASE WHEN target_name IS NOT NULL AND layer_target_match = 1 AND is_system_like_process = 0 THEN 15 ELSE 0 END +
|
|
370
|
-
CASE WHEN target_thread IS NOT NULL AND target_thread_match = 1 THEN 20 ELSE 0 END
|
|
493
|
+
CASE WHEN target_thread IS NOT NULL AND target_thread_match = 1 THEN 20 ELSE 0 END +
|
|
494
|
+
CASE WHEN target_name IS NULL AND target_upid IS NULL AND target_pid IS NULL AND target_thread IS NOT NULL AND target_thread_match = 1 THEN 35 ELSE 0 END
|
|
371
495
|
) AS identity_score,
|
|
372
496
|
(
|
|
373
497
|
CASE WHEN frame_rows > 0 THEN 15 ELSE 0 END +
|
|
@@ -469,6 +593,11 @@ sql: |
|
|
|
469
593
|
ROUND(battery_top_ns / 1e6, 2) AS battery_top_ms,
|
|
470
594
|
thread_count,
|
|
471
595
|
key_thread_names,
|
|
596
|
+
thread_utid,
|
|
597
|
+
thread_tid,
|
|
598
|
+
thread_name,
|
|
599
|
+
thread_role,
|
|
600
|
+
thread_target_matched,
|
|
472
601
|
layer_packages,
|
|
473
602
|
CASE
|
|
474
603
|
WHEN package_name IS NOT NULL
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
# Copyright (C) 2024-2026 Gracker (Chris)
|
|
3
|
+
# This file is part of SmartPerfetto. See LICENSE for details.
|
|
4
|
+
|
|
5
|
+
# =============================================================================
|
|
6
|
+
# 进程 Slice CPU 热点(原子 Skill)
|
|
7
|
+
# =============================================================================
|
|
8
|
+
# 按进程统计 named slice 的实际 Running CPU time。不同于 wall duration,
|
|
9
|
+
# 这里把 slice 时间段和 thread_state=Running 区间求交,避免把睡眠、IO 等
|
|
10
|
+
# 非执行时间误算成 CPU 消耗。
|
|
11
|
+
|
|
12
|
+
name: process_slice_cpu_hotspots
|
|
13
|
+
version: "1.0"
|
|
14
|
+
type: atomic
|
|
15
|
+
category: cpu
|
|
16
|
+
tier: B
|
|
17
|
+
|
|
18
|
+
meta:
|
|
19
|
+
display_name: "进程 Slice CPU 热点"
|
|
20
|
+
description: "按进程聚合 named slice 的实际 Running CPU 时间"
|
|
21
|
+
icon: "query_stats"
|
|
22
|
+
tags: [cpu, slice, thread_state, running, hotspot, atomic]
|
|
23
|
+
|
|
24
|
+
triggers:
|
|
25
|
+
keywords:
|
|
26
|
+
zh: [slice CPU, 函数 CPU, 热点 slice, CPU 热点, Running 时间, named slice]
|
|
27
|
+
en: [slice cpu, function cpu, hot slices, cpu hotspots, running time, named slice]
|
|
28
|
+
patterns:
|
|
29
|
+
- ".*(slice|函数|方法).*(CPU|cpu|消耗|热点).*"
|
|
30
|
+
- ".*(CPU|cpu).*(slice|function|method|named).*"
|
|
31
|
+
|
|
32
|
+
prerequisites:
|
|
33
|
+
modules:
|
|
34
|
+
- sched
|
|
35
|
+
required_tables:
|
|
36
|
+
- slice
|
|
37
|
+
- thread_track
|
|
38
|
+
- thread
|
|
39
|
+
- process
|
|
40
|
+
- thread_state
|
|
41
|
+
|
|
42
|
+
identity:
|
|
43
|
+
policy: verify_if_present
|
|
44
|
+
scope: process
|
|
45
|
+
aliases: [package, process_name]
|
|
46
|
+
rewriteTo: recommended_process_name_param
|
|
47
|
+
|
|
48
|
+
inputs:
|
|
49
|
+
- name: package
|
|
50
|
+
type: string
|
|
51
|
+
required: false
|
|
52
|
+
description: "目标应用包名或进程名前缀"
|
|
53
|
+
- name: process_name
|
|
54
|
+
type: string
|
|
55
|
+
required: false
|
|
56
|
+
description: "目标进程名;当 package 为空时使用"
|
|
57
|
+
- name: upid
|
|
58
|
+
type: integer
|
|
59
|
+
required: false
|
|
60
|
+
description: "可选 trace 内进程 ID;优先级高于 package/process_name"
|
|
61
|
+
- name: slice_name
|
|
62
|
+
type: string
|
|
63
|
+
required: false
|
|
64
|
+
description: "可选 slice 名称过滤;默认字面包含匹配,包含 % 时按 SQL LIKE 模式匹配"
|
|
65
|
+
- name: thread_scope
|
|
66
|
+
type: string
|
|
67
|
+
required: false
|
|
68
|
+
default: all
|
|
69
|
+
description: "线程范围:all/main/render/main_render"
|
|
70
|
+
- name: start_ts
|
|
71
|
+
type: timestamp
|
|
72
|
+
required: false
|
|
73
|
+
description: "分析起始时间戳(ns),默认 trace_start()"
|
|
74
|
+
- name: end_ts
|
|
75
|
+
type: timestamp
|
|
76
|
+
required: false
|
|
77
|
+
description: "分析结束时间戳(ns),默认 trace_end()"
|
|
78
|
+
- name: min_cpu_ns
|
|
79
|
+
type: integer
|
|
80
|
+
required: false
|
|
81
|
+
default: 0
|
|
82
|
+
description: "聚合后最小 CPU 时间阈值(ns)"
|
|
83
|
+
- name: top_k
|
|
84
|
+
type: integer
|
|
85
|
+
required: false
|
|
86
|
+
default: 10
|
|
87
|
+
description: "返回 TopK 条目"
|
|
88
|
+
|
|
89
|
+
display:
|
|
90
|
+
level: detail
|
|
91
|
+
layer: list
|
|
92
|
+
title: "进程 Slice CPU 热点"
|
|
93
|
+
columns:
|
|
94
|
+
- name: process_name
|
|
95
|
+
label: "进程"
|
|
96
|
+
type: string
|
|
97
|
+
format: truncate
|
|
98
|
+
- name: slice_name
|
|
99
|
+
label: "Slice"
|
|
100
|
+
type: string
|
|
101
|
+
format: truncate
|
|
102
|
+
- name: count
|
|
103
|
+
label: "次数"
|
|
104
|
+
type: number
|
|
105
|
+
format: compact
|
|
106
|
+
- name: thread_count
|
|
107
|
+
label: "线程数"
|
|
108
|
+
type: number
|
|
109
|
+
format: compact
|
|
110
|
+
- name: sample_threads
|
|
111
|
+
label: "样例线程"
|
|
112
|
+
type: string
|
|
113
|
+
format: truncate
|
|
114
|
+
- name: total_cpu_ms
|
|
115
|
+
label: "CPU时间"
|
|
116
|
+
type: duration
|
|
117
|
+
format: duration_ms
|
|
118
|
+
unit: ms
|
|
119
|
+
- name: total_wall_ms
|
|
120
|
+
label: "Wall时间"
|
|
121
|
+
type: duration
|
|
122
|
+
format: duration_ms
|
|
123
|
+
unit: ms
|
|
124
|
+
- name: avg_cpu_ms
|
|
125
|
+
label: "平均CPU"
|
|
126
|
+
type: duration
|
|
127
|
+
format: duration_ms
|
|
128
|
+
unit: ms
|
|
129
|
+
- name: max_cpu_ms
|
|
130
|
+
label: "最大CPU"
|
|
131
|
+
type: duration
|
|
132
|
+
format: duration_ms
|
|
133
|
+
unit: ms
|
|
134
|
+
- name: cpu_efficiency_pct
|
|
135
|
+
label: "CPU/Wall"
|
|
136
|
+
type: percentage
|
|
137
|
+
format: percentage
|
|
138
|
+
- name: selected_cpu_share_pct
|
|
139
|
+
label: "所选CPU占比"
|
|
140
|
+
type: percentage
|
|
141
|
+
format: percentage
|
|
142
|
+
- name: first_ts
|
|
143
|
+
label: "首次出现"
|
|
144
|
+
type: timestamp
|
|
145
|
+
- name: last_ts
|
|
146
|
+
label: "最后出现"
|
|
147
|
+
type: timestamp
|
|
148
|
+
|
|
149
|
+
sql: |
|
|
150
|
+
WITH
|
|
151
|
+
raw_input AS (
|
|
152
|
+
SELECT
|
|
153
|
+
COALESCE(${start_ts}, trace_start()) AS raw_start_ts,
|
|
154
|
+
COALESCE(${end_ts}, trace_end()) AS raw_end_ts,
|
|
155
|
+
${upid} AS target_upid,
|
|
156
|
+
NULLIF(COALESCE(NULLIF('${process_name|}', ''), NULLIF('${package|}', '')), '') AS target_process,
|
|
157
|
+
NULLIF('${slice_name|}', '') AS target_slice,
|
|
158
|
+
CASE
|
|
159
|
+
WHEN '${thread_scope|all}' IN ('all', 'main', 'render', 'main_render') THEN '${thread_scope|all}'
|
|
160
|
+
ELSE 'all'
|
|
161
|
+
END AS thread_scope,
|
|
162
|
+
MAX(COALESCE(${min_cpu_ns|0}, 0), 0) AS min_cpu_ns,
|
|
163
|
+
MIN(MAX(COALESCE(${top_k|10}, 10), 1), 100) AS top_k
|
|
164
|
+
),
|
|
165
|
+
input AS (
|
|
166
|
+
SELECT
|
|
167
|
+
MIN(raw_start_ts, raw_end_ts) AS start_ts,
|
|
168
|
+
MAX(raw_start_ts, raw_end_ts) AS end_ts,
|
|
169
|
+
target_upid,
|
|
170
|
+
target_process,
|
|
171
|
+
target_slice,
|
|
172
|
+
thread_scope,
|
|
173
|
+
min_cpu_ns,
|
|
174
|
+
top_k
|
|
175
|
+
FROM raw_input
|
|
176
|
+
),
|
|
177
|
+
target_threads AS (
|
|
178
|
+
SELECT
|
|
179
|
+
p.upid,
|
|
180
|
+
p.pid,
|
|
181
|
+
p.name AS process_name,
|
|
182
|
+
t.utid,
|
|
183
|
+
t.tid,
|
|
184
|
+
COALESCE(t.name, '') AS thread_name
|
|
185
|
+
FROM process p
|
|
186
|
+
JOIN thread t ON t.upid = p.upid
|
|
187
|
+
CROSS JOIN input i
|
|
188
|
+
WHERE (
|
|
189
|
+
(
|
|
190
|
+
i.target_upid IS NOT NULL
|
|
191
|
+
AND p.upid = i.target_upid
|
|
192
|
+
)
|
|
193
|
+
OR (
|
|
194
|
+
i.target_upid IS NULL
|
|
195
|
+
AND (
|
|
196
|
+
i.target_process IS NULL
|
|
197
|
+
OR p.name GLOB i.target_process || '*'
|
|
198
|
+
OR p.name LIKE '%' || i.target_process || '%'
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
AND (
|
|
203
|
+
i.thread_scope = 'all'
|
|
204
|
+
OR (
|
|
205
|
+
i.thread_scope IN ('main', 'main_render')
|
|
206
|
+
AND (t.is_main_thread = 1 OR t.tid = p.pid)
|
|
207
|
+
)
|
|
208
|
+
OR (
|
|
209
|
+
i.thread_scope IN ('render', 'main_render')
|
|
210
|
+
AND (
|
|
211
|
+
t.name = 'RenderThread'
|
|
212
|
+
OR t.name = 'GPU completion'
|
|
213
|
+
OR t.name GLOB '[0-9]*.ui'
|
|
214
|
+
OR t.name GLOB '[0-9]*.raster'
|
|
215
|
+
)
|
|
216
|
+
)
|
|
217
|
+
)
|
|
218
|
+
),
|
|
219
|
+
candidate_slices AS (
|
|
220
|
+
SELECT
|
|
221
|
+
s.id,
|
|
222
|
+
s.name AS slice_name,
|
|
223
|
+
s.ts,
|
|
224
|
+
s.dur,
|
|
225
|
+
tt.upid,
|
|
226
|
+
tt.process_name,
|
|
227
|
+
tt.utid,
|
|
228
|
+
tt.thread_name
|
|
229
|
+
FROM slice s
|
|
230
|
+
JOIN thread_track track ON s.track_id = track.id
|
|
231
|
+
JOIN target_threads tt ON track.utid = tt.utid
|
|
232
|
+
CROSS JOIN input i
|
|
233
|
+
WHERE s.dur > 0
|
|
234
|
+
AND s.ts < i.end_ts
|
|
235
|
+
AND s.ts + s.dur > i.start_ts
|
|
236
|
+
AND (
|
|
237
|
+
i.target_slice IS NULL
|
|
238
|
+
OR (
|
|
239
|
+
INSTR(i.target_slice, '%') > 0
|
|
240
|
+
AND s.name LIKE i.target_slice
|
|
241
|
+
)
|
|
242
|
+
OR (
|
|
243
|
+
INSTR(i.target_slice, '%') = 0
|
|
244
|
+
AND INSTR(s.name, i.target_slice) > 0
|
|
245
|
+
)
|
|
246
|
+
)
|
|
247
|
+
),
|
|
248
|
+
per_slice_cpu AS (
|
|
249
|
+
SELECT
|
|
250
|
+
cs.id,
|
|
251
|
+
cs.process_name,
|
|
252
|
+
cs.slice_name,
|
|
253
|
+
cs.utid,
|
|
254
|
+
cs.thread_name,
|
|
255
|
+
MAX(cs.ts, i.start_ts) AS clipped_start_ts,
|
|
256
|
+
MIN(cs.ts + cs.dur, i.end_ts) AS clipped_end_ts,
|
|
257
|
+
MIN(cs.ts + cs.dur, i.end_ts) - MAX(cs.ts, i.start_ts) AS wall_ns,
|
|
258
|
+
COALESCE(SUM(
|
|
259
|
+
MIN(MIN(cs.ts + cs.dur, i.end_ts), ts.ts + ts.dur)
|
|
260
|
+
- MAX(MAX(cs.ts, i.start_ts), ts.ts)
|
|
261
|
+
), 0) AS cpu_ns
|
|
262
|
+
FROM candidate_slices cs
|
|
263
|
+
CROSS JOIN input i
|
|
264
|
+
LEFT JOIN thread_state ts ON ts.utid = cs.utid
|
|
265
|
+
AND ts.state = 'Running'
|
|
266
|
+
AND ts.dur > 0
|
|
267
|
+
AND ts.ts < MIN(cs.ts + cs.dur, i.end_ts)
|
|
268
|
+
AND ts.ts + ts.dur > MAX(cs.ts, i.start_ts)
|
|
269
|
+
GROUP BY
|
|
270
|
+
cs.id,
|
|
271
|
+
cs.process_name,
|
|
272
|
+
cs.slice_name,
|
|
273
|
+
cs.utid,
|
|
274
|
+
cs.thread_name,
|
|
275
|
+
cs.ts,
|
|
276
|
+
cs.dur,
|
|
277
|
+
i.start_ts,
|
|
278
|
+
i.end_ts
|
|
279
|
+
),
|
|
280
|
+
aggregate_cpu AS (
|
|
281
|
+
SELECT
|
|
282
|
+
process_name,
|
|
283
|
+
slice_name,
|
|
284
|
+
COUNT(*) AS count,
|
|
285
|
+
COUNT(DISTINCT utid) AS thread_count,
|
|
286
|
+
SUBSTR(GROUP_CONCAT(DISTINCT COALESCE(NULLIF(thread_name, ''), '<unnamed>')), 1, 240) AS sample_threads,
|
|
287
|
+
SUM(cpu_ns) AS total_cpu_ns,
|
|
288
|
+
SUM(wall_ns) AS total_wall_ns,
|
|
289
|
+
AVG(cpu_ns) AS avg_cpu_ns,
|
|
290
|
+
MAX(cpu_ns) AS max_cpu_ns,
|
|
291
|
+
MIN(clipped_start_ts) AS first_ts,
|
|
292
|
+
MAX(clipped_end_ts) AS last_ts
|
|
293
|
+
FROM per_slice_cpu
|
|
294
|
+
GROUP BY process_name, slice_name
|
|
295
|
+
HAVING SUM(cpu_ns) >= (SELECT min_cpu_ns FROM input)
|
|
296
|
+
),
|
|
297
|
+
selected_total AS (
|
|
298
|
+
SELECT SUM(total_cpu_ns) AS total_cpu_ns
|
|
299
|
+
FROM aggregate_cpu
|
|
300
|
+
)
|
|
301
|
+
SELECT
|
|
302
|
+
process_name,
|
|
303
|
+
slice_name,
|
|
304
|
+
count,
|
|
305
|
+
thread_count,
|
|
306
|
+
sample_threads,
|
|
307
|
+
ROUND(total_cpu_ns / 1e6, 2) AS total_cpu_ms,
|
|
308
|
+
ROUND(total_wall_ns / 1e6, 2) AS total_wall_ms,
|
|
309
|
+
ROUND(avg_cpu_ns / 1e6, 2) AS avg_cpu_ms,
|
|
310
|
+
ROUND(max_cpu_ns / 1e6, 2) AS max_cpu_ms,
|
|
311
|
+
ROUND(100.0 * total_cpu_ns / NULLIF(total_wall_ns, 0), 1) AS cpu_efficiency_pct,
|
|
312
|
+
ROUND(100.0 * total_cpu_ns / NULLIF((SELECT total_cpu_ns FROM selected_total), 0), 1) AS selected_cpu_share_pct,
|
|
313
|
+
printf('%d', first_ts) AS first_ts,
|
|
314
|
+
printf('%d', last_ts) AS last_ts
|
|
315
|
+
FROM aggregate_cpu
|
|
316
|
+
WHERE total_cpu_ns > 0
|
|
317
|
+
ORDER BY total_cpu_ns DESC
|
|
318
|
+
LIMIT (SELECT top_k FROM input)
|
|
319
|
+
|
|
320
|
+
output:
|
|
321
|
+
format: structured
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
# Copyright (C) 2024-2026 Gracker (Chris)
|
|
3
|
+
# This file is part of SmartPerfetto. See LICENSE for details.
|
|
4
|
+
|
|
5
|
+
name: code_pinpoint
|
|
6
|
+
version: "1.0"
|
|
7
|
+
type: composite
|
|
8
|
+
tier: S
|
|
9
|
+
|
|
10
|
+
meta:
|
|
11
|
+
display_name: "代码定位线索"
|
|
12
|
+
description: "从 trace 中提取可用于 codebase-aware resolve_symbol / lookup_source 的线程、slice、module 和 symbol 线索"
|
|
13
|
+
icon: "code"
|
|
14
|
+
tags: [codebase, symbol, source, root_cause]
|
|
15
|
+
|
|
16
|
+
triggers:
|
|
17
|
+
keywords:
|
|
18
|
+
zh: [代码, 源码, 函数, 符号, patch, 修复建议, file line]
|
|
19
|
+
en: [code, source, symbol, function, patch, file line]
|
|
20
|
+
|
|
21
|
+
prerequisites:
|
|
22
|
+
modules:
|
|
23
|
+
- slices.with_context
|
|
24
|
+
- android.process_metadata
|
|
25
|
+
|
|
26
|
+
inputs:
|
|
27
|
+
- name: package
|
|
28
|
+
type: string
|
|
29
|
+
required: false
|
|
30
|
+
description: "应用包名或进程名(可选)"
|
|
31
|
+
- name: start_ts
|
|
32
|
+
type: timestamp
|
|
33
|
+
required: false
|
|
34
|
+
description: "分析起始时间戳(纳秒,可选)"
|
|
35
|
+
- name: end_ts
|
|
36
|
+
type: timestamp
|
|
37
|
+
required: false
|
|
38
|
+
description: "分析结束时间戳(纳秒,可选)"
|
|
39
|
+
|
|
40
|
+
identity:
|
|
41
|
+
policy: verify_if_present
|
|
42
|
+
scope: process
|
|
43
|
+
aliases: [package, process_name]
|
|
44
|
+
rewriteTo: recommended_process_name_param
|
|
45
|
+
|
|
46
|
+
steps:
|
|
47
|
+
- id: hot_slices
|
|
48
|
+
type: atomic
|
|
49
|
+
name: "代码定位候选 slice"
|
|
50
|
+
display:
|
|
51
|
+
level: detail
|
|
52
|
+
layer: list
|
|
53
|
+
title: "Code Pinpoint Candidates"
|
|
54
|
+
columns:
|
|
55
|
+
- name: process_name
|
|
56
|
+
label: "Process"
|
|
57
|
+
type: string
|
|
58
|
+
- name: thread_name
|
|
59
|
+
label: "Thread"
|
|
60
|
+
type: string
|
|
61
|
+
- name: slice_name
|
|
62
|
+
label: "Slice"
|
|
63
|
+
type: string
|
|
64
|
+
- name: dur_ms
|
|
65
|
+
label: "Duration"
|
|
66
|
+
type: duration
|
|
67
|
+
unit: ms
|
|
68
|
+
sql: |
|
|
69
|
+
INCLUDE PERFETTO MODULE slices.with_context;
|
|
70
|
+
|
|
71
|
+
SELECT
|
|
72
|
+
process_name,
|
|
73
|
+
thread_name,
|
|
74
|
+
name AS slice_name,
|
|
75
|
+
ROUND(dur / 1e6, 3) AS dur_ms
|
|
76
|
+
FROM thread_slice
|
|
77
|
+
WHERE dur > 0
|
|
78
|
+
AND (${package} IS NULL OR process_name GLOB ${package} || '*')
|
|
79
|
+
AND (${start_ts} IS NULL OR ts >= ${start_ts})
|
|
80
|
+
AND (${end_ts} IS NULL OR ts + dur <= ${end_ts})
|
|
81
|
+
ORDER BY dur DESC
|
|
82
|
+
LIMIT 30;
|
|
83
|
+
|
|
84
|
+
- id: native_modules
|
|
85
|
+
type: atomic
|
|
86
|
+
name: "Native module / build-id 线索"
|
|
87
|
+
display:
|
|
88
|
+
level: debug
|
|
89
|
+
layer: deep
|
|
90
|
+
title: "Native Module Hints"
|
|
91
|
+
columns:
|
|
92
|
+
- name: module_name
|
|
93
|
+
label: "Module"
|
|
94
|
+
type: string
|
|
95
|
+
- name: build_id
|
|
96
|
+
label: "Build ID"
|
|
97
|
+
type: string
|
|
98
|
+
- name: frame_count
|
|
99
|
+
label: "Frames"
|
|
100
|
+
type: number
|
|
101
|
+
optional: true
|
|
102
|
+
sql: |
|
|
103
|
+
SELECT
|
|
104
|
+
COALESCE(m.name, '(unknown)') AS module_name,
|
|
105
|
+
COALESCE(m.build_id, '') AS build_id,
|
|
106
|
+
COUNT(*) AS frame_count
|
|
107
|
+
FROM stack_profile_frame f
|
|
108
|
+
JOIN stack_profile_mapping m ON f.mapping = m.id
|
|
109
|
+
GROUP BY module_name, build_id
|
|
110
|
+
ORDER BY frame_count DESC
|
|
111
|
+
LIMIT 30;
|
|
@@ -108,7 +108,7 @@ fetch_artifact(artifactId, detail="rows", offset=0, limit=50)
|
|
|
108
108
|
|--------|------|------|--------|
|
|
109
109
|
| Q4 Sleeping 极高 | >80% | **主线程被阻塞**(ANR 最常见原因) | → 第二步:用 blocked_functions 定位 |
|
|
110
110
|
| Q3 Runnable 高 | >30% | CPU 饥饿——可运行但得不到 CPU | → 检查 `sched_latency`、`cpu_health`、后台进程抢占 |
|
|
111
|
-
| Q1+Q2 Running 高 | >70% | CPU-bound——主线程在执行重计算 | → 检查 `main_thread_slices
|
|
111
|
+
| Q1+Q2 Running 高 | >70% | CPU-bound——主线程在执行重计算 | → 检查 `main_thread_slices`,并调用 `invoke_skill("process_slice_cpu_hotspots", { process_name, start_ts, end_ts, thread_scope: "main" })` 定位主线程热点函数/slice 的 Running CPU time |
|
|
112
112
|
| 混合 | 无明显主导 | 多因素共同导致 | → 依次排查 Q4→Q3→Q1 |
|
|
113
113
|
|
|
114
114
|
### 第二步:当 Q4 占比高时 — 用 blocked_functions + 线程状态定位
|
|
@@ -197,4 +197,4 @@ fetch_artifact(artifactId, detail="rows", offset=0, limit=50)
|
|
|
197
197
|
- 忽略 `wakeup_chain` 数据(这是定位间接依赖链的关键)
|
|
198
198
|
- 把所有 ANR 统一用同一个决策路径分析,不区分 ANR 类型
|
|
199
199
|
- 忽略 `app_freeze_check`(应用完全冻结 vs 部分响应是重要区分)
|
|
200
|
-
- 不交叉检查 CPU/内存/IO 系统上下文就下结论
|
|
200
|
+
- 不交叉检查 CPU/内存/IO 系统上下文就下结论
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
|
|
2
|
+
<!-- Copyright (C) 2024-2026 Gracker (Chris) | SmartPerfetto -->
|
|
3
|
+
|
|
4
|
+
## Codebase-Aware Analysis
|
|
5
|
+
|
|
6
|
+
本 session 已启用代码库感知分析:
|
|
7
|
+
|
|
8
|
+
- `codeAwareMode`: `{{codeAwareMode}}`
|
|
9
|
+
- whitelisted `codebaseIds`: `{{codebaseIds}}`
|
|
10
|
+
|
|
11
|
+
### 工具顺序
|
|
12
|
+
|
|
13
|
+
1. 先用 trace/Skill/SQL 找到性能现象和可疑线程、阶段、slice、symbol。
|
|
14
|
+
2. 如果 trace 证据指向 App 代码,调用 `resolve_symbol(kind="app")`,再调用 `lookup_app_source`。
|
|
15
|
+
3. 如果 trace 证据指向 AOSP/native,调用 `resolve_symbol(kind="native")`,再调用 `lookup_aosp_source`。
|
|
16
|
+
4. 如果 trace 证据指向 kernel/vendor fork,调用 `resolve_symbol(kind="kernel")`,再调用 `lookup_kernel_source`,必须带 `vendor` 或明确 `codebase_id`。
|
|
17
|
+
5. 只有在已有 successful lookup 的 `chunkId` 后,才可调用 `propose_patch`。
|
|
18
|
+
|
|
19
|
+
### 输出纪律
|
|
20
|
+
|
|
21
|
+
- 最终回答、阶段总结、报告和 export 中只能写 `chunkId`、相对 `filePath`、`lineRange`、`symbol`、`patchProposalId`。
|
|
22
|
+
- 不要在自然语言中复述源码正文、secret、rootPath 或 absolute path。
|
|
23
|
+
- `metadata_only` / `provider_send_disabled_for_session` 结果只能作为定位引用,不能引用源码内容。
|
|
24
|
+
- `symbol_only_low_confidence` 或 `build_id_missing_cannot_pin_codebase` 时,必须说明无法可靠定位 file:line,不能生成 patch。
|
|
25
|
+
|
|
26
|
+
### Patch 纪律
|
|
27
|
+
|
|
28
|
+
- `patchStatus="verified"`:可以引用结构化 diff block 或 patch id。
|
|
29
|
+
- `patchStatus="sketch"`:只能输出 rationale + patchSketch,不能输出 unified diff,也不能暗示可直接复制。
|
|
30
|
+
- `patchStatus="unverified"`:只输出拒绝原因和下一步取证建议。
|
|
31
|
+
- `multi_codebase_not_supported_phase1`:把 App/AOSP/kernel 修复拆成多个 proposal,不要合成跨库 diff。
|
|
32
|
+
|
|
33
|
+
### Plan 44/54/55 边界
|
|
34
|
+
|
|
35
|
+
- `recall_project_memory` / `recall_similar_case` / legacy `lookup_blog_knowledge` 可作为背景知识,不等同于用户代码证据。
|
|
36
|
+
- 代码级根因必须来自 codebase registry chunk 或明确的 AOSP/OEM source chunk。
|
|
37
|
+
|
|
@@ -100,7 +100,7 @@ invoke_skill("mali_gpu_power_state")
|
|
|
100
100
|
| CPU 频率下降 | `invoke_skill("thermal_throttling")` | 游戏长时间运行容易触发热节流 |
|
|
101
101
|
| 内存压力 | `invoke_skill("memory_analysis")` | 游戏内存占用大,可能触发 LMK |
|
|
102
102
|
| CPU 调度 | `invoke_skill("cpu_analysis")` | 游戏线程调度到小核会造成帧率波动 |
|
|
103
|
-
| 线程/进程 CPU 利用率 | `invoke_skill("cpu_thread_utilization_period")` / `invoke_skill("cpu_process_utilization_period")` | 判断 UnityMain/GameThread/RenderThread 是否 CPU-bound |
|
|
103
|
+
| 线程/进程 CPU 利用率 | `invoke_skill("cpu_thread_utilization_period")` / `invoke_skill("cpu_process_utilization_period")`;需要函数/slice 级热点时补 `invoke_skill("process_slice_cpu_hotspots", { process_name, start_ts, end_ts })` | 判断 UnityMain/GameThread/RenderThread 是否 CPU-bound,并用 Running CPU time 定位 named slice 热点 |
|
|
104
104
|
| 功耗归因 | `invoke_skill("wattson_thread_power_attribution")` | 仅在 power_rails + cpu_freq_idle 可用时做线程能耗归因 |
|
|
105
105
|
| 独立 GL swap 间隔 | `invoke_skill("gl_standalone_swap_jank")` | NativeActivity/GLSurfaceView 或引擎自管 swap 时检查生产端 present 节奏 |
|
|
106
106
|
|
|
@@ -19,7 +19,7 @@ keywords: []
|
|
|
19
19
|
|
|
20
20
|
| 用户关注方向 | 推荐路径 | 说明 |
|
|
21
21
|
|-------------|---------|------|
|
|
22
|
-
| **CPU / 调度 / 线程** | `invoke_skill("cpu_analysis")` → 如果发现 throttling → `invoke_skill("thermal_throttling")` |
|
|
22
|
+
| **CPU / 调度 / 线程** | `invoke_skill("cpu_analysis")` → 需要函数/slice CPU 热点时 `invoke_skill("process_slice_cpu_hotspots", { process_name: "<包名或进程名>" })` → 如果发现 throttling → `invoke_skill("thermal_throttling")` | 用 Running CPU time 区分真实计算热点和 wall-time 阻塞,再交叉检查热节流和 CPU 频率 |
|
|
23
23
|
| **内存 / OOM / 泄漏** | `invoke_skill("memory_analysis")` → 如果有 heap dump → `invoke_skill("android_heap_graph_summary")` → 如果有 LMK → `invoke_skill("lmk_analysis")` → 如果涉及 GPU 内存 → `invoke_skill("dmabuf_analysis")` | 层层深入内存问题;heap graph 用 retained/cumulative size 定位 retainer |
|
|
24
24
|
| **IO / 磁盘 / 存储** | `invoke_skill("block_io_analysis")` 或 `invoke_skill("io_pressure")` | 磁盘 IO 和系统 IO 压力 |
|
|
25
25
|
| **GPU / 渲染** | `invoke_skill("gpu_analysis")` | GPU 频率、利用率、Fence 等待 |
|
|
@@ -31,6 +31,8 @@ successCriteria: "确定掉帧根因并提供可操作的优化建议"
|
|
|
31
31
|
3. **execute_sql** — 仅在没有匹配 Skill 或需要自定义查询时使用。**写 SQL 前务必先 lookup_sql_schema**
|
|
32
32
|
4. **list_skills** — 不确定用哪个 Skill 时,先列出可用选项
|
|
33
33
|
5. **detect_architecture** — 分析开始时调用,了解渲染管线类型
|
|
34
|
+
6. **resolve_symbol / lookup_app_source / lookup_aosp_source / lookup_kernel_source** — 只有当 session 启用 codebase-aware 且 trace 证据已经指向具体代码域时使用;先定位 symbol,再查源码,最终只引用 CodeRef
|
|
35
|
+
7. **propose_patch** — 只有在已有 successful code lookup 的 chunkId 后使用;未 verified 的 patch 只能作为 sketch,不能输出 copyable diff
|
|
34
36
|
|
|
35
37
|
### 参数说明
|
|
36
38
|
- 调用 invoke_skill 时使用 `process_name` 参数(系统会自动映射为 YAML skill 中的 `package`)
|