Skip to content
lainme edited this page Mar 8, 2013 · 18 revisions

HOW TO DEBUG

1.编译带调试信息

因为从ppa上安装的版本都不含有调试信息.所以首先我们需要下载源代码编译.

git clone git://github.com/xiehuc/pidgin-lwqq.git

然后需要满足编译的时候带有-g标识.VERBOSE可以打开大部分控制台输出

mkdir build;cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DVERBOSE=3
make
sudo make install

VERBOSE的输出等级分为下面5类:

0---无输出
1---常规信息输出(一些错误提示)
2---poll信息输出
3---所有的请求输出(url,post,response)
4---图片上传下载和离线文件上传的详细HTTP信息.
5---extra输出(输出当前活跃的url),timeout输出(不是超时,可以认为是curl的时间片)

一般是选择3,在调试图片和离线文件传输问题的时候需要打开到4. 安装debug版本。

2.带gdb运行

然后请运行源代码包里面的debug.sh,它设定了一些gdb的flags. 主要是不要拦截开启了SSL之后的SIGPIPE信号.

会有如图的消息:

GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.<br>
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"<br>
and "show warranty" for details.<br>
This GDB was configured as "x86_64-linux-gnu".<br>
For bug reporting instructions, please see:<br>
<http://bugs.launchpad.net/gdb-linaro/>...<br>
Reading symbols from /usr/bin/pidgin...Reading symbols from /usr/lib/debug/usr/bin/pidgin...done.<br>
done.<br>
(gdb)

此时输入run (r)回车

(gdb) r

就会开始运行pidgin了.

其中控制台会出现许多信息.不用管它.

[Sep  9 09:18:48] DEBUG[18627]: /home/xiehuc/PROJECT/pidgin-lwqq/src/liblwqq/info.c:1210     lwqq_info_get_friend_detail_info: in function.hi
r={"to":2505299203,"face":0,"content":"[\"hi\",[\"font\",{\"name\":\"宋体\",\"size\":\"13\",\"style\": [0,0,0],\"color\":\"000000\"}]]","msg_id":3310000,"clientid":"84684545","psessionid":"8368046764001f636f6e6e7365727665725f7765627171403137322e32332e3133342e323136000055cb00000ce1016e04009563e4146d0000000a40744f4462614167355a6d00000028f74c3012cadb51c60b55ab412e8d1dd7070b0ce4bb78d5f2acf877a6afa94b3ee508bc7e56de8383"}&clientid=84684545&psessionid=8368046764001f636f6e6e7365727665725f7765627171403137322e32332e3133342e323136000055cb00000ce1016e04009563e4146d0000000a40744f4462614167355a6d00000028f74c3012cadb51c60b55ab412e8d1dd7070b0ce4bb78d5f2acf877a6afa94b3ee508bc7e56de8383
{"retcode":0,"result":"ok"}

你有兴趣的话可以看一下.大部分是POST消息.
然后运行操作让它崩溃.

Program received signal SIGINT, Interrupt.
0x00007ffff46afb03 in __GI___poll (fds=<optimized out>, nfds=<optimized out>, 
    timeout=<optimized out>) at ../sysdeps/unix/sysv/linux/poll.c:87
87	../sysdeps/unix/sysv/linux/poll.c: 没有那个文件或目录.
(gdb) 

现在已经在gdb里面了.当然这些信息还根本没有什么作用.
运行(gdb) bt可以查看系统调用栈,如下:

(gdb) bt
#0  qq_send_im (gc=0x5555565f20c0, who=0x555555e15e00 "2505299203", 
    what=0x555555dcff60 "hi", UNUSED_flags=PURPLE_MESSAGE_SEND)
    at /home/xiehuc/PROJECT/pidgin-lwqq/src/webqq.c:771
#1  0x00007ffff4d0fb94 in serv_send_im (gc=0x5555565f20c0, 
    name=0x555555e15e00 "2505299203", message=0x555555dcff60 "hi", 
    flags=PURPLE_MESSAGE_SEND)
    at /build/buildd/pidgin-2.10.3/./libpurple/server.c:145
#2  0x00007ffff4cdeb9f in common_send (conv=0x555556655440, 
    message=<optimized out>, msgflags=PURPLE_MESSAGE_SEND)
    at /build/buildd/pidgin-2.10.3/./libpurple/conversation.c:182
#3  0x00005555555b5065 in send_cb (widget=<optimized out>, 
    gtkconv=0x5555566efe00)
    at /build/buildd/pidgin-2.10.3/./pidgin/gtkconv.c:612
#4  0x00007ffff52b6ca2 in g_closure_invoke ()
   from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#5  0x00007ffff52c7fdd in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#6  0x00007ffff52cf289 in g_signal_emitv ()
   from /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#7  0x00007ffff617380a in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#8  0x00007ffff6173d68 in ?? ()
   from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0

可以看到第#0号就是pidgin-lwqq的代码了.有另外一些情况是在#i,i>0是pidgin-lwqq的代码,而#0是其他地方的比如libc.so的.
这里我们能改的只能是pidgin-lwqq的代码.所以需要用(gdb)f i来跳到第几层,f是frame的意思.
其中可以看到是在qq_send_im这个函数挂调的(我这里是设置的断点,其实没有问题)
而且提示是在771行,因为不同的版本行肯定会改变的.
(你用的是19日编译版本,我用的是29日编译版本,中间添加了这么多代码,肯定会造成行移位)
所以使用(gdb) l可以查看代码.中间一行就是出错的位置.

(gdb) l
766	
767	
768	//send a message to a friend.
769	//called by purple
770	static int qq_send_im(PurpleConnection *gc, const gchar *who, const gchar *what, PurpleMessageFlags UNUSED(flags))
771	{
772	    qq_account* ac = (qq_account*)purple_connection_get_protocol_data(gc);
773	    LwqqClient* lc = ac->qq;
774	    char nick[32],gname[32];
775	    const char* pos;

(我这里是加的断点,所以是函数一开始).
有了具体的位置了.调试起来就容易了.
最后.把这些消息都贴在github上.或者发给我.帮助调试.

最后运行(gdb) c继续运行.如果中间操作时间太长了,就会掉线.需要重新登录.