gpt4 book ai didi

go - ptracing 长时间运行的进程挂起

转载 作者:行者123 更新时间:2023-12-01 22:12:49 27 4
gpt4 key购买 nike

我正在使用 Go 的系统调用包 Ptrace 接口(interface)来跟踪进程。问题是,如果被跟踪者长时间运行,跟踪似乎会挂起。我尝试用 C 实现复制这个问题,但一切似乎都运行良好。
这是重现该问题的 Go 代码:

import (
"fmt"
"os"
"os/exec"
"syscall"
)

func main() {
len := "9999999"
cmd := exec.Command("openssl", "rand", "-hex", len)
cmd.SysProcAttr = &syscall.SysProcAttr{Ptrace: true}
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Start()
pid, _ := syscall.Wait4(-1, nil, syscall.WALL, nil)

for {
syscall.PtraceSyscall(pid, 0)
_, err := syscall.Wait4(-1, nil, syscall.WALL, nil)

if err != nil {
fmt.Println(err)
break
}
}
}
运行上述代码时,该过程永远不会完成,必须中断。如果 len变量更改为更小的值,例如 9 ,该过程将毫无问题地完成,输出将如下所示:
$ go run main.go
d2ff963e65e8e1926b
no child processes

最佳答案

找到了。当 Go 运行时更改运行 goroutine 的线程时,程序会挂起。可以通过打印 fmt.Println(syscall.Gettid()) 在示例代码中进行验证循环内:

package main

import (
"fmt"
"os/exec"
"syscall"
)

func main() {
len := "9999999"
cmd := exec.Command("openssl", "rand", "-hex", len)
cmd.SysProcAttr = &syscall.SysProcAttr{Ptrace: true}
cmd.Start()

pid, _ := syscall.Wait4(-1, nil, syscall.WALL, nil)

for {
fmt.Println(syscall.Gettid())
syscall.PtraceSyscall(pid, 0)
_, err := syscall.Wait4(-1, nil, syscall.WALL, nil)

if err != nil {
fmt.Println(err)
break
}
}
}
解决方案:使用 runtime.LockOSThread() 将 goroutine 的执行锁定到其当前线程:
....
func main() {
runtime.LockOSThread()
len := "9999999"
cmd := exec.Command("openssl", "rand", "-hex", len)
....

关于go - ptracing 长时间运行的进程挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62517488/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com