微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

requests.request 上的分段错误

如何解决requests.request 上的分段错误

在使用 python 请求库连接到 Twitter 的 v2 API 端点后,我遇到了分段错误

请求是在生成器对象中的单独线程上创建的

class TwitterStream:
    def __init__():
        self.response = self.build_response()    

    def build_response():
        response = requests.request("GET",url,headers,stream=True)
        if response.status_code != 200:
            raise Exception("Exception")
        for record in response.iter_lines():
            yield record

    def __next__():
        return next(self.response)

然后在执行线程上,我使用一个 ThreadPoolExecutor 来获取每个响应行:

record_future = threadpoolexecutor.submit(next,TwitterStreamObjectInstance)
if record_future.done():
   # do stuff  with record_future.result()

我一直在 response = requests.request("GET",stream=True) 行遇到分段错误,我很确定,基于大量的 print() 调试。

我尝试了 gdb 调试方法,并取回了这个堆栈跟踪——我假设 libssl.so.1 导致了这个问题,但我真的不知道如何进一步调查。

#0  0x000000000001d85e in ?? ()
#1  0x00007ffff406ffa0 in OPENSSL_init_ssl () from /mnt/d/Projects/EBKA/edna_env/lib/python3.7/site-packages/MysqL/vendor/libssl.so.1.1
#2  0x00007ffff4074be3 in SSL_CTX_new () from /mnt/d/Projects/EBKA/edna_env/lib/python3.7/site-packages/MysqL/vendor/libssl.so.1.1
#3  0x00007ffff43c855d in ?? () from /usr/lib/python3.7/lib-dynload/_ssl.cpython-37m-x86_64-linux-gnu.so
#4  0x00005555556c9ff2 in ?? ()
#5  0x00005555556857d0 in _PyMethodDef_RawFastCallKeywords ()
#6  0x0000555555685560 in _PyCFunction_FastCallKeywords ()
#7  0x00005555556fa4e4 in _PyEval_EvalFrameDefault ()
#8  0x00005555556f4e2f in _PyEval_EvalCodeWithName ()
#9  0x0000555555687591 in _PyObject_Call_Prepend ()
#10 0x00005555556c9e3c in ?? ()
#11 0x00005555556c5ce5 in ?? ()
#12 0x0000555555685f72 in _PyObject_FastCallKeywords ()
#13 0x00005555556fa00d in _PyEval_EvalFrameDefault ()
#14 0x00005555556f4e2f in _PyEval_EvalCodeWithName ()
#15 0x0000555555686efa in _PyFunction_FastCallKeywords ()
#16 0x00005555556f6b0a in _PyEval_EvalFrameDefault ()
#17 0x0000555555686e1a in _PyFunction_FastCallKeywords ()
.
.
.
#58 0x00005555555c5d24 in _PyFunction_FastCallDict ()
#59 0x00005555556f73d0 in _PyEval_EvalFrameDefault ()
#60 0x0000555555686e1a in _PyFunction_FastCallKeywords ()
#61 0x00005555556f5fde in _PyEval_EvalFrameDefault ()
#62 0x0000555555686e1a in _PyFunction_FastCallKeywords ()
#63 0x00005555556f5fde in _PyEval_EvalFrameDefault ()
#64 0x0000555555687359 in _PyObject_Call_Prepend ()
#65 0x00005555556879b8 in PyObject_Call ()
#66 0x0000555555800193 in ?? ()
#67 0x00005555557c30d7 in ?? ()
#68 0x00007ffff7bbb6db in start_thread (arg=0x7fffd0f92700) at pthread_create.c:463
#69 0x00007ffff6cf071f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

附注 - 我在关闭线程时遇到问题,我得到以下信息

libgcc_s.so.1 must be installed for pthread_cancel to work

我得到的建议是在执行开始时执行以下操作:

import ctypes
libgcc_s = ctypes.CDLL('libgcc_s.so.1')

但这没有用。我之所以提到这一点,是因为在我尝试之后,我不断收到“找不到 libssl”的错误消息,我不确定它是否相关。

解决方法

根据我的经验,OPENSSL_init_ssl 中的崩溃通常是由于将 libssl.so.x.y 的多个版本(或多个实例)链接到单个进程中造成的。

在崩溃点使用 GDB info shared libssl

如果您看到多个版本,这很可能是根本原因。

如果不这样做,您的某些二进制文件仍有可能在 libssl.a 中链接。对于每个二进制文件(主 python 可执行文件和 info shared 输出中的每个共享库),运行 nm -A python lib1.so lib2.so ... | grep OPENSSL

如果唯一匹配的库是 /mnt/d/Projects/EBKA/edna_env/lib/python3.7/site-packages/mysql/vendor/libssl.so.1.1,那么一定有其他一些根本原因。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。