|
Tools / 获取 c 文件函数名的几种方法 目录: 1. 方法1: grep 配合正则表达式2. 方法2: nm 类的调试工具! t. ]1 [# w# ^& [0 q 3. 方法3: 开源软件 ctags9 @0 }+ Z! T* s D; P4 b% T 4. 使用 list function 的方法简单分析 Linux Input 子系统% T: E! G4 `$ a. { 5. 相关参考8 s" y0 |/ z! c# X 1. 方法1: grep 配合正则表达式 1) private 函数: $ grep -E '^(\w+ )?\w+ (\w+ )?\w+( )?\(.*)' SDL_events.c -o | sort | grep static | sortstatic int SDL_AddEvent(SDL_Event *event) static int SDLCALL SDL_GobbleEvents(void *unused)8 ^" Q0 J) D# S' W4 H static int SDL_CutEvent(int spot) static int SDL_StartEventThread(Uint32 flags)( ~5 g9 R) h2 O% S/ v static void SDL_StopEventThread(void)9 \& N/ P8 R; K, \! v9 K 2) public 函数: $ grep -E '^(\w+ )?\w+ (\w+ )?\w+( )?\(.*)' SDL_events.c -o | sort | grep -v static | sort9 l3 W/ H8 C9 xint SDL_PollEvent (SDL_Event *event)) d- Z; x$ {/ r) Q- z8 j" ]( b ... int SDL_WaitEvent (SDL_Event *event)1 e, q9 J- A. L q- G, m SDL_EventFilter SDL_GetEventFilter(void) Uint32 SDL_EventThreadID(void) Uint8 SDL_EventState (Uint8 type, int state). n! Y- w$ r4 D$ m+ ] void SDL_Lock_EventThread(void) ... void SDL_Unlock_EventThread(void) 3) 优点:
4) 缺点:
2. 方法2: nm 类的调试工具 1) 什么是 nm? nm 用于检查二进制文件 (包括库,编译后的目标模块,共享目标文件,和独立可执行文件),并显示这些文件的内容,或存储在其中的元信息,特别是符号表。 输出格式:
另外,objdump -t 和 readelf -s 也可以查看目标文件的符号表。 2) 例子: 全局/静态 变量: int global_var;int global_var_init = 26;# i- z' j2 j: a 8 A( h( X4 U9 n static int static_var; static int static_var_init = 25;& }9 V6 Y0 Y7 T% ~" g9 U8 S" f extern int extern_var;/ Y* u4 B+ D$ l; S3 j extern int extern_function(int);/ k) S4 v( b4 A0 _ 静态函数: static int static_function(int x, int y){& Q1 L. ]' A9 z6 A* C* f int local_automatic_var;$ O4 A+ ]- H( E) ^( w 5 p2 G: v, T1 m5 a, j* f# f local_automatic_var = x + y;: {7 a, i( k* r. M) _! R! H return local_automatic_var;7 q7 e3 s# s& E } 全局函数: int global_function(int p){ m2 U7 O! m) g# B9 S% S- j static int local_static_var; static int local_static_var_init=5;9 F2 N* M6 ^% ?2 Z u$ l( w - ~, S y, c2 @: F9 m& _: q local_static_var = static_function(local_static_var_init, p); return local_static_var;" G) ]8 J1 G1 B( [% Q }2 j' L* n5 ~9 G7 J# t. H4 b int main(int argc, char** argv) { static_var = 1; global_var = global_function(2); extern_var = extern_function(3); Z( D* n8 K0 f; {! o return 0;& |# W1 I) }6 t5 Y- S2 p, D4 J$ l } #ifdef __cplusplus5 F2 F1 R9 O3 ~. C extern "C"1 h; N7 J1 ?+ i #endif void non_mangled_function(void) {8 B4 b2 m/ a% A$ l3 k: n% O2 a // I do nothing }% F; ~0 M- |/ E 3) private 函数: $ gcc -c c_obj.c `. V6 D2 Y5 n. z6 Z* O& o9 a$ nm c_obj.o | grep " t " | cut -d' ' -f33 ^9 |9 z9 F1 W8 l static_function+ p4 b( u: A- @2 Q# o 4) public 函数: $ gcc -c c_obj.c/ B$ _7 G- m" O. ]/ c# K$ nm c_obj.o | grep " T " | cut -d' ' -f32 @8 E0 M" t* m5 T, a global_function$ H- x- k- i0 V. o/ l1 p7 | main non_mangled_function$ E/ D* q/ x/ e6 p9 d8 m" Z 5) 优点:
6) 缺点:
3. 方法3: 开源软件 Ctags 1) 什么是 ctags? Ctags 支持下列的编程语言: 2) private 函数: $ ctags -x SDL_events.c | grep function | tr -s ' ' | cut -d' ' -f5- | grep static | sort' w8 y# N" S& u! t+ _# y! u; {static int SDL_AddEvent(SDL_Event *event) static int SDLCALL SDL_GobbleEvents(void *unused) static int SDL_CutEvent(int spot) static int SDL_StartEventThread(Uint32 flags)4 i F2 M9 f1 O" T static void SDL_StopEventThread(void)* Z; a; H! b2 T% x 3) public 函数: $ ctags -x SDL_events.c | grep function | tr -s ' ' | cut -d' ' -f5- | grep -v static | sortint SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, int SDL_PollEvent (SDL_Event *event) ... int SDL_WaitEvent (SDL_Event *event) SDL_EventFilter SDL_GetEventFilter(void) ..." H8 d- x% M3 a# j7 I void SDL_Lock_EventThread(void)* L/ e1 O5 S/ H7 R2 h7 Z ...) K9 h3 T# L& W6 h" O void SDL_Unlock_EventThread(void) 4) 优点:
5) 缺点:
6) 我有必要了解 ctags 的内部实现吗?
4. 使用 list function 的方法简单分析 Linux Input 子系统 先是发散思维,Linux input 的整体框架大致如下:
然后慢慢专注在自己关心的内容上,例如我想多了解一下input core的内容,我就去查看它提供了什么 API: $ ctags -x input.c | grep function | tr -s ' ' | cut -d' ' -f5- | grep -v static5 k; A/ r ^3 r ]8 W$ ~struct input_dev *devm_input_allocate_device(struct device *dev) void input_alloc_absinfo(struct input_dev *dev)) I. N; L4 w o9 ^+ y, w. U struct input_dev *input_allocate_device(void), R6 [9 X( U$ E8 I' Z+ i( r ... void input_free_device(struct input_dev *dev)) n U+ F% ^6 }- F5 Y void input_free_minor(unsigned int minor)' [+ q j( H \2 C8 @1 d, R ... bool input_match_device_id(const struct input_dev *dev, int input_open_device(struct input_handle *handle)3 [+ H6 {6 `) l: @* b int input_register_device(struct input_dev *dev) int input_register_handle(struct input_handle *handle)& _+ o8 c( P2 Q7 ?: [: } int input_register_handler(struct input_handler *handler)- `" O( X0 P& q9 a) _- } void input_release_device(struct input_handle *handle)$ I0 A0 ]) e7 L' e3 E: r, v ... void input_unregister_device(struct input_dev *dev)" ?! a7 t/ n1 F- d% F% M6 [ void input_unregister_handle(struct input_handle *handle)9 X) L5 y7 H3 w ~, x: p' [ void input_unregister_handler(struct input_handler *handler)) m% U+ E' F7 U% Z: Z 然后就可以重点去阅读上述函数了。 5. 相关参考
|
微信公众号
手机版