Get the name of the function a function Pointer points to?


#1

Hi *,

is there any way to get the name of a function a function pointer points to? The Debug/Display traits show the address so i guess it’s simply impossible. One can test for equality and the like, but i haven’t found a way to get to the name:

https://play.rust-lang.org/?gist=2b6e3d8117d71f1e24ce32002f6f0e7b&version=stable


#2

I don’t believe there is any way built into the language. A function pointer is just a pointer, so it’s not like we can add attach any more information to it.

You could try reading the current binary and figure out the function name using debug info and the function pointer’s address, similar to what happens when generating a backtrace… But that seems a little painful.


#3

i don’t think you can get the name of the fn pointer but since it implements equality you could workaround the problem with a helper function like this

fn get_fn_name(f: fn() -> ()) -> &'static str {
    match f {
        _ if f == gonzo => "gonzo",
        _ if f == frumpy => "frumpy",
        _ => unimplemented!(),
    }
}

but i don’t think that the performance will be great with all the equality checks

edit: here is a playground of it inclusive a macro to generate the get_fn_name function


#4

Maybe you can read it from debug info? https://github.com/gimli-rs/gimli


#5

You can use backtrace.rs for that: https://github.com/alexcrichton/backtrace-rs

backtrace::resolve(f as *mut std::os::raw::c_void, |symbol| {
                        println!("symbol: {:?}", symbol);
});

(where f is the function pointer)

Note: this doesn’t demangle or deduplicate. This will be the name of the specific version of the function if the function is generic.


#6

If you’re free to use a type other than fn() itself, you can use this “Debug anything” wrapper type. (you can ignore the PolFn stuff)

It might be a bit overkill for non-closure function pointers, but it works.

fn i_am_a_function(x: &u32) -> u32 { *x }

// example of a type storing a debuggable fn
#[derive(Debug)]
struct A {
    func: Debuggable<fn(&u32) -> u32>,
}

fn main() {
    let d = dbg!(i_am_a_function);
    println!("{:?}", d);
    assert_eq!(d.call(&4), 4);
    println!("{:?}", A { func: dbg!(i_am_a_function) });
}

output

i_am_a_function
A { func: i_am_a_function }

playground


#7

That’s a nice way to debug functions and closure.

one thing with i just tried was

let d = dbg!(i_am_a_function);
println!("{}", d(&4));

and it also works