Linux下GTK界面调试

2013年6月8日 发表评论 阅读评论 11,780 次浏览

初学GTK,各种不懂,问题多多,遇到的第一个值得记录一下的问题就是在Linux下对GTK界面的调试问题。之前Linux下的各种操作从未考虑图形界面的问题,而全在终端下进行,使用gdb或cgdb是各种顺畅。现在在ubuntu图形系统Unity下调试GTK程序,竟然发现出现卡死的情况。
具体情况是这样,目前我正在做Linux下输入法的开发,暂选定的输入法为fcitx,在Unity的伪终端里用gdb启动fcitx,在TrayWindowInit处下断点,执行r运行程序,断下来后,整个X Window就hang住了,这个时候,自然无法再去操作伪终端,里面的gdb程序也响应不了。

lenky@lenky-Inspiron-545s:/opt/fcitx/bin$ gdb fcitx -q
Reading symbols from /opt/fcitx/bin/fcitx...done.
(gdb) b TrayWindowInit
Function "TrayWindowInit" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (TrayWindowInit) pending.
(gdb) r
...

这个时候,我是切换进入到1号终端(按ctrl+alt+f1),把gdb进程以及fcitx进程kill掉,重新切换回X Window(按ctrl+alt+f7)才能继续响应。不过,这样无法调试我的fcitx程序界面。

我自己想了一个比较矬的办法,即根据源代码,把fcitx需要的几个env参数从X Window的伪终端获取到(比如DISPLAY=:0、DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-VCM20hYfhM,guid=93ee8bee9037d4930e15bc9c51afe18b等),然后在1号终端内export出来:

lenky@lenky-Inspiron-545s:~$ cat ct7.sh
export DISPLAY=:0
export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-VCM20hYfhM,guid=93ee8bee9037d4930e15bc9c51afe18b

然后在终端1内用gdb调式fcitx,这样X Window挂住不影响终端1内的gdb调式操作。

实际用了用,感觉还行,不过这方法比较山寨,在1号终端和7号终端之间反复切换也不方便,Google了一下,搜索到这个链接:https://developer.gnome.org/gtk-faq/stable/x461.html

防失效,全文引用如下:

I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea? [GTK 2.x]

From Federico Mena Quintero:

“X is not locked up. It is likely that you are hitting a breakpoint inside a callback that is called from a place in Gtk that has a mouse grab.”

“Run your program with the –sync option; it will make it easier to debug. Also, you may want to use the console for running the debugger, and just let the program run in another console with the X server.”

Eric Mouw had another solution:

“An old terminal connected to an otherwise unused serial port is also great for debugging X programs. Old vt100/vt220 terminals are dirt cheap but a bit hard to get (here in The Netherlands, YMMV).”

Another option is to run your application on Xnest. Xnest is an X server which displays its root window in a regular window of another X server. A pointer grab on the Xnest display will not affect the GUI of your debugger running on your regular X server.

Xnest :1
twm -display :1
myapp –display=:1

又找到据说比Xnest更好的Xephyr,所以,更正式、更方便的方法如下:
1,安装xephyr:

lenky@lenky-Inspiron-545s:~$ apt-cache search xephyr
sugar-emulator-0.96 - Sugar graphical shell - emulator
xnest - Nested X server
xoo - graphical wrapper around Xnest/Xephyr
xserver-xephyr - nested X server
lenky@lenky-Inspiron-545s:~$ sudo apt-get install xserver-xephyr
正在读取软件包列表... 完成
正在分析软件包的依赖关系树       
正在读取状态信息... 完成       
...

2,启动xephyr:

lenky@lenky-Inspiron-545s:~$ Xephyr :1
...

参数:1表示Xsession,0号Xsession已经默认被7号终端Unity桌面占用了,所以这里用1号即可。

3,在伪终端里修改环境变量DISPLAY,然后启动gdb调试:

lenky@lenky-Inspiron-545s:~$ export DISPLAY=:1
lenky@lenky-Inspiron-545s:~$ gdb /opt/fcitx-configtool/bin/fcitx-config-gtk3 -q
Reading symbols from /opt/fcitx-configtool/bin/fcitx-config-gtk3...done.
(gdb) r
Starting program: /opt/fcitx-configtool/bin/fcitx-config-gtk3 
...

Xephyr中显示的效果图:

不错,而且我也可以很方便的进行gdb调试了。

参考资料:
http://en.wikipedia.org/wiki/Xnest
http://box.matto.nl/xnest.html
http://a3linux.blogspot.com/2007/08/fedoraxnest-x.html
http://www.dedoimedo.com/computers/xephyr.html
http://ubuntuforums.org/showthread.php?t=620003
http://blog.csdn.net/dbzhang800/article/details/6433496

转载请保留地址:http://www.lenky.info/archives/2013/06/2298http://lenky.info/?p=2298


备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并欢迎来讨论。另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了一下归纳&转述,在此也一并表示感谢。关于本站的所有技术文章,欢迎转载,但请遵从CC创作共享协议,而一些私人性质较强的心情随笔,建议不要转载。

法律:根据最新颁布的《信息网络传播权保护条例》,如果您认为本文章的任何内容侵犯了您的权利,请以Email或书面等方式告知,本站将及时删除相关内容或链接。

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.