免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6526 | 回复: 6
打印 上一主题 下一主题

[FreeBSD] 请问freeBSD gdb下如何查看宏?(已解决) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-09-06 09:29 |只看该作者 |倒序浏览
编译时使用了
gcc -gdwarf-2 -g3
的选项,启动gdb后使用macro expand还是看不到宏的信息,求教!

[ 本帖最后由 qiuhanty 于 2007-9-8 10:00 编辑 ]

评分

参与人数 1可用积分 +3 收起 理由
congli + 3 写得不错

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2007-09-08 09:59 |只看该作者
没人帮忙,只好自己解决了!

分析:
借用jjh编译的cc1编译程序,就可以展开宏。于是想到是gcc的原因。
使用readelf命令把编译后的程序进行对比,得到的主要差别如下:
161,166c195,201
<   1   0   0   0   test.c
<   2   1   0   0   stdlib.h
<   3   2   0   0   cdefs.h
<   4   2   0   0   _null.h
<   5   2   0   0   _types.h
<   6   3   0   0   _types.h
---
>   1   1   0   0   stdlib.h
>   2   2   0   0   cdefs.h
>   3   2   0   0   _null.h
>   4   2   0   0   _types.h
>   5   3   0   0   _types.h
>   6   0   0   0   test.c
>   7   0   0   0   <internal>

226,300c244,314
<  DW_MACINFO_start_file - lineno: 0 filenum: 1
<  DW_MACINFO_define - lineno : 0 macro : __STDC__ 1
...
---
>  DW_MACINFO_define - lineno : 1 macro : __STDC_HOSTED__ 1
>  DW_MACINFO_define - lineno : 2 macro : __GNUC__ 3

前者可以展开宏,后者不能展开宏。主要区别在于test.c的位置以及是否含有DW_MACINFO_start_file


解决:
有两种方法:
1 使用官方的gcc。但是发现编译内核的时候有些编译选项不能识别。影响太大。
2 修改gdb。费些事,但可以使影响降到最小。
我们采用第二种方法。主要修改文件为dwarf2read.c中的函数dwarf_decode_macros和file_full_name.
# diff dwarf2read.c.bak dwarf2read.c
9038a9039,9041
>
>     if (!strcmp("<internal>", fe->name))
>             fe = &lh->file_names[file - 2];
9333,9346c9336,9344
<             if (! current_file)
<         complaint (&symfile_complaints,
<            _("debug info gives macro %s outside of any file: %s"),
<            macinfo_type ==
<            DW_MACINFO_define ? "definition" : macinfo_type ==
<            DW_MACINFO_undef ? "undefinition" :
<            "something-or-other", body);
<             else
<               {
<                 if (macinfo_type == DW_MACINFO_define)
<                   parse_macro_definition (current_file, line, body);
<                 else if (macinfo_type == DW_MACINFO_undef)
<                   macro_undef (current_file, line, body);
<               }
---
>             if (! current_file) {
>               current_file = macro_start_file (lh->num_file_names, line,
>                                       current_file, comp_dir, lh, cu->objfile);
>           }
>
>             if (macinfo_type == DW_MACINFO_define)
>                  parse_macro_definition (current_file, line, body);
>             else if (macinfo_type == DW_MACINFO_undef)
>                  macro_undef (current_file, line, body);


调试内核展开宏注意事项:
1 在config生成的Makefile中如下行
.include "$S/conf/kern.pre.mk"
后加入:
CFLAGS+=-gdwarf-2 -g3
2 make cleandepend; make depend; make kernel
3 启动虚拟机完成连接
4 (gdb) macro expand LINKER_GET_NEXT_FILE_ID(lf->id)
expands to: do { linker_file_t lftmp; retry: do { uintptr_t _tid = (uintptr_t)((__curthread())); if (!atomic_cmpset_int(&((((&kld_mtx))))->mtx_lock, 0x00000004, (_tid))) _mtx_lock_sleep((((&kld_mtx))), _tid, ((0)), (((void *)0)), (0)); } while (0); for ((lftmp) = (((&linker_files))->tqh_first); (lftmp); (lftmp) = (((lftmp))->link.tqe_next)) { if (next_file_id == lftmp->id) { next_file_id++; do { uintptr_t _tid = (uintptr_t)((__curthread())); if (!atomic_cmpset_int(&((((&kld_mtx))))->mtx_lock, (_tid), 0x00000004)) _mtx_unlock_sleep((((&kld_mtx))), ((0)), (((void *)0)), (0)); } while (0); goto retry; } } (lf->id) = next_file_id; do { uintptr_t _tid = (uintptr_t)((__curthread())); if (!atomic_cmpset_int(&((((&kld_mtx))))->mtx_lock, (_tid), 0x00000004)) _mtx_unlock_sleep((((&kld_mtx))), ((0)), (((void *)0)), (0)); } while (0); } while(0)

嗯,太难看了,可惜set print pretty对它也没用。没关系,我们可以把它拷贝到一个临时文件tmp里,然后执行:
# indent tmp
再看看:
do {
    linker_file_t   lftmp;
retry:  do {
        uintptr_t   _tid = (uintptr_t) ((__curthread()));
        if (!atomic_cmpset_int(&((((&kld_mtx))))->mtx_lock, 0x00000004, (_tid)))
            _mtx_lock_sleep((((&kld_mtx))), _tid, ((0)), (((void *)0)), (0));
    } while (0);
    for ((lftmp) = (((&linker_files))->tqh_first); (lftmp); (lftmp) = (((lftmp))->link.tqe_next)) {
        if (next_file_id == lftmp->id) {
            next_file_id++;
            do {
                uintptr_t   _tid = (uintptr_t) ((__curthread()));
                if (!atomic_cmpset_int(&((((&kld_mtx))))->mtx_lock, (_tid), 0x00000004))
                    _mtx_unlock_sleep((((&kld_mtx))), ((0)), (((void *)0)), (0));
            } while (0);
            goto retry;
        }
    } (lf->id) = next_file_id;
    do {
        uintptr_t   _tid = (uintptr_t) ((__curthread()));
        if (!atomic_cmpset_int(&((((&kld_mtx))))->mtx_lock, (_tid), 0x00000004))
            _mtx_unlock_sleep((((&kld_mtx))), ((0)), (((void *)0)), (0));
    } while (0);
} while (0)


Enjoy!

论坛徽章:
0
3 [报告]
发表于 2007-09-10 08:30 |只看该作者
好文,支持!!!

论坛徽章:
0
4 [报告]
发表于 2007-09-10 09:07 |只看该作者
多谢支持!

顺便修正了gdb6.6不能展开宏中的"#"和"##"的bug

# diff macroexp.c.bak macroexp.c
29a30,31
> int nospace = 1; //indicate if we should add a ' '
>
217a220,237
> get_sharp(struct macro_buffer *tok, char *p, char *end)
> {
>   if (p < end && (*p == '#'))
>     {
>       char *tok_start = p;
>
>       while (p < end && (*p == '#'))
>         p++;
>
>       set_token (tok, tok_start, p);
>       tok->is_identifier = 0;
>       return 1;
>     }
>   else
>     return 0;
> }
>
> static int
497c517
<     else if (get_pp_number (tok, p, end)
---
>     else if (get_sharp(tok, p, end) || get_pp_number (tok, p, end)
585a606
> #if 0
593a615
> #endif
599c621,622
<   appendc (dest, ' ');
---
>   if (!nospace)
>       appendc (dest, ' ');
605a629,633
>   dest->last_token = original_dest_len + src->last_token;
>   if (!nospace)
>         dest->last_token++;
>   return;
>
821a850
>   int quotes = 0;
832a862,878
>       /* Is this token the stringification operator?  */
>       if (tok.len == 1
>           && tok.text[0] == '#') {
>               appendc (dest, '"');
>               quotes = 1;
>               nospace = 1;
>               continue;
>         }
>
>       /* Is this token the splicing operator?  */
>       if (tok.len == 2
>           && tok.text[0] == '#'
>           && tok.text[1] == '#') {
>                 nospace = 1;
>                 continue;
>         }
>
841,851d886
<       /* Is this token the stringification operator?  */
<       if (tok.len == 1
<           && tok.text[0] == '#')
<         error (_("Stringification is not implemented yet." ));
<
<       /* Is this token the splicing operator?  */
<       if (tok.len == 2
<           && tok.text[0] == '#'
<           && tok.text[1] == '#')
<         error (_("Token splicing is not implemented yet." ));
<
883a919,923
>         //nospace = 1;
>         if (quotes) {
>               appendc (dest, '"');
>               quotes = 0;
>         }

Enjoy!

论坛徽章:
0
5 [报告]
发表于 2007-09-13 09:23 |只看该作者
希望搂住多在版内讨论gdb的问题,呵呵!

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2007-09-13 09:32 |只看该作者
原帖由 雨丝风片 于 2007-9-13 09:23 发表
希望搂住多在版内讨论gdb的问题,呵呵!

咳 以后主楼就在这个版混吧

论坛徽章:
0
7 [报告]
发表于 2007-10-27 02:18 |只看该作者
楼主强人啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP