Bug: dkapture::read(paths, cb, ctx) 解析出的 pid 被忽略,返回所有进程数据
- 文件:
so/dkapture.cpp
- 行号: 293-314
- 影响: 使用回调读取“指定进程/指定路径”数据时,实际读到的是所有进程的数据
现象 / 问题描述
ssize_t
dkapture::read(std::vector<const char *> &paths, DKCallback cb, void *ctx)
{
ssize_t total = 0;
for (auto path : paths)
{
DataType dt;
pid_t pid = parse_path(path, dt); // pid 被解析出来...
if (pid < 0)
{
pr_warn("try read %s: not implemented yet or invalid", path);
continue;
}
ssize_t rsz = read(dt, cb, ctx); // ...但这里被丢弃,pid 从未被使用
if (rsz <= 0) continue;
total += rsz;
}
return total;
}
parse_path() 会把路径解析出 pid 和 dt(例如 /proc/1234/stat → pid=1234, dt=PROC_PID_STAT),但随后调用的是 read(dt, cb, ctx),而该重载内部是 read(dt, 0, nullptr, 0)(pid=0),走 DataMap::sub_iterator() 的“所有进程”迭代路径。因此:
- 传入
/proc/1234/stat,实际回调收到的是所有进程的 stat 数据,而不是 pid=1234 的;
pid 变量被赋值但从未使用(编译器会告警 unused variable),且与配套的 buffer 版本 read(vector<const char*>&, buf, bsz)(内部会调用 read(dt, pid, buf, bsz) 正确使用 pid)行为不一致;
read(DataType dt, DKCallback cb, void *ctx) 的文档是“读取所有进程的指定数据类型”,而带 paths 的重载本意是支持“通过路径交叉指定多个进程和多个数据类型”(同 buffer 版本文档),二者语义冲突。
复现步骤
DKapture *dk = DKapture::new_instance(); dk->open(...);
std::vector<const char*> paths = {"/proc/1/stat"};
dk->read(paths, callback, nullptr);
- 观察:回调收到的记录中 pid 不止 1,而是所有进程的 stat。
期望行为
按路径解析出的 pid 读取对应进程的数据,并将每条记录经回调返回。例如可基于 buffer 读取实现单进程回调:
ssize_t dkapture::read(std::vector<const char *> &paths, DKCallback cb, void *ctx)
{
if (!cb) return -EINVAL;
ssize_t total = 0;
std::vector<char> buf(64 * 1024);
for (auto path : paths)
{
DataType dt;
pid_t pid = parse_path(path, dt);
if (pid < 0)
{
pr_warn("try read %s: not implemented yet or invalid", path);
continue;
}
ssize_t rsz = read(dt, pid, (DataHdr *)buf.data(), buf.size());
if (rsz <= 0) continue;
DataHdr *p = (DataHdr *)buf.data();
ssize_t left = rsz;
while (left >= (ssize_t)sizeof(DataHdr))
{
int ret = cb(ctx, p, p->dsz);
if (ret != 0) return ret;
total++;
left -= p->dsz;
p = (DataHdr *)((char *)p + p->dsz);
}
}
return total;
}
环境信息
- 分支: master (
8cdb788)
- 相关 PR/Issue: 未发现已有相同问题
Bug:
dkapture::read(paths, cb, ctx)解析出的 pid 被忽略,返回所有进程数据so/dkapture.cpp现象 / 问题描述
parse_path()会把路径解析出pid和dt(例如/proc/1234/stat→ pid=1234, dt=PROC_PID_STAT),但随后调用的是read(dt, cb, ctx),而该重载内部是read(dt, 0, nullptr, 0)(pid=0),走DataMap::sub_iterator()的“所有进程”迭代路径。因此:/proc/1234/stat,实际回调收到的是所有进程的 stat 数据,而不是 pid=1234 的;pid变量被赋值但从未使用(编译器会告警 unused variable),且与配套的 buffer 版本read(vector<const char*>&, buf, bsz)(内部会调用read(dt, pid, buf, bsz)正确使用 pid)行为不一致;read(DataType dt, DKCallback cb, void *ctx)的文档是“读取所有进程的指定数据类型”,而带 paths 的重载本意是支持“通过路径交叉指定多个进程和多个数据类型”(同 buffer 版本文档),二者语义冲突。复现步骤
DKapture *dk = DKapture::new_instance(); dk->open(...);std::vector<const char*> paths = {"/proc/1/stat"};dk->read(paths, callback, nullptr);期望行为
按路径解析出的 pid 读取对应进程的数据,并将每条记录经回调返回。例如可基于 buffer 读取实现单进程回调:
环境信息
8cdb788)