Golang-语言源码级调试器 Delve

在这里插入图片描述

前言

Go 目前的调试器有如下几种:

  • GDB 最早期的调试工具,现在用的很少。
  • LLDB macOS 系统推荐的标准调试工具,单 Go 的一些专有特性支持的比较少。
  • Delve 专门为 Go 语言打造的调试工具,使用最为广泛。

本篇简单说明如何使用 Delve 工具来调试 Go 程序,使用的 delve 版本为 1.20.1。

delve 的汉语意思是:钻研、探索;用这个来命名一个debug工具还是非常的形象。

安装

已知以下说明适用于 Linux、macOS、Windows 和 FreeBSD。

克隆 git 存储库并构建:

$ git clone https://github.com/go-delve/delve
$ cd delve
$ go install github.com/go-delve/delve/cmd/dlv

或者,在 Go 版本 1.16 或更高版本上:

Install the latest release:
$ go install github.com/go-delve/delve/cmd/dlv@latest

Install at tree head:
$ go install github.com/go-delve/delve/cmd/dlv@master

安装在一个特定的版本或:

$ go install github.com/go-delve/delve/cmd/dlv@v1.7.3
$ go install github.com/go-delve/delve/cmd/dlv@v1.7.4-0.20211208103735-2f13672765fe

命令

Usage:dlv [command]Available Commands:attach      附加到正在运行的进程并开始调试.connect     使用终端客户端连接到无头调试服务器.core        检查核心转储.dap         启动一个通过调试适配器协议(DAP)通信的无头TCP服务器.debug       编译并开始调试当前目录中的主包或指定的包.exec        执行预编译的二进制文件,并开始调试会话.help        Help about any commandrun         弃用的命令。使用'debug'代替.test        编译测试二进制文件并开始调试程序.trace       编译并开始跟踪程序.version     Prints version.

[操作] 示例代码

下面是检查操作的代码

.test/
├── go.mod
├── main.go
└── main_test.go
module debug_samplego 1.18

main.go 执行以下处理:

package mainimport ("fmt"
)var abc stringfunc init() {abc = "wakuwaku bank"
}func add(a, b int) int {fmt.Printf("func add %v\n", abc)return a + b
}func sub(a, b int) int {fmt.Printf("func sub %v\n", abc)return a - b
}func calculate(a, b int) (addValue, subValue int) {addValue = add(a, b)subValue = sub(a, b)return addValue, subValue
}func sampleFunc1() {for i := 0; i < 10; i++ {a := i + 10b := iaddValue, subValue := calculate(a, b)fmt.Printf("addValue: %v subValue: %v\n", addValue, subValue)}
}func main() {sampleFunc1()
}

main_test.go 执行以下处理:

package mainimport "testing"func Test_add(t *testing.T) {type args struct {a intb int}tests := []struct {name stringargs argswant int}{{name: "Both positive values", args: args{10, 3}, want: 13}}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {if got := add(tt.args.a, tt.args.b); got != tt.want {t.Errorf("add() = %v, want %v", got, tt.want)}})}
}func Test_sub(t *testing.T) {type args struct {a intb int}tests := []struct {name stringargs argswant int}{{name: "Both positive values", args: args{10, 3}, want: 7}}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {if got := sub(tt.args.a, tt.args.b); got != tt.want {t.Errorf("sub() = %v, want %v", got, tt.want)}})}
}

[调试] dlv 调试

开始调试

$ dlv debug main.go
Type 'help' for list of commands.
(dlv) 

检查功能/代码( funcs list )

funcs main\..* 查看 main 文件 所有定义的方法

(dlv) funcs main\..*
main.add
main.calculate
main.init.0
main.main
main.sampleFunc1
main.sub
runtime.main.func1
runtime.main.func2

list 您可以在以下位置查看某个方法源代码

(dlv) list main.main
Showing /debug_sample/main.go:38 (PC: 0x1029dda10)33:                 addValue, subValue := calculate(a, b)34:                 fmt.Printf("addValue: %v subValue: %v\n", addValue, subValue)35:         }36: }37: 38: func main() {39:         sampleFunc1()40: }
(dlv) list main.sampleFunc1:3
Showing /debug_sample/main.go:32 (PC: 0x1029dd8c0)27: }28: 29: func sampleFunc1() {30:         for i := 0; i < 10; i++ {31:                 a := i + 1032:                 b := i33:                 addValue, subValue := calculate(a, b)34:                 fmt.Printf("addValue: %v subValue: %v\n", addValue, subValue)35:         }36: }37: 

设置/删除断点 ( break clear )

break 您可以使用以下命令设置断点

(dlv) break main.main
Breakpoint 1 set at 0x1029dda10 for main.main() ./main.go:38
(dlv) break main.sampleFunc1:3
Breakpoint 2 set at 0x1029dd8c0 for main.sampleFunc1() ./main.go:32

breakpoints 您可以检查中设置的断点。

(dlv) breakpoints
Breakpoint runtime-fatal-throw (enabled) at 0x10296c880 for runtime.throw() /Users/w/.gvm/gos/go1.18/src/runtime/panic.go:982 (0)
Breakpoint unrecovered-panic (enabled) at 0x10296cb90 for runtime.fatalpanic() /Users/w/.gvm/gos/go1.18/src/runtime/panic.go:1065 (0)print runtime.curg._panic.arg
Breakpoint 1 (enabled) at 0x1029dda10 for main.main() ./main.go:38 (0)
Breakpoint 2 (enabled) at 0x1029dd8c0 for main.sampleFunc1() ./main.go:32 (0)

clear 您可以使用 删除指定的断点。

(dlv) clear 1
Breakpoint 1 cleared at 0x1029dda10 for main.main() ./main.go:38
(dlv) breakpoints
Breakpoint runtime-fatal-throw (enabled) at 0x10296c880 for runtime.throw() /Users/w/.gvm/gos/go1.18/src/runtime/panic.go:982 (0)
Breakpoint unrecovered-panic (enabled) at 0x10296cb90 for runtime.fatalpanic() /Users/w/.gvm/gos/go1.18/src/runtime/panic.go:1065 (0)print runtime.curg._panic.arg
Breakpoint 2 (enabled) at 0x1029dd8c0 for main.sampleFunc1() ./main.go:32 (0)

clearall 删除所有断点。

(dlv) clearall
Breakpoint 1 cleared at 0x4986e6 for main.main() ./main.go:38
Breakpoint 5 cleared at 0x49858c for main.sampleFunc1() ./main.go:32

提前处理到断点( continue )

continue 让我们继续执行中设置的断点。

(dlv) continue
> main.sampleFunc1() ./main.go:32 (hits goroutine(1):1 total:1) (PC: 0x1029dd8c0)27: }28: 29: func sampleFunc1() {30:         for i := 0; i < 10; i++ {31:                 a := i + 10
=>  32:                 b := i33:                 addValue, subValue := calculate(a, b)34:                 fmt.Printf("addValue: %v subValue: %v\n", addValue, subValue)35:         }36: }37: 

continue 或者,您可以继续执行以下命令。

next
向前迈出一行(跨过)。
step
前进一行。
stepout
退出当前功能。

检查并覆盖变量 ( locals set )

[root@cdh2 test]# dlv debug main.go  // 调试
Type 'help' for list of commands.(dlv) break main.sampleFunc1:3  // 设置断点
Breakpoint 1 set at 0x49858c for main.sampleFunc1() ./main.go:32(dlv) c  // 跳到断点
> main.sampleFunc1() ./main.go:32 (hits goroutine(1):1 total:1) (PC: 0x49858c)27:	}28:29:	func sampleFunc1() {30:		for i := 0; i < 10; i++ {31:			a := i + 10
=>  32:			b := i33:			addValue, subValue := calculate(a, b)34:			fmt.Printf("addValue: %v subValue: %v\n", addValue, subValue)35:		}36:	}37:(dlv) locals  // 打印局部变量
i = 0
a = 10(dlv) vars main.abc
main.abc = "wakuwaku bank"(dlv) print i
0
(dlv) print a
10(dlv) set i = 2  // 重新给变量赋值
(dlv) print i
2

堆栈跟踪显示( stack frame )

首先,要检查操作,请继续添加功能。

(dlv) break main.add
Breakpoint 3 set at 0x1029dd610 for main.add() ./main.go:13
(dlv) c
> main.add() ./main.go:13 (hits goroutine(1):1 total:1) (PC: 0x1029dd610)8: 9: func init() {10:         abc = "wakuwaku bank"11: }12: 
=>  13: func add(a, b int) int {14:         fmt.Printf("func add %v\n", abc)15:         return a + b16: }17: 18: func sub(a, b int) int {

显示堆栈跟踪

(dlv) stack
0  0x00000000004982aa in main.addat ./main.go:13
1  0x00000000004984df in main.calculateat ./main.go:24
2  0x00000000004985a5 in main.sampleFunc1at ./main.go:33
3  0x00000000004986f7 in main.mainat ./main.go:39
4  0x00000000004372d8 in runtime.mainat /root/.go/src/runtime/proc.go:250
5  0x0000000000461661 in runtime.goexitat /root/.go/src/runtime/asm_amd64.s:1571

frame 您可以通过指定堆栈跟踪编号来检查代码和变量

(dlv) frame 2 ls
Goroutine 1 frame 2 at /debug_sample/main.go:33 (PC: 0x1029dd8d0)28: 29: func sampleFunc1() {30:         for i := 0; i < 10; i++ {31:                 a := i + 1032:                 b := i
=>  33:                 addValue, subValue := calculate(a, b)34:                 fmt.Printf("addValue: %v subValue: %v\n", addValue, subValue)35:         }36: }37: 38: func main() {
(dlv) frame 2 locals
i = 2
a = 10
b = 2

指定条件 ( condition )

首先,进行for语句的处理

$ dlv debug main.go
Type 'help' for list of commands.
(dlv) b main.sampleFunc1:3
Breakpoint 1 set at 0x1050958c0 for main.sampleFunc1() ./main.go:32
(dlv) c
> main.sampleFunc1() ./main.go:32 (hits goroutine(1):1 total:1) (PC: 0x1050958c0)27: }28: 29: func sampleFunc1() {30:         for i := 0; i < 10; i++ {31:                 a := i + 10
=>  32:                 b := i33:                 addValue, subValue := calculate(a, b)34:                 fmt.Printf("addValue: %v subValue: %v\n", addValue, subValue)35:         }36: }37: 
(dlv) locals
i = 0
a = 10

condition 您可以使用 设置断点条件。
i==5 让我们将其设置为停止时

(dlv) condition 1 i==5(dlv) c
func add wakuwaku bank
func sub wakuwaku bank
addValue: 10 subValue: 10
func add wakuwaku bank
func sub wakuwaku bank
addValue: 12 subValue: 10
func add wakuwaku bank
func sub wakuwaku bank
addValue: 14 subValue: 10
func add wakuwaku bank
func sub wakuwaku bank
addValue: 16 subValue: 10
func add wakuwaku bank
func sub wakuwaku bank
addValue: 18 subValue: 10
> main.sampleFunc1() ./main.go:32 (hits goroutine(1):2 total:2) (PC: 0x1050958c0)27: }28: 29: func sampleFunc1() {30:         for i := 0; i < 10; i++ {31:                 a := i + 10
=>  32:                 b := i33:                 addValue, subValue := calculate(a, b)34:                 fmt.Printf("addValue: %v subValue: %v\n", addValue, subValue)35:         }36: }37: (dlv) locals
i = 5
a = 15

调试结束( exit )

exit 您可以使用 完成调试。

(dlv) exit

[debug] dlv测试(调试测试)

dlv test 您可以使用以下命令调试您的测试代码

$ dlv test
Type 'help' for list of commands.
(dlv) funcs test.Test*  // test.Test*  test 包含 Xxx_test.go 文件夹
debug_sample.Test_add
debug_sample.Test_add.func1
debug_sample.Test_sub
debug_sample.Test_sub.func1(dlv) b test.Test_add
Breakpoint 1 set at 0x104891e90 for debug_sample.Test_add() ./main_test.go:5(dlv) c
> debug_sample.Test_add() ./main_test.go:5 (hits goroutine(4):1 total:1) (PC: 0x104891e90)1: package main2: 3: import "testing"4: 
=>   5: func Test_add(t *testing.T) {6:         type args struct {7:                 a int8:                 b int9:         }10:         tests := []struct { 

[debug] dlv Attach(调试运行进程)

更正操作检查代码

对其进行修改以保持作为 Web 服务器运行,如下所示。

package mainimport ("fmt""net/http"
)var abc stringfunc init() {abc = "wakuwaku bank"
}func add(a, b int) int {fmt.Printf("func add %v\n", abc)return a + b
}func sub(a, b int) int {fmt.Printf("func sub %v\n", abc)return a - b
}func calculate(a, b int) (addValue, subValue int) {addValue = add(a, b)subValue = sub(a, b)return addValue, subValue
}func sampleFunc1(w http.ResponseWriter, r *http.Request) {for i := 0; i < 10; i++ {a := i * 2b := iaddValue, subValue := calculate(a, b)fmt.Fprintf(w, "addValue: %v subValue: %v\n", addValue, subValue)}
}func main() {http.HandleFunc("/sample_func_1", sampleFunc1)http.ListenAndServe(":80", nil)
}

启动。

$ go build     
$ ./test

调试运行进程

检查进程 ID。

$ ps -ef | grep "test"
root     254882  56889  0 15:24 pts/2    00:00:00 ./test
root     257090  18100  0 15:25 pts/0    00:00:00 grep --color=auto test

调试

# dlv attach 254882
Type 'help' for list of commands.
(dlv)

设置断点并等待进程被调用。

(dlv) b main.sampleFunc1
Breakpoint 1 set at 0x1010e8470 for main.sampleFunc1() ./main.go:30(dlv) c

尝试在另一个控制台中向端点发出请求。

$ curl http://localhost/sample_func_1

处理在设置的断点处停止,如下所示。

(dlv) c
> main.sampleFunc1() ./main.go:30 (hits goroutine(21):1 total:1) (PC: 0x1010e8470)
Warning: debugging optimized function25:         addValue = add(a, b)26:         subValue = sub(a, b)27:         return addValue, subValue28: }29: 
=>  30: func sampleFunc1(w http.ResponseWriter, r *http.Request) {31:         for i := 0; i < 10; i++ {32:                 a := i * 233:                 b := i34:                 addValue, subValue := calculate(a, b)35:                 fmt.Fprintf(w, "addValue: %v subValue: %v\n", addValue, subValue)

命令说明

以下是一些最常用的命令。

断点相关

命令别名解释
breakb设置断点
breakpointsbp显示活动断点
clear删除断点
clearall删除所有断点
conditioncond设置断点条件

继续

命令别名解释
continuec继续到“下一个断点”或“程序结束”或“指定点”。(例如 c main.add:1 )
nextn向前迈出一行(跨过)。
steps前进一行。
stepoutso退出当前功能。
restart恢复该过程。
exitq退出调试器。

其他的

命令别名解释
funcs检查功能列表。(例如 funcs main…* )
listl显示代码。(例如 l 10 l main.main:3 )
locals检查局部变量。
vars检查包变量。
printp评估一个表达式。
set覆盖变量。
stackbt显示堆栈跟踪。

您还可以通过在调试过程中执行来查看如何使用其他命令 help

(dlv) help
The following commands are available:Running the program:call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!)continue (alias: c) --------- Run until breakpoint or program termination.next (alias: n) ------------- Step over to next source line.rebuild --------------------- Rebuild the target executable and restarts it. It does not work if the executable was not built by delve.restart (alias: r) ---------- Restart process.step (alias: s) ------------- Single step through program.step-instruction (alias: si)  Single step a single cpu instruction.stepout (alias: so) --------- Step out of the current function.Manipulating breakpoints:break (alias: b) ------- Sets a breakpoint.breakpoints (alias: bp)  Print out info for active breakpoints.clear ------------------ Deletes breakpoint.clearall --------------- Deletes multiple breakpoints.condition (alias: cond)  Set breakpoint condition.on --------------------- Executes a command when a breakpoint is hit.toggle ----------------- Toggles on or off a breakpoint.trace (alias: t) ------- Set tracepoint.watch ------------------ Set watchpoint.Viewing program variables and memory:args ----------------- Print function arguments.display -------------- Print value of an expression every time the program stops.examinemem (alias: x)  Examine raw memory at the given address.locals --------------- Print local variables.print (alias: p) ----- Evaluate an expression.regs ----------------- Print contents of CPU registers.set ------------------ Changes the value of a variable.vars ----------------- Print package variables.whatis --------------- Prints type of an expression.Listing and switching between threads and goroutines:goroutine (alias: gr) -- Shows or changes current goroutinegoroutines (alias: grs)  List program goroutines.thread (alias: tr) ----- Switch to the specified thread.threads ---------------- Print out info for every traced thread.Viewing the call stack and selecting frames:deferred --------- Executes command in the context of a deferred call.down ------------- Move the current frame down.frame ------------ Set the current frame, or execute command on a different frame.stack (alias: bt)  Print stack trace.up --------------- Move the current frame up.Other commands:config --------------------- Changes configuration parameters.disassemble (alias: disass)  Disassembler.dump ----------------------- Creates a core dump from the current process stateedit (alias: ed) ----------- Open where you are in $DELVE_EDITOR or $EDITORexit (alias: quit | q) ----- Exit the debugger.funcs ---------------------- Print list of functions.help (alias: h) ------------ Prints the help message.libraries ------------------ List loaded dynamic librarieslist (alias: ls | l) ------- Show source code.source --------------------- Executes a file containing a list of delve commandssources -------------------- Print list of source files.transcript ----------------- Appends command output to a file.types ---------------------- Print list of typesType help followed by a command for full documentation.

参考

go-delve/delve:Delve 是 Go 编程语言的调试器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/87946.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mongoose http server 例子

今天抽了点时间看了一下 mongoose的源码&#xff0c; github 地址&#xff0c;发现跟以前公司内部使用的不太一样&#xff0c;这里正好利用其 http server 例子来看一下。以前的 http message 结构体是这样的&#xff1a; /* HTTP message */ struct http_message {struct mg_…

CentOS7.7.1908升级python3版本

介绍 本文将详细介绍在CentOS7.7.1908系统的服务器将自带的python版本升级到3.8.0版本的过程。 在升级前CentOS7.7.1908中已经存在旧python版本。 查看CentOS版本命令&#xff1a; cat /etc/centos-release升级前后的python版本&#xff08;python3升级前为3.6.8&#xff09…

css3背景渐变

1.线性渐变 <style>.box {width: 200px;height: 200px;border: 1px solid black;float: left;margin-left: 50px;}.box1 {background-image: linear-gradient(green, yellow, red);}/* 右上 */.box2 {background-image: linear-gradient(to right top, green, yellow, re…

基于Java+SpringBoot+Vue的书籍学习平台设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

Leetcode-每日一题【剑指 Offer 20. 表示数值的字符串】

题目 请实现一个函数用来判断字符串是否表示数值&#xff08;包括整数和小数&#xff09;。 数值&#xff08;按顺序&#xff09;可以分成以下几个部分&#xff1a; 若干空格一个 小数 或者 整数&#xff08;可选&#xff09;一个 e 或 E &#xff0c;后面跟着一个 整数若干空…

Matlab时频工具箱tftb下载及安装

Matlab 时频工具箱下载及安装 首先下载安装包安装包地址如下 链接: https://tftb.nongnu.org/ 点击下面的download 跳转到如下界面&#xff0c;选择下面的安装包下载 下载之后得到一个压缩包 然后找到Matlab的安装目录&#xff0c;右键桌面图标&#xff0c;打开文件所在位置…

图论——最短路算法

引入&#xff1a; 如上图&#xff0c;已知图G。 问节点1到节点3的最短距离。 可心算而出为d[1,2]d[2,3]112,比d[1,3]要小。 求最短路径算法&#xff1a; 1.Floyd(弗洛伊德) 是一种基于三角形不等式的多源最短路径算法。边权可以为负数 表现为a[i,j]a[j,k]<a[i,k]。 …

电脑mfc140u.dll丢失的怎么办呢?这个方法亲测可以解决

修复mfc140u.dll是我最近遇到的一个技术问题&#xff0c;虽然在解决过程中遇到了一些困难&#xff0c;但最终的成功修复让我对技术的力量有了更深的体会。 首先&#xff0c;我想谈谈遇到问题时的困惑。当我尝试运行一个应用程序时&#xff0c;突然弹出一个错误提示&#xff0c;…

Fireworks CS6 不能把文件拖进去

打开软件安装文件夹 我的是&#xff1a;C:\Program Files\Adobe Fireworks CS6\Adobe Fireworks CS6 在该位置找到文件【Fireworks.exe】 右键属性 取消勾选&#xff0c;【以管理员身份运行此程序】

使用 HTML、CSS 和 JavaScript 创建多步骤表单

使用 HTML、CSS 和 JavaScript 创建多步骤表单 为了处理又长又复杂的表单&#xff0c;我们需要将它们分成多个步骤。通过一次只在屏幕上显示一些输入&#xff0c;表单会感觉更容易理解&#xff0c;并防止用户感到被大量的表单字段淹没。 在本文中&#xff0c;我将逐步指导如何…

CCLINK转MODBUS-TCP网关cclink通讯接线图 终端电阻

大家好&#xff0c;今天我们要聊的是生产管理系统中的CCLINK和MODBUS-TCP协议&#xff0c;它们的不同使得数据互通比较困难&#xff0c;但捷米JM-CCLK-TCP网关的出现改变了这一切。 1捷米JM-CCLK-TCP是一款自主研发的CCLINK从站功能的通讯网关&#xff0c;它的主要功能是将各种…

Arcgis中影像图切片有白斑或者白点

效果 步骤 1、3dmax渲染或者其它原片 2、Arcgis中加载图片 原数据效果 3、定义投影和转换坐标系等等 我这边测试数据是EPSG:4326的坐标系 4、导出jp2(JPG2000)格式 转换后效果 5、发布服务 6、效果对比

为MySQL新增一张performance_schema表 | StoneDB 技术分享会 #4

StoneDB开源地址 https://github.com/stoneatom/stonedb 设计&#xff1a;小艾 审核&#xff1a;丁奇、李浩 编辑&#xff1a;宇亭 作者&#xff1a;王若添 中国科学技术大学-软件工程-在读硕士、StoneDB 内核研发实习生 performance_schema 简介 MySQL 启动后会自动创建四…

ESP8266(RTOS SDK)内嵌网页以实现WEB配网以及数据交互

【本文发布于https://blog.csdn.net/Stack_/article/details/131997098&#xff0c;未经允许不得转载&#xff0c;转载须注明出处】 1、执行make menuconfig&#xff0c;将http头由512改为更大的值&#xff0c;否则用电脑浏览器访问正常&#xff0c;但用手机浏览器访问会因为ht…

检测文本是否由AI生成,GPT、文心一言等均能被检测

背景 目前很多机构推出了ChatGPT等AI文本检测工具&#xff0c;但是准确率主打一个模棱两可&#xff0c;基本和抛硬币没啥区别。 先说结论&#xff0c;我们对比了常见的几款AI检测工具&#xff0c;copyleaks检测相比较而言最准确。 检测文本 AI文本片段1 来源&#xff1a;G…

数据结构——单链表的实现(c语言版)

前言 单链表作为顺序表的一种&#xff0c;了解并且熟悉它的结构对于我们学习更加复杂的数据结构是有一定意义的。虽然单链表有一定的缺陷&#xff0c;但是单链表也有它存在的价值&#xff0c; 它也是作为其他数据结构的一部分出现的&#xff0c;比如在图&#xff0c;哈希表中。…

378. 有序矩阵中第 K 小的元素

378. 有序矩阵中第 K 小的元素 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;__378有序矩阵中第K小的元素__直接排序__378有序矩阵中第K小的元素__归并排序__378有序矩阵中第K小的元素__二分查找 原题链接&#xff1a; 378. 有序矩阵中…

gitee(码云)如何生成并添加公钥配置用户信息

一&#xff0c;简介 在使用Gitee的时候&#xff0c;公钥是必须的&#xff0c;无论是克隆还是上传。本文主要介绍如何本地生成和添加公钥到服务器&#xff0c;然后配置自己的用户信息&#xff0c;方便日后拉取与上传代码。 二&#xff0c;步骤介绍 2.1 本地生成公钥 打开git ba…

Prometheus技术文档-概念

Prometheus是一个开源的项目连接如下&#xff1a; Prometheus首页、文档和下载 - 服务监控系统 - OSCHINA - 中文开源技术交流社区 基本概念&#xff1a; Prometheus是一个开源的系统监控和告警系统&#xff0c;由Google的BorgMon监控系统发展而来。它主要用于监控和度量各种…

Modbus TCP转Profibus DP网关modbus tcp报文解析

捷米JM-DPM-TCP网关。在Profibus总线侧作为主站&#xff0c;在以太网侧作为ModbusTcp服务器功能&#xff0c; 下面是介绍捷米JM-DPM-TCP主站网关组态工具的配置方法 2, Profibus主站组态工具安装 执行资料光盘中的安装文件setup64.exe或setup.exe安装组态工具。安装过程中一直…