Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2314277
  • 博文数量: 527
  • 博客积分: 10343
  • 博客等级: 上将
  • 技术积分: 5565
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-26 23:05
文章分类

全部博文(527)

文章存档

2014年(4)

2012年(13)

2011年(19)

2010年(91)

2009年(136)

2008年(142)

2007年(80)

2006年(29)

2005年(13)

我的朋友

分类: LINUX

2010-11-26 09:44:31

原因: 用flexe lint 检查C程序时, 对于下面的定义
struct foo
{
   ...
   char data[0];
};

data的定义会引起一个

Error 43: Vacuous type for ...

对于大一点的程序, 使用这种技巧的结构往往有多处, 如何一次性找到所有这些定义?

最简单的办法是用 grep -r, 但正则表达式无法处理诡异的C声明语法, 对于简单的情况, 这一招是可以的, 复杂的就不行了.

另一个办法是利用 flexe lint 本身的输出, 它里面会把出错的文件列出来. 但这个办法有个缺点: 其一flexe lint 运行很慢, 代价很大, 其二, flexe 如果前面出现错误, 后面的输出就不靠谱了.

使用gdb 的info types 命令可以得到所有的struct. 再用ptype 即可列出相应的定义. 下面是一个脚本自动列出一个程序中的所有结构定义, 稍加改动就可以处理enum, union, typedef



#!/bin/bash

elf="$1"

file_type_mix="$(mktemp)"

hput() {
    eval "$1""$2"='$3'
}

hget() {
    eval echo '${'"$1$2"'}'
}

# Assuming has debug info
# Prepend a ! to every line. Because read will discard the leading spaces.
# This cause confuse when struct member is also a struct.
gdb -ex "info types" -ex "quit" "$elf" | sed 's/^/!/' > "$file_type_mix"

while read line ; do
    if [[ "$line" =~ "^!File " ]]; then
        latest_file="${line#!File }"
    elif [[ "$line" =~ "^!struct " ]]; then
        type_name="${line#!struct }"
        type_name="${type_name%;}"
        hput type_2_file "$type_name" "$latest_file"
    fi
done < "$file_type_mix"

gdb_src="$(mktemp)"
for i in $(compgen -A variable type_2_file); do
    echo -n 'shell echo '
    hget "$i" ""
    echo ptype struct ${i#type_2_file}
done > "$gdb_src"

# When output to pipe, gdb will NOT ask you press Enter to continue
gdb -ex "source $gdb_src" -ex "quit" "$elf" | cat


使用这个方法的好处是, 程序已经是经过编译和链接的最终结果, gdb的输出是规范的, 可以用简单的正则表达式进行匹配.
缺点是, 如果用宏把一些代码关闭掉, 这样的结构就不会被记录到debug 信息中, gdb也就无从得到.

以上只针对C的 struct, 要同时输出C++的类, 以及对namespace的支持, 还需要做进一步的修改.
阅读(1233) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~