尝试在 libc 上使用 ctypes 调用 environ 时,为啥 Python 会出现段错误?

Posted

技术标签:

【中文标题】尝试在 libc 上使用 ctypes 调用 environ 时,为啥 Python 会出现段错误?【英文标题】:Why does Python segfault when attempting to call environ using ctypes on libc?尝试在 libc 上使用 ctypes 调用 environ 时,为什么 Python 会出现段错误? 【发布时间】:2012-01-30 10:44:36 【问题描述】:

在 Ubuntu 和 ArchLinux 上都测试过,我明白了

from ctypes import *
libc = CDLL('libc.so.6')
libc.environ()
Segmentation fault

为什么?

【问题讨论】:

【参考方案1】:

如果我正确阅读了手册页,environchar**,而不是函数。 如果你想得到环境变量,根据this post,你可以这样做:

from ctypes import *
libc = CDLL('libc.so.6')
environ = c_char_p.in_dll(libc, 'environ')

但它为我返回 'c_void_p(None)',不知道为什么会发生这种情况(我知道我只声明为 char *,但由于它返回 None,它们没有什么可取消引用的)。

不管怎样,你还是有“python”的方式:

import os
print os.environ

或者,如果你使用 ctypes 在环境中搜索特定的字符串,对于某些函数,你需要重新定义默认的 restype:

from ctypes import *
libc = CDLL('libc.so.6')
getenv = libc.getenv
getenv.restype = c_char_p
print getenv('HOME')

【讨论】:

【参考方案2】:

这是在 Ubuntu 上使用 ctypes 打印 C 环境的方法:

#!/usr/bin/env python2
import ctypes

libc = ctypes.CDLL(None)
environ = ctypes.POINTER(ctypes.c_char_p).in_dll(libc, 'environ')
for envvar in iter(iter(environ).next, None):
    print envvar

输出

LC_PAPER=en_GB.UTF-8
LC_ADDRESS=en_GB.UTF-8
CLUTTER_IM_MODULE=xim
LC_MONETARY=en_GB.UTF-8
VIRTUALENVWRAPPER_PROJECT_FILENAME=.project
SESSION=ubuntu
...

【讨论】:

以上是关于尝试在 libc 上使用 ctypes 调用 environ 时,为啥 Python 会出现段错误?的主要内容,如果未能解决你的问题,请参考以下文章

使用ctypes和python并调用libc accept时的EFAULT

在 Python 和 C++ 中使用 ctypes 时出现 Seg 错误

ctype中的结构

请教python调用dll动态库的传参问题

使用 ctypes/cffi 解决循环共享对象依赖关系

使用 ctypes 返回值