iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Golang标准库syscall的示例分析
  • 804
分享到

Golang标准库syscall的示例分析

2023-06-15 05:06:11 804人浏览 八月长安
摘要

小编给大家分享一下golang标准库syscall的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、什么是系统调用In computing, a sys

小编给大家分享一下golang标准库syscall的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一、什么是系统调用

In computing, a system call is the programmatic way in which a computer program requests a service from the kernel of the operating system it is executed on. This may include hardware-related services (for example, accessing a hard disk drive), creation and execution of new processes, and communication with integral kernel services such as process scheduling. System calls provide an essential interface between a process and the operating system.

系统调用是程序向操作系统内核请求服务的过程,通常包含硬件相关的服务(例如访问硬盘),创建新进程等。系统调用提供了一个进程和操作系统之间的接口。

二、Golang标准库-syscall

syscall包包含一个指向底层操作系统原语的接口。

注意:该软件包已被定。标准以外的代码应该被迁移到golang.org/x/sys存储库中使用相应的软件包。这也是应用新系统或版本所需更新的地方。 Signal , Errno 和 SysProcAttr 在 golang.org/x/sys 中尚不可用,并且仍然必须从 syscall 程序包中引用。有关更多信息,请参见 https://golang.org/s/go1.4-syscall。

Https://pkg.go.dev/golang.org/x/sys
该存储库包含用于与操作系统进行低级交互的补充Go软件包。

1. syscall无处不在

举个最常用的例子, fmt.Println(“hello world”), 这里就用到了系统调用 write, 我们翻一下源码

func Println(a ...interface{}) (n int, err error) {return Fprintln(os.Stdout, a...)}
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout") func (f *File) write(b []byte) (n int, err error) {    if len(b) == 0 {        return 0, nil    }    // 实际的write方法,就是调用syscall.Write()    return fixCount(syscall.Write(f.fd, b))}

2. syscall demo举例:

 go版本的strace Strace

strace 是用于查看进程系统调用的工具, 一般使用方法如下:

strace -c 用于统计各个系统调用的次数

[root@localhost ~]# strace -c echo hellohello% time     seconds  usecs/call     calls    errors syscall------ ----------- ----------- --------- --------- ----------------  0.00    0.000000           0         1           read  0.00    0.000000           0         1           write  0.00    0.000000           0         3           open  0.00    0.000000           0         5           close  0.00    0.000000           0         4           fstat  0.00    0.000000           0         9           mmap  0.00    0.000000           0         4           mprotect  0.00    0.000000           0         2           munmap  0.00    0.000000           0         4           brk  0.00    0.000000           0         1         1 access  0.00    0.000000           0         1           execve  0.00    0.000000           0         1           arch_prctl------ ----------- ----------- --------- --------- ----------------100.00    0.000000                    36         1 total[root@localhost ~]#

stace 的实现原理是系统调用 ptrace, 我们来看下 ptrace 是什么。

man page 描述如下:

The ptrace() system call provides a means by which one process (the “tracer”) may observe and control the execution of another process (the “tracee”), and examine and change the tracee's memory and reGISters. It is primarily used to implement breakpoint debuggingand system call tracing.

简单来说有三大能力:

追踪系统调用
读写内存和寄存器
向被追踪程序传递信号

ptrace接口:

int ptrace(int request, pid_t pid, caddr_t addr, int data); request包含:PTRACE_ATTACHPTRACE_SYSCALLPTRACE_PEEKTEXT, PTRACE_PEEKDATA等

tracer 使用 PTRACE_ATTACH 命令,指定需要追踪的PID。紧接着调用 PTRACE_SYSCALL。
tracee 会一直运行,直到遇到系统调用,内核会停止执行。 此时,tracer 会收到 SIGTRAP 信号,tracer 就可以打印内存和寄存器中的信息了。

接着,tracer 继续调用 PTRACE_SYSCALL, tracee 继续执行,直到 tracee退出当前的系统调用。
需要注意的是,这里在进入syscall和退出syscall时,tracer都会察觉。

go版本的strace

了解以上内容后,presenter 现场实现了一个go版本的strace, 需要在 linux amd64 环境编译。
https://GitHub.com/silentred/gosys

// strace.go

package main import (    "fmt"    "os"    "os/exec"    "syscall") func main() {    var err error    var regs syscall.PtraceRegs    var ss syscallCounter    ss = ss.init()     fmt.Println("Run: ", os.Args[1:])     cmd := exec.Command(os.Args[1], os.Args[2:]...)    cmd.Stderr = os.Stderr    cmd.Stdout = os.Stdout    cmd.Stdin = os.Stdin    cmd.SysProcAttr = &syscall.SysProcAttr{        Ptrace: true,    }     cmd.Start()    err = cmd.Wait()    if err != nil {        fmt.Printf("Wait err %v \n", err)    }     pid := cmd.Process.Pid    exit := true     for {        // 记得 PTRACE_SYSCALL 会在进入和退出syscall时使 tracee 暂停,所以这里用一个变量控制,RAX的内容只打印一遍        if exit {            err = syscall.PtraceGetRegs(pid, &regs)            if err != nil {                break            }            //fmt.Printf("%#v \n",regs)            name := ss.getName(regs.Orig_rax)            fmt.Printf("name: %s, id: %d \n", name, regs.Orig_rax)            ss.inc(regs.Orig_rax)        }        // 上面Ptrace有提到的一个request命令        err = syscall.PtraceSyscall(pid, 0)        if err != nil {            panic(err)        }        // 猜测是等待进程进入下一个stop,这里如果不等待,那么会打印大量重复的调用函数名        _, err = syscall.Wait4(pid, nil, 0, nil)        if err != nil {            panic(err)        }         exit = !exit    }     ss.print()}

// 用于统计信息的counter, syscallcounter.go

package main import (    "fmt"    "os"    "text/tabwriter"     "github.com/seccomp/libseccomp-golang") type syscallCounter []int const maxSyscalls = 303 func (s syscallCounter) init() syscallCounter {    s = make(syscallCounter, maxSyscalls)    return s} func (s syscallCounter) inc(syscallID uint64) error {    if syscallID > maxSyscalls {        return fmt.Errorf("invalid syscall ID (%x)", syscallID)    }     s[syscallID]++    return nil} func (s syscallCounter) print() {    w := tabwriter.NewWriter(os.Stdout, 0, 0, 8, ' ', tabwriter.AlignRight|tabwriter.Debug)    for k, v := range s {        if v > 0 {            name, _ := seccomp.ScmpSyscall(k).GetName()            fmt.Fprintf(w, "%d\t%s\n", v, name)        }    }    w.Flush()} func (s syscallCounter) getName(syscallID uint64) string {    name, _ := seccomp.ScmpSyscall(syscallID).GetName()    return name}

最后结果:

Run:  [echo hello]
Wait err stop signal: trace/breakpoint trap
name: execve, id: 59
name: brk, id: 12
name: access, id: 21
name: mmap, id: 9
name: access, id: 21
name: open, id: 2
name: fstat, id: 5
name: mmap, id: 9
name: close, id: 3
name: access, id: 21
name: open, id: 2
name: read, id: 0
name: fstat, id: 5
name: mmap, id: 9
name: mprotect, id: 10
name: mmap, id: 9
name: mmap, id: 9
name: close, id: 3
name: mmap, id: 9
name: arch_prctl, id: 158
name: mprotect, id: 10
name: mprotect, id: 10
name: mprotect, id: 10
name: munmap, id: 11
name: brk, id: 12
name: brk, id: 12
name: open, id: 2
name: fstat, id: 5
name: mmap, id: 9
name: close, id: 3
name: fstat, id: 5
hello
name: write, id: 1
name: close, id: 3
name: close, id: 3
        1|read
        1|write
        3|open
        5|close
        4|fstat
        7|mmap
        4|mprotect
        1|munmap
        3|brk
        3|access
        1|execve
        1|arch_prctl

golang适合做什么

golang可以做服务器开发,但golang很适合做日志处理、数据打包、虚拟机处理、数据库代理等工作。在网络编程方面,它还广泛应用于WEB应用、api应用等领域。

以上是“Golang标准库syscall的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网GO频道!

您可能感兴趣的文档:

--结束END--

本文标题: Golang标准库syscall的示例分析

本文链接: https://www.lsjlt.com/news/277941.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Golang标准库syscall的示例分析
    小编给大家分享一下Golang标准库syscall的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、什么是系统调用In computing, a sys...
    99+
    2023-06-15
  • JavaScript中标准库的示例分析
    这篇文章将为大家详细讲解有关JavaScript中标准库的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.什么是标准库(Standard Library)标准库...
    99+
    2024-04-02
  • Golang标准库syscall详解(什么是系统调用)
    目录一、什么是系统调用二、Golang标准库-syscall1. syscall无处不在2. syscall demo举例:go版本的strace三、参考一、什么是系统调用 In c...
    99+
    2024-04-02
  • Python标准库的强大功能的示例分析
    Python标准库的强大功能的示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Python标准库是十分庞大的,其中也有一些质量比较高的库,例如,wXPython、Py...
    99+
    2023-06-17
  • C标准库堆内存函数的示例分析
    这篇文章主要为大家展示了“C标准库堆内存函数的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C标准库堆内存函数的示例分析”这篇文章吧。概述C标准库堆内存函数有4个:malloc、free...
    99+
    2023-06-15
  • Golang常用标准库的使用和示例
    Golang常用标准库介绍及示例 Golang(也被称为Go)是一种使用简洁语法和高效性能的编程语言。作为一种开源语言,它的标准库提供了许多有用的功能,这些功能可以节省我们开发过程中的时间和精力。在本文中,我...
    99+
    2024-01-20
  • Python标准库sys实例分析
    这篇文章主要介绍了Python标准库sys实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python标准库sys实例分析文章都会有所收获,下面我们一起来看看吧。sys作用Python的sys模块提供访问...
    99+
    2023-06-29
  • Node.js api中POSIX标准的示例分析
    这篇文章主要介绍Node.js api中POSIX标准的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!如果你用过 Node.js 的 api,会不会觉得奇怪,为什么 api ...
    99+
    2024-04-02
  • Python标准库os库的常用功能实例分析
    本篇内容主要讲解“Python标准库os库的常用功能实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python标准库os库的常用功能实例分析”吧!1、目录操作1.1、获取当前目录#&nb...
    99+
    2023-07-02
  • Golang网络编程实践示例在标准库中
    Golang标准库中的网络编程实践 引言:网络编程是现代软件开发中必不可少的一部分,它可以用来实现客户端与服务器之间的通信。Golang是一种开发框架和编程语言,拥有强大的网络编程能力。本文将介绍Golang...
    99+
    2024-01-20
    Golang 网络编程 标准库
  • 深入解析golang中的标准库flag
    Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单。 os.Args 如果你只是简单的想要获取命令行参数,可以像下面的代码示例一样使用os.Args...
    99+
    2024-04-02
  • 解析Golang标准库中的常用功能
    Golang标准库中的常见功能解析 作为一种强大且高效的编程语言,Golang在其标准库中提供了众多常见功能。本文将详细解析几个常见的功能,并提供具体的代码示例。 一、文件操作 创建和写入文件 Golang的...
    99+
    2024-01-20
  • GScript 编写标准库示例详解
    目录版本更新引言使用 Docker编写 GScript 标准库 版本更新 最近 GScript 更新了 v0.0.11 版本,重点更新了: Docker 运行环境新增了 byte 原...
    99+
    2024-04-02
  • Sysbench基准测试的示例分析
    这篇文章给大家分享的是有关Sysbench基准测试的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 Sysbench和TPCC-MySQL一样...
    99+
    2024-04-02
  • golang逃逸的示例分析
    这篇文章主要介绍了golang逃逸的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。垃圾回收是Go的一个很方便的特性--其自动的内存管理使代码更整洁,同时减少内存泄漏的...
    99+
    2023-06-20
  • HTML5标签的示例分析
    这篇文章给大家分享的是有关HTML5标签的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。可以进行省略的标签不允许写结束标记的标签:area(定义图像映射中的区域)、bas...
    99+
    2024-04-02
  • Instagram标签的示例分析
    这篇文章将为大家详细讲解有关Instagram标签的示例分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。人们很容易忽视一些看似无足轻重的小标签,正如Instagram标签的重要性是让人着迷...
    99+
    2023-06-04
  • HTML标签的示例分析
    这篇文章主要为大家展示了“HTML标签的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“HTML标签的示例分析”这篇文章吧。   结构   <html...
    99+
    2024-04-02
  • AmazeUI 图标的示例分析
    小编给大家分享一下AmazeUI 图标的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Amaze UI 面向 HTML5 开发,使用 CSS3 来做动画交...
    99+
    2023-06-09
  • 解析golang 标准库template的代码生成方法
    curd-gen 项目 curd-gen 项目的创建本来是为了做为 illuminant 项目的一个工具,用来生成前端增删改查页面中的基本代码。 最近,随着 antd Pro v5 ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作