首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查找threading.Lock的futex id

查找threading.Lock的futex id
EN

Stack Overflow用户
提问于 2016-06-15 19:22:49
回答 2查看 764关注 0票数 2

我想要检测一个大型Python项目,以便能够调试如下所示的生产问题:

代码语言:javascript
复制
23321 07:49:57.925037 futex(0x23b2c20, FUTEX_WAIT_PRIVATE, 0, NULL <unfinished ...>
23321 07:50:12.435793 <... futex resumed> ) = 0

在这里,一个线程在某个锁(或条件变量)上等待了14.4秒。

我不确定这个锁是在Python代码中创建的,还是在第三方C扩展中创建的,但从统计上讲,Python是一个很好的猜测。

在我附加strace的时候,这个futex已经创建好了。我怀疑它是在应用程序启动时创建的。

我想要戳threading.Lock()threading.Condition()对象,并找出它们的底层futex id。

至少,我会记录这些id,这样以后,如果我必须堆叠一个正在运行的应用程序,我可以将我看到的futex调用解析为一些符合逻辑的东西。

EN

回答 2

Stack Overflow用户

发布于 2016-06-15 19:40:49

您可以通过rr记录程序执行,然后可以像这样设置条件断点:

代码语言:javascript
复制
b futex if $rdi==0x23b2c20
票数 2
EN

Stack Overflow用户

发布于 2016-06-16 20:31:20

我设法为Python2破解了一些东西,下面是一个演示:

代码语言:javascript
复制
$ strace -T -e signal=none -e futex python2 test.py
futex(0x7f6da47be0a8, FUTEX_WAKE_PRIVATE, 2147483647) = 0 <0.000006>
('futex address', '0x55de8d1105b0')
futex(0x55de8d123a30, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 0, NULL, ffffffff) = 0 <0.000038>
futex(0x55de8d074bf0, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 0, NULL, ffffffff) = 0 <0.000032>
futex(0x55de8d074bf0, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 0, NULL, ffffffff) = 0 <0.000036>
before
futex(0x55de8d1105b0, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 0, NULL, ffffffff) = 0 <5.017658>
inside
+++ exited with 0 +++

请注意,Python和strace都报告了相同的futex地址0x55de8d1105b0

代码:

代码语言:javascript
复制
import threading
import time
import sys
import ctypes

l = threading.Lock()

if sys.getsizeof(l) == 48:
    OFFSET = 4  # debug build: next, prev, refcnt, type, payload(lock_lock, ...)
elif sys.getsizeof(l) == 32:
    OFFSET = 2  # normal build: refcnt, type, payload(lock_lock, ...)
else:
    assert 0, "Don't do this shit to me"

lp = ctypes.cast(id(l), ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)))[OFFSET]

print("futex address", hex(ctypes.addressof(lp.contents)))


class holder(threading.Thread):
    def run(self):
        with l:
            time.sleep(5)


holder().start()

print("before")
with l:
    print("inside")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37834039

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档