0

我们如何告诉 Rust 编译器在输入函数之前和之后内联一个特殊函数?

我正在尝试实现一种跟踪函数调用的方法,并且可能使用这种方法来跟踪借用引用的使用(很像一个简单的影子堆栈)。一种替代方法是使用宏,但我需要在#[xxx]任何地方添加。

我看到添加了拉取请求 57220-Z instrument-mcount

a.rs

#[no_mangle]
fn mcount() {
    println!("enter function");
}

#[no_mangle]
fn foo(x: i32) -> i32 {
  x + 1
}

fn bar(y: i32) -> i32 {
    2 * foo(y)
} 

fn main() {
    println!("{}",bar(10));
}

编译它 ( rustc a.rs --emit asm -Z instrument-mcount) 产生:

    .globl  _foo
    .p2align    4, 0x90
_foo:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    callq   mcount
        ^^^^^^^^^^^^^^
    movl    -4(%rbp), %eax
    incl    %eax
    seto    %cl
    testb   $1, %cl
    movl    %eax, -8(%rbp)
    jne LBB10_2
    movl    -8(%rbp), %eax
    addq    $16, %rsp
    popq    %rbp
    retq
LBB10_2:
    leaq    l___unnamed_2(%rip), %rdi
    callq   __ZN4core9panicking5panic17had60f09514be3bbcE
    .cfi_endproc

    .globl  _mcount
    .p2align    4, 0x90
_mcount:
^^^^^^^^
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    $48, %rsp
    callq   mcount
    leaq    l___unnamed_3(%rip), %rax
    leaq    l___unnamed_4(%rip), %rcx
    xorl    %edx, %edx
    movl    %edx, %r8d
    leaq    -48(%rbp), %rdi
    movq    %rax, %rsi
    movl    $1, %edx
    callq   __ZN4core3fmt9Arguments6new_v117hcdff95254bf53f10E
    leaq    -48(%rbp), %rdi
    callq   __ZN3std2io5stdio6_print17hec5f1d503bfcb744E
    addq    $48, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .globl  _bar
    .p2align    4, 0x90

mcount函数已翻译为_mcount,但我如何调用my mcount而不是一些默认实现?

它似乎设置在这里

#[inline]
pub fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
    if cx.sess().instrument_mcount() {
        // Similar to `clang -pg` behavior. Handled by the
        // `post-inline-ee-instrument` LLVM pass.
        llvm::AddFunctionAttrStringValue(
            llfn, llvm::AttributePlace::Function,
            const_cstr!("instrument-function-entry-inlined"), const_cstr!("mcount"));
    }
}

GCC 中类似的事情是

 void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
4

0 回答 0