2020年7月

阿里将打造自主可控、安全可靠的国产操作系统

阿里副总裁今天表示,打造国产自主可控、安全可靠的操作系统是阿里重要的战略布局。在阿里,操作系统项目已经有多个,其中 AliOS 一度成为手机厂商替代安卓的选择,不过这几年 AliOS 已经转向物联网、车联网等领域,AliOS 官网上也很久没有更新了。

来源:快科技

拍一拍:希望不是下一个 Linux 发行版。

Chrome 和 Firefox 浏览器将很快支持全新的 AVIF 图像格式

继流媒体视频网站 Netflix、Windows 10 操作系统、VLC 视频播放器、以及某些图像编辑器之后,Google Chrome 和 Mozilla Firefox 浏览器也终于添加了对全新的 AVIF 图像格式的支持。作为一种新面世的图像格式,AVIF 最大的特点就是轻量和免授权。与现有的 JPEG、PNG、甚至 WebP 等图像格式相比,AVIF 的压缩效率可以做到更高,Netflix 等企业更是对其赞赏有加。

来源:cnBeta.COM

拍一拍:这真是一个好消息,相比 H.264 等专有格式,这种免授权的格式才会得到更多的支持。

利用区块链“智能合约”,3 名 95 后诈骗 1300 余人上亿元

3 名大学刚毕业就“创业”的 95 后,不到一年获利亿元,开上了价值 400 万的迈凯伦-650S、300 万的法拉利-California T,买了价值 800 万的豪华奢景别墅。此类新型犯罪,传统的侦查手段难以奏效。警方发现受害人加入的群管理人员一直在利用其自身发布的 HT “智能合约”非法获取受害人的 ETH,将 ETH 转到“群主”提供的账户内,返还没有任何价值的虚假 HT,从而非法获利。

来源:澎湃新闻

拍一拍:不能据此就对“智能合约”污名化,这个事情和智能合约无关,这是嫌犯和贪婪者的问题。

有史最贵游戏诞生:1985 年的《超级马里奥》以 11.4 万美元拍出

日前,一个未拆封的 1985 年美国版《超级马里奥》在美国遗产拍卖公司以 11.4 万美元的价格拍出,这打破了该游戏在此前创下的纪录。

来源:cnBeta.COM

拍一拍:这是当文物收藏了啊!

Linux Mint 毫无疑问是 最佳 Linux 发行版 之一,特别是考虑到 Linux Mint 20 的功能,我确信你也会同意这一说法。

假设你错过了我们的新闻报道,Linux Mint 20 终于可以下载了

当然,如果你使用 Linux Mint 有一段时间了,你可能知道最好做一些什么。但是,对于新用户来说,在安装 Linux Mint 20 后,你需要做一些事,让你的体验更比以往任何时候都好。

在安装 Linux Mint 20 后建议做的事

在这篇文章中,我将列出其中一些要做的事来帮助你改善 Linux Mint 20 的用户体验。

1、执行一次系统更新

安装后首先应该马上检查的是 —— 使用更新管理器进行系统更新,如上图所示。

为什么?因为你需要构建可用软件的本地缓存。更新所有软件包的更新也是一个好主意。

如果你喜欢使用终端,只需输入下面的命令来执行系统更新:

sudo apt update && sudo apt upgrade -y

2、使用 Timeshift 来创建系统快照

如果你想在意外更改或错误更新后快速地恢复系统状态,有一个系统快照总是很有用的。

因此,如果你希望能够随时备份你的系统状态,那么使用 Timeshift 配置和创建系统快照是超级重要的。

如果你还不知道如何使用它的话,你可以遵循我们 使用 Timeshift 的详细指南。

3、安装有用的软件

尽管在 Linux Mint 20 中已经安装有一些有用的预安装应用程序,你可能需要安装一些没有随之一起出炉的必不可少的应用程序。

你可以简单地使用软件包管理器或 synaptic 软件包管理器来查找和安装所需要的软件。

对于初学者来说,如果你想探索各种各样的工具,那么你可以遵循我们的 必不可少的 Linux 应用程序 的列表。

也参见:

这里是一个我最喜欢的软件包列表,我希望你也来尝试一下:

4、自定义主题和图标

当然,这在技术上不是必不可少的事,除非你想更改 Linux Mint 20 的外观和感觉。

但是,在 Linux Mint 中更改主题和图标是非常容易的 ,而不需要安装任何额外的东西。

你会在欢迎屏幕中获得优化外观的选项。或者,你只需要进入 “主题”,并开始自定义主题。

为此,你可以搜索它或在系统设置中如上图所示找到它。

根据你正在使用的桌面环境,你也可以看看可用的 最佳图标主题

5、启用 Redshift 来保护你的眼睛

你可以在 Linux Mint 上搜索 “Redshift”,并启用它以在晚上保护你的眼睛。如你在上面的截图所见,它将根据时间自动地调整屏幕的色温。

你可能想启用自动启动选项,以便它在你重新启动计算机时自动启动。它可能与 Ubuntu 20.04 LTS 的夜光功能不太一样,但是如果你不需要自定义时间表或微调色温的能力,那么它就足够好了。

6、启用 snap(如果需要的话)

尽管 Ubuntu 比前所未有的更倾向于推崇使用 Snap,但是 Linux Mint 团队却反对使用它。因此,它禁止 APT 使用 snapd。

因此,你将无法获得 snap 开箱即用的支持。然而,你迟早会意识到一些软件包只以 Snap 的格式打包。在这种情况下,你将不得不在 Mint 上启用对 snap 的支持。

sudo apt install snapd

在你完成后,你可以遵循我们的指南来了解更多关于 在 Linux 上安装和使用 snap 的信息。

7、学习使用 Flatpak

默认情况下,Linux Mint 带有对 Flatpak 的支持。所以,不管你是讨厌使用 snap 或只是更喜欢使用 Flatpak,在系统中保留它是个好主意。

现在,你只需要遵循我们关于 在 Linux 上使用 Flatpak 的指南来开始吧!

8、清理或优化你的系统

优化或清理系统总是好的,以避免不必要的垃圾文件占用存储空间。

你可以通过在终端机上输入以下内容,快速删除系统中不需要的软件包:

sudo apt autoremove

除此之外,你也可以遵循我们 在 Linux Mint 上释放空间的一些建议

9、使用 Warpinator 通过网络发送/接收文件

Warpinator 是 Linux Mint 20 的一个新功能,可以让你在连接到网络的多台电脑上共享文件。这里是它看起来的样子:

你只需要在菜单中搜索它就可以开始了!

10、使用驱动程序管理器

如果你正在使用需要驱动程序的 Wi-Fi 设备、NVIDIA 显卡或 AMD 显卡,以及其它设备(如果适用的话)时,驱动程序管理器是一个重要的部分。

你只需要找到驱动程序管理器并启用它。它应该可以检测到正在使用的任何专有驱动程序,或者你也可以使用驱动程序管理器来利用 DVD 来安装驱动程序。

11、设置防火墙

在大多数情况下,你可能已经保护了你的家庭网络。但是,如果你想在 Linux Mint 上有一些特殊的防火墙设置,你可以通过在菜单中搜索 “Firewall” 来实现。

正如你在上述截图中所看到的,你可以为家庭、企业和公共设置不同的配置文件。你只需要添加规则,并定义什么是允许访问互联网的,什么是不允许的。

你可以阅读我们关于 使用 UFW 配置防火墙 的详细指南。

12、学习管理启动应用程序

如果你是一个有经验的用户,你可能已经知道这一点了。但是,新用户经常忘记管理他们的启动应用程序,最终影响了系统启动时间。

你只需要从菜单中搜索 “Startup Applications” ,你可以启动它来查找像这样的东西:

你可以简单地切换你想要禁用的那些启动应用程序,添加一个延迟计时器,或从启动应用程序的列表中完全地移除它。

13、安装必不可少的游戏应用程序

当然,如果你对游戏感兴趣,你可能想去阅读我们关于 在 Linux 上的游戏 的文章来探索所有的选择。

但是,对于初学者来说,你可以尝试安装 GameHubSteamLutris 来玩一些游戏。

总结

就是这样,各位!在大多数情况下,如果你在安装 Linux Mint 20 后按照上面的要点进行操作,使其发挥出最好的效果,应该就可以了。

我确信你还能够做更多的事。我想知道你喜欢在安装 Linux Mint 20 后马上做了什么。在下面的评论中告诉我你的想法吧!


via: https://itsfoss.com/things-to-do-after-installing-linux-mint-20/

作者:Ankush Das 选题:lujun9972 译者:robsean 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这是一篇简短的文章。我是最近才发现 entr 的,我很惊奇从来没有人告诉过我?!因此,如果你和我一样,那么我告诉你它是什么。

entr 的网站上对它已经有很好的解释,也有很多示例。

总结在其头部:entr 是一个命令行工具,当每次更改一组指定文件中的任何一个时,都能运行一个任意命令。你在标准输入给它传递要监控的文件列表,如下所示:

git ls-files | entr bash my-build-script.sh

或者

find . -name *.rs | entr cargo test

或者任何你希望的。

快速反馈很棒

就像世界上的每个程序员一样,我发现每次更改代码时都必须手动重新运行构建/测试非常烦人。

许多工具(例如 hugo 和 flask)都有一个内置的系统,可以在更改文件时自动重建,这很棒!

但是通常我会自己编写一些自定义的构建过程(例如 bash build.sh),而 entr 让我有了一种神奇的构建经验,我只用一行 bash 就能得到即时反馈,知道我的改变是否修复了那个奇怪的 bug。万岁!

重启服务器(entr -r)

但是如果你正在运行服务器,并且每次都需要重新启动服务器怎么办?如果你传递 -r,那么 entr 会帮你的

git ls-files | entr -r python my-server.py

清除屏幕(entr -c)

另一个简洁的标志是 -c,它让你可以在重新运行命令之前清除屏幕,以免被前面构建的输出分散注意力。

与 git ls-files 一起使用

通常,我要跟踪的文件集和我在 git 中的文件列表大致相同,因此将 git ls-files 传递给 entr 是很自然的事情。

我现在有一个项目,有时候我刚创建的文件还没有在 git 里。那么如果你想包含未被跟踪的文件怎么办呢?这些 git 命令行参数就可以做到(我是从一个读者的邮件中得到的,谢谢你!):

git ls-files -cdmo --exclude-standard  | entr your-build-script

有人给我发了邮件,说他们做了一个 git-entr 命令,可以执行:

git ls-files -cdmo --exclude-standard | entr -d "$@"

我觉得这真是一个很棒的主意。

每次添加新文件时重启:entr -d

git ls-files 的另一个问题是有时候我添加一个新文件,当然它还没有在 git 中。entr 为此提供了一个很好的功能。如果你传递 -d,那么如果你在 entr 跟踪的任何目录中添加新文件,它就会退出。

我将它与一个 while 循环配合使用,它将重启 entr 来包括新文件,如下所示:

while true
do
{ git ls-files; git ls-files . --exclude-standard --others; } | entr -d your-build-scriot
done

entr 在 Linux 上的工作方式:inotify

在 Linux 中,entr 使用 inotify(用于跟踪文件更改这样的文件系统事件的系统)工作。如果用 strace 跟踪它,那么你会看到每个监控文件的 inotify_add_watch 系统调用,如下所示:

inotify_add_watch(3, "static/stylesheets/screen.css", IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE_SELF|IN_MOVE_SELF) = 1152

就这样了

我希望这可以帮助一些人了解 entr


via: https://jvns.ca/blog/2020/06/28/entr/

作者:Julia Evans 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

英伟达市值超过英特尔

英伟达超过英特尔成为美国市值最高的芯片公司。市值并不反映公司本身的销售收入,而是反映了投资者对该公司未来的期望。英特尔的股价在 2020 年内下降了 3%,而英伟达同期增长了 68%。但英伟达的收入只占芯片巨人的很小一部分,分析师估计当前财年英伟达的收入能达到 146 亿美元,而英特尔则高达 738 亿美元。

来源:solidot

拍一拍:风起于青萍之末,半导体行业正在向着一个新的方向发展。

Google 和 Canonical 合作将 Flutter Apps 带到 Linux

Google 和 Canonical 合作将它的开源 UI 框架 Flutter 带到 Linux 平台,将 Flutter Apps 带到 Canonical 的 Snap 商店。Google 和 Canonical 称,Flutter SDK snap 提供了在 Linux 发行版上开发 Flutter app 所需的所有组件,无需安装大量的依赖。

来源:solidot

拍一拍:从大的方面来看是利好,但是社区对 Snap 有所不喜。

KeePassXC 2.6.0 释出

KeePassXC 是另一个开源密码管理器 KeePassX 的分支,起因是 KeePassX 开发停滞;而 KeePassX 则是 KeePass 的净室实现,它的最新版本还是 2016 年发布的。KeePassXC 2.6.0 的主要新特性包括:大幅修改了用户界面,引入了轻色和暗色自定义主题;加入了 Have I Been Pwned 密码检查功能检查密码是否泄露;改进了 YubiKey 和 OnlyKey 密钥整合,支持同时插入 4 个 USB 密钥;等等。

来源:

拍一拍:密码管理器是安全基石之一。

Debian 8 LTS 生命周期已结束

Debian 8 首发于2015年4月26日,在接收来自官方 5 年的技术支持后,已于2020年6月30日到达 EOL 阶段。而 Debian 项目的 LTS 团队将转移至为 Debian 9 “Stretch” 提供技术支持,LTS 团队已于 2020 年 7 月 6 日从安全团队接管了对 Debian 9 的支持,“Stretch” 的最后一个小数点版本更新将于 7 月 18 日发布。

来源:开源中国

拍一拍:感觉 Debian 8 还在耳边,这就过了 LTS 了?

立陶宛央行开始预售数字货币 LBCoin

本月 2日,立陶宛中央银行发布消息,将发行数字货币 LBcoin。LBCoin 数字货币基于区块链技术生产,也是立陶宛试点具有国家支持背景的数字货币和区块链技术项目的一部分。7 月 9 日,立陶宛央行发行的数字货币 LBCoin 开始在网站上注册预售,7 月 23 日将正式发售。LBCoin 可以直接与中央银行以及专用区块链网络进行交换。

来源:央视网

拍一拍:船小好调头啊。

据称加密货币交易所 Coinbase 计划最早于今年上市

消息人士称,Coinbase 可能会在今年晚些时候或明年年初进行上市,并警告说计划仍可能会发生变化。消息人士补充说,该公司尚未向美国证券交易委员会(SEC)登记上市意向,但一直在就聘请投行和律所进行谈判。Coinbase 成立于 2012 年,是全球最知名的加密货币平台之一,拥有超过 3500 万用户。

来源:新浪美股

拍一拍:如果真能上市,那一定是极大的利好。

曾经创建独立 Linux 发行版 Solus 的开发人员 Ikey Doherty 宣布了他的新项目:Serpent OS。

Serpent OS 是一个不想被归类为“轻量级、用户友好、注重隐私的 Linux 桌面发行版”。

相反,Serpent OS 具有“与主流产品不同的目标”。具体怎么样?请继续阅读。

Serpent OS:制作“真正现代”的 Linux 发行版

Serpent 采用发行版优先,兼容靠后的方法。这使他们可以做出一些非常大胆的决定。

Ikey 表示,这个项目不会对阻碍 Linux 的负面角色容忍。例如,不会容忍 NVIDIA 在其 GPU 上缺乏对 Wayland 加速的支持,并将 NVIDIA 专有驱动加入发行版黑名单。

这是 Serpent Linux 项目的拟议计划(摘自其网站):

  • 不再分割 usrbin
  • 100% clang 构建(包括内核)
  • musl 作为 libc,依靠编译器优化而不是内联 asm
  • 使用 libc++ 而不是 libstdc++
  • LLVM 的 binutils 变体(lld、as 等)
  • 混合源代码/二进制分发
  • 从 x86\_64 通用基线转移到更新的 CPU,包括针对 Intel 和 AMD 的优化
  • 包管理器中基于功能的订阅(硬件/用户选择等)
  • 只支持 UEFI。不支持老式启动方式
  • 完全开源,包括引导程序/重建脚本
  • 针对高工作负载进行了认真的优化
  • 第三方应用仅依赖于容器。没有兼容性修改
  • 仅支持 Wayland。将调查通过容器的 X11 兼容性
  • 完全无状态的管理工具和上游补丁

Ikey 大胆地宣称 Serpent Linux 不是 Serpent GNU/Linux,因为它不再依赖于 GNU 工具链或运行时。

Serpent OS 项目的开发将于 7 月底开始。没有确定最终稳定版本的时间表。

要求过高?但是 Ikey 过去做到了

你可能会怀疑 Serpent OS 是否会出现,是否能够兑现其所作的所有承诺。

但是 Ikey Doherty 过去已经做到了。如果我没记错的话,他首先基于 Debian 创建了 SolusOS。他于 2013 年停止了基于 Debian 的 SolusOS 的开发,甚至它还没有进入 Beta 阶段。

然后,他从头开始创建 evolve OS,而不是使用其他发行版作为基础。由于某些命名版权问题,项目名称已更改为 Solus(是的,相同的旧名称)。Ikey 在 2018 年退出了 Solus 项目,其他开发人员现在负责该项目。

Solus 是一个独立的 Linux 发行版,它为我们提供了漂亮的 Budgie 桌面环境。

Ikey 过去做到了(当然,在其他开发人员的帮助下)。他现在也应该能够做到。

看好还是不看好?

你如何看待这个 Serpent Linux?你是否认为是时候让开发人员采取大胆的立场,并着眼于未来开发操作系统,而不是坚持过去?请分享你的观点。


via: https://itsfoss.com/serpent-os-announcement/

作者:Abhishek Prakash 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Delve 是能让调试变成轻而易举的事的万能工具包。

你上次尝试去学习一种新的编程语言时什么时候?你有没有持之以恒,你是那些在新事物发布的第一时间就勇敢地去尝试的一员吗?不管怎样,学习一种新的语言也许非常有用,也会有很多乐趣。

你尝试着写简单的 “Hello, world!”,然后写一些示例代码并执行,继续做一些小的修改,之后继续前进。我敢保证我们都有过这个经历,不论我们使用哪种技术。假如你尝试用一段时间一种语言,并且你希望能够精通它,那么有一些事物能在你的进取之路上帮助你。

其中之一就是调试器。有些人喜欢在代码中用简单的 “print” 语句进行调试,这种方式很适合代码量少的简单程序;然而,如果你处理的是有多个开发者和几千行代码的大型项目,你应该使用调试器。

最近我开始学习 Go 编程语言了,在本文中,我们将探讨一种名为 Delve 的调试器。Delve 是专门用来调试 Go 程序的工具,我们会借助一些 Go 示例代码来了解下它的一些功能。不要担心这里展示的 Go 示例代码;即使你之前没有写过 Go 代码也能看懂。Go 的目标之一是简单,因此代码是始终如一的,理解和解释起来都很容易。

Delve 介绍

Delve 是托管在 GitHub 上的一个开源项目。

它自己的文档中写道:

Delve 是 Go 编程语言的调试器。该项目的目标是为 Go 提供一个简单、全功能的调试工具。Delve 应该是易于调用和易于使用的。当你使用调试器时,事情可能不会按你的思路运行。如果你这样想,那么你不适合用 Delve。

让我们来近距离看一下。

我的测试系统是运行着 Fedora Linux 的笔记本电脑,Go 编译器版本如下:

$ cat /etc/fedora-release
Fedora release 30 (Thirty)
$
$ go version
go version go1.12.17 linux/amd64
$

Golang 安装

如果你没有安装 Go,你可以运行下面的命令,很轻松地就可以从配置的仓库中获取。

$ dnf install golang.x86_64

或者,你可以在安装页面找到适合你的操作系统的其他安装版本。

在开始之前,请先确认已经设置好了 Go 工具依赖的下列各个路径。如果这些路径没有设置,有些示例可能不能正常运行。你可以在 SHELL 的 RC 文件中轻松设置这些环境变量,我的机器上是在 $HOME/bashrc 文件中设置的。

$ go env | grep GOPATH
GOPATH="/home/user/go"
$
$ go env | grep GOBIN
GOBIN="/home/user/go/gobin"
$

Delve 安装

你可以像下面那样,通过运行一个简单的 go get 命令来安装 Delve。go get 是 Golang 从外部源下载和安装需要的包的方式。如果你安装过程中遇到了问题,可以查看 Delve 安装教程

$ go get -u github.com/go-delve/delve/cmd/dlv
$

运行上面的命令,就会把 Delve 下载到你的 $GOPATH 的位置,如果你没有把 $GOPATH 设置成其他值,那么默认情况下 $GOPATH$HOME/go 是同一个路径。

你可以进入 go/ 目录,你可以在 bin/ 目录下看到 dlv

$ ls -l $HOME/go
total 8
drwxrwxr-x. 2 user user 4096 May 25 19:11 bin
drwxrwxr-x. 4 user user 4096 May 25 19:21 src
$
$ ls -l ~/go/bin/
total 19596
-rwxrwxr-x. 1 user user 20062654 May 25 19:17 dlv
$

因为你把 Delve 安装到了 $GOPATH,所以你可以像运行普通的 shell 命令一样运行它,即每次运行时你不必先进入它所在的目录。你可以通过 version 选项来验证 dlv 是否正确安装。示例中安装的版本是 1.4.1。

$ which dlv
~/go/bin/dlv
$
$ dlv version
Delve Debugger
Version: 1.4.1
Build: $Id: bda606147ff48b58bde39e20b9e11378eaa4db46 $
$

现在,我们一起在 Go 程序中使用 Delve 来理解下它的功能以及如何使用它们。我们先来写一个 hello.go,简单地打印一条 Hello, world! 信息。

记着,我把这些示例程序放到了 $GOBIN 目录下。

$ pwd
/home/user/go/gobin
$
$ cat hello.go
package main

import "fmt"

func main() {
        fmt.Println("Hello, world!")
}
$

运行 build 命令来编译一个 Go 程序,它的输入是 .go 后缀的文件。如果程序没有语法错误,Go 编译器把它编译成一个二进制可执行文件。这个文件可以被直接运行,运行后我们会在屏幕上看到 Hello, world! 信息。

$ go build hello.go
$
$ ls -l hello
-rwxrwxr-x. 1 user user 1997284 May 26 12:13 hello
$
$ ./hello
Hello, world!
$

在 Delve 中加载程序

把一个程序加载进 Delve 调试器有两种方式。

在源码编译成二进制文件之前使用 debug 参数

第一种方式是在需要时对源码使用 debug 命令。Delve 会为你编译出一个名为 __debug_bin 的二进制文件,并把它加载进调试器。

在这个例子中,你可以进入 hello.go 所在的目录,然后运行 dlv debug 命令。如果目录中有多个源文件且每个文件都有自己的主函数,Delve 则可能抛出错误,它期望的是单个程序或从单个项目构建成单个二进制文件。如果出现了这种错误,那么你就应该用下面展示的第二种方式。

$ ls -l
total 4
-rw-rw-r--. 1 user user 74 Jun  4 11:48 hello.go
$
$ dlv debug
Type 'help' for list of commands.
(dlv)

现在打开另一个终端,列出目录下的文件。你可以看到一个多出来的 __debug_bin 二进制文件,这个文件是由源码编译生成的,并会加载进调试器。你现在可以回到 dlv 提示框继续使用 Delve。

$ ls -l
total 2036
-rwxrwxr-x. 1 user user 2077085 Jun  4 11:48 __debug_bin
-rw-rw-r--. 1 user user      74 Jun  4 11:48 hello.go
$

使用 exec 参数

如果你已经有提前编译好的 Go 程序或者已经用 go build 命令编译完成了,不想再用 Delve 编译出 __debug_bin 二进制文件,那么第二种把程序加载进 Delve 的方法在这些情况下会很有用。在上述情况下,你可以使用 exec 命令来把整个目录加载进 Delve 调试器。

$ ls -l
total 4
-rw-rw-r--. 1 user user 74 Jun  4 11:48 hello.go
$
$ go build hello.go
$
$ ls -l
total 1956
-rwxrwxr-x. 1 user user 1997284 Jun  4 11:54 hello
-rw-rw-r--. 1 user user      74 Jun  4 11:48 hello.go
$
$ dlv exec ./hello
Type 'help' for list of commands.
(dlv)

查看 delve 帮助信息

dlv 提示符中,你可以运行 help 来查看 Delve 提供的多种帮助选项。命令列表相当长,这里我们只列举一些重要的功能。下面是 Delve 的功能概览。

(dlv) help
The following commands are available:

Running the program:

Manipulating breakpoints:

Viewing program variables and memory:

Listing and switching between threads and goroutines:

Viewing the call stack and selecting frames:

Other commands:

Type help followed by a command for full documentation.
(dlv)

设置断点

现在我们已经把 hello.go 程序加载进了 Delve 调试器,我们在主函数处设置断点,稍后来确认它。在 Go 中,主程序从 main.main 处开始执行,因此你需要给这个名字提供个 break 命令。之后,我们可以用 breakpoints 命令来检查断点是否正确设置了。

不要忘了你还可以用命令简写,因此你可以用 b main.main 来代替 break main.main,两者效果相同,bpbreakpoints 同理。你可以通过运行 help 命令查看帮助信息来找到你想要的命令简写。

(dlv) break main.main
Breakpoint 1 set at 0x4a228f for main.main() ./hello.go:5
(dlv) breakpoints
Breakpoint runtime-fatal-throw at 0x42c410 for runtime.fatalthrow() /usr/lib/golang/src/runtime/panic.go:663 (0)
Breakpoint unrecovered-panic at 0x42c480 for runtime.fatalpanic() /usr/lib/golang/src/runtime/panic.go:690 (0)
        print runtime.curg._panic.arg
Breakpoint 1 at 0x4a228f for main.main() ./hello.go:5 (0)
(dlv)

程序继续执行

现在,我们用 continue 来继续运行程序。它会运行到断点处中止,在我们的例子中,会运行到主函数的 main.main 处中止。从这里开始,我们可以用 next 命令来逐行执行程序。请注意,当我们运行到 fmt.Println("Hello, world!") 处时,即使我们还在调试器里,我们也能看到打印到屏幕的 Hello, world!

(dlv) continue
> main.main() ./hello.go:5 (hits goroutine(1):1 total:1) (PC: 0x4a228f)
     1: package main
     2:
     3: import "fmt"
     4:
=>   5:      func main() {
     6:         fmt.Println("Hello, world!")
     7: }
(dlv) next
> main.main() ./hello.go:6 (PC: 0x4a229d)
     1: package main
     2:
     3: import "fmt"
     4:
     5: func main() {
=>   6:              fmt.Println("Hello, world!")
     7: }
(dlv) next
Hello, world!
> main.main() ./hello.go:7 (PC: 0x4a22ff)
     2:
     3: import "fmt"
     4:
     5: func main() {
     6:         fmt.Println("Hello, world!")
=>   7:      }
(dlv)

退出 Delve

你随时可以运行 quit 命令来退出调试器,退出之后你会回到 shell 提示符。相当简单,对吗?

(dlv) quit
$

Delve 的其他功能

我们用其他的 Go 程序来探索下 Delve 的其他功能。这次,我们从 golang 教程 中找了一个程序。如果你要学习 Go 语言,那么 Golang 教程应该是你的第一站。

下面的程序,functions.go 中简单展示了 Go 程序中是怎样定义和调用函数的。这里,我们有一个简单的把两数相加并返回和值的 add() 函数。你可以像下面那样构建程序并运行它。

$ cat functions.go
package main

import "fmt"

func add(x int, y int) int {
        return x + y
}

func main() {
        fmt.Println(add(42, 13))
}
$

你可以像下面那样构建和运行程序。

$ go build functions.go  && ./functions
55
$

进入函数

跟前面展示的一样,我们用前面提到的一个选项来把二进制文件加载进 Delve 调试器,再一次在 main.main 处设置断点,继续运行程序直到断点处。然后执行 next 直到 fmt.Println(add(42, 13)) 处;这里我们调用了 add() 函数。我们可以像下面展示的那样,用 Delve 的 step 命令从 main 函数进入 add() 函数。

$ dlv debug
Type 'help' for list of commands.
(dlv) break main.main
Breakpoint 1 set at 0x4a22b3 for main.main() ./functions.go:9
(dlv) c
> main.main() ./functions.go:9 (hits goroutine(1):1 total:1) (PC: 0x4a22b3)
     4:
     5: func add(x int, y int) int {
     6:         return x + y
     7: }
     8:
=>   9:      func main() {
    10:         fmt.Println(add(42, 13))
    11: }
(dlv) next
> main.main() ./functions.go:10 (PC: 0x4a22c1)
     5: func add(x int, y int) int {
     6:         return x + y
     7: }
     8:
     9: func main() {
=>  10:              fmt.Println(add(42, 13))
    11: }
(dlv) step
> main.add() ./functions.go:5 (PC: 0x4a2280)
     1: package main
     2:
     3: import "fmt"
     4:
=>   5:      func add(x int, y int) int {
     6:         return x + y
     7: }
     8:
     9: func main() {
    10:         fmt.Println(add(42, 13))
(dlv)

使用文件名:行号来设置断点

上面的例子中,我们经过 main 函数进入了 add() 函数,但是你也可以在你想加断点的地方直接使用“文件名:行号”的组合。下面是在 add() 函数开始处加断点的另一种方式。

(dlv) break functions.go:5
Breakpoint 1 set at 0x4a2280 for main.add() ./functions.go:5
(dlv) continue
> main.add() ./functions.go:5 (hits goroutine(1):1 total:1) (PC: 0x4a2280)
     1: package main
     2:
     3: import "fmt"
     4:
=>   5:      func add(x int, y int) int {
     6:         return x + y
     7: }
     8:
     9: func main() {
    10:         fmt.Println(add(42, 13))
(dlv)

查看当前的栈信息

现在我们运行到了 add() 函数,我们可以在 Delve 中用 stack 命令查看当前栈的内容。这里在 0 位置展示了栈顶的函数 add() ,紧接着在 1 位置展示了调用 add() 函数的 main.main。在 main.main 下面的函数属于 Go 运行时,是用来处理加载和执行该程序的。

(dlv) stack
0  0x00000000004a2280 in main.add
   at ./functions.go:5
1  0x00000000004a22d7 in main.main
   at ./functions.go:10
2  0x000000000042dd1f in runtime.main
   at /usr/lib/golang/src/runtime/proc.go:200
3  0x0000000000458171 in runtime.goexit
   at /usr/lib/golang/src/runtime/asm_amd64.s:1337
(dlv)

在帧之间跳转

在 Delve 中我们可以用 frame 命令实现帧之间的跳转。在下面的例子中,我们用 frame 实现了从 add() 帧跳到 main.main 帧,以此类推。

(dlv) frame 0
> main.add() ./functions.go:5 (hits goroutine(1):1 total:1) (PC: 0x4a2280)
Frame 0: ./functions.go:5 (PC: 4a2280)
     1: package main
     2:
     3: import "fmt"
     4:
=>   5:      func add(x int, y int) int {
     6:         return x + y
     7: }
     8:
     9: func main() {
    10:         fmt.Println(add(42, 13))
(dlv) frame 1
> main.add() ./functions.go:5 (hits goroutine(1):1 total:1) (PC: 0x4a2280)
Frame 1: ./functions.go:10 (PC: 4a22d7)
     5: func add(x int, y int) int {
     6:         return x + y
     7: }
     8:
     9: func main() {
=>  10:              fmt.Println(add(42, 13))
    11: }
(dlv)

打印函数参数

一个函数通常会接收多个参数。在 add() 函数中,它的入参是两个整型。Delve 有个便捷的 args 命令,它能打印出命令行传给函数的参数。

(dlv) args
x = 42
y = 13
~r2 = 824633786832
(dlv)

查看反汇编码

由于我们是调试编译出的二进制文件,因此如果我们能查看编译器生成的汇编语言指令将会非常有用。Delve 提供了一个 disassemble 命令来查看这些指令。在下面的例子中,我们用它来查看 add() 函数的汇编指令。

(dlv) step
> main.add() ./functions.go:5 (PC: 0x4a2280)
     1: package main
     2:
     3: import "fmt"
     4:
=>   5:      func add(x int, y int) int {
     6:         return x + y
     7: }
     8:
     9: func main() {
    10:         fmt.Println(add(42, 13))
(dlv) disassemble
TEXT main.add(SB) /home/user/go/gobin/functions.go
=>   functions.go:5  0x4a2280   48c744241800000000   mov qword ptr [rsp+0x18], 0x0
        functions.go:6  0x4a2289   488b442408           mov rax, qword ptr [rsp+0x8]
        functions.go:6  0x4a228e   4803442410           add rax, qword ptr [rsp+0x10]
        functions.go:6  0x4a2293   4889442418           mov qword ptr [rsp+0x18], rax
        functions.go:6  0x4a2298   c3                   ret
(dlv)

单步退出函数

另一个功能是 stepout,这个功能可以让我们跳回到函数被调用的地方。在我们的例子中,如果我们想回到 main.main 函数,我们只需要简单地运行 stepout 命令,它就会把我们带回去。在我们调试大型代码库时,这个功能会是一个非常便捷的工具。

(dlv) stepout
> main.main() ./functions.go:10 (PC: 0x4a22d7)
Values returned:
        ~r2: 55

     5: func add(x int, y int) int {
     6:         return x + y
     7: }
     8:
     9: func main() {
=>  10:              fmt.Println(add(42, 13))
    11: }
(dlv)

打印变量信息

我们一起通过 Go 教程 的另一个示例程序来看下 Delve 是怎么处理 Go 中的变量的。下面的示例程序定义和初始化了一些不同类型的变量。你可以构建和运行程序。

$ cat variables.go
package main

import "fmt"

var i, j int = 1, 2

func main() {
        var c, python, java = true, false, "no!"
        fmt.Println(i, j, c, python, java)
}
$

$ go build variables.go &&; ./variables
1 2 true false no!
$

像前面说过的那样,用 delve debug 在调试器中加载程序。你可以在 Delve 中用 print 命令通过变量名来展示他们当前的值。

(dlv) print c
true
(dlv) print java
"no!"
(dlv)

或者,你还可以用 locals 命令来打印函数内所有的局部变量。

(dlv) locals
python = false
c = true
java = "no!"
(dlv)

如果你不知道变量的类型,你可以用 whatis 命令来通过变量名来打印它的类型。

(dlv) whatis python
bool
(dlv) whatis c
bool
(dlv) whatis java
string
(dlv)

总结

现在我们只是了解了 Delve 所有功能的皮毛。你可以自己去查看帮助内容,尝试下其它的命令。你还可以把 Delve 绑定到运行中的 Go 程序上(守护进程!),如果你安装了 Go 源码库,你甚至可以用 Delve 导出 Golang 库内部的信息。勇敢去探索吧!


via: https://opensource.com/article/20/6/debug-go-delve

作者:Gaurav Kamathe 选题:lujun9972 译者:lxbwolf 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出