0

I'd like to print the information stored a memory pointed by a void* pointer.

But the type information is not available at the compile type.

Instead, the string of the definition of the type will be available at the run time. Is there a way to cast the pointer to the appropriate type at the run time so that the data stored in the memory pointed by the pointer can be accessed?

I think that this should be possible as debugger can access raw pointers in the process being debugged and use the debugging information (say in DWARF format) attached to the executable to print human-readable information. I just don't know how this is done in code.

Could anybody let me know who this is done? Thanks.

EDIT. Here is what I want to do in code.

//definition
void myprint(void *p, const char *struct_def) {
//print the content in p according to struct_def, struct_def can be any valid struct definition in C.
}

//call
myprint(p, "struct s { int n; double d[10]; }");
}

EDIT: The struct definition may not have be in C, it could be in other user defined format, like LLVM IR or drawf.

user1424739
  • 11,937
  • 17
  • 63
  • 152
  • If the type information is available *as a string* - then no, there is no way other than "manually" parsing and reinterpreting the data. – Eugene Sh. Jan 29 '19 at 17:53
  • If it is in dwarf format, then it is possible? – user1424739 Jan 29 '19 at 17:54
  • 1
    C has no knowledge of dwarf or whatever formats. You might find some library to help you, but that would be off-topic here. – Eugene Sh. Jan 29 '19 at 17:55
  • Ecactly as @EugeneSh. wrote. It parses the dwarf tree and interprets the data. – 0___________ Jan 29 '19 at 17:56
  • Then, how debugger is able to print structs in a human readable fashion? – user1424739 Jan 29 '19 at 17:57
  • 2
    Debugger is a serious piece of software. It is using metadata stored in the compiled binary (symbols) - if it was compiled in specific way, and doing some non-trivial work as pointed in my first comment. – Eugene Sh. Jan 29 '19 at 17:59
  • I suspect if you wanted to do something incredibly sketchy, you could try invoking a foreign function to build a second program with the structure's information injected into the source in some sort of horrendous rube-goldberg solution, BUT I don't think you'd want to do that. What are you really trying to achieve? Maybe we could help with that – Daniel Jan 29 '19 at 18:14
  • Can you post a *specific* example of what you are trying to do? – dbush Jan 29 '19 at 18:19
  • I add some code to show what I want to do. – user1424739 Jan 29 '19 at 18:23
  • @user1424739 is `struct s` defined somewhere that `myprint` can see it? – dbush Jan 29 '19 at 18:28
  • you want to parse the C syntax as well. It is doable, but I think (I am actually sure) that is much too early for you. It is rather advanced topic. – 0___________ Jan 29 '19 at 18:28
  • @dbush, Ultimately, I have the complete debug information in LLVM IR, so that should doable. – user1424739 Jan 29 '19 at 18:30
  • Related: [Can we define a new data type in a GDB session](https://stackoverflow.com/q/7272558/2554472) – Mark Plotnick Jan 29 '19 at 21:38

1 Answers1

0

To show you how to interpret here you have small snippet. It char array formated as : one char as type, next bytes data. The array can contain more than one pair (type, data)

#include <stdio.h>
#include <string.h>

char *print_x(char *str)
{
    union
    {
        int i;
        unsigned u;
        long l;
        long long ll;
        float f;
        double d;
    }data;

    switch(*str)
    {
        case 'd':
            memcpy(&data, str + 1, sizeof(double));
            printf("%f", data.d);
            return str + 1 + sizeof(double);
        case 'i':
            memcpy(&data, str + 1, sizeof(int));
            printf("%d", data.i);
            return str + 1 + sizeof(int);
        /* another formats */
        default:
            printf("Not implemented");
            return NULL;
    }
}
int main()
{
    char data[100];
    double x = 1.234;
    int z = 4567;

    char *str = data;

    data[0] = 'd';
    memcpy(&data[1], &x, sizeof(double));
    data[1 + sizeof(double)] = 'i';
    memcpy(&data[2 + sizeof(double)], &z, sizeof(int));

    while((str = print_x(str)))
    {
        printf("\n");
    }

    return 0;
}

You can test it and add other types. https://ideone.com/178ALz

0___________
  • 60,014
  • 4
  • 34
  • 74