Golang插件中无法打开任何文件的解决方法
Golang插件中无法打开任何文件的解决方法 go version go version go1.17.13 linux/amd64
在我的Go插件代码中,当我尝试读取文件时,应用程序崩溃了。
我在插件中编写了以下函数(用于获取操作系统版本):
func getosversion() string {
content, err := ioutil.ReadFile(“/proc/sys/kernel/version”)
if err != nil {
return “”
}
return strings.TrimSpace(string(content))
}
每当我调用此函数时,应用程序就会崩溃并显示以下消息: 致命错误:运行时:在空闲的polldesc上发生阻塞写入。
调用栈:
goroutine 1 [运行中]: runtime.throw({0x7f6ab1a7dc57, 0xc0000001a0}) /usr/local/go/src/runtime/panic.go:1198 +0x71 fp=0xc001831fc8 sp=0xc001831f98 pc=0x7f6ab15c1e31 internal/poll.runtime_pollOpen(0xf) /usr/local/go/src/runtime/netpoll.go:221 +0x1e5 fp=0xc001832020 sp=0xc001831fc8 pc=0x7f6ab15bca65 internal/poll.(*pollDesc).init(0xc001a3e378, 0x80001) /usr/local/go/src/internal/poll/fd_poll_runtime.go:40 +0x53 fp=0xc001832040 sp=0xc001832020 pc=0x7f6ab166bc53 internal/poll.(*FD).Init(0xc001a3e360, {0x7f6ab1a6968e, 0xffffffffffffff9c}, 0x0) /usr/local/go/src/internal/poll/fd_unix.go:63 +0x46 fp=0xc001832060 sp=0xc001832040 pc=0x7f6ab166cf26 os.newFile(0xf, {0x7f6ab1a73da0, 0x18}, 0x1) /usr/local/go/src/os/file_unix.go:172 +0x118 fp=0xc0018320a0 sp=0xc001832060 pc=0x7f6ab16796b8 os.openFileNolog({0x7f6ab1a73da0, 0x0}, 0x0, 0x0) /usr/local/go/src/os/file_unix.go:241 +0x176 fp=0xc0018320f0 sp=0xc0018320a0 pc=0x7f6ab16798f6 os.OpenFile({0x7f6ab1a73da0, 0x18}, 0x0, 0x0) /usr/local/go/src/os/file.go:338 +0x45 fp=0xc001832128 sp=0xc0018320f0 pc=0x7f6ab1677c65 os.Open(…) /usr/local/go/src/os/file.go:318 os.ReadFile({0x7f6ab1a73da0, 0x6}) /usr/local/go/src/os/file.go:670 +0x6a fp=0xc001832208 sp=0xc001832128 pc=0x7f6ab167816a io/ioutil.ReadFile(…) /usr/local/go/src/io/ioutil/ioutil.go:37 plugin/unnamed-c8c363a741895c0986b2fc8df5678d5b37ef70bc.getosversion() /root/go/src/testsample.go:679 +0x25 fp=0xc001832230 sp=0xc001832208 pc=0x7f6ab1990245
有人能提供一个解决方案吗?更多关于Golang插件中无法打开任何文件的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang插件中无法打开任何文件的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个典型的Go插件与文件系统交互时出现的运行时问题。错误信息"在空闲的polldesc上发生阻塞写入"表明插件在尝试进行文件I/O操作时与主程序的运行时环境发生了冲突。
问题根源在于Go插件与主程序共享相同的运行时,但插件中的文件操作可能触发了主程序运行时未预期的状态。以下是解决方案:
解决方案:使用系统调用直接读取文件
import (
"syscall"
"unsafe"
)
func getosversion() string {
// 使用系统调用打开文件
fd, err := syscall.Open("/proc/sys/kernel/version", syscall.O_RDONLY, 0)
if err != nil {
return ""
}
defer syscall.Close(fd)
// 读取文件内容
var buf [1024]byte
n, err := syscall.Read(fd, buf[:])
if err != nil {
return ""
}
// 转换为字符串并去除空白
version := string(buf[:n])
for i := len(version) - 1; i >= 0; i-- {
if version[i] != '\n' && version[i] != '\r' && version[i] != ' ' {
return version[:i+1]
}
}
return ""
}
替代方案:使用os包但避免标准I/O
import (
"os"
"syscall"
)
func getosversion() string {
// 使用低级文件描述符
fd, err := syscall.Open("/proc/sys/kernel/version", syscall.O_RDONLY, 0)
if err != nil {
return ""
}
// 将文件描述符转换为os.File
file := os.NewFile(uintptr(fd), "/proc/sys/kernel/version")
if file == nil {
syscall.Close(fd)
return ""
}
defer file.Close()
// 直接读取
buf := make([]byte, 1024)
n, err := file.Read(buf)
if err != nil {
return ""
}
// 处理结果
version := string(buf[:n])
for i := len(version) - 1; i >= 0; i-- {
if version[i] > ' ' {
return version[:i+1]
}
}
return ""
}
如果必须使用标准库,可以尝试以下方法:
import (
"os"
"strings"
"sync"
)
var fileOpenOnce sync.Once
var fileOpenErr error
func getosversion() string {
// 使用sync.Once确保文件操作只执行一次
var content []byte
fileOpenOnce.Do(func() {
f, err := os.Open("/proc/sys/kernel/version")
if err != nil {
fileOpenErr = err
return
}
defer f.Close()
// 使用固定大小的缓冲区
buf := make([]byte, 1024)
n, err := f.Read(buf)
if err != nil {
fileOpenErr = err
return
}
content = buf[:n]
})
if fileOpenErr != nil || content == nil {
return ""
}
return strings.TrimSpace(string(content))
}
第一个使用纯系统调用的方案是最可靠的,因为它完全绕过了Go的运行时文件系统抽象层,避免了与插件运行时环境的冲突。

