Есть ли способ внедрить вызов пользовательской функции до и после каждого вызова функции в Rust?

Как мы можем сказать компилятору 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, но как я могу назвать свой 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));

0 ответов

Другие вопросы по тегам