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

基于aarch64无头嵌入式Linux的编译C程序变量非侵入式监控需求

解决方案:aarch64嵌入式Linux监控运行中C程序变量

一、修复GDB非停止模式用法(解决你之前的GDB问题)

你之前按帖子操作后无法在continue后查看变量,是因为没正确开启非停止模式。正确步骤如下:

  1. 确保C程序编译时添加-g参数生成调试符号,否则GDB找不到变量。
  2. 启动GDB并附加到目标进程(允许启动时短暂暂停):
    gdb -p <你的进程PID>
    
  3. 在GDB中开启非停止模式相关设置:
    set target-async on
    set non-stop on
    set schedule-multiple on
    
  4. 让程序后台运行(不阻塞GDB交互):
    continue &
    
  5. 此时直接用p <变量名>就能查看变量值,程序不会持续暂停——GDB只会在读取变量时短暂暂停目标线程,几乎不影响程序运行。

二、Python自动化监控(基于GDB脚本)

如果需要自动定时获取变量并导出数据,可以写GDB Python脚本实现:

import gdb
import threading
import time

# 初始化GDB非停止模式
gdb.execute("set target-async on")
gdb.execute("set non-stop on")
gdb.execute("set schedule-multiple on")
gdb.execute("set pagination off")

# 替换为你的进程PID和要监控的变量名
TARGET_PID = 1234
MONITOR_VAR = "global_counter"

# 附加到进程并后台运行
gdb.execute(f"attach {TARGET_PID}")
gdb.execute("continue &")

def fetch_variable():
    try:
        var_val = gdb.parse_and_eval(MONITOR_VAR)
        # 这里可以把变量值写入文件、发送到其他服务等
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {MONITOR_VAR}: {var_val}")
    except gdb.error as e:
        print(f"获取变量失败: {e}")
    # 每1秒执行一次
    threading.Timer(1.0, fetch_variable).start()

# 启动监控
fetch_variable()

# 保持GDB事件循环运行
gdb.execute("interpreter-exec console \"while true; do sleep 1; done\"")

运行脚本:

gdb -x monitor_script.py

三、ptrace底层监控(无需GDB)

用Linux的ptrace系统调用直接读取进程内存,适合不想依赖GDB的场景。可以用python-ptrace库(嵌入式系统需提前编译安装):

from ptrace.debugger import PtraceDebugger
import time

# 替换为进程PID和变量的内存地址(可通过GDB的`p &<变量名>`获取)
TARGET_PID = 1234
VAR_ADDRESS = 0xaaaaaaabbbbbbbb

debugger = PtraceDebugger()
process = debugger.addProcess(TARGET_PID, attach_now=True)

try:
    # 附加后立即让进程继续运行
    process.cont()
    while True:
        # 读取int类型变量,其他类型需调整读取方式
        var_val = process.readWord(VAR_ADDRESS)
        print(f"变量值: {var_val}")
        time.sleep(1)
finally:
    debugger.quit()

四、编译插桩(无暂停,性能最优)

如果可以修改C程序代码,推荐用共享内存/套接字让程序主动导出变量,完全不影响运行:

C程序端(添加共享内存导出)

#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

// 要监控的变量
int global_counter = 0;
// 共享内存结构
typedef struct {
    int counter;
} SharedData;
SharedData* shm_data;

void init_shared_memory() {
    int fd = shm_open("/app_monitor_shm", O_CREAT | O_RDWR, 0666);
    ftruncate(fd, sizeof(SharedData));
    shm_data = mmap(NULL, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);
}

int main() {
    init_shared_memory();
    while (1) {
        global_counter++;
        // 更新共享内存中的变量值
        shm_data->counter = global_counter;
        sleep(1);
    }
    return 0;
}

编译时需链接rt库:

gcc -g -o app app.c -lrt

Python端(读取共享内存)

import mmap
import os
import struct
import time

SHM_NAME = "/app_monitor_shm"
SHM_SIZE = struct.calcsize("i")

# 打开共享内存
fd = os.open(f"/dev/shm{SHM_NAME}", os.O_RDONLY)
shm = mmap.mmap(fd, SHM_SIZE, mmap.MAP_SHARED, mmap.PROT_READ)
os.close(fd)

try:
    while True:
        shm.seek(0)
        var_val = struct.unpack("i", shm.read(SHM_SIZE))[0]
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] global_counter: {var_val}")
        time.sleep(1)
finally:
    shm.close()

方案对比

方案是否改C程序依赖工具性能影响适用场景
GDB非停止模式否GDB轻微无法修改程序,快速验证
Python+GDB脚本否GDB、Python轻微需要自动化导出数据
ptrace底层监控否python-ptrace轻微无GDB环境,底层需求
编译插桩(共享内存)是无额外依赖无长期监控、生产环境

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 10:33:17