Problem Solved
Analyze cppcrash log files related to the graphics module of the OpenHarmony system to locate the root cause of process crashes.
Input
- cppcrash log file
code/Relevant source code in the directorylib.unstripped/so file with symbol table in the directory
Output
- Crash root cause analysis report
- Precise code line number localization
- Fix suggestions
Inapplicable Cases
- Pure ArkTS/JS layer crash (no native call stack)
- No cppcrash log file
- No so file with symbol table (cannot unwind stack)
Task Trigger Words
- Analyze cppcrash
- Parse cppcrash log
- Locate native crash
Symptom Words
- SIGSEGV、SIGABRT
- Use-After-Free
- Wild pointer
- Memory corruption
- 0x6b6b address
Scenario Words
- Graphics module crash
- render_service crash
Before starting the analysis, ask yourself
-
What is the crash type? → Determines the priority analysis path
- SIGSEGV → Memory access exception, prioritize address pattern matching
- SIGABRT → Active termination, prioritize call stack business analysis
-
What are the characteristics of the address pattern? → Determines whether deep data flow tracing is needed
0x6b6b...At the beginning → Use-After-Free analysis must be performed- Abnormal high-order bytes → Address pattern matching must be performed
-
Is there a multithreaded context? → Determines whether race analysis is needed
- If yes
Other thread info→ Lock contention and race conditions must be checked
- If yes
1. Check input completeness
Check in the following order:
- Whether the cppcrash file exists
lib.unstripped/Whether the directory existscode/Whether the directory exists
If required input is missing, terminate and report to the user.
2. Check crash type
Read from the cppcrash headerReason:
- If signal is SIGSEGV: memory access exception
- If signal is SIGABRT: active termination or exception
- If the address starts with
0x6b6b: Use-After-Free
3. Check buildId match
Before unwinding the stack, the so buildId must be verified to be consistent with that in cppcrash; otherwise, terminate.
Execution StrategyAnalysis Flow
Select the analysis path according to the crash type:
| Crash Type | Priority Path | Reason |
|---|---|---|
SIGSEGV + 0x6b6bAddress |
Stack unwinding → Data flow tracing → Address matching | Use-After-Free requires tracing the release point |
| SIGSEGV + abnormal high-order bytes | Stack unwinding → Address matching → Memory analysis | Memory corruption requires locating the corruption source |
| SIGABRT + abort/raise | Stack unwinding → Business code analysis | Active exit requires understanding the exit reason |
Includescfi_slowpath_comm |
Prioritize the memory corruption analysis path | CFI failure indicates memory corruption |
The complete flow is as follows (execute as needed):
- Metadata analysis: Read Device Info, Module name, Reason, LastFatalMessage
- Call stack unwinding: See
references/stack-unwinding.md - Code location and reading: Locate the source code based on the unwinding result
- Disassembly analysis: See
references/disassembly-analysis.md - Deep data flow tracing: See
references/memory-pattern-analysis.md - Call chain backtracking analysis: See
references/call-chain-backtrace.md - Multithreaded race analysis: See
references/thread-competition-analysis.md - Memory data analysis: See
references/memory-data-analysis.md - Special case determination: See
references/special-cases.md - Generate analysis report: See
references/report-template.md
Key decision points
Crash address characteristic determination
0x6b6b...Starts with → Use-After-Free (freed memory is accessed)- Address is 0 or close to 0 → null pointer or wild pointer
- Address differs from a valid address in the high-order bytes → out-of-bounds write trampling
Multithreading issue determination
ViewOther thread info:
- If other threads hold the same lock → lock contention
- If other threads modify the same object → race condition
- If the crashing thread is iterating over a container while other threads modify it → iterator invalidation
Code investigation focus
See references/code-review-checklist.md, focus on checking:
- Multithreaded lock usage
- Type cast safety
- lambda capture lifetime
- Smart pointer lifetime
Do not guess the root cause
- Do not infer the root cause without evidence
- Do not skip data flow tracing and give a conclusion directly
- Do not use vague expressions such as "may be" or "perhaps"
Common incorrect practices:
- Concluding it is a null pointer just because SIGSEGV is seen → must first verify whether fault_addr is really 0 or close to 0
- Concluding it is UAF just because a 0x6b6b address is seen → must trace the data flow to find who freed the object
- Concluding that the crashing thread's code caused it just because that code has a problem → must check whether other threads are concurrently modifying the same object
Reason: it leads to the wrong fix direction and wastes debugging time.
Do not skip unwinding verification
- Do not use an so with a mismatched buildId for unwinding
- Do not unwind directly without verifying the buildId
Common incorrect practices:
- Unwinding with a different version of the so (buildId mismatch) → the resolved line numbers correspond to a different version of the code, and the location is completely wrong
Reason: it leads to incorrect code line number location.
Do not ignore multithreaded analysis
- Do not analyze only the crashing thread while ignoring other threads
- Do not ignore lock contention and race conditions
Common incorrect practices:
- Concluding it is not a code problem just because the crashing thread's code "looks fine" → it may be caused by other threads concurrently modifying and causing the crashing thread to access an invalid object
Reason: multithreading issues are a common root cause of graphics module crashes.
Do not skip address pattern matching
- Do not fail to compare the difference between the crash address and a valid address
Common incorrect practices:
- Only checking whether the crash address is in Maps → ignoring the subtle difference of high-order bytes being trampled (such as 0x59→0x09)
- Not calculating the actual access address of the crashing instruction → unable to verify whether the address pattern matches
Reason: Address pattern matching is a key means of identifying memory corruption.
Exceptions and FallbacksWhen information is insufficient
- If the corresponding so cannot be found → report that the user needs to provide the correct symbol table file
- If the source code cannot be located → report that the user needs to provide the complete code directory
- If the buildId does not match → report that the user's versions are inconsistent and terminate the analysis
When evidence is insufficient
- If a single root cause cannot be determined → list all possible root causes and explain the basis for the judgment
- Clearly indicate which conclusions are certain and which are inferred
- Explain the directions requiring further analysis
Special Call Stack Handling
- If the top of the stack is abort/raise → analyze the reason for the active exit in conjunction with the business code
- If the top of the stack is terminate → analyze the reason for the exception being thrown, and note that memory corruption may also cause exception mismatch
- If it contains
cfi_slowpath_comm→ prioritize analysis as a memory corruption issue
Read the corresponding files according to the following conditions:
| Condition | File | Note |
|---|---|---|
| When performing stack unwinding steps | references/stack-unwinding.md |
Load only during stack unwinding |
| When performing disassembly analysis | references/disassembly-analysis.md |
Load only when the crash instruction needs to be confirmed |
| When performing call chain backtracking analysis | references/call-chain-backtrace.md |
Load only when tracing the origin of parameters |
| When performing data flow tracing or address pattern matching | references/memory-pattern-analysis.md |
Load only when the address is abnormal |
| When performing multithreaded race analysis | references/thread-competition-analysis.md |
Load only when there is a multithreaded context |
| When performing memory data analysis | references/memory-data-analysis.md |
Load only when a memory dump needs to be analyzed |
| When determining special cases | references/special-cases.md |
Load only when matching call stack characteristics |
| When troubleshooting code issues | references/code-review-checklist.md |
Load only after the code has been located |
| When generating the analysis report | references/report-template.md |
Load only at the end when generating the report |
Do NOT Load: Do not load all references files at once at the start of the analysis; load them on demand to save context space.
Preliminary Information
The user has provided the relevant source code in thecode/directory.
The user has provided the relevant so with symbol table information in thelib.unstripped/directory.
The user environment provides llvm tools (llvm-readelf/llvm-addr2line/llvm-objdump, etc.).
During analysis, interact in Chinese, and all files involved are UTF-8 encoded.