原因: 用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的支持, 还需要做进一步的修改.
阅读(1287) | 评论(0) | 转发(0) |