网站标题关键词用什么隔开,苏州快速建站模板,wordpress怎么使用七牛云储存,seo实战论坛文章目录 1 情况概要#xff08;和文件结构#xff09;2 具体设置和启动步骤2.1 具体配置Step 1 针对attach debugger到子进程Step 2 针对子进程的暂停(可选) Step 3 判断哪个进程id是需要的子进程 2.2 启动步骤和过程 3 其他问题解决3.13.2 ptrace: Operation not permitted… 文章目录 1 情况概要和文件结构2 具体设置和启动步骤2.1 具体配置Step 1 针对attach debugger到子进程Step 2 针对子进程的暂停(可选) Step 3 判断哪个进程id是需要的子进程 2.2 启动步骤和过程 3 其他问题解决3.13.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()跑起来的是子进程文件。
附上文件结构的简单示意。 test.shpython launch.py并传一堆参数 launch.py父进程主要内容为
def python_launch(args):Vanilla python launcher for degbugging purposes# ....# 构造cmdcmd fpython {args.run_file} # 省略一堆参数# 启动subprocesssubprocess.run(cmd, shellTrue)
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(fParent PID (PPID): {os.getppid()})print(fCurrent PID: {os.getpid()})Current PID就是我们要的子进程id
以上配置完了我的run.py最终长这样
def main(cfg):#### for debug ########## 输出父进程和子进程idprint(fParent PID (PPID): {os.getppid()})print(fCurrent PID: {os.getpid()})# 可选用来检查user id原因后面说print(fUID: {os.getuid()}, EUID: {os.geteuid()}) # 暂停input(Continue...)########################## 环境变量设置数据读取新建文件夹之类的之类的# ...trainer build_trainer(cfg)trainer.run()
2.2 启动步骤和过程
需要你操作的地方写了人工其他的是自动执行顺序。 人工正常通过命令行执行sh test.sh启动脚本 程序进入launch.py启动subprocess 程序进入run.py 3.1. 输出父进程id和子进程id供参考 3.2. 在input(Continue...)处暂停等待键入字符才能继续执行 人工启动debug的Subprocess Attach选择子进程附加到正确的id上等待… attach到子进程可能需要一会。 在DEBUG CONSOLE里会提示结果要么是attach成功如图要么是弹窗报错然后在DEBUG CONSOLE里看错误信息。 此时可以看到调试工具栏表示正在执行、没有暂停因为我们还在被input()暂停着。 人工在命令行里敲个回车跳出input(Continue...) 断点停止在run.py中的对应位置 人工正常调试
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 gdb3.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(fUID: {os.getuid()}, EUID: {os.geteuid()}) 但是到处折腾了一圈别的方案没解决还是回来把这个值设为0了真就解决了。
这个值的设置需要root权限。废话如果本来就是用root在跑的话权限统一也不会报这个错了。
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scopeChatGPT也说了这个值设置为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 1echo; # 换行echo current value $current_value # 获取当前值# 根据当前值在0和1之间切换if [ $current_value -eq 1 ]; thenecho Now changing to 0...echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scopeelif [ $current_value -eq 0 ]; thenecho Now changing to 1 ...echo 1 | sudo tee /proc/sys/kernel/yama/ptrace_scopeelseecho [Warning] Unknown ptrace_scope current value. Nothing takes effect.exit 1fi# 检查是否执行成功并提醒恢复0值current_value$(cat /proc/sys/kernel/yama/ptrace_scope)echo [INFO] ptrace_scope changed to $current_valueecho;if [ $current_value -eq 1 ]; thenecho [INFO] Safe default setting ^-^elif [ $current_value -eq 0 ]; thenecho [INFO] Unsafe setting, remember to change back to value 1.fiecho;
}记得source ~/.bashrc使配置生效。
效果如下通过ptrace_scope change指令实现0-1切换。
其他解决方案*2
方案一ChatGPT提供对我不可行
针对debugger监听子进程这个事情ChatGPT还给了我一套方案但用不了。记一下大概配置哪哪都折腾过了这个debugpy的wait for client啊就是不知道wait到了什么直接就监听到了但我明明还没开debugger的attach
在子进程文件里写
import debugpyint 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…小白还不知道不开子进程会不会有影响就没碰
参考
StackOverflow Attaching a VSCode Debugger to a Sub Process in PythonGitHub: embodied-generalist/issues/33