当前位置: > > > > ptracing 长时间运行的进程挂起
来源:stackoverflow
2024-04-21 08:18:32
0浏览
收藏
一分耕耘,一分收获!既然打开了这篇文章《ptracing 长时间运行的进程挂起》,就坚持看下去吧!文中内容包含等等知识点…希望你能在阅读本文后,能真真实实学到知识或者帮你解决心中的疑惑,也欢迎大佬或者新人朋友们多留言评论,多给建议!谢谢!
问题内容
我正在使用 go 的系统调用包 ptrace 接口来跟踪进程。问题是,如果被跟踪者长时间运行,跟踪似乎会挂起。我尝试用 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) ....
今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注公众号,一起学习编程~