在gdb
标签中,前几天只有question。我在下面列出了我的答案。正如俄罗斯就业指出的那样,在C库中实现反射似乎是可能的,因为它是在gdb中完成的。
正如其他人所指出的那样,反射并不是C或C++语言中的内容。有各种各样的想法here
但是,反射是可能的在C/C + +第三方库和调试符号在可执行文件或外部文件。
dwarfdump
可执行文件或多或少地做你所期望的。通过函数的DWARF信息细节,可以使用变量,类型等。以类似的方式,一个进程可以使用libdwarfdump功能来检查自身。
下面是一个简单的手动例如:
typedef struct somestruct
{
int i;
int j;
} somestruct ;
int abc(int x, float y , struct somestruct z){
char a;
int b ;
}
int main(int argc, char* argv[])
{
struct somestruct z;
abc(1,1.0f,z);
return 0;
}
和从dwarfdump
< 1><0x00000055> DW_TAG_subprogram
DW_AT_external yes(1)
DW_AT_name "abc"
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000009
DW_AT_prototyped yes(1)
DW_AT_type <0x0000004e>
DW_AT_low_pc 0x004004ed
DW_AT_high_pc <offset-from-lowpc>18
DW_AT_frame_base len 0x0001: 9c: DW_OP_call_frame_cfa
DW_AT_GNU_all_call_sites yes(1)
DW_AT_sibling <0x000000ad>
< 2><0x00000076> DW_TAG_formal_parameter
DW_AT_name "x"
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000009
DW_AT_type <0x0000004e>
DW_AT_location len 0x0002: 916c: DW_OP_fbreg -20
< 2><0x00000082> DW_TAG_formal_parameter
DW_AT_name "y"
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000009
DW_AT_type <0x000000ad>
DW_AT_location len 0x0002: 9168: DW_OP_fbreg -24
< 2><0x0000008e> DW_TAG_formal_parameter
DW_AT_name "z"
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000009
DW_AT_type <0x0000002d>
DW_AT_location len 0x0002: 9160: DW_OP_fbreg -32
通过仔细研究的部分输出中,我们可以看到片段定义了函数 'ABC' 与arguements X, y和z。
参数x的类型是对键类型为0x4e的类型表的间接引用。
查看输出中的其他位置,我们可以看到类型为0x4e的定义。类型0x2d是绑定回参数z的somestruct。
< 1><0x0000002d> DW_TAG_structure_type
DW_AT_name "somestruct"
DW_AT_byte_size 0x00000008
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000003
DW_AT_sibling <0x0000004e>
< 1><0x0000004e> DW_TAG_base_type
DW_AT_byte_size 0x00000004
DW_AT_encoding DW_ATE_signed
DW_AT_name "int"
ptrace的所述的组合,ELF,DWARF和/ proc文件系统允许GDB一个用于读取过程的静态和动态信息。另一个进程可以使用类似的功能来创建反射功能。
我已经使用此策略的变体来创建自定义调试器和内存泄漏检测器。然而,我从来没有见过这种用于商业逻辑的策略。
局部变量的名字是'z'。不知道你的问题是什么。无论如何,没有必要使用标准堆栈。而在x86/x64/ARM等最新平台上,它很可能不会。而类型显然是'int' C不支持动态类型(这包括编译器扩展)。 – Olaf
使用标准C?不,没有办法。对于GCC,您可能需要[阅读文档](https://gcc.gnu.org/onlinedocs/)以查看它具有哪些(非标准)功能来帮助您。 –
[内省](https://en.wikipedia.org/wiki/Introspection_(computer_science))或[反思](https://en.wikipedia.org/wiki/Reflection_(computer_programming))是描述什么你想...... – gilez