You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程C++程序如何无源码修改记录特定前缀外部库函数调用?

无需修改源码记录特定前缀外部库函数调用的方案

针对你的多线程C++程序场景,这里有几种无需改动源码的方法,适配VSCode的调试工作流:

1. 调试器条件断点+自动日志(跨平台)

VSCode自带的调试器(GDB/MSVC调试引擎都支持)能直接实现这个需求:

  • 打开调试面板(Ctrl+Shift+D),编辑launch.json配置确保调试器正确关联你的程序
  • 在断点面板点击"+",输入要追踪的函数前缀(比如libfoo_*,GDB和MSVC都支持这种通配符)
  • 右键这个断点,选"添加日志动作",输入日志内容,比如[TRACE] Called: ${function}, args: ${arg0}, ${arg1}
  • 启动调试,程序运行时会自动在调试控制台输出所有匹配前缀的函数调用记录

2. Linux环境:LD_PRELOAD动态劫持

Linux下可以用动态链接的特性劫持函数,不用改原程序:

  • 写一个简单的C劫持库(比如trace_lib.c),通过dlsym拿到原函数地址,包装后打日志:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>

#define PREFIX "libfoo_"

void* get_original_func(const char* func_name) {
    static void* handle = NULL;
    if (!handle) handle = dlopen(NULL, RTLD_LAZY);
    return dlsym(handle, func_name);
}

// 示例包装函数,可根据实际函数参数调整,或者用脚本批量生成
void libfoo_init(int arg) {
    static void (*original)(int) = NULL;
    if (!original) original = get_original_func(__func__);
    printf("[TRACE] Called %s with arg: %d\n", __func__, arg);
    original(arg);
}

int libfoo_process(const char* str, size_t len) {
    static int (*original)(const char*, size_t) = NULL;
    if (!original) original = get_original_func(__func__);
    printf("[TRACE] Called %s with str: %s, len: %zu\n", __func__, str, len);
    return original(str, len);
}
  • 编译成共享库:gcc -shared -fPIC -o libtrace.so trace_lib.c -ldl
  • 在VSCode的launch.json里加环境变量:"environment": [{"name": "LD_PRELOAD", "value": "${workspaceFolder}/libtrace.so"}]
  • 启动调试,终端会自动输出匹配前缀的函数调用

3. 跨平台动态插桩:Frida

Frida是轻量的动态插桩工具,支持Windows/Linux/macOS,不用编译额外代码:

  • 先装Frida工具:pip install frida-tools
  • 写个JS脚本(比如trace_lib.js)拦截特定前缀的函数:
const targetPrefix = "libfoo_";

Process.enumerateModules().forEach(module => {
    module.enumerateExports().forEach(exp => {
        if (exp.name.startsWith(targetPrefix)) {
            Interceptor.attach(exp.address, {
                onEnter(args) {
                    console.log(`[TRACE] Called: ${exp.name}`);
                    // 要打印参数的话,可根据参数类型调用args[0].readUtf8String()这类方法
                }
            });
        }
    });
});
  • 在VSCode启动你的程序,或者先启动程序拿PID,然后跑命令:frida -n your_program.exe -l trace_lib.js(Windows)或frida -n your_program -l trace_lib.js(Linux/macOS)
  • 运行过程中会实时输出匹配的函数调用记录

4. Windows环境:API Monitor或WinDbg脚本

Windows下还有更简便的工具:

  • API Monitor:直接打开工具,附加到你的程序,设置过滤规则(指定库和函数前缀),就能自动记录所有匹配的调用
  • WinDbg脚本:在VSCode里配置WinDbg作为调试器,然后写个脚本断点:
bp your_lib.dll!libfoo_* "echo [TRACE] Called ${$funcname}; g"

启动调试后,WinDbg会自动输出符合前缀的函数调用

内容的提问来源于stack exchange,提问作者user2384330

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 17:05:30