首先是在 Windows 上遇到的,有时候上线的时候就崩溃了,然后重新启动仍然还是会崩溃,这样几次才能起来。
由于在 Windows 上不好调试,不知道到底是哪里的问题。后来在 Linux 也碰到,会产生 core。gdb 后,
发现是 jabber 的问题,backtrace 如下:
-
(gdb) bt
-
#0 0xb75ba7c7 in raise () from /lib/tls/libc.so.6
-
#1 0xb75bc06b in abort () from /lib/tls/libc.so.6
-
#2 0x080f6a5b in sighandler (sig=11) at gtkmain.c:175
-
#3 <signal handler called>
-
#4 0xb7717c56 in xmlCreateEntityParserCtxt () from /usr/lib/libxml2.so.2
-
#5 0xb77294a3 in xmlParseChunk () from /usr/lib/libxml2.so.2
-
#6 0xb6e90aef in jabber_parser_process (js=0x84c4708, buf=0x1 <Address 0x1 out of bounds>, len=1701999730) at parser.c:287
-
#7 0xb6e88cef in jabber_recv_cb_ssl (data=0x84c4908, gsc=0x84eb7f8, cond=GAIM_INPUT_READ) at jabber.c:356
-
#8 0x080e2393 in gaim_gtk_io_invoke (source=0x84c84d0, condition=G_IO_IN, data=0x84de8f8) at gtkeventloop.c:74
-
#9 0xb78587ef in g_io_channel_unix_get_fd () from /usr/lib/libglib-2.0.so.0
-
#10 0xb782fe2c in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
-
#11 0xb7833176 in g_main_context_check () from /usr/lib/libglib-2.0.so.0
-
#12 0xb7833537 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
-
#13 0xb7ca64e1 in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0
-
#14 0x080f68f7 in main (argc=Cannot access memory at address 0x65727472) at gtkmain.c:769
而且 gaim -d 出来的信息也非常固定,相关的如下:
-
jabber: Sending:
-
<?xml version='1.0' ?>
-
jabber: Sending:
-
<stream:stream to='gmail.com' xmlns='jabber:client'
-
xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
-
jabber: Recv (177):
-
1) <?xml version="1.0" encoding="UTF-8"?>
-
<stream:stream from="gmail.com" id="X1E24799AB597443A" version="1.0"
-
xmlns:stream="http://etherx.jabber.org/streams"
-
xmlns="jabber:client">
-
jabber: Recv (189):
-
2) <stream:features>
-
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
-
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
-
<mechanism>X-GOOGLE-TOKEN</mechanism>
-
</mechanisms>
-
</stream:features>
-
jabber: Sending:
-
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
-
jabber: Recv (50):
-
3) <proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
-
......
-
jabber: Sending (ssl):
-
<stream:stream to='gmail.com' xmlns='jabber:client'
-
xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
-
jabber: Recv (ssl)(177):
-
4) <?xml version="1.0" encoding="UTF-8"?>
-
<stream:stream from="gmail.com" id="XF341BDEC9BA25263" version="1.0"
-
xmlns:stream="http://etherx.jabber.org/streams"
-
xmlns="jabber:client">
-
jabber: Recv (ssl)(166):
-
5) <stream:features>
-
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
-
<mechanism>PLAIN</mechanism>
-
<mechanism>X-GOOGLE-TOKEN</mechanism>
-
</mechanisms>
-
</stream:features>
-
sasl: Mechs found: PLAIN X-GOOGLE-TOKEN
-
jabber: Sending (ssl):
-
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
-
mechanism='PLAIN'>XXXXXXXX</auth>
-
jabber: Recv (ssl)(51):
-
6) <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
-
jabber: Sending (ssl):
-
<stream:stream to='gmail.com' xmlns='jabber:client'
-
xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
在对照了 [XMPP Core] 以后,协议是没错的,
但错误总是发生在第二次 Jabber 协议初始化并且发送了一次客户端消息之后。相关的代码如下:
-
01 jabber.c:510:jabber_login() 开始登录
-
02 jabber.c:472:jabber_login_connect()
-
03 jabber.c:421:jabber_login_callback()
-
jabber.c:982:jabber_stream_set_state() 参数是 JABBER_STREAM_INITIALIZING
-
jabber.c:57:jabber_stream_init() XML 解析器清零,客户端发起协议,
-
04 jabber.c:366:jabber_recv_cb() 接收到数据后,回调函数被调用,进行处理
-
05 parser.c:271:jabber_parser_process() (391 行) 如果是第一次,则初始化 XML 解析器,
-
其解析的处理函数在 parser.c:207:jabber_parser_libxml 定义中。然后对数据进行 XML 解析。
-
06 parser.c:171:jabber_parser_element_end_libxml() 在一个元素结束的时候进行一些操作,
-
通常是一次数据全部解析完以后才真正开始解析 Jabber 协议数据。
-
07 jabber.c:167:jabber_process_packet() 针对包中不同元素的名字可能会采取不同的操作。
-
-
从上面提供的调试数据(主要针对 Recv)可以看到,处理了 stream:features 和 starttls,然后返回。
-
-
然后在收到 proceed 包的时候:
-
08 jabber.c:464:tls_init()
-
09 jabber.c:400:jabber_login_callback_ssl() SSL 登录的回调函数,并增加输入的回调函数
-
10 jabber.c:339:jabber_recv_cb_ssl() 接下来的处理就和第 5-7 步一样了。
-
以后的调试信息就有了(ssl)的标记
-
-
接下来就收到了第 5 个包,开始处理:
-
11 jabber.c:125:jabber_stream_features_parse()
-
12 auth.c:302:jabber_auth_start()
-
13 auth.c:62:finish_plaintext_authentication() 发送了 auth 这个包。
-
-
接着收到了第 6 个包,是 success:
-
14 auth.c:736:jabber_auth_handle_success()
-
15 jabber.c:982:jabber_stream_set_state() 参数是 JABBER_STREAM_REINITIALIZING
-
16 jabber.c:57:jabber_stream_init() XML 解析器清零,客户端重新发起协议,
这里发送完以后就发生了 core dump,应该还没有收到服务器端的响应,不然会有调试信息打出来的。
所以就有了矛盾,不知道为什么会出错。我感觉可能是 XML 解析器的状态问题。




Gaim-dev 上有人提交了 patch
原因是在 reinit 的时候,还是在 xml 的回调函数中运行的,而它把 xml context 给释放了,所以会发生错误。
我上面的猜想是对的,不过没有再仔细想想。SVN Trunk 上应该已经解决。
Post new comment