笔记分享 - shell脚本实现C程序中变量的查找

原创
2018/06/10 17:04
阅读数 605

1. 概述

github项目地址:https://github.com/superwujc

尊重原创,欢迎转载,注明出处:https://my.oschina.net/superwjc/blog/1827736

阅读内核源码的过程中,经常需要查看变量的定义与赋值情况,虽然有诸如elixir.bootlin.com与source insight等工具,但不够快速与直观:全局变量的值经常在多个文件中被引用与更改,需要跨文件查找,且变量为结构体成员时,elixir通常无法查看该变量的定义与引用情况;本例基于awk与bash实现了一个简单的功能,以字符串(通常为全局变量或结构体实例)为关键字作为输入,输出为该字符串所在的函数名称,便于快速定位变量的位置,以及跟踪变量的赋值情况。

2. 示例程序

awk规则用于关键字查找以及相应的函数定位

search_rules.awk

​#! /usr/bin/env awk
# search_rules.awk

BEGIN {
	if (str == "") {
		print "invalid string to search"
		exit;
	}
}

{ lines[NR] = $0; }

END {
	for (i = 1; i <= NR; i++) {
		if (index(lines[i], str) == 0) { continue; }
		for (j = i - 1; j >= 1; j--) {
			if (match(lines[j], /^{/) == 0) { continue; }
			for (k = j - 1; k >= 1; k--) {
				if (match(lines[k], /^\s+/)) { continue; }
				split(lines[k], temp, "(");
				split(temp[1], tokens, /[* ]/);
				printf("\n%s: %-6d    %s: %d", str, i, tokens[length(tokens)], k);
				fflush();
				break;
			}
			break;
		}
	}
	print "\n"
}

通过shell脚本向awk传递参数,包括需要查找的字符串(-s/--string),以及文件名(-f/--file)

funcsearch.sh

#! /bin/bash
# funcsearch.sh

[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :

set -o errexit
set -o nounset

if [[ $# != 4 ]]; then
	echo -ne "Usage: \n"
	echo -ne " -s|--string  the string to search\n"
	echo -ne " -f|--file  the filename to contains the string\n\n"
fi

TEMP=$(getopt -o f:s: -l file:,string: -n 'bash.getopt(1)' -- "$@")

s_rules="./search_rules.awk"
unset s_file
unset s_str

if [ $? != 0 ] ; then echo "Error occurred, abort." >&2 ; exit 1 ; fi

eval set -- "$TEMP"

while true ; do
	case "$1" in
		-f|--file) s_file=$2; shift 2 ;;
		-s|--string) s_str=$2; shift 2 ;;
		--) shift; break ;;
		*) echo "Internal error!" ; exit 1 ;;
	esac
done

echo "string: \"${s_str}\""
echo "file: \"${s_file}\""
echo "rules: \"${s_rules}\":"
awk -v str="${s_str}" -f "${s_rules}" "${s_file}" 

例如,在sock.c文件中查找->sk_sndbuf

# ./funcsearch.sh -s "->sk_sndbuf" -f sock.c
string: "->sk_sndbuf"
file: "sock.c"
rules: "./search_rules.awk":

->sk_sndbuf: 717       sock_setsockopt: 657
->sk_sndbuf: 1010      sock_getsockopt: 975
->sk_sndbuf: 1725      sock_wmalloc: 1722
->sk_sndbuf: 1798      sock_wait_for_wmem: 1786
->sk_sndbuf: 1833      sock_alloc_send_pskb: 1815
->sk_sndbuf: 2070      __sk_mem_raise_allocated: 2012
->sk_sndbuf: 2296      sock_def_write_space: 2287
->sk_sndbuf: 2297      sock_def_write_space: 2287
->sk_sndbuf: 2351      sock_init_data: 2339

输出的格式为字符串或变量的行号,以及所在函数的行号

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部