鸿蒙 V8 Proxy SIGSEGV 崩溃复现 Demo
环境:HarmonyOS 6.1.0 (nova 12 Ultra),uni-app + Vue 3 + Pinia + pinia-plugin-persistedstate
崩溃特征:libv8_shared.so → Builtins_ProxySetProperty → Builtins_JumpIfToBooleanFalseHandler,SIGSEGV(SEGV_MAPERR),寄存器 x0 含 0x6b6b(freed memory pattern)
复现步骤:首页 → 列表页 → 点击任意一项 → 返回首页 → SIGSEGV
1. store/config.js(Pinia 持久化配置)
export const PINIA_PERSIST_CONFIG = {
persist: {
storage: {
getItem: key => {
try { return uni.getStorageSync(key) } catch { return null }
},
setItem: (key, val) => {
try { uni.setStorageSync(key, val) } catch {}
},
removeItem: key => uni.removeStorageSync(key)
}
}
}
2. store/useDemoStore.js(含异步 setCurrent 的 store)
export const useDemoStore = defineStore('PINIA_DEMO', () => {
const current = shallowRef({ eid: 0 })
async function setCurrent(value) {
await new Promise(r => setTimeout(r, 100))
current.value = { ...value } // 触发持久化 uni.setStorageSync 写入
}
return { current, setCurrent }
}, PINIA_PERSIST_CONFIG)
3. pages/index/index.vue(首页:onShow 中 Promise.all + 连续响应式赋值)
<template>
<view>
<view @click="goToList">进入列表页</view>
<view>当前 eid:{{ store.current.eid }}</view>
</view>
</template>
<script setup>
import { useDemoStore } from '@/store'
const store = useDemoStore()
const pageHide = ref(true)
const list1 = shallowRef([])
const list2 = shallowRef([])
const list3 = shallowRef([])
const data1 = shallowRef({})
const data2 = shallowRef({})
const data3 = shallowRef({})
const counter = ref(0)
onShow(async () => {
pageHide.value = false
try {
const [r1, r2, r3] = await Promise.all([
mockApi(), mockApi(), mockApi()
])
if (pageHide.value) return
// 同一同步块连续 7 次响应式赋值,每次触发 Vue Proxy set 陷阱
list1.value = r1
list2.value = r2
list3.value = r3
data1.value = { total: 100 }
data2.value = { online: 50 }
data3.value = { offline: 50 }
counter.value = r1.length
} catch (e) {}
})
onHide(() => { pageHide.value = true })
function goToList() {
uni.navigateTo({ url: '/pages/list/list' })
}
async function mockApi() {
await new Promise(r => setTimeout(r, 200))
return Array.from({ length: 10 }, (_, i) => ({ id: i }))
}
</script>
4. pages/list/list.vue(列表页:store 更新 + navigateBack)
<template>
<view>
<view v-for="n in 5" :key="n" @click="onSelect(n)">选择 {{ n }}</view>
</view>
</template>
<script setup>
import { useDemoStore } from '@/store'
const store = useDemoStore()
async function onSelect(n) {
await store.setCurrent({ eid: n }) // 更新 store + 触发持久化写入
uni.navigateBack() // 返回首页 → onShow 触发
}
</script>
5. main.js
import { createSSRApp } from 'vue'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
export function createApp() {
const app = createSSRApp(App)
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
app.use(pinia)
return { app, pinia }
}
6. pages.json
{
"pages": [
{ "path": "pages/index/index" },
{ "path": "pages/list/list" }
]
}