<2023-11-08 Wed>
emacs
源码分析(四)在调试emacs
源码时一个使用gdb
的小技巧:如果要查看一个Lisp_Symbol
结构体变量中名称的字符串可以这么来,比如这个0xdd70
就是一个Lisp_Symbol
变量,它对应的名称字符串是"top-level"
,如下:
(gdb) p XSTRING(XSYMBOL(0xdd70).u.s.name).u.s.data
$8 = (unsigned char *) 0x100a6c4c3 <o_fwd+15843> "top-level"
(gdb) macro define sym_name(lisp_obj) XSTRING(XSYMBOL(lisp_obj).u.s.name).u.s.data
(gdb) p sym_name(0xdd70)
$9 = (unsigned char *) 0x100a6c4c3 <o_fwd+15843> "top-level"
(gdb) macro exp sym_name(Lisp_Object)
expands to: XSTRING(XSYMBOL(Lisp_Object).u.s.name).u.s.data
需要解释一下的话:
XSYMBOL
从Lisp_Object
中获得Lisp_Symbol
,Lisp_Symbol
的u.s.name
里存放着Lisp_Object
。XSTRING
从Lisp_Object
里获得Lisp_String
,Lisp_String
的u.s.data
里存放着unsigned char *
。macro define
命令定义了一个gdb
宏sym_name
,方便调试过程中使用。另外,可以通过XTYPE
来查看一个Lisp_Object
的类型,比如我看代码里不知道Vtop_level
是什么类型,我可以:
(gdb) p XTYPE(Vtop_level)
$10 = Lisp_Cons
(gdb) p XTYPE(0xdd70)
$11 = Lisp_Symbol
(gdb) p XCONS(Vtop_level)
$12 = (struct Lisp_Cons *) 0xa000ef5d0
(gdb) p XCONS(Vtop_level).u.s.car
$13 = (Lisp_Object) 0x9210
(gdb) p XTYPE(XCONS(Vtop_level).u.s.car)
$14 = Lisp_Symbol
(gdb) p sym_name(XCONS(Vtop_level).u.s.car)
$15 = (unsigned char *) 0x100a6b020 <o_fwd+10560> "load"
这里用上了刚才定义的sym_name
宏。看上面的输出非常直观,胜过千言万语,另参考一下:“EmacsWiki Hacker Guide”会有大收获。
看了上面的Vtop_level
的car
,我想再看看cdr
:
(gdb) p XTYPE(XCONS(Vtop_level).u.s.u.cdr)
$17 = Lisp_Cons
(gdb) p XCONS(XCONS(Vtop_level).u.s.u.cdr)
$18 = (struct Lisp_Cons *) 0xa000ef5c0
(gdb) p XCONS(XCONS(Vtop_level).u.s.u.cdr).u.s.car
$19 = (Lisp_Object) 0xa001251e4
(gdb) p XTYPE(XCONS(XCONS(Vtop_level).u.s.u.cdr).u.s.car)
$20 = Lisp_String
(gdb) p XSTRING(XCONS(XCONS(Vtop_level).u.s.u.cdr).u.s.car).u.s.data
$21 = (unsigned char *) 0xa000dfe08 "loadup.el"
所以这里的Vtop_level
就是一段lisp
代码:
(load loadup.el)