当前位置: > > > > ptracing 长时间运行的进程挂起
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的技术知识我们会一点点深入介绍,欢迎大家关注米云公众号,一起学习编程~
