恩智浦和论坛成员,你们好、
我们正在使用 i.MX93,并希望使用共享内存在 M33 和 A55 内核之间进行交互,在该内存区域使用共享环形缓冲区结构。
M33 可以顺利访问共享内存,这在 A55 端也基本正常,但是:只要连接的 GDB 客户端尝试打印共享内存的内容,程序就会因分段故障而崩溃:
无法处理内核从虚拟地址 ffff8000822e7000 处的不可读内存读取的数据。
这就很奇怪了,因为共享内存块的底部从 0x8F600000 开始,映射到虚拟内存的位置是 FFFFF73E0000。
再详细一点:
我们希望避免根据需要编写完整的内核驱动程序,而是使用 UIO 驱动程序处理用户空间的内存访问。
为此,我们在设备树中创建了两个条目,定义了内存区域并将其分配给 UIO 驱动程序。
使用 mmap() 将内存区域映射到用户空间区域后,在不使用 GDB 调试/打印内存区域的情况下,我们就可以在双方都没有问题的情况下读写共享区域。
大多数集成开发环境和调试前端都会在遇到断点时立即打印本地/函数本地变量,这导致我们无法使用调试器,目前完全阻塞了我们的项目
如https://stackoverflow.com/questions/654393/examining-mmaped-addresses-using-gdb所述,解决这个问题的方法是在.access 中添加一个.access.config。成员到相应(自定义)内核驱动程序中的 vm_operations_struct。
但就我所知,我们使用的 UIO 驱动程序(已启用 CONFIG_HAVE_IOREMAP_PROT)中似乎实现了相应的方法:https://github.com/phytec/linux-phytec-imx/blob/v6.6.52-2.2.0-phy/drivers/uio/uio.c
我们正在使用 PHYTEC 的 SOM 板,目前正在使用他们的载板硬件 " PhyBoard Nash " 直到我们自己的硬件完工。因此,我们目前在 yocto 层中主要使用补丁作为 " 快速和肮脏 "。
这篇文章附有一个存档,其中包含一个最小的工作应用程序示例,以及我们当前 yocto 元层的精简版本。
在我看来非常奇怪的是,网上关于 UIO、mmap 和 gdb 问题的搜索结果并不多,但这似乎是从用户空间访问原始内存的一种相当常见的方式。
您知道 GDB 为什么会访问错误的、未映射/不可访问的内存区域,或者是什么原因导致了我们的问题吗?
预先感谢& ,致以最崇高的敬意
马尔库斯
你好@Bio_TICFSL、
感谢您的快速回复。
是的,我知道内存访问故障是如何发生的,也知道你提到和描述的例子/原因。
GDB 客户端本身似乎执行了错误的内存读取,导致 SIGSEGV 崩溃,因此这无助于我们调试此问题,但似乎是导致此问题的原因。
也许您能告诉我,理论上 GDB 是否应该能够像我们一样访问处理过的内存(UIO + mmap)?
不幸的是,我们目前无法使用 " vanilla " /mainline 内核树在这里进行测试,因为我们在 PHYTEC 载板上,我们无法自己检查这是一个 PHYTEC 分支问题还是常规(主线)问题。
顺祝商祺!
马尔库斯
你好
越界数组访问: 访问超出声明大小的数组元素。
堆栈溢出: 过度递归或大型局部变量占用了所有可用堆栈空间。
写入只读内存: 试图修改指定为只读的内存段,如代码段。
Use-after-free 错误: 在内存被重新分配后访问内存。
bt(回溯)命令查看导致崩溃的调用堆栈。 这有助于确定发生故障的函数和代码行。 帧 N浏览堆栈帧(其中 N 是反向跟踪中的帧号),并使用print variable_name检查相关变量(尤其是指针)的值,以识别空地址或无效地址等潜在问题。