variable name, function arguments at run time in C
Asked Answered
D

4

6

Is it possible to know a function arguments and variables' name types at runtime in C program ? For example, if I have a function:

int abc(int x, float y , somestruct z ){
    char a;
    int b ;
}

Can I know inside this function abc(), what are the names of arguments and variables i.e. in this case its x, y, z, a, b and they are of type int, float, somestruct, char, int.

Say if there is another function:

float some_func(specialstruct my_struct, int index){

} 

I should know that arguments name are my_struct, index and types are specialstruct, int.

I need this info at runtime ?

I have access to base pointer and return address , can I get required info using above pointer.

I was able to extract function name using return address and dladdr() function.

I see GDB does this, so it should be possible to extract this info?

Desimone answered 15/9, 2016 at 7:49 Comment(9)
Why do you need those names at runtime? What could you do with them?Unscathed
C is a compiled language. Once the program has been compiled (or in other words once it has been transformed into machine code) all variable names, function names etc. are gone. So the answer is: No. On the other hand GDB knows about variable and function names, because the program has been compiled with special options, but this is useful for debugging only.Calculate
gdb use debugging information that are generated by the compiler. See eli.thegreenplace.net/2011/02/07/…Siblee
@MichaelWalz: If compiled or not is not the problem. A compiled language can also "refelcect" attributes back to the code itself. Reflection was part of c++17 but is removed as I know. Other languages have this feature.Perpetua
@Perpetua correct, but there is no reflection what so ever in C.Calculate
Possible duplicate of Programmatic way to get variable name in C?Presto
No. Types aren't (in general) part of the runtime execution of the program. Types only exist in the language, i.e. in the thing that describes the program. A C program does not generally know its own description (unless you explicitly make it so).Siloxane
@Unscathed ,Lets say assert condition is true but i dont want to stop execution, so i want to dump my call stack along with argument and variable name along with values.Desimone
Edit that into your question (should have been there from the start). There are no portable ways to get that. Accurate variable dump for optimized dump is prob. impossible.Unscathed
H
2

As others noted, reflection is not built into the C or C++ language. There are a variety of ideas here

However, Reflection is possible in C/C++ with a 3rd party library and debugging symbols in the executable or an external file.

The dwarfdump executable more or less does what you are hoping for. With the DWARF information details on function, variables, types, etc are available. In a similar fashion, the libdwarfdump functionality could be used by a process to inspect itself.

Here is a simple manual example:

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;
}

and the partial output from 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

With careful study, we can see the fragment defines the function 'abc' with arguements x, y and z.

The type of parameter x is an indirection to a type table with key 0x4e.

Looking elsewhere in the output, we can see the definition for type 0x4e. Type 0x2d is the somestruct which ties back to parameter z.

< 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"

The combination of ptrace, ELF, DWARF and the /proc filesystem allow gdb to read static and dynamic information for a process. Another process could use similar functionality to create Reflection functionality.

I have used variants of this strategy to create custom debuggers and memory leak detectors. I have never seen this strategy used for business logic however.

Hyperpyrexia answered 15/9, 2016 at 14:21 Comment(0)
A
1

There is no kind of reflection or similar things in C. If you want such facility - you should design some utilities, macros for this purpose and use special coding rules to achieve desired effect. But IMO - it won't be a readable and understandable C code.

Antimere answered 15/9, 2016 at 8:22 Comment(0)
L
1

There isn't really a native way to do this in C. In other languages, what you'd be looking for would be reflection. You can cheese it with macros and some tricks, but on a basic principle, you need to know variable names and arguments at compile time.

Logistic answered 15/9, 2016 at 8:35 Comment(1)
@Unscathed Apparently, I did a brainfart there. I was referring to the arguments the program is launched with. Correcting.Logistic
T
0

There is a limited way of introspection provided by shared library functions dlsym and dladdr providing a name-to-address and vice versa translation. That is, however, not part of the C language, but rather a function supplied by the OS dynamic loader. You can, however, not deduct, for example, whether that symbol you found is a variable or function.

backtrace et al make up a GNU extension to the standard that allows to analyze the call stack of a function (call history). If there are symbols (function names) still present in the binary, backtrace_symbols will allow you to retrieve them.

The __LINE__ and __FILE__ predefined macros provide a way to dump where you are as well and can be the basis of some very useful macros for tracing.

And that's it. C does not provide any more introspection than that. Parameter names and types are gone in the binary, function signatures are gone and function result types as well.

Trawick answered 15/9, 2016 at 9:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.