我一直在使用ctypes处理sysdig libscap库的包装器。这一切都很好,除了一件让我感到沮丧的事情。 Libscap使用uthash库来实现C语言中的数据结构之类的哈希表。我对uthash使用的结构有这个声明。
if sizeof(c_void_p) == 4:
ptrdiff_t = c_int32
elif sizeof(c_void_p) == 8:
ptrdiff_t = c_int64
# uthash.h
class UT_hash_table(Structure):
pass
class UT_hash_handle(Structure):
pass
UT_hash_handle._fields_ = [ ("tbl", POINTER(UT_hash_table)),
("prev", c_void_p),
("next", c_void_p),
("hh_prev", POINTER(UT_hash_handle)),
("hh_next", POINTER(UT_hash_handle)),
("key", c_void_p),
("keylen", c_uint),
("hashv", c_uint)]
class UT_hash_bucket(Structure):
_fields_ = [ ("hh_head", POINTER(UT_hash_handle)),
("count", c_uint),
("expand_mult", c_uint)]
UT_hash_table._fields_ = [
("buckets", POINTER(UT_hash_bucket)),
("num_buckets", c_uint),
("log2_num_buckets", c_uint),
("num_items", c_uint),
("tail", POINTER(UT_hash_handle)),
("hho", ptrdiff_t),
("ideal_chain_maxlen", c_uint),
("nonideal_items", c_uint),
("ineff_expands", c_uint),
("noexpand", c_uint),
("signature", c_uint32),
("bloom_sig", c_uint32),
("bloom_bv", POINTER(c_uint8)),
("bloom_nbits", c_char)]
还有另一个结构scap_threadinfo,它充当哈希表,并保存从/ proc文件系统解析的进程列表。
class scap_threadinfo(Structure):
_fields_ = [ ("tid", c_uint64),
("pid", c_uint64),
("ptid", c_uint64),
("comm", c_char * SCAP_MAX_PATH_SIZE),
("exe", c_char * SCAP_MAX_PATH_SIZE),
("args", c_char * SCAP_MAX_PATH_SIZE),
("args_len", c_uint16),
("env", c_char * SCAP_MAX_ENV_SIZE),
("env_len", c_uint16),
("cwd", c_char * SCAP_MAX_PATH_SIZE),
("fdlimit", c_uint64),
("flags", c_uint32),
("uid", c_uint32),
("gid", c_uint32),
("vmsize_kb", c_uint32),
("vmrss_kb", c_uint32),
("vmswap_kb", c_uint32),
("pfmajor", c_uint64),
("pfminor", c_uint64),
("scap_fdinfo", POINTER(scap_fdinfo)),
("hh", UT_hash_handle)]
此结构的最后一个成员将其标记为hasheable。当我调用scap_get_proc_table函数时,问题出现了,接下来UT_hash_handle的prev指针总是被评估为None。像exe或comm这样的其他成员对我系统上的第一个进程有正确的价值。感谢任何帮助。