You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ObjectBox一对多关联在ARMv7 Linux设备触发panic求助

问题分析与解决方案

问题概述

代码未使用一对多关联时,可在x86 Windows和ARMv7 Linux设备正常运行;添加Task与Workers的一对多关联后,x86 Windows仍正常,但ARMv7 Linux设备执行box.Get(id)时触发空指针panic。

环境信息

  • ObjectBox Go版本:objectbox-go v1.8.0
  • ObjectBox核心库版本:libobjectbox.so v4.0.1
  • 运行设备:x86 Windows、ARMv7 Linux
  • 复现概率:100%

代码示例

main.go

package main

import (
    "fmt"
    "github.com/objectbox/objectbox-go/objectbox"
    "objectboxTest/objectboxlib/model"
)

func initObjectBox() *objectbox.ObjectBox {
    objectBox, err := objectbox.NewBuilder().Model(model.ObjectBoxModel()).Directory("./opt").Build()
    if err != nil {
        fmt.Println(err)
        return nil
    }
    return objectBox
}

func main() {
    // 初始化ObjectBox
    ob := initObjectBox()
    defer ob.Close() // 服务端应用中只需保留实例, shutdown时关闭即可
    box := model.BoxForTask(ob)
    box2 := model.BoxForWorkers(ob)
    if box == nil || box2 == nil {
        panic("box初始化失败")
    }
    worker1 := model.Workers{Name: "Petter", Age: 18}
    worker2 := model.Workers{Name: "Leven", Age: 28}
    workers := []*model.Workers{&worker1, &worker2}
    id, _ := box.Put(&model.Task{
        Text:    "Buy milk",
        Workers: workers,
    })
    tasks, err := box.Get(id) // 此处触发panic.......
    if err != nil {
        fmt.Println("读取错误 ", err)
        return
    }
    fmt.Println(tasks)
}

model/task.go

package model

//go:generate go run github.com/objectbox/objectbox-go/cmd/objectbox-gogen

// 新增一行启用同步: // `objectbox:"sync"`
type Task struct {
    Id           uint64
    Text         string
    Name         string
    DataType     string
    Value        float64
    ValueStr     string
    DateCreated  int64
    DateFinished int64
    Workers      []*Workers // 一对多关联字段
}

type Workers struct {
    Id   uint64
    Name string
    Age  int
}

运行日志

Windows平台日志

&{6 Buy milk   0  0 0 [0xc000086020 0xc000086040]}

ARMv7 Linux平台日志

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x13d6c8]

goroutine 1 [running, locked to thread]:
github.com/objectbox/objectbox-go/objectbox.dataVisitorDispatch(0xb55f17b0, 0x40, 0x4137c0)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/datavisitorc.go:43 +0x50
github.com/objectbox/objectbox-go/objectbox._Cfunc_obx_box_visit_many(0x2cdff0, 0x2ce078, 0x142d4c, 0x4137c0)
    _cgo_gotypes.go:745 +0x38
github.com/objectbox/objectbox-go/objectbox.(*Box).GetManyExisting.func2.1(0x5147b0, 0x5147e0, 0x4137c0)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/box.go:531 +0xc8
github.com/objectbox/objectbox-go/objectbox.(*Box).GetManyExisting.func2(0x4137c0)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/box.go:531 +0x70
github.com/objectbox/objectbox-go/objectbox.(*Box).readUsingVisitor.func2.1()
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/box.go:621 +0x24
github.com/objectbox/objectbox-go/objectbox.cCall(0x4d7cf4)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/c-tools.go:34 +0x20
github.com/objectbox/objectbox-go/objectbox.(*Box).readUsingVisitor.func2()
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/box.go:621 +0x4c
github.com/objectbox/objectbox-go/objectbox.(*ObjectBox).runInTxn(0x505860, 0x1, 0x4d7d64)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/objectbox.go:155 +0xcc
github.com/objectbox/objectbox-go/objectbox.(*ObjectBox).RunInReadTx(...)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/objectbox.go:110
github.com/objectbox/objectbox-go/objectbox.(*Box).readUsingVisitor(0x5147b0, 0x1, 0x4d7da0)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/box.go:620 +0x27c
github.com/objectbox/objectbox-go/objectbox.(*Box).GetManyExisting(0x5147b0, {0x4137b0, 0x2, 0x2})
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/box.go:533 +0x158
objectboxTest/objectboxlib/model.(*WorkersBox).GetManyExisting(...)
    /mnt/d/gitlab/tools/objectboxTest/objectboxlib/model/task.obx.go:617
objectboxTest/objectboxlib/model.task_EntityInfo.Load({{0x1}, 0x284bb4920ec6bdbe}, 0x505860, {0xb55f1680, 0x80, 0x80})
    /mnt/d/gitlab/tools/objectboxTest/objectboxlib/model/task.obx.go:170 +0x144
github.com/objectbox/objectbox-go/objectbox.(*Box).Get.func1()
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/box.go:479 +0x18c
github.com/objectbox/objectbox-go/objectbox.(*ObjectBox).runInTxn(0x505860, 0x1, 0x4d7f10)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/objectbox.go:155 +0xcc
github.com/objectbox/objectbox-go/objectbox.(*ObjectBox).RunInReadTx(...)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/objectbox.go:110
github.com/objectbox/objectbox-go/objectbox.(*Box).Get(0x514790, 0x3)
    /home/lich/go/pkg/mod/github.com/levin-go/objectbox-go@v0.0.0-20240826085105-f32fc4305353/objectbox/box.go:470 +0x80
objectboxTest/objectboxlib/model.(*TaskBox).Get(0x4d7f90, 0x3)
    /mnt/d/gitlab/tools/objectboxTest/objectboxlib/model/task.obx.go:258 +0x30
main.main()
    /mnt/d/gitlab/tools/objectboxTest/main.go:34 +0x198

解决方案

从panic栈信息来看,问题出在ARMv7平台下ObjectBox处理一对多关联的C层调用中,空指针访问导致段错误。可尝试以下方案:

  1. 升级ObjectBox版本
    当前使用的版本并非最新,后续版本大概率修复了ARM架构下的关联处理bug:

    • 执行go get github.com/objectbox/objectbox-go@latest更新Go绑定
    • 下载对应ARMv7平台的最新libobjectbox.so替换现有文件
  2. 显式定义关联关系
    仅通过切片声明一对多未明确ObjectBox规则,可能导致代码生成工具在ARM平台生成的逻辑异常。修改Task结构体的关联字段,添加标签明确关联:

    type Task struct {
        // ... 其他字段
        Workers      []*Workers `objectbox:"link"`
    }
    

    修改后重新执行go generate生成模型代码,再测试运行。

  3. 手动处理关联数据
    如果升级版本和显式标签无效,可临时绕过ObjectBox的自动关联加载:

    • 先存储所有Workers实例,获取它们的ID
    • 在Task中添加WorkerIds []uint64字段存储关联ID
    • 查询Task后,再通过ID批量查询Workers实例

    修改后的模型示例:

    type Task struct {
        Id           uint64
        Text         string
        // ... 其他字段
        WorkerIds    []uint64 `objectbox:"long"`
    }
    
    type Workers struct {
        Id   uint64
        Name string
        Age  int
    }
    

    对应的业务代码调整:

    // 先存储Workers
    workerIds, _ := box2.PutMany(workers)
    // 存储Task,关联Worker ID
    id, _ := box.Put(&model.Task{
        Text:      "Buy milk",
        WorkerIds: workerIds,
    })
    // 查询Task后手动加载Workers
    task, err := box.Get(id)
    if err != nil {
        fmt.Println("读取错误 ", err)
        return
    }
    workers, _ := box2.GetMany(task.WorkerIds)
    task.Workers = workers // 手动赋值关联数据
    fmt.Println(task)
    

内容的提问来源于stack exchange,提问作者Huihui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 03:07:05