【发布时间】:2015-10-01 05:36:51
【问题描述】:
我维护了一个用 C 编写的库,Linux 上的用户可以直接从 Python 访问该库,该模块使用加载共享库和调用函数的模块。该模块非常常用,就像这个版本的共享库一样,人们在做popular tutorial。
用户遇到分段错误。在 gdb 下运行他的 Python 脚本,他看到它在共享库中,在一个函数中,该函数为结构分配内存并返回指针。他正在获取一个指针,但是当他尝试在后续调用共享库中使用它时,由于内存不可访问而发生分段错误。
如果他以 root 身份运行 Python 脚本,则不会出现问题。它也不会出现在备用 Linux 安装中。
回顾一下:
- 他的 Python 代码加载了共享库。
- 然后它调用一个函数,该函数返回一个指向在共享库中分配的内存的指针。
- 然后他调用共享库中的另一个函数,并传入它返回给他的指针,共享库被它自己的指针阻塞。
- 只有当他以普通用户身份在“4.0.7-2-ARCH x86_64 GNU/Linux”上运行它时才会出现这种情况。当他切换到 root 并运行它时,它不会在那个操作系统上发生。
- 当他尝试在 Ubuntu 机器上重现该问题时不会发生这种情况。
什么给了?这是一些 ARCH 错误吗?或者是否有可以清除的编程细微差别?
您可以阅读minutiae here,其中包含足够的详细信息来重现该问题,如果对于具有比我更多 Linux 编程经验的用户来说问题不是不言而喻的话。
共享库函数的快速链接:
- TCOD_map_new 的源代码。
- TCOD_map_set_properties 的源代码。
摘录他的 Python 代码以供后代和易于访问:
#!/usr/bin/env python2
import curses
import libtcodpy as libtcod
def main(stdscr):
curses.start_color()
curses.use_default_colors()
map = libtcod.map_new(10, 10) # any numbers work
libtcod.map_set_properties(map, 0, 0, True, True) # any in bounds integer coordinates fail
stdscr.getch()
curses.wrapper(main)
【问题讨论】:
-
C 函数的源码在哪里?
-
我在相关共享库文件的行号处添加了指向 1.5.1 Mercurial 标记(用户正在使用)的文件的链接。好点子。
-
像
TCOD_IFNOT(map != NULL && (unsigned)x < (unsigned)m->width && (unsigned)y < (unsigned)m->height) return false;这样的表达把我吓坏了。我肯定会考虑添加括号......另外:是否有任何线程/并发问题可能是一个因素? -
Valgrind 是你的朋友。
-
分段错误的位置并不总是指示错误的位置。
标签: c pointers segmentation-fault malloc posix