---
title: Workload 切片组装问题定位案例分享-官方技术文章-鲲鹏社区
description: 本文介绍了Workload 单线程组装工具在进行切片组装时遇到的一个组装问题，以及解决问题的定位流程
keywords: Workload,切片组装问题,定位案例分享,官方技术文章,鲲鹏社区,Segmentation,Load,LD
url: https://www.hikunpeng.com/developer/techArticles/20250610-1?envFlag=1
section: (其他)
---

# Workload 切片组装问题定位案例分享-官方技术文章-鲲鹏社区

URL: https://www.hikunpeng.com/developer/techArticles/20250610-1?envFlag=1
描述: 本文介绍了Workload 单线程组装工具在进行切片组装时遇到的一个组装问题，以及解决问题的定位流程
关键词: Workload,切片组装问题,定位案例分享,官方技术文章,鲲鹏社区,Segmentation,Load,LD

官方技术文章 [了解详情](https://www.hikunpeng.com/zh/developer/techArticles)

Workload 切片组装问题定位案例分享

Workload 切片组装问题定位案例分享

案例分享

发表于 2025/06/10

0

Workload 单线程组装工具（xtrace2elfies）基于开源binutils实现，通过trace采集工具，从原业务获得真实的指令流与寄存器状态（trace），然后基于trace的信息，加入必要的修正代码（补偿），重新组装为可执行的二进制切片

本文介绍组装工具在适配一款新应用时，对一个设计缺陷问题的定位

问题现象

在工具的组装使用过程中，我们遇到了一个段错误问题

段错误（Segmentation fault）一般由错误的内存访问导致，对于工具源码，猜测可能由空指针引用、踩内存等引起

我们通过GDB查看源码报错位置

打开源码，查看相应位置的逻辑，发现报错在一行数组的赋值语句

以一条ldp（load pair）指令为例，假设这条指令从0x1230地址取出64位数据0x1，放在寄存器x0中，从0x1238地址取出64位数据0x2，放在寄存器x1中，我们将这条指令涉及的这些数据存入buf

易知，该用例中，offset最大不会超过mems[1].addr – mems[0].addr = 0x8

那么难道是一条访存跨度较大的指令引入的问题吗，我们在arm指令手册中选择一条NEON指令继续分析

ld4（Load single 4-element structure to one lane of four registers），ld4是一条NEON指令，它从一块连续地址中取出4个128位的数，存放到四个NEON寄存器的一个通道中

ld4 { v0.16b, v1.16b, v2.16b, v3.16b }, [sp]- LD 64-bit M[0x1000] -> 0x1- LD 64-bit M[0x1008] -> 0x2- LD 64-bit M[0x1010] -> 0x3- LD 64-bit M[0x1018] -> 0x4- LD 64-bit M[0x1020] -> 0x5- LD 64-bit M[0x1028] -> 0x6- LD 64-bit M[0x1030] -> 0x7- LD 64-bit M[0x1038] -> 0x8

该指令在采集工具采集时，会被拆分记录为N个ld/st指令，每条指令最大操作64bit数据，这是由qemu微指令最大访存单元为ld/st_i64决定的。因此该用例会记录为8个ld指令，offset最大不会超过mems[7].addr – mems[0].addr = 0x38，实际使用的buf范围是0x40（ld4指令访存连续，不会填入多余的0，因此此处的buf范围即是最终范围），可以容纳8 * 64bit = 64Bytes的数据

查看上层调用位置，发现buf数组的最大数据容纳是1024Bytes，因此即使是最大的NEON指令，也不会超过buf范围我们继续怀疑下一个点，由于该应用是SVE应用，我们怀疑产生问题的指令可能会是一条SVE指令，SVE访存指令特点如下：

寄存器可变长度：

例如SVE 512的场景下，8通道访存涉及的连续地址范围为512bit * 8 = 512Bytes，而SVE理论最高上限是2048bit，即使我们提高

MAX_DATA_PER_INST，也无法满足未来的所有场景

地址离散性：

地址离散性使得SVE/SME访存指令所涉及的地址范围理论上无限扩大，在前文的函数设计中，offset(mems[i].addr – baseAddr)也会无限放大，即使是SVE 128也有超出MAX_DATA_PER_INST的可能

为了验证猜想，我们通过添加打印，结合GDB命令，查看这条引发数组越界访存指令的实际指令码，定位到此时的指令码为0x850640a0，通过反汇编工具得到指令为一条ld1w指令

Ld1w（Gather load unsigned words to vector），是一条sve指令，用于从内存加载多个32位无符号整数到向量寄存器中，已知当前Trace的sve_len为256，可知这条ld1w指令为8通道访存，通过gdb验证信息一致，且通道8与通道1的地址偏移较大，远远超过1024 bytes在buf填充过程中，由于地址离散，相邻地址的差值较大，因此buf中将会填充许多的0

以上两张图是相邻ld i64访存的地址差值，以及地址不可达的最终位置（0x73e0）

解决方案：

该问题定位为数据结构设计不满足SVE/SME指令场景，因此我们需要在工具中添加地址连续性检测，当检测到离散访存时，切换为多buf模式进行记录，避免buf越界
