Linux:有没有办法在不停止/暂停进程(SIGSTOP)的情况下使用 ptrace?

2023-11-27

我正在尝试将程序从 Windows 移植到 Linux。
当我发现没有“真实”的时候,我遇到了一个问题ReadProcessMemoryLinux 上的对应项;我寻找替代方案,然后发现ptrace,一个强大的进程调试器。
我快速用 C++ 编写了两个小型控制台应用程序来测试ptrace,然后在程序中使用它。

TestApp

这是tracee;它每 50 毫秒打印两个整数,同时每次将它们的值加 1。

#include <QCoreApplication>
#include <QThread>
#include <iostream>

using namespace std;

class Sleeper : public QThread
{
public:
    static void usleep(unsigned long usecs){QThread::usleep(usecs);}
    static void msleep(unsigned long msecs){QThread::msleep(msecs);}
    static void sleep(unsigned long secs){QThread::sleep(secs);}
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int value = 145;
    int i = 0;

    do {
    cout << "i: " << i << " " << "Value: " << value << endl;
    value++;
    i++;
    Sleeper::msleep(50);
    } while (true);

    return a.exec();
}

记忆测试

这是追踪器;它询问进程名称并使用命令检索 PIDpidof -s, then ptrace附加到进程并每 500 毫秒检索一次内存地址的值,共 10 次。

#include <QCoreApplication>
#include <QThread>
#include <iostream>
#include <string>
#include <sys/ptrace.h>
#include <errno.h>

using namespace std;

class Sleeper : public QThread
{
public:
    static void usleep(unsigned long usecs){QThread::usleep(usecs);}
    static void msleep(unsigned long msecs){QThread::msleep(msecs);}
    static void sleep(unsigned long secs){QThread::sleep(secs);}
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    char process_name[50];
    cout << "Process name: ";
    cin >> process_name;

    char command[sizeof(process_name) + sizeof("pidof -s ")];
    snprintf(command, sizeof(command), "pidof -s %s", process_name);

    FILE* shell = popen(command, "r");
    char pidI[sizeof(shell)];
    fgets(pidI, sizeof(pidI), shell);
    pclose(shell);

    pid_t pid = atoi(pidI);
    cout << "The PID is " << pid << endl;

    long status = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
    cout << "Status: " << status << endl;
    cout << "Error: " << errno << endl;

    unsigned long addr = 0x012345; // Example address, not the true one
    int i = 0;
    do {
    status = ptrace(PTRACE_PEEKDATA, pid, addr, NULL);
    cout << "Status: " << status << endl;
    cout << "Error: " << errno << endl;
    i++;
    Sleeper::msleep(500);
    } while (i < 10);

    status = ptrace(PTRACE_DETACH, pid, NULL, NULL);
    cout << "Status: " << status << endl;
    cout << "Error: " << errno << endl;

    return a.exec();
}

一切正常,但 TestApp 被暂停 (SIGSTOP) 直到ptrace脱离它。
另外,当它附加到进程时,状态为0,错误为2;第一次尝试检索内存地址值时失败,状态为 -1,错误为 3。这正常吗?
有没有办法阻止 ptrace 向进程发送 SIGSTOP 信号? 我已经尝试过使用PTRACE_SEIZE代替PTRACE_ATTACH,但它不起作用:状态 -1 和错误 3。

Update: Using Sleeper在MemoryTest中的“do-while”循环之前修复了第一个内存地址值检索的问题,即使秒、毫秒或微秒的值是0。为什么?


经过大量研究后,我很确定没有办法使用ptrace无需停止该过程。
我发现了一个真实的ReadProcessMemory对应的,称为process_vm_readv,这要简单得多。

我发布代码是希望能够帮助处于我(以前)情况的人。

非常感谢mkrautz感谢他帮助用这个漂亮的函数编写 MemoryTest 代码。

#include <QCoreApplication>
#include <QThread>
#include <sys/uio.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <iostream>

using namespace std;

class Sleeper : public QThread
{
public:
    static void usleep(unsigned long usecs){QThread::usleep(usecs);}
    static void msleep(unsigned long msecs){QThread::msleep(msecs);}
    static void sleep(unsigned long secs){QThread::sleep(secs);}
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    char process_name[50];
    cout << "Process name: ";
    cin >> process_name;

    char command[sizeof(process_name) + sizeof("pidof -s ")];
    snprintf(command, sizeof(command), "pidof -s %s", process_name);

    FILE* shell = popen(command, "r");
    char pidI[sizeof(shell)];
    fgets(pidI, sizeof(pidI), shell);
    pclose(shell);

    pid_t pid = atoi(pidI);

    cout << "The PID is " << pid << endl;

    if (pid == 0)
        return false;

    struct iovec in;
    in.iov_base = (void *) 0x012345; // Example address, not the true one
    in.iov_len = 4;

    uint32_t foo;

    struct iovec out;
    out.iov_base = &foo;
    out.iov_len = sizeof(foo);

    do {
        ssize_t nread = process_vm_readv(pid, &out, 1, &in, 1, 0);
        if (nread == -1) {
            fprintf(stderr, "error: %s", strerror(errno));
        } else if (nread != in.iov_len) {
            fprintf(stderr, "error: short read of %li bytes", (ssize_t)nread);
        }
        cout << foo << endl;
        Sleeper::msleep(500);
    } while (true);

    return a.exec();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux:有没有办法在不停止/暂停进程(SIGSTOP)的情况下使用 ptrace? 的相关文章

  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 如何判断计算机是否已重新启动?

    我曾经使用过一个命令行 SMTP 邮件程序 作为试用版的限制 它允许您在每个 Windows 会话中最多接收 10 封电子邮件 如果您重新启动计算机 您可能还会收到 10 个以上 我认为这种共享软件破坏非常巧妙 我想在我的应用程序中复制它
  • 在 Linux 上使用多处理时,TKinter 窗口不会出现

    我想生成另一个进程来异步显示错误消息 同时应用程序的其余部分继续 我正在使用multiprocessingPython 2 6 中的模块来创建进程 我试图用以下命令显示窗口TKinter 这段代码在Windows上运行良好 但在Linux上
  • 函数参数的默认参数是否被视为该参数的初始值设定项?

    假设我有这样的函数声明 static const int R 0 static const int I 0 void f const int r R void g int i I 根据 dcl fct default 1 如果在参数声明中指
  • C# 数据表更新多行

    我如何使用数据表进行多次更新 我找到了这个更新 1 行 http support microsoft com kb 307587 my code public void ExportCSV string SQLSyntax string L
  • 使用 LINQ to SQL 时避免连接超时的最佳实践

    我需要知道在 net 应用程序中使用 LINQ to SQL 时避免连接超时的最佳实践 特别是在返回时IQueryable
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • iptables通过注释删除特定规则

    我需要删除一些具有相同评论的规则 例如 我有带有 comment test it 的规则 所以我可以像这样获得它们的列表 sudo iptables t nat L grep test it 但是我怎样才能删除所有带有注释 测试它 的 PR
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • 检测到严重错误 c0000374 - C++ dll 将已分配内存的指针返回到 C#

    我有一个 c dll 它为我的主 c 应用程序提供一些功能 在这里 我尝试读取一个文件 将其加载到内存 然后返回一些信息 例如加载数据的指针和内存块的计数到 c Dll 成功将文件读取到内存 但在返回主应用程序时 程序由于堆损坏而崩溃 检测
  • 将数组作为参数传递

    如果我们修改作为方法内参数传递的数组的内容 则修改是在参数的副本而不是原始参数上完成的 因此结果不可见 当我们调用具有引用类型参数的方法时 会发生什么过程 这是我想问的代码示例 using System namespace Value Re
  • 可访问性不一致:参数类型的可访问性低于方法

    我试图在两个表单之间传递一个对象 基本上是对当前登录用户的引用 目前 我在登录表单中有一些类似的内容 private ACTInterface oActInterface public void button1 Click object s
  • ubuntu:升级软件(cmake)-版本消歧(本地编译)[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我的机器上安装了 cmake 2 8 0 来自 ubuntu 软件包 二进制文件放置在 usr bin cmake 中 我需要将 cmake 版本至少
  • OpenCV SIFT 描述符关键点半径

    我正在深入研究OpenCV的SIFT描述符提取的实现 https github com Itseez opencv blob master modules nonfree src sift cpp 我发现了一些令人费解的代码来获取兴趣点邻域

随机推荐

  • 如何在Python中获取两个时间对象之间的差异

    我在 Python 中有两个 datetime time 对象 例如 gt gt gt x datetime time 9 30 30 0 gt gt gt y datetime time 9 30 31 100000 但是 当我对 dat
  • 在 com.google.android.gms.measurement.internal 解除绑定时抛出异常

    我收到此异常 但我不知道如何找到问题所在 也不知道是什么原因导致的 你能帮我吗 W ConnectionTracker Exception thrown while unbinding java lang IllegalArgumentEx
  • perl6 插入数组以匹配 AND、OR、NOT 函数

    我正在尝试重新执行我的程序 以匹配数组中的所有项目 匹配任意项目 不匹配项目 Perl6 的一些文档没有解释当前实现的行为 Rakudo 2018 04 我还有几个问题 1 正则表达式的文档说将数组插入匹配正则表达式意味着 最长匹配 但是
  • 如何让 IntelliJ IDEA 理解我的空检查方法?

    我有一个方法 其中参数标记为 Nonnull注解 调用该方法的代码必须检查该值是否为空 而不仅仅是直x null检查 它正在调用另一个类上的实用方法 在实际代码中 实用程序方法还会检查它是否为空字符串 我的问题是 Intellij Idea
  • 获取QTreeView中当前选定的项目

    我在 QTreeView 中有很多项目 每个项目都是使用此类生成的 class Branch QStandardItem def init self label uri None QStandardItem init self label
  • python 本地模块

    我有几个项目目录 并且想要特定于它们的库 模块 例如 我可能有这样的目录结构 myproject mymodules init py myfunctions py myreports mycode py 假设有一个函数叫做add in my
  • 如何使用 XmlPullParser 解析 RSS 提要?

    我想解析 RSS 提要 我的问题是如何解析之间的所有标签
  • Python中跨平台获取用户配置主目录的方法?

    我的程序需要存储一些配置文件 主要操作系统似乎都有一个指定的位置来放置它们 例如 在 Freedesktop org 兼容系统上 它将是存储在 XDG CONFIG HOME环境变量 是否有方法 或库 可以跨主要操作系统获取此配置主目录 W
  • 如何从 int 正确设置 UIColor?

    我正在尝试设置textColor of a UITextView通过给它赋值 在该计划的早期我有 textView textColor 0x000000 但后来 当我有 textView textColor 0x888888 弹出致命错误
  • Springboot 日志配置

    我尝试配置我的 springboot 应用程序以登录一个文件一天 所以我配置我的 logback xml 就像这样
  • jquery 更改在动态值更改的情况下不起作用

    在 jQuery 中我如何跟踪onchange如果文本框的值因其他事件而动态变化 则发生事件 我尝试过这个但它不起作用 txtbox change function alert change keyup不涵盖所有自然情况 两种情况当chan
  • “adb screencap /sdcard/screenshot.raw”生成什么格式? (没有“-p”标志)

    我正在寻找使用adb screencap实用程序没有 p旗帜 我想象输出将以原始格式转储 但看起来并非如此 我尝试打开原始图像文件Pillow python 库导致 adb pull sdcard screenshot raw screen
  • 页面加载时将光标更改为忙

    我了解如何在页面进行和 ajax 调用时使用 javascript 将光标更改为忙 但是我有一个不使用ajax的页面 它使用回发来重新加载页面 然而 加载的数据量相当大 并且需要几秒钟的时间 在此期间用户仍然可以点击该页面 我想将光标转到
  • `script` 和 `link as="script"` 标签有什么区别?

    除了加载脚本的标准方法之外 我见过人们这样做 有什么区别吗 注 还有一个类似的使用 link 和 script 标签引用 JavaScript 源代码有什么区别 问题询问关于 这是不同的 If that link标签有rel preload
  • 如何禁用谷歌浏览器自动更新? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 有谁知道如何禁用 Google Chrome 自动更新本身 它会导致我的网络应用程序总是发生变化 我已尝试使用此页面上提供的或如中所述的 Google Update ADM 模板这篇
  • 将MaterialToolbar的标题更改为center

    我正在使用导航组件和材质工具栏 我刚刚使用材质工具栏设置了导航组件 通过这样做 每当片段更改显示的后退按钮时 导航组件就会自动更改材质工具栏的标题 问题是我只想将标题重力更改为中心而不删除那些导航组件工具栏支持 我怎样才能做到这一点 注意
  • 如何配置 rspec 以使用 spork 显示输出?

    我运行了 spork 来加速我的测试 但是当我运行它们时没有输出 是否有我需要修改的配置 刚刚也遇到了这个问题 在 spork 1 0 0rc4 和 rspec 2 14 1 rspec core 2 14 8 上运行 据我所知 问题在于以
  • 时间戳和日期时间

    我有一个包含两列的表 第一列是 当前日期 时间戳 另一列是 日期返回 日期时间列 我需要从天数中获取当前日期和日期返回之间的差异 这可能吗 不 这是不可能的 与流行的看法 以及名称本身 相反 timestamp column 实际上与时间无
  • “当前不会命中断点” - 我无法添加 .pdb 文件

    我在 Visual Studio 中有一个包含一个项目的解决方案2013 视觉C 但是当我构建它时debug模式 那么运行它debug我得到的模式 当前不会命中断点 尚未加载任何符号 对于本文档 我试图以类似于人们建议的 Visual C
  • Linux:有没有办法在不停止/暂停进程(SIGSTOP)的情况下使用 ptrace?

    我正在尝试将程序从 Windows 移植到 Linux 当我发现没有 真实 的时候 我遇到了一个问题ReadProcessMemoryLinux 上的对应项 我寻找替代方案 然后发现ptrace 一个强大的进程调试器 我快速用 C 编写了两