对subprocess启动的子进程使用VSCode python debugger

news2024/11/22 9:56:59

文章目录

  • 1 情况概要(和文件结构)
  • 2 具体设置和启动步骤
    • 2.1 具体配置
      • Step 1 针对attach debugger到子进程
      • Step 2 针对子进程的暂停
      • (可选) Step 3 判断哪个进程id是需要的子进程
    • 2.2 启动步骤和过程
  • 3 其他问题解决
    • 3.1
    • 3.2 ptrace: Operation not permitted
  • 其他解决方案*2
    • 方案一(ChatGPT提供,对我不可行)
    • 方案二(Github issue翻到)
  • 参考

1 情况概要(和文件结构)

环境:Linux Ubuntu

最近在跑大模型,遇到一份代码的具体程序是通过subprocess.run()来启动的,而vscode的debug功能无法追踪进去。也就是说,我有父进程launch.py来启动subprocess.run(),调用子进程文件run.py。我可以单步调试追踪到subprocess这一步并进入run()函数,但是无法继续进入子进程的工作,无法追踪到run.py看我真正想看的代码。

这里父进程文件和子进程文件的概念我没有细究,大概意思是主动调用subprocess.run()来创建子进程的是父进程文件,被subprocess.run()跑起来的是子进程文件。

附上文件结构的简单示意。

  1. test.sh:python launch.py并传一堆参数

  2. launch.py:父进程,主要内容为

def python_launch(args):
    """
    Vanilla python launcher for degbugging purposes
    """
    # ....
    # 构造cmd
    cmd = f"python {args.run_file}" # 省略一堆参数
    # 启动subprocess
    subprocess.run(cmd, shell=True)
    
  1. run.py:子进程,主要内容为
def main(cfg):
 
    # 环境变量设置,数据读取,新建文件夹之类的之类的
    # ...
    
    # 初始化trainer并训练
    trainer = build_trainer(cfg)
    trainer.run()

2 具体设置和启动步骤

我们的目标是,我从某个地方把程序起起来并创建了子进程,然后把debugger连接到子进程上,于是它可以在子进程的断点地方停下、正常调试。

那么我们需要做到两件事情:1)把Debugger attach到子进程;2)子进程要能等待我们attach,而不是一股脑往下运行,那就来不及停在断点。

2.1 具体配置

我们分别对这两件事情做配置。

Step 1 针对attach debugger到子进程

采用vscode的python debugger插件,新建debugger config如下(编辑的是launch.json)

{
    "name": "Python: Attach to Subprocess", //随便起名
    "type": "python",
    "request": "attach", //附加到子进程
    "processId": "${command:pickProcess}" //选择进程id
}

这里用${command:pickProcess}是采用vscode自带的命令,从进程列表中手动选择,而不是写死进程id。
实测这些内容就够了,不需要其他key比如ChatGPT建议的justMyCode和subProcess。

Step 2 针对子进程的暂停

在子进程文件,你需要断点的代码前面,或者索性最前面,加上一行:

    input("Continue...")

这行会让代码停下,直到你在命令行中随便敲点什么,回车也行,才继续执行。

(可选) Step 3 判断哪个进程id是需要的子进程

因为我实在小白,我不确定哪个进程才是我要的,所以我在子进程文件里加了几行,输出父进程id和子进程id。

    print(f"Parent PID (PPID): {os.getppid()}")
    print(f"Current PID: {os.getpid()}")

Current PID就是我们要的子进程id

以上,配置完了,我的run.py最终长这样:

def main(cfg):

    #### for debug #########
    # 输出父进程和子进程id
    print(f"Parent PID (PPID): {os.getppid()}")
    print(f"Current PID: {os.getpid()}")
    
    # 可选,用来检查user id,原因后面说
    print(f"UID: {os.getuid()}, EUID: {os.geteuid()}") 
    
    # 暂停
    input("Continue...")
    #########################
    
    # 环境变量设置,数据读取,新建文件夹之类的之类的
    # ...
    
    trainer = build_trainer(cfg)
    trainer.run()
    

2.2 启动步骤和过程

需要你操作的地方写了人工,其他的是自动执行顺序。

  1. (人工)正常通过命令行执行sh test.sh,启动脚本

  2. 程序进入launch.py,启动subprocess

  3. 程序进入run.py
    3.1. 输出父进程id和子进程id供参考
    3.2. 在input(Continue...)处暂停,等待键入字符才能继续执行
    在这里插入图片描述

  4. (人工)启动debug的Subprocess Attach,选择子进程,附加到正确的id上,等待…
    在这里插入图片描述
    在这里插入图片描述

  5. attach到子进程,可能需要一会。
    在DEBUG CONSOLE里会提示结果,要么是attach成功(如图),要么是弹窗报错然后在DEBUG CONSOLE里看错误信息。
    此时可以看到调试工具栏表示正在执行、没有暂停,因为我们还在被input()暂停着。
    在这里插入图片描述

  6. (人工)在命令行里敲个回车,跳出input(Continue...)

  7. 断点停止在run.py中的对应位置

  8. (人工)正常调试

3 其他问题解决

3.1

--- Starting attach to pid: 1103 ---
/bin/sh: 1: gdb: not found

解决方案是安装gdb

apt-get update
apt-get upgrade -y
apt-get install gdb

3.2 ptrace: Operation not permitted

解释一下前面python里为什么写了一句进程创建用户id查询

我在第5步attach环节遇到了一个错误,ptrace: Operation not permitted,是个权限错误。

--- Starting attach to pid: 654608 ---
Could not attach to process.  If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user.  For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.

问了下ChatGPT:

/proc/sys/kernel/yama/ptrace_scope 文件
这个文件控制了 ptrace 系统调用的访问权限。ptrace 是 Linux 的一个系统调用,允许一个进程跟踪和控制另一个进程,是调试器工作的核心。
ptrace_scope 参数的值
0: 允许任何进程使用 ptrace 附加到其他进程(受用户权限约束)。
1: 仅允许父进程(如直接启动的调试器进程)附加到子进程。
2: 禁止所有非父子关系的调试。
3: 禁止所有 ptrace 附加操作。
默认值通常为 1,为了安全性避免恶意进程滥用 ptrace。

查询了一下这个值(cat /proc/sys/kernel/yama/ptrace_scope),输出是1。但是显然我的父进程和子进程都是同一个user启用的,不懂为什么说我权限错误。

查询进程创建用户有好几个方法,我是在python里写了一句这个。(解释了前文的查询用户id是啥用)

print(f"UID: {os.getuid()}, EUID: {os.geteuid()}") 

但是到处折腾了一圈别的方案没解决,还是回来把这个值设为0了,真就解决了。

这个值的设置需要root权限。废话,如果本来就是用root在跑的话权限统一也不会报这个错了。

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

ChatGPT也说了,这个值设置为0的话不太安全,建议用完就给它改回去。于是写了个脚本方便切换值,插入在.bashrc文件里(vim ~/.bashrc

ptrace_scope() {
	current_value=$(cat /proc/sys/kernel/yama/ptrace_scope) 
	echo "[INTRO] Script for changing between 0 & 1 value for /proc/sys/kernel/yama/ptrace_scope. The value should vary from [0,3] for different safety levels, default as 1"
    echo; # 换行
    echo "current value = $current_value" # 获取当前值
    
    # 根据当前值,在0和1之间切换
    if [ "$current_value" -eq 1 ]; then
        echo "Now changing to 0..."
        echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
    elif [ "$current_value" -eq 0 ]; then
        echo "Now changing to 1 ..."
        echo 1 | sudo tee /proc/sys/kernel/yama/ptrace_scope
    else
        echo "[Warning] Unknown ptrace_scope current value. Nothing takes effect."
        exit 1
    fi

    # 检查是否执行成功,并提醒恢复0值
    current_value=$(cat /proc/sys/kernel/yama/ptrace_scope)
    echo "[INFO] ptrace_scope changed to $current_value"
    echo;
    if [ "$current_value" -eq 1 ]; then
        echo "[INFO] Safe default setting ^-^"
    elif [ "$current_value" -eq 0 ]; then
        echo "[INFO] Unsafe setting, remember to change back to value = 1."
    fi

    echo;
}

记得source ~/.bashrc使配置生效。

效果如下,通过ptrace_scope change指令实现0-1切换。
在这里插入图片描述

其他解决方案*2

方案一(ChatGPT提供,对我不可行)

针对debugger监听子进程这个事情,ChatGPT还给了我一套方案,但用不了。记一下大概配置,哪哪都折腾过了,这个debugpy的wait for client啊就是不知道wait到了什么,直接就监听到了,但我明明还没开debugger的attach!

在子进程文件里写

import debugpy

int main():
	# 启动调试服务
	debugpy.listen(("0.0.0.0", 5678))
	print("Debugpy is listening on port 5678")
	# 等待客户端连接
	debugpy.wait_for_client()
	print("Debugger is attached!")

	# trainer.......

在debugger config里写一个针对test脚本执行的config,和debug普通python文件一个写法。另外再写一个attach用的config,用的监听路径,大概如下:

{
    "name": "Python: Attach to Subprocess",
    "type": "python",
    "request": "attach",
    "connect": {
        "host": "localhost",
        "port": 5678
    },
    "justMyCode": false,
    "subProcess": false
}

方案二(Github issue翻到)

还看到一个更暴力的是是直接改写,不用subprocess,见GitHub: embodied-generalist/issues/33
因为它只是inference但是我要train…小白还不知道不开子进程会不会有影响,就没碰

参考

  1. StackOverflow Attaching a VSCode Debugger to a Sub Process in Python
  2. GitHub: embodied-generalist/issues/33

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2245246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

cocos creator 3.8 一些简单的操作技巧,材质的创建 1

这是一个飞机的3D模型与贴图 导入到cocos中,法线模型文件中已经包含了mesh、material、prefab,也就是模型、材质与预制。界面上创建一个空节点Plane,将模型直接拖入到Plane下。新建材质如图下 Effect属性选择builtin-unlit,不需…

基于web的音乐网站(Java+SpringBoot+Mysql)

目录 1系统概述 1.1 研究背景 1.2研究目的 1.3系统设计思想 2相关技术 2.1 MYSQL数据库 2.2 B/S结构 2.3 Spring Boot框架简介 3系统分析 3.1可行性分析 3.1.1技术可行性 3.1.2经济可行性 3.1.3操作可行性 3.2系统性能分析 3.2.1 系统安全性 3.2.2 数据完整性 …

Web中间件漏洞总结——IIS篇

0x01 前言 渗透过程中会遇到各种中间件,某些中间件版本存在远程执行、任意文件上传等漏洞。本文对IIS相关漏洞进行整理,方便我们在渗透过程中快速查阅IIS漏洞。文章粗略浅显,适合刚入行的新手观看。 0x02 目录 IIS6.0 PUT漏洞IIS6.0 远程代…

关于中断向量表中没有EXTIx_IRQHandler的问题

如果你在中断向量表查找中断向量服务函数时,没有查找到EXTI7_IRQHandler等,是因为中断向量中根本就没有这个函数。 STM32 的中断向量表通常由启动文件(如 startup_stm32f1xx.s)定义。在该文件中,所有的中断服务例程&a…

idea启动服务报错Application run failed

现象是这样,在宝兰德部署报错: NoClassDefFoundError: org/apache/tomcat/util/codec/binary/Base64 本地启动报错:Application run failed:Failed to parse configuration class [***.WebApplication]; nested exception is java.lang.Illeg…

Easyexcel(4-模板文件)

相关文章链接 Easyexcel(1-注解使用)Easyexcel(2-文件读取)Easyexcel(3-文件导出)Easyexcel(4-模板文件) 文件导出 获取 resources 目录下的文件,使用 withTemplate 获…

神经网络问题之:梯度不稳定

梯度不稳定是深度学习中,特别是在训练深度神经网络时常见的一个问题,其本质涉及多个方面。 一、根本原因 梯度不稳定问题的根本原因在于深度神经网络的结构和训练过程中的一些固有特性。随着网络层数的增加,梯度在反向传播过程中会逐层累积变…

动态规划子数组系列一>等差数列划分

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public int numberOfArithmeticSlices(int[] nums) {int n nums.length;int[] dp new int[n];int ret 0;for(int i 2; i < n; i){dp[i] nums[i] - nums[i-1] nums[i-1] - nums[i-2] ? dp[i-1]1 : 0;ret dp[i…

RedHat系统配置静态IP

1、执行nmtui命令进入字符配置界面如下图所示 2、选择编辑连接进入 3、选择编辑进入后&#xff0c;将IPv4设置为手动模式后&#xff0c;选择显示后进行ip地址、网关、DNS的配置&#xff0c;配置完成后选择确定退出编辑 4、进入主界面后选择启用连接进入后&#xff0c;选择启用&…

batchnorm与layernorn的区别

1 原理 简单总结&#xff1a; batchnorn 和layernorm是在不同维度上对特征进行归一化处理。 batchnorm在batch这一维度上&#xff0c; 对一个batch内部所有样本&#xff0c; 在同一个特征通道上进行归一化。 举个例子&#xff0c; 假设输入的特征图尺寸为16x224x224x256&…

【Redis】持久化机制RDB与AOF

一、RDB RDB模式是就是将内存中的数据存储到磁盘中&#xff0c;等到连接断开的时候会进行持久化操作。但是如果服务器宕机&#xff0c;会导致这个持久化机制不会执行&#xff0c;但是内存中的文件会直接丢失。所以可以设置一个触发机制&#xff0c;save 60 1000 就是代表60秒 执…

JSON,事件绑定

文章目录 JSON事件绑定输入框input和div的内容返回获取dom元素数组还是单个对象for循环为什么要写const那一行&#xff0c;直接写 hobbys[index].checked true;可以吗const不是常量吗&#xff0c;为什么用const声明的element的属性值可以改变&#xff1f; 黑马学习笔记 JSON 定…

Kotlin Multiplatform 未来将采用基于 JetBrains Fleet 定制的独立 IDE

近期 Jetbrains 可以说是动作不断&#xff0c;我们刚介绍了 IntelliJ IDEA 2024.3 K2 模式发布了稳定版支持 &#xff0c;而在官方最近刚调整过的 Kotlin Multiplatform Roadmap 优先关键事项里&#xff0c;可以看到其中就包含了「独立的 Kotlin Multiplatform IDE&#xff0c;…

并行优化策略

并行优化策略汇总 并行优化策略 数据并行&#xff08;DP&#xff09; 将数据集分散到m个设备中&#xff0c;进行训练。得到训练数据后在进行allreduce操作。确保每个worker都有相同模型参数。 整体流程如下 若干块计算GPU&#xff0c;如图中GPU0~GPU2&#xff1b;1块梯度收集…

解决 Android 单元测试 No tests found for given includes:

问题 报错&#xff1a; Execution failed for task :testDebugUnitTest. > No tests found for given includes: 解决方案 1、一开始以为是没有给测试类加public修饰 2、然后替换 Test 注解的包可以解决&#xff0c;将 org.junit.jupiter.api.Test 修改为 org.junit.Tes…

知识见闻 - 数学: 均方根 Root Mean Square

What is Root Mean Square (RMS)? 在统计学上&#xff0c;均方根&#xff08;RMS&#xff09;是均方的平方根&#xff0c;而均方是一组数值的平方的算术平均数。均方根也称为二次均值&#xff0c;是指数为 2 的广义均值的一种特例。均方根也被定义为基于一个周期内瞬时值的平方…

寻找用户推荐人(考点:ifnull)【SQL+Pandas】

今天尝试刷一下力扣的sql面试题&#xff0c;这个写法我也是第一次见 题目是 我们需要在这个表中查出referee_id&#xff01;2的 正确写法是 select name from customer where ifnull(referee_id,0) ! 2 -- 不等于还可以这么写&#xff1a;<>

Java Database Connectivity (JDBC + Servlet)

Java Database Connectivity (JDBC)是一个Java API&#xff0c;用于与数据库进行连接和操作。通过JDBC&#xff0c;Java程序可以与各种关系型数据库进行通信&#xff0c;执行SQL查询、更新数据等操作。 一、Java连接数据库两种方式 ​​​​​ ​​ 二、Java中…

【Python爬虫实战】深入解析 Scrapy 爬虫框架:高效抓取与实战搭建全指南

&#x1f308;个人主页&#xff1a;易辰君-CSDN博客 &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html ​ 目录 前言 一、Srapy简介 &#xff08;一&#xff09;什么是Srapy &#xff08;二&#xff09;Scrapy 的设计目标 …

编程之路,从0开始:动态内存管理

Hello&#xff0c;大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路。 我们今天来学习C语言中的动态内存管理。 目录 1、为什么要有动态内存管理&#xff1f; 2、malloc和free &#xff08;1&#xff09;malloc函数 &…