登录
首页 >  Golang >  Go问答

ptracing 长时间运行的进程挂起

来源:stackoverflow

时间:2024-04-21 08:18:32 124浏览 收藏

一分耕耘,一分收获!既然打开了这篇文章《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的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>