簡體   English   中英

查找線程鎖的futex ID

[英]Find threading.Lock's futex id

我想檢測一個大型Python項目,以便能夠調試如下所示的生產問題:

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調用。

您可以通過rr記錄程序的執行,然后可以設置條件斷點,如下所示:

b futex if $rdi==0x23b2c20

我設法為Python2破解了一些東西,這是一個演示:

$ 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

碼:

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")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM