我有一个C ++共享库对象,它包含GLib library。
当我使用空main()
函数创建一个最小测试程序,并且我与共享库链接时,程序会在运行时立即中止,并显示以下GLib错误消息:
GLib (gthread-posix.c): Unexpected error from C library during 'pthread_cond_init': Invalid argument. Aborting.
由于我的main函数为空,因此必须在某些预主要初始化函数中发生错误。因此,使用GDB我发现GLib有一个静态初始化构造函数(在glib-init.c
中),它在main()
之前在运行时调用。在该初始化函数中,它调用pthread_cond_init
,这会神秘地失败。
以下是完整的回溯:
(gdb) run
Starting program: ~/example
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
GLib (gthread-posix.c): Unexpected error from C library during 'pthread_cond_init': Invalid argument. Aborting.
Program received signal SIGABRT, Aborted.
0x0000003891830265 in raise () from /lib64/libc.so.6
(gdb) bt
#0 0x0000003891830265 in raise () from /lib64/libc.so.6
#1 0x0000003891831d10 in abort () from /lib64/libc.so.6
#2 0x00002aaaab9aed32 in g_thread_abort (status=22,
function=0x2aaaabcbdd2b "pthread_cond_init")
at ~/libs/glib/gthread-posix.c:75
#3 0x00002aaaab9af349 in g_cond_impl_new ()
at ~/libs/glib/gthread-posix.c:656
#4 0x00002aaaab9af39b in g_cond_get_impl (
cond=0x2aaaac15f690 <g_once_cond>)
at ~/libs/glib/gthread-posix.c:677
#5 0x00002aaaab9af4b2 in g_cond_broadcast (
cond=0x2aaaac15f690 <g_once_cond>)
at ~/libs/glib/gthread-posix.c:792
#6 0x00002aaaab9ab529 in g_once_init_leave (
location=0x2aaaac160510 <g_define_type_id__volatile.11714>,
result=6524000) at ~/libs/glib/gthread.c:682
#7 0x00002aaaaba34a2f in g_value_array_get_type ()
at ~/libs/gobject/gboxed.c:132
#8 0x00002aaaaba41b28 in _g_param_spec_types_init ()
at ~/libs/gobject/gparamspecs.c:1511
#9 0x00002aaaaba30c72 in gobject_init_ctor ()
at ~/libs/gobject/gtype.c:4391
#10 0x00002aaaabb2bc36 in __do_global_ctors_aux ()
from ./MYLIB.so
#11 0x00002aaaaad368eb in _init () from ./MYLIB.so
#12 0x00002aaab0180e60 in ?? ()
#13 0x000000389140d4ab in call_init ()
from /lib64/ld-linux-x86-64.so.2
#14 0x000000389140d5b5 in _dl_init_internal ()
from /lib64/ld-linux-x86-64.so.2
#15 0x0000003891400aaa in _dl_start_user ()
from /lib64/ld-linux-x86-64.so.2
#16 0x0000000000000001 in ?? ()
#17 0x00007fffffffe6de in ?? ()
#18 0x0000000000000000 in ?? ()
所以,我的第一个想法可能是.so
文件没有与pthread库正确链接。所以,我使用ldd
实用程序来检查它如何链接到pthread:
$ ldd MYLIB.so
linux-vdso.so.1 => (0x00007fff56ed1000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b8a747bf000)
librt.so.1 => /lib64/librt.so.1 (0x00002b8a749db000)
libpng12.so.0 => /usr/lib64/libpng12.so.0 (0x00002b8a74be5000)
libfontconfig.so.1 => /usr/lib64/libfontconfig.so.1 (0x00002b8a74e09000)
libz.so.1 => /lib64/libz.so.1 (0x00002b8a7503d000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b8a75252000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b8a75456000)
libm.so.6 => /lib64/libm.so.6 (0x00002b8a75756000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b8a759da000)
libc.so.6 => /lib64/libc.so.6 (0x00002b8a75be8000)
/lib64/ld-linux-x86-64.so.2 (0x0000003891400000)
libfreetype.so.6 => /usr/lib64/libfreetype.so.6 (0x00002b8a75f41000)
libexpat.so.0 => /lib64/libexpat.so.0 (0x00002b8a761c6000)
因此,它通过/usr/lib64/pthread.so.0
然后我查看了pthread_cond_init
失败的GLib源代码。这非常简单。为清晰起见,我删除了一些#ifdef
语句:
pthread_condattr_t attr;
pthread_cond_t *cond;
gint status;
pthread_condattr_init (&attr);
cond = malloc (sizeof (pthread_cond_t));
if G_UNLIKELY (cond == NULL)
g_thread_abort (errno, "malloc");
if G_UNLIKELY ((status = pthread_cond_init (cond, &attr)) != 0) <--- this fails
g_thread_abort (status, "pthread_cond_init");
所以没有什么是错的,我怀疑GLib会有这样的明显错误,因为它被广泛用于许多主要的Linux代码库。
所以,在这一点上,我没有想法。这个问题有哪些可能和/或可能的原因?这可能是一个初始化顺序问题,其中pthread lib需要在GLib可以使用它之前执行一些静态初始化吗?
答案 0 :(得分:0)
在import socket, sys
from struct import *
#create an INET, STREAMing socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
except socket.error , msg:
print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
# receive a packet
while True:
packet = s.recvfrom(65565)
#packet string from tuple
packet = packet[0]
#take first 20 characters for the ip header
ip_header = packet[0:20]
#now unpack them :)
iph = unpack('!BBHHHBBH4s4s' , ip_header)
version_ihl = iph[0]
version = version_ihl >> 4
ihl = version_ihl & 0xF
iph_length = ihl * 4
ttl = iph[5]
protocol = iph[6]
s_addr = socket.inet_ntoa(iph[8]);
d_addr = socket.inet_ntoa(iph[9]);
print 'Version : ' + str(version) + ' IP Header Length : ' + str(ihl) + ' TTL : ' + str(ttl) + ' Protocol : ' + str(protocol) + ' Source Address : ' + str(s_addr) + ' Destination Address : ' + str(d_addr)
tcp_header = packet[iph_length:iph_length+20]
#now unpack them :)
tcph = unpack('!HHLLBBHHH' , tcp_header)
source_port = tcph[0]
dest_port = tcph[1]
sequence = tcph[2]
acknowledgement = tcph[3]
doff_reserved = tcph[4]
tcph_length = doff_reserved >> 4
print 'Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port) + ' Sequence Number : ' + str(sequence) + ' Acknowledgement : ' + str(acknowledgement) + ' TCP header length : ' + str(tcph_length)
h_size = iph_length + tcph_length * 4
data_size = len(packet) - h_size
#get data from the packet
data = packet[h_size:]
print 'Data : ' + data
print
中,glibc-2.5
有两个版本。可能使用的旧版本有一个评论
除了CLOCK_REALTIME
之外,都不是时钟
受支持,可以返回pthread_cond_init
。
在EINVAL
的{{3}}行中,有一个电话
gthread-posix.c
可能导致pthread_condattr_setclock (&attr, CLOCK_MONOTONIC);
从EINVAL
返回。
如果您可以重新编译pthread_cond_init
,则可以取消定义glib
。
否则我会尽可能更新HAVE_PTHREAD_CONDATTR_SETCLOCK
。