月度归档:2019年03月

linux下DDD进行调试

在嵌入式程序开发过程中,程序员要进行大量的调试,以此验证程序的正确性,修改潜在的错误。调试器对于程序员来说是不可或缺的必备工具。在Linux环境 中,有很多调试工具和调试辅助工具,例如GDB、XXGDB、RHIDE、XWPE、GVD和DDD等。其中,DDD是命令行调试器的图形前端,除了一般 的程序调试功能以外,还具有交互式图形数据显示的功能。它在嵌入式应用开发中也十分出色。本文主要讲述DDD(Data Display Debugger)的使用方法。

1.认识DDD

GNU DDD是命令行调试程序,如GDB、DBX、WDB、Ladebug、JDB、XDB、Perl Debugger或Python Debugger的可视化图形前端。它特有的图形数据显示功能(Graphical Data Display)可以把数据结构按照图形的方式显示出来。DDD最初源于1990年Andreas Zeller编写的VSL结构化语言,后来经过一些程序员的努力,演化成今天的模样。DDD的功能非常强大,可以调试用C\C++、Ada、 Fortran、Pascal、Modula-2和Modula-3编写的程序;可以超文本方式浏览源代码;能够进行断点设置、回溯调试和历史纪录编辑;具有程序在终端运行的仿真窗口,并在远程主机上进行调试的能力;图形数据显示功能(Graphical Data Display)是创建该调试器的初衷之一,能够显示各种数据结构之间的关系,并将数据结构以图形化形式显示;具有GDB/DBX/XDB的命令行界面,包括完全的文本编辑、历史纪录、搜寻引擎。

DDD是开源软件,用户可以去http://www.cs.tubs.de/softech/ddd/下载.rpm格式的DDD源码文件。

图1显示的是DDD的主窗口。它主要由选单栏、工具条、数据窗口、源文件窗口、机器码窗口、控制台和命令工具窗口等几部分组成。其中,数据窗口用于观察复杂的数据结构,在删除数据之后,显示仍然有效;源文件窗口显示源代码、断点和当前执行到达的位置,选择该窗口中的“Display”项,可以显示任意表达式的值;机器码窗口显示当前所选函数的机器代码,但仅对于GDB来说是可用的;在Debugger控制台里,用户可以与DDD内置调试器的命令行接口进行交互,等同于执行命令工具栏中的命令。


图1 DDD的主窗口

2.DDD运行机理

在设计DDD的时候,主创人员决定把它与GDB之间的耦合度尽可能降小。因为像GDB这样的开源软件,更新要比商业软件快。所以为了使GDB的变化不会影响到DDD,在DDD中,GDB是作为独立的进程运行的,通过命令行接口与DDD进行交互。

DDD 的运行机理如图2所示。它显示了用户、DDD、GDB和被调试进程之间的关系。为了使响应时间变小,DDD和GDB之间的所有通信都是异步进行的。在 DDD中发出的GDB命令都会与一个回调例程相连,放入命令队列中。这个回调例程在合适的时间会处理GDB的输出。例如,如果用户手动输入一条GDB的命令,DDD就会把这条命令与显示GDB输出的一个回调例程连起来。一旦GDB命令完成,就会触发回调例程,GDB的输出就会显示在DDD的命令窗口中。


图2 DDD的运行机理

DDD 在事件循环时等待用户输入和GDB输出,同时等着GDB进入等待输入状态。当GDB可用时,下一条命令就会从命令队列中取出,送给GDB。GDB到达的输出由上次命令的回调过程来处理。这种异步机制避免了DDD在等待GDB输出时发生阻塞现象,到达的事件可以在任何时间得到处理。

DDD和GDB的分离使得DDD运行速度变慢,但这种方法还有很多好处。例如,用户可以把GDB调试器换成其它调试器,如DBX等。另外,还可以在不同的机器上运行GDB和DDD。

3. DDD调试示例

现在就用DDD来实际调试下面sample.c这段程序,为了节省空间,去掉了所有的注释。

#include <stdio.h>
#include <stdlib.h>

#define MAXINPUTSTRINGSIZE 5
int n;
int factn;
char resultstring[100]; 

int getInt()
{
	char * inputString;
	int inputInt;
	inputString = (char *) malloc (MAXINPUTSTRINGSIZE * sizeof(char));
	printf("Enter the value:");
	fgets(inputString, MAXINPUTSTRINGSIZE, stdin);
	printf("You entered %s\n", inputString);
	inputInt = atoi(inputString);
	return inputInt;
}

int computeFact(int n)
{
	int accum=0;
	while(n>1) {
		accum *= n;
		n--;
	}
	return accum;
}

char * buildResultString(int x, int factx)
{
	char * resultString = (char *) malloc(100 * sizeof(char));
	sprintf(resultString, "The factorial of %d is %d\n", x, factx);
	return resultString;
}

void main(int argc, char * argv[])
{
	char * outString;  // The string we will print out
	n = getInt();
	factn = computeFact(n);
	outString = buildResultString(n, factn);
	printf("%s\n",outString);
}

首先,使用下面的命令编译sample.c,切记要使用“-g”选项生成调试信息:
#gcc -g -o sample sample.c

接着运行sample程序,输入数值“5”后,可以看到如下结果:
You entered 5
The factorial of 5 is 0

可以看出,上面程序中是有错误的,需要进行调试。输入下面的命令启动DDD调试器,调试这个可执行程序:
#ddd sample

一段时间之后,DDD的主窗口就会出现。找到怀疑出错的地方,在相应的代码上设置断点(在有怀疑的行上单击鼠标左键,然后单击工具栏中的“Break”按钮)。然后单击命令工具栏上的运行按钮或在选单栏“Commands”里选择运行相关命令,如图3所示。


图3 使用DDD进行调试

在控制台中提示符下输入数字“5”后按回车键,就会运行到图3中箭头指示的位置。这时候检查可疑变量accum的值,在控制台提示后输入下面的命令:
(gdb) display accum

接着往下单步运行,多次点击工具栏中的“Step”按钮,观察变量accum的结果。具体参考如下:

(gdb) step
43 while(n>1) {
1: accum = 0
(gdb)
44 accum *= n;
1: accum = 0
(gdb)
45 n--;
1: accum = 0
(gdb)
43 while(n>1) {
1: accum = 0
(gdb)
44 accum *= n;
1: accum = 0
(gdb)
45 n--;
1: accum = 0

可以看出问题出在accum上。这时点击命令工具栏上的“Kill”按钮将程序断掉,把初始化accum的那一句改为“int accum = 1;”。重新运行之后,发现结果正确。至此,调试过程完毕。

   4. 特殊功能

上面只是粗略地介绍了DDD调试的方法。实际上,DDD还有一些与众不同的功能,例如可视化显示数据结构(单个结构体、二叉树、链表等)和绘制数据集等。

图4就是按点集绘制的数组sval中保存的数据(首先在源码窗口选中要显示的数组,然后点击工具栏中的“Plot”按钮,即会出现绘制窗口)。用户也可以不按数据点集显示,在弹出窗口选单“Plot”下选择“Lines”,就可以显示成连线段。这个功能非常直观,对于程序员调试程序来说是有很大帮助作用的。


图4 绘制数据集

DDD包含的内容不止这些,由于篇幅的限制,这里就不多说了。希望能起到抛砖引玉的作用。如果用户想进一步学习,可以参考DDD的用户手册。

 

  1. 调试前的准备工作:制作一个程序文档,作为我们后面调试的对象

    打开终端命令行窗口,输入命令vi test.c,建立test.c文件

  2. 在test.c文件中输入一些C语言的程序数据,DDD工具可以调试很多种程序设置基于的代码,本文只以C语言作为说明对象,其它的有兴趣的可以去参考研究

  3. 把test.c文件编译成可以执行的文件test,命令:gcc -g -o test test.c,注意一定要带-g参数,否则生成的可执行文件中没有必要的调试信息,最终使用DDD工具不能调试

  4. 运行DDD调试工具,直接输入命令ddd就可以打开DDD工具

  5. DDD工具打开后如下图所示,上面空白部分为代码区,和工具区,分割线下面是调试生成信息区

  6. 点击菜单栏上的“文件”----->“打开程序”,准备打开我们上面准备的test.c文件

  7. 在打开程序框中,定位到我们要调试的程序的目录下,在Files列表下选择我们要调试 信息,之后点击左下方的打开按钮

  8. 调试程序打开后,在代码区可以看到我们的代码,因为中文显示有点问题,其它都正常,右边的一些按钮是我们调试要用的工具

  9. 在代码区点鼠标右键,会弹出如图所示的菜单,我们可以给程序设置断点等,点击工具区里面的Run按钮,可以执行程序,在下面的调试信息区可以看到程序的执行结果。

宇宙最强调试器DDD

在写程序的时候,经常会遇到一些问题,比如某些变量计算结果不是我们预期的那样,这时我们需要对程序进行调试。本文主要介绍调试C/C++在Linux操作系统下主要的调试工具。

在Linux下写程序,C/C++主要的编译器有GCC/G++,ICC等,像我等穷码农,最喜欢GCC了,很大原因是他免费!所以,我们以GCC/G++为例介绍主要的调试工具。

分以下几个内容介绍:

1、调试之前的工作

2、选择调试工具

3、调试步骤

调试之前的工作
编译器在编译阶段需要产生可供调试的代码,才能被调试器调试。可以如下做:

gcc -g -ggdb ./yourcode.c -o yourapp.exe

这样编译代码可以产生供gdb调试的符号信息。
选择调试工具
gdb当时我们要使用的调试工具,不过他是命令行中使用的,多少有点不方便。

CGDB和DDD都是基于GDB开发的,他们只是增加了更加容易交互的界面。其中CGDB也是在命令行中使用的,使用方式与GDB一样,只是增加了代码显示的界面。

DDD也是GNU开发的,他也是基于GDB的,只是使用了可视化界面,比CGDB更加容易操作。

在有些情况下,我的Linux上可能没有装X-Sever,这样就没有图形显示功能,此时我们只能用命令行方式使用调试工具,所以gdb和cgdb应用更广泛些。一般我会使用CGDB,他的操作跟gdb完全类似,很容易上手。

调试
使用下面的命令启动程序。

cgdb ./youapp.exe

注意,这里我们使用的是cgdb,如果你没有安装cgdb,首先应该安装它!ubuntu用户的安装方式如下:
sudo apt-get install cgdb

启动软件后,常用的几个命令因该熟练掌握:
1、设置断点命令,程序在执行时遇到断点会停下来,执行停止后可以进行变量值的检查。

break [line_number]

例如:break youcode.cpp:32,这个命令是说在youcode.cpp第32行代码处设置断点,程序运行至此时会停下来。
2、显示变量的值,程序在断点处停止时可以打印变量的值。

print [var]

例如:print a,这句命令表示打印变量a的值。print也可以缩写成p。
3、单步执行,程序在断点处停止后,使用单步调试命令让程序一步步往下执行。使用next命令可以完成这个任务,可以缩写为n。

4、进入内部,在调试过程中,如果想进入某个函数的内部,则可使用step命令。

5、继续执行到下一个断点处。使用continue命令可以完成这个任务。

以上命令是gdb调试时常用的命令,也是应该必须掌握的命令。如果你想知道更多如何使用这些命令,使用help command查看相关的帮助。

Linux主流调试器是gdb,但它是纯命令行界面的,调试起来不方便,我需要更强大的力量。在试用了各种工具之后,我相信我找到了,是的没错,就是它——宇宙最强调试器——DDD。


DDD介绍

DDD全称Data Display Debugger,当我第一次见到它时,它的界面着实让我吃了一惊,如此的简陋,如此的怪异,我甚至想立刻删了它,但是当我见识到它强大的功能时,我被深深的震撼了,如此的飘逸,如此的不羁,我的脑海中突然想到了一个词来形容它——犀利!

没错,就是这么犀利,它是gdb的最优图形化前端,它继承了gdb的所有功能,它还加入了数据结构可视化能力,什么一维二维栈数组,二叉三叉N叉树,DDD统统都能用图形显示出来。

小伙子,你还在为调试犯愁么,你还在为红黑树写了半天就是不对而沮丧么,如果你真的遇到了这样的问题,那么我想DDD一定适合你。

它含蓄深沉,它隽永内敛,它在百度上搜不到多少资料,它就是这么低调,这么孤寂,它等待着你去发现,去使用,去震撼这个世界,去拿起它的锋芒——傲视群雄!

DDD安装

嗯,说了这么多我想你一定累了,下面让我们来看看DDD的安装吧。 DDD可以从官网下载到。

下载解压我就不说了。在编译前先安装完依赖包,我的系统是CentOS 6.4,使用yum软件包管理器。

yum install openmotif.i686 ncurses-devel.i686 openmotif-devel.i686 gdb.i686

它当时开发时使用的gcc 3.x,现在大部分系统上都是gcc 4.4,不要告诉我你还在用零一年的机子。正因为这个缘故,必须修改一个地方才能编译成功,这也是官方推荐的修改方式。

编辑ddd/strclass.C文件,在头文件声明里加入#include <cstdio>

之后就很好办了,

  1. ./configure
  2. make
  3. sudo make install

安装完,运行命令ddd就可以打开了。

更改DDD字体

刚打开DDD界面你也许会这么想,这字体这么小,看来我需要把眼睛升级为钛合金的。

下面教大家设置DDD字体。DDD似乎无法识别/usr/share/fonts/内的各种系统字体,只能手动调节了。

yum install xorg-x11-apps-7.7-6.el6 xorg-x11-fonts-misc

这两个包必须安装,缺少前面的会导致DDD无法改变字体和大小,因为这个软件包里面有个工具叫xfontsel,这是DDD调节字体所必须的。缺少后面的就会导致DDD字体大小可调范围很小,因为只有两种大小让你选。

打开DDD字体选择页面,Edit => Preferences => Fonts,点一下Browse就会弹出xfontsel菜单,选择字体时fmly选fixed字体,ptSz开到230,只要更改这两项就可以了。你可以把Default Font、Variable Font之类的全改成这样的字体。然后重启DDD,世界瞬间变化了,字体够不够大?再将DDD全屏,怎么样,是不是从没有感觉到调试程序也是如此的痛快。

使用

DDD内嵌gdb,你可以在窗口下方使用gdb的所有功能。在窗口上方是数据结构可视化窗口。看下面俩图。

 

在变量上点右键都是功能菜单,Display一下就能把变量显示到数据显示区域了。要是对二维数组Display的话,整个数组就呈现一个矩阵显示出来,还能将数组转置显示,对二叉树Display的话会把当前节点显示出来,再在节点上Display就能把下一个节点显示出来,二叉树结点可以这样一个个的显示出来,不用再在纸上画了。犀利!太犀利了!

上几张图你们感受一下。(DDD至强之图放在最后一节)

你以为这就完了?

DDD实力证明它是宇宙最强调试器。看图!

结语

DDD——让天下没有难调的程序

犀利!

-----------------------

linux下的程序调试方法汇总

       搞电子都知道,电路不是焊接出来的,是调试出来的。程序员也一定认同,程序不是写出来的,是调试出来的。那么调试工具就显得尤为重要,linux作为笔者重要的开发平台,在linux中讨论调试工具主要是为那些入门者提供一些帮助。调试工具能让我们能够监测、控制和纠正正在运行的程序。我们在运行一些程序的时候,可能被卡住或出现错误,或者运行过程或结果,没能如我们预期,此时,最迫切需要明白究竟发生了什么。为了修复程序,剖析和了解程序运行的细节, 调试工具就成为了我们的必备工具,工于善其事,必先利其器。在Linux下的用户空间调试工具主要有系统工具和专门调试工具:'print' 打印语句,这是新手最常用的,也是最不提倡使用的;查询 (/proc, /sys 等)系统的虚拟文件查看,这个方法有局限性;跟踪 (strace/ltrace)工具使用这个比较普遍,值得提倡;Valgrind (memwatch)内存排除工具,在内存排除方面比较独到,是内存排错的法宝;GDB大名鼎鼎的程序调试工具,这个是个全能的工具,没有完不成的,只有你不知道的。

1.'print' 语句

这是一个基本的调试问题的方法。 我们在程序中怀疑的地方插入print语句来了解程序的运行流程控制流和变量值的改变。 这是一个最简单的技术, 它的缺点。 需要进行程序编辑,添加'print'语句,必须重新编译,重新运行来获得输出。若需要调试的程序比较大,这将是一个耗时费力的方法。

2. 查询

在某些情况下,我们需要弄清楚在一个运行在内核中的进程的状态和内存映射。为了获得这些信息,我们不需要在内核中插入任何代码。 相反,可以用 /proc 文件系统。在/proc的伪文件系统,保留系统启动运行就收集的运行时信息 (cpu信息, 内存容量等)。

ls -l /proc'的输出结果,通过对 系统中运行的每一个进程在/proc文件系统中有一个以进程id命名的项。每个进程的细节信息可以在进程id对应的目录下的文件中获得。也可以'ls /proc/pid'的输出

解释/proc文件系统内的所有条目超出了本文的范围。一些有用的列举如下:

  • /proc/cmdline -> 内核命令行
  • /proc/cpuinfo -> 关于处理器的品牌,型号信息等
  • /proc/filesystems -> 文件系统的内核支持的信息
  • /proc/<pid>/cmdline -> 命令行参数传递到当前进程
  • /proc/<pid>/mem -> 当前进程持有的内存
  • /proc/<pid>/status -> 当前进程的状态

3. 跟踪

strace的和ltrace是两个在Linux中用来追踪程序的执行细节的跟踪工具。

strace:

strace拦截和记录系统调用及其接收的信号。对于用户,它显示了系统调用、传递给它们的参数和返回值。strace的可以附着到已在运行的进程或一个新的进程。它作为一个针对开发者和系统管理员的诊断、调试工具是很有用的。它也可以用来当做一个通过跟踪不同的程序调用来了解系统的工具。这个工具的好处是不需要源代码,程序也不需要重新编译。

使用strace的基本语法是:

strace 命令

strace有各种各样的参数。可以检查看strace的手册页来获得更多的细节。

strace的输出非常长,我们通常不会对显示的每一行都感兴趣。我们可以用'-e expr'选项来过滤不想要的数据。

用 '-p pid' 选项来绑到运行中的进程.

用'-o'选项,命令的输出可以被重定向到文件。

strace过滤成只有系统调用的输出

ltrace:

ltrace跟踪和记录一个进程的动态(运行时)库的调用及其收到的信号。它也可以跟踪一个进程所作的系统调用。它的用法是类似与strace。

ltrace command

'-i' 选项在调用库时打印指令指针。

'-S' 选项被用来现实系统调用和库调用

所有可用的选项请参阅ltrace手册。

ltrace捕捉'STRCMP'库调用的输出

4. Valgrind

Valgrind是一套调试和分析工具。它的一个被广泛使用的默认工具——'Memcheck'——可以拦截malloc(),new(),free()和delete()调用。换句话说,它在检测下面这些问题非常有用:

  • 内存泄露
  • 重释放
  • 访问越界
  • 使用未初始化的内存
  • 使用已经被释放的内存等。

它直接通过可执行文件运行。

Valgrind也有一些缺点,因为它增加了内存占用,会减慢你的程序。它有时会造成误报和漏报。它不能检测出静态分配的数组的访问越界问题。

为了使用它,首先请下载并安装在你的系统上。可以使用操作系统上的包管理器来安装。

使用命令行安装需要解压缩和解包下载的文件。

  1. tar -xjvf valgring-x.y.z.tar.bz2 (where x.y.z is the version number you are trying to install)

进入新创建的目录(的valgrind-XYZ)内运行以下命令:

  1. ./configure
  2. make
  3. make install

让我们通过一个小程序(test.c)来理解valgrind怎么工作的:

  1. #include <stdio.h>
  2. void f(void)
  3. {
  4. int x = malloc(10 * sizeof(int));
  5. x[10] = 0;
  6. }
  7. int main()
  8. {
  9. f();
  10. return 0;
  11. }

编译程序:

  1. gcc -o test -g test.c

现在我们有一个可执行文件叫做'test'。我们现在可以用valgrind来检测内存错误:

  1. valgrind –tool=memcheck –leak-check=yes test

这是valgrind呈现错误的输出:

valgrind显示堆溢出和内存泄漏的输出

正如我们在上面看到的消息,我们正在试图访问函数f未分配的内存以及分配尚未释放的内存。

5. GDB

GDB是来自自由软件基金会的调试器。它对定位和修复代码中的问题很有帮助。当被调试的程序运行时,它给用户控制权去执行各种动作, 比如:

  • 启动程序
  • 停在指定位置
  • 停在指定的条件
  • 检查所需信息
  • 改变程序中的数据 等。

你也可以将一个崩溃的程序coredump附着到GDB并分析故障的原因。

GDB提供很多选项来调试程序。 然而,我们将介绍一些重要的选择,来感受如何开始使用GDB。

如果你还没有安装GDB,可以在这里下载:GDB官方网站。

编译程序:

为了用GDB调试程序,必须使用gcc的'-g'选项进行编译。这将以操作系统的本地格式产生调试信息,GDB利用这些信息来工作。

下面是一个简单的程序(example1.c)执行被零除用来显示GDB的用法:

  1. #include
  2. int divide()
  3. {
  4. int x=5, y=0;
  5. return x / y;
  6. }
  7. int main()
  8. {
  9. divide();
  10. }

展示GDB用法的例子

调用 GDB:

通过在命令行中执行'gdb'来启动gdb:

调用 gdb

调用后, 它将等待终端命令并执行,直到退出。

如果一个进程已经在运行,你需要将GDB连接到它上面,可以通过指定进程ID来实现。假设程序已经崩溃,要分析问题的原因,则用GDB分析core文件。

启动程序:

一旦你在GDB里面,使用'run'命令来启动程序进行调试。

给程序传参数:

使用'set args'给你的程序传参数,当程序下次运行时将获得该参数。'show args'将显示传递给程序的参数。

 

检查堆栈:

每当程序停止,任何人想明白的第一件事就是它为什么停止,以及怎么停在那里的。该信息被称为反向跟踪。由程序产生每个函数调用和局部变量,传递的参数,调用位置等信息一起存储在堆栈内的数据块种,被称为一帧。我们可以使用GDB来检查所有这些数据。 GDB从最底层的帧开始给这些帧编号。

  • bt: 打印整个堆栈的回溯
  • bt 打印n个帧的回溯
  • frame : 切换到指定的帧,并打印该帧
  • up : 上移'n'个帧
  • down : 下移'n'个帧 ( n默认是1)

 

检查数据:

程序的数据可以在里面GDB使用'print'命令进行检查。例如,如果'x'是调试程序内的变量,'print x'会打印x的值。

 

检查源码:

源码可以在GDB中打印。默认情况下,'list'命令会打印10行代码。

  • list : 列出'linenum'行周围的源码
  • list : 从'function'开始列出源码
  • disas : 显示该函数机器代码

 

停止和恢复程序:

使用GDB,我们可以在必要的地方设置断点,观察点等来停止程序。

  • break : 在'location'设置一个断点。当在程序执行到这里时断点将被击中,控制权被交给用户。
  • watch : 当'expr'被程序写入而且它的值发生变化时GDB将停止
  • catch : 当'event'发生时GDB停止
  • disable : 禁用指定断点
  • enable : 启用指定断点
  • delete : 删除 断点/观察点/捕获点。 如果没有传递参数默认操作是在所有的断点
  • step: 一步一步执行程序
  • continue: 继续执行程序,直到执行完毕

退出 GDB:

用'quit'命令还从GDB中退出。

GDB还有更多的可用选项。里面GDB使用help选项了解更多详情。

在GDB中获得帮助

 

总结

在这篇文章中,我们已经看到不同类型的Linux用户空间的调试工具。总结以上所有内容,如下是什么时候使用该什么的快速指南:

  • 基本调试,获得关键变量 - print 语句
  • 获取有关文件系统支持,可用内存,CPU,运行程序的内核状态等信息 - 查询 /proc 文件系统
  • 最初的问题诊断,系统调用或库调用的相关问题,了解程序流程 – strace / ltrace
  • 应用程序内存空间的问题 – valgrind
  • 检查应用程序运行时的行为,分析应用程序崩溃 – gdb

Arthas使用指南

Arthas 能为你做什么?

  • 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  • 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  • 遇到问题无法在预发 debug 一下,难道只能通过加日志再重新预发布吗?
  • 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现,怎么办?
  • 是否有一个全局视角来查看系统的运行状况?
  • 有什么办法可以监控到容器和中间件的实时运行状态?

Arthas 是基于 Greys 进行二次开发的全新在线诊断工具,利用Java6的Instrumentation特性,动态增强你所指定的类,获取你想要到的信息, 采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,让你在定位、分析诊断问题时看每一个操作都看起来是那么的 666

阿里已开源 https://github.com/alibaba/ar...

Arthas安装及使用

下载压缩包,上传到需要被诊断的机器, 解压缩

  • 安装: 执行 ./install.sh
  • 启动: 执行 ./as.sh pid

常用命令

dashboard

当前系统的实时数据面板

thread

查看当前 JVM 的线程堆栈信息

jvm

查看当前 JVM 的信息

sc

查看JVM已加载的类信息

sm

查看已加载类的方法信息

jad

反编译指定已加载类的源码

classloader

查看classloader的继承树,urls,类加载信息,使用classloader去getResource

monitor

方法执行监控

watch

方法执行数据观测

trace

方法内部调用路径,并输出方法路径上的每个节点上耗时

stack

输出当前方法被调用的调用路径

tt

方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测

reset

重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类

quit

退出当前 Arthas 客户端,其他 Arthas 客户端不受影响

shutdown

关闭 Arthas 服务端,所有 Arthas 客户端全部退出

dashboard

参数解释

ID: Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应

NAME: 线程名

GROUP: 线程组名

PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高

STATE: 线程的状态

CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。

TIME: 线程运行总时间

INTERRUPTE: 线程当前的中断位状态

DAEMON: 是否是daemon线程

thread

参数说明

id

线程id

-n

指定最忙的前N个线程并打印堆栈

b

找出当前阻塞其他线程的线程

-i

指定cpu占比统计的采样间隔,单位为毫秒

PS: 这里的cpu统计的是,一段采样间隔内,当前JVM里各个线程所占用的cpu时间占总cpu时间的百分比。其计算方法为: 首先进行一次采样,获得所有线程的cpu的使用时间(调用的是java.lang.management.ThreadMXBean#getThreadCpuTime这个接口),然后睡眠一段时间,默认100ms,可以通过-i参数指定,然后再采样一次,最后得出这段时间内各个线程消耗的cpu时间情况,最后算出百分比。注意: 这个统计也会产生一定的开销(JDK这个接口本身开销比较大),因此会看到as的线程占用一定的百分比,为了降低统计自身的开销带来的影响,可以把采样间隔拉长一些,比如5000毫秒。

sc

参数说明

class-pattern

类名表达式匹配

-d

输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。如果一个类被多个ClassLoader所加载,则会出现多次

-E

开启正则表达式匹配,默认为通配符匹配

-f

输出当前类的成员变量信息(需要配合参数-d一起使用)

-x

指定输出静态变量时属性的遍历深度,默认为 0,即直接使用 toString 输出

PS: class-pattern支持全限定名,如com.test.AAA,也支持com/test/AAA这样的格式,这样,我们从异常堆栈里面把类名拷贝过来的时候,不需要在手动把/替换为.啦,
sc 默认开启了子类匹配功能,也就是说所有当前类的子类也会被搜索出来,想要精确的匹配,请打开options disable-sub-class true开关

sm

参数说明

class-pattern

类名表达式匹配

method-pattern

方法名表达式匹配

-d
展示每个方法的详细信息

-E
开启正则表达式匹配,默认为通配符匹配

PS:查看已加载类的方法信息, “Search-Method” 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。
sm 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到

monitor

monitor 命令是一个非实时返回命令,实时返回命令是输入之后立即返回,而非实时返回的命令,则是不断的等待目标 Java 进程返回信息,直到用户输入 Ctrl+C 为止。服务端是以任务的形式在后台跑任务,植入的代码随着任务的中止而被不会被执行,所以任务关闭后,不会对原有性能产生太大影响,而且原则上,任何 Arthas 的命令也不会引起任何原有业务逻辑的改变

参数说明

class-pattern

类名表达式匹配

method-pattern

方法名表达式匹配

-c
统计周期,默认值为120秒

监控项

timestamp 时间戳
class java类
method 方法(构造方法、普通方法)
total 调用次数
success 成功次数
fail 失败次数
rt 平均rt
fail-rate 失败率

PS:方法执行监控, 对匹配 class-pattern/method-pattern的类、方法的调用进行监控。

trace

方法内部调用路径,并输出方法路径上的每个节点上耗时, trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。

trace 能方便的帮助你定位和发现因 RT 高而导致的性能问题缺陷,但其每次只能跟踪一级方法的调用链路

trace 在执行的过程中本身是会有一定的性能开销,在统计的报告中并未像 JProfiler 一样预先减去其自身的统计开销。所以这统计出来有些许的不准,渲染路径上调用的类、方法越多,性能偏差越大。但还是能让你看清一些事情的。

参数说明

class-pattern

类名表达式匹配

method-pattern

方法名表达式匹配

condition-express

条件表达式

-n

命令执行次数

#cost

方法执行耗时

PS: 很多时候我们只想看到某个方法的rt大于某个时间之后的trace结果,例如trace *StringUtils isBlank '$cost>100'表示当执行时间超过100ms的时候,才会输出trace的结果。

stack

输出当前方法被调用的调用路径, 很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。

参数说明

class-pattern

类名表达式匹配

method-pattern

方法名表达式匹配

condition-express

条件表达式

-n

执行次数限制

watch

方法执行数据观测, 让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 groovy 表达式进行对应变量的查看。

参数说明

class-pattern

类名表达式匹配

method-pattern

方法名表达式匹配

express

观察表达式

condition-express

条件表达式

-b
在方法调用之前观察(默认关闭)

-e
在方法异常之后观察(默认关闭)

-s
在方法返回之后观察(默认关闭)

-f
在方法结束之后(正常返回和异常返回)观察 (默认开启)

-x
指定输出结果的属性遍历深度,默认为0

PS:这里重点要说明的是观察表达式,观察表达式的构成主要由 groovy 表达式组成,只要是一个合法的 groovy 表达式,都能被正常支持。

观察的维度也比较多,主要体现在参数 advice 的数据结构上。Advice 参数最主要是封装了通知节点的所有信息。

来源: https://segmentfault.com/a/1190000014618329

---------------------------------

Java 诊断利器-Arthas的基本使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w57685321/article/details/84307516

简介

Arthas 是阿里巴巴最近才开源出来的一款 Java 诊断利器,它主要是针对线上环境,能够帮助我们更好的定位问题。
Case:https://github.com/alibaba/arthas/issues?q=label%3Auser-case
官方文档: https://alibaba.github.io/arthas
官方文档还是比较详细的,这里就挑几个觉得好用的来实操一下

实操

在这里插入图片描述
下载好后,目录是这样的,win运行bat脚本即可, as.bat +
在这里插入图片描述
pid可以通过jps命令找出来

package com.bfxy.springboot;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Demo {
    private static AtomicInteger count = new AtomicInteger(0);
    public static void increment() {
        count.incrementAndGet();
    }
    public static int value() {
        return count.get();
    }
    public static void main(String[] args) throws InterruptedException {
        while (true) {
            increment();
            System.out.println("counter: " + value());
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

然后写了个demo,attach上去
在这里插入图片描述
就到了启动界面

watch

方法执行数据观测
让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 OGNL 表达式进行对应变量的查看。
在这里插入图片描述
在这里插入图片描述
输入watch命令,监视Demo类中的value方法的返回值
在这里插入图片描述
发现跟这个是对应的,监控有效!
在这里插入图片描述
表达式使用”{params,returnObj}”,表示将入参和返回值打印出来,这里没有入参,result中的第一个@Object为空

trace

方法内部调用路径,并输出方法路径上的每个节点上耗时
trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。
在这里插入图片描述
查看调用increment方法的链路耗时
在这里插入图片描述
也可以使用通配符监控所有方法

sc

查看JVM已加载的类信息
“Search-Class” 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息,这个命令支持的参数有 [d]、[E]、[f] 和 [x:]。

在这里插入图片描述
在这里插入图片描述
打印出了类的详细信息,看case里面,通过这种方法可以更好的判断NoSuchMethodError的原因

jad

反编译指定已加载类的源码
jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻辑;

redefine

加载外部的.class文件,redefine jvm已加载的类。
注意, redefine后的原来的类不能恢复,redefine有可能失败(比如增加了新的field),参考jdk本身的文档。

这个命令可以结合上面的jad命令一起使用,当需要调试正在运行的程序时,先jad反编译,然后修改了再redefine上去

redefine实战日志打印捕获

这也是根据里面的case学到的

背景:
随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如:
在这里插入图片描述
这个程序是一个短信发送程序,由于连接不上ISMG网关而报的错误,使用的短信开发包比较老,是直接在控制台打印的,都没有使用日志,有点坑,这样看起来就比较烦了,都不知道从哪里打印的这个,找源码又太慢,现在使用Arthas来解决它

在java代码里,字符串拼接基本都是通过StringBuilder来实现的,所以把StringBuilder复制下来,然后在toString方法中修改一下

    @Override
    public String toString() {
        // Create a copy, don't share the array
        String result = new String(value, 0, count);
        if(result.contains("Connection refused")) {
            System.err.println(result);
            new Throwable().printStackTrace();
        }
        return result;
    }

这里加上一个判断,为异常字符串中的就打印出堆栈
然后javac StringBuilder.java编译
在这里插入图片描述
还是attach上这个程序后,通过redefine命令去修改StringBuilder字节码
在这里插入图片描述
程序的运行也发生改变,这个功能还是很强大,都可以运行中动态调试程序了

 

-----

快速入门

1. 启动Demo

wget https://alibaba.github.io/arthas/arthas-demo.jar
java -jar arthas-demo.jar

arthas-demo是一个简单的程序,每隔一秒生成一个随机数,再执行质因式分解,并打印出分解结果。

arthas-demo源代码:

2. 启动arthas

在命令行下面执行(使用和目标进程一致的用户启动,否则可能attach失败):

wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar
  • 执行该程序的用户需要和目标进程具有相同的权限。比如以admin用户来执行:sudo su admin && java -jar arthas-boot.jar 或 sudo -u admin -EH java -jar arthas-boot.jar
  • 如果attach不上目标进程,可以查看~/logs/arthas/ 目录下的日志。
  • 如果下载速度比较慢,可以使用aliyun的镜像:java -jar arthas-boot.jar --repo-mirror aliyun --use-http
  • java -jar arthas-boot.jar -h 打印更多参数信息。

选择应用java进程:

$ $ java -jar arthas-boot.jar
* [1]: 35542
[2]: 71560 arthas-demo.jar

Demo进程是第2个,则输入2,再输入回车/enter。Arthas会attach到目标进程上,并输出日志:

[INFO] Try to attach process 71560
[INFO] Attach process 71560 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki: https://alibaba.github.io/arthas
version: 3.0.5.20181127201536
pid: 71560
time: 2018-11-28 19:16:24
$

3. 查看dashboard

输入dashboard,按回车/enter,会展示当前进程的信息,按ctrl+c可以中断执行。

$ dashboard
ID NAME GROUP PRIORI STATE %CPU TIME INTERRU DAEMON
17 pool-2-thread-1 system 5 WAITIN 67 0:0 false false
27 Timer-for-arthas-dashb system 10 RUNNAB 32 0:0 false true
11 AsyncAppender-Worker-a system 9 WAITIN 0 0:0 false true
9 Attach Listener system 9 RUNNAB 0 0:0 false true
3 Finalizer system 8 WAITIN 0 0:0 false true
2 Reference Handler system 10 WAITIN 0 0:0 false true
4 Signal Dispatcher system 9 RUNNAB 0 0:0 false true
26 as-command-execute-dae system 10 TIMED_ 0 0:0 false true
13 job-timeout system 9 TIMED_ 0 0:0 false true
1 main main 5 TIMED_ 0 0:0 false false
14 nioEventLoopGroup-2-1 system 10 RUNNAB 0 0:0 false false
18 nioEventLoopGroup-2-2 system 10 RUNNAB 0 0:0 false false
23 nioEventLoopGroup-2-3 system 10 RUNNAB 0 0:0 false false
15 nioEventLoopGroup-3-1 system 10 RUNNAB 0 0:0 false false
Memory used total max usage GC
heap 32M 155M 1820M 1.77% gc.ps_scavenge.count 4
ps_eden_space 14M 65M 672M 2.21% gc.ps_scavenge.time(m 166
ps_survivor_space 4M 5M 5M s)
ps_old_gen 12M 85M 1365M 0.91% gc.ps_marksweep.count 0
nonheap 20M 23M -1 gc.ps_marksweep.time( 0
code_cache 3M 5M 240M 1.32% ms)
Runtime
os.name Mac OS X
os.version 10.13.4
java.version 1.8.0_162
java.home /Library/Java/JavaVir
tualMachines/jdk1.8.0
_162.jdk/Contents/Hom
e/jre

4. 通过thread命令来获取到arthas-demo进程的Main Class

thread 1会打印线程ID 1的栈,通常是main函数的线程。

$ thread 1 | grep 'main('
at demo.MathGame.main(MathGame.java:17)

5. 通过jad来反编译Main Class

$ jad demo.MathGame
ClassLoader:
+-sun.misc.Launcher$AppClassLoader@3d4eac69
+-sun.misc.Launcher$ExtClassLoader@66350f69
Location:
/tmp/arthas-demo.jar
/*
* Decompiled with CFR 0_132.
*/
package demo;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class MathGame {
private static Random random = new Random();
private int illegalArgumentCount = 0;
public static void main(String[] args) throws InterruptedException {
MathGame game = new MathGame();
do {
game.run();
TimeUnit.SECONDS.sleep(1L);
} while (true);
}
public void run() throws InterruptedException {
try {
int number = random.nextInt();
List<Integer> primeFactors = this.primeFactors(number);
MathGame.print(number, primeFactors);
}
catch (Exception e) {
System.out.println(String.format("illegalArgumentCount:%3d, ", this.illegalArgumentCount) + e.getMessage());
}
}
public static void print(int number, List<Integer> primeFactors) {
StringBuffer sb = new StringBuffer("" + number + "=");
Iterator<Integer> iterator = primeFactors.iterator();
while (iterator.hasNext()) {
int factor = iterator.next();
sb.append(factor).append('*');
}
if (sb.charAt(sb.length() - 1) == '*') {
sb.deleteCharAt(sb.length() - 1);
}
System.out.println(sb);
}
public List<Integer> primeFactors(int number) {
if (number < 2) {
++this.illegalArgumentCount;
throw new IllegalArgumentException("number is: " + number + ", need >= 2");
}
ArrayList<Integer> result = new ArrayList<Integer>();
int i = 2;
while (i <= number) {
if (number % i == 0) {
result.add(i);
number /= i;
i = 2;
continue;
}
++i;
}
return result;
}
}
Affect(row-cnt:1) cost in 970 ms.

6. watch

通过watch命令来查看demo.MathGame#primeFactors函数的返回值:

$ watch demo.MathGame primeFactors returnObj
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 107 ms.
ts=2018-11-28 19:22:30; [cost=1.715367ms] result=null
ts=2018-11-28 19:22:31; [cost=0.185203ms] result=null
ts=2018-11-28 19:22:32; [cost=19.012416ms] result=@ArrayList[
@Integer[5],
@Integer[47],
@Integer[2675531],
]
ts=2018-11-28 19:22:33; [cost=0.311395ms] result=@ArrayList[
@Integer[2],
@Integer[5],
@Integer[317],
@Integer[503],
@Integer[887],
]
ts=2018-11-28 19:22:34; [cost=10.136007ms] result=@ArrayList[
@Integer[2],
@Integer[2],
@Integer[3],
@Integer[3],
@Integer[31],
@Integer[717593],
]
ts=2018-11-28 19:22:35; [cost=29.969732ms] result=@ArrayList[
@Integer[5],
@Integer[29],
@Integer[7651739],
]

更多的功能可以查看进阶使用

7. 退出arthas

如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。

如果想完全退出arthas,可以执行shutdown命令。

 

基于Linux生态的十大AI开源框架盘点

前不久,雷锋网曾盘点了一系列机器学习相关的开源平台,包括谷歌的 TensorFlow、微软的 CNTK 以及百度的 PaddlePaddle 等等(详情见文末“相关阅读”)。这些平台各具特点,其中某些已经在业内得到了广泛认可和应用。

与此前不同,本文将从开发者的角度出发,特别是针对开发者中为数众多的 Linux 系统和 Mac 系统用户,奉上一篇针对泛 Linux 生态的顶级人工智能开源工具盘点(当然,有些工具也并非只兼容 Linux)。

1. Deeplearning4j:为 Java 用户量身定制

开发者必备:基于Linux生态的十大AI开源框架盘点

Deeplearning4j(Deep Learning For Java)是 Java 和 Scala 环境下的一个开源分布式的深度学习项目,由总部位于美国旧金山的商业智能和企业软件公司 Skymind 牵头开发,并得到了腾讯的投资。正如它的命名,Deeplearning4j 的运行需要 Java 虚拟机 JVM 的支持。

Deeplearning4j 团队在官网表示,他们希望通过一些深度学习算法的开发,将商业带入智能化数据的时代。也正是为了实现这一理想,惠及更多的用户,因此选择了移植性更好的 Java 环境来实现这些算法。目前,Deeplearning4j 的这些算法已经在谷歌、Facebook 和微软等平台得到了广泛应用。

值得一提的是,为了便于开发者自由定制,Deeplearning4j 已经开放了尽可能多的算法调节接口,并对接口参数做出了详尽解释。同时,Deeplearning4j 团队还开发了针对矩阵运算的 ND4J 和 ND4S 库(N-Dimensional Arrays for Java/Scala),同样需要 JVM 的支持。

Deeplearning4j 遵循 Apache 2.0 开源协议,提供了基于 AWS 云服务的 GPU 运算支持,以及微软服务器框架的支持。

官网:http://deeplearning4j.org/

2. Caffe:广受欢迎的深度学习框架

开发者必备:基于Linux生态的十大AI开源框架盘点

Caffe 的全称是 “Convolution Architecture For Feature Extraction”,意为“用于特征提取的卷积架构”,主要开发者来自伯克利大学的视觉与学习中心(Berkeley Vision and Learning Center,BVLC),基于 BSD 2-Clause 开源许可协议发布。

Caffe 是业内著名的深度学习框架,根据官网介绍,其主要特点是:运算速度快(官方显示在单片 NVIDIA K40 GPU 的运算能力下,Caffe 每天可以处理超过 60M 的图片数据),模块定制方便(在 CPU 或 GPU 之间的转换只需要简单修改一下参数设定),扩展能力强大(目前有超过一千名开发者基于 Caffe 开发了分支版本),以及丰富的社区支持(Caffe 已经被授权给各种研究机构、初创公司和工业集团),因此特别适合于神经网络建模和图像处理任务。

官网:http://caffe.berkeleyvision.org/

3. H2O:企业级机器学习框架

开发者必备:基于Linux生态的十大AI开源框架盘点

H2O(即水的化学式)是一个开源、快速、可扩展的分布式机器学习框架,同时提供了大量的算法实现。它支持深度学习、梯度推进(Gradient Boosting)、随机森林(Random Forest)、广义线性模型(即逻辑回归,弹性网络)等各种机器学习算法。

H2O 框架的核心代码由 Java 编写,数据和模型通过分布式的 key/value 存储在各个集群节点的内存中,算法使用 Map/Reduce 框架实现,并使用了 Java 中的 Fork/Join 机制来实现多线程。

H2O 是一个更关注企业用户的人工智能分析工具,它聚焦于为掌握大量数据的企业用户提供快速精准的预测分析模型,从海量数据中提取有助于商业决策的信息。

根据 H2O 官方的数据,目前已经有超过 7 万名数据科学家和 8 万家组织机构成为了 H2O 平台的忠实拥趸。

官网:http://www.h2o.ai/

4. MLlib:基于 Spark 框架的机器学习算法实现库

开发者必备:基于Linux生态的十大AI开源框架盘点

MLlib 是 Apache 开源项目 Spark 针对一些常用的机器学习算法的实现库,同时也包括了相关的测试程序和数据生成器。

按照官网的描述,MLlib 的主要特点是易用(天生兼容 Spark 框架的 API 接口和 Python、Java、Scala 等多种语言)、高性能(依靠 Spark 的数据管理能力,运行迭代和逻辑回归算法时比 Hadoop 框架快 100 倍)和易于部署(可以直接在现有的 Hadoop 数据集群上运行)。

MLlib 目前支持分类、回归、推荐、聚类、生存分析等多种机器学习算法。

官网:https://spark.apache.org/mllib/

5. Apache Mahout:Hadoop 广泛采用的机器学习开源框架

开发者必备:基于Linux生态的十大AI开源框架盘点

Apache Mahout 同样也是一个 Apache 开源项目,与 MLlib 相对应,Mahout 是应用在 Hadoop 平台下的机器学习开源框架。

Mahout 有如下三个主要特点:

1) 提供简单、可扩展的编程环境和框架;

2) 同时为 Scala Apache Spark、H2O 以及 Apache Flik 平台提供打包好的算法实现;

3) 支持R语言的语法规则进行矩阵计算。

官网:http://mahout.apache.org/

6. OpenNN:专注神经网络的实现库

开发者必备:基于Linux生态的十大AI开源框架盘点

OpenNN 的全称为“Open Neural Networks Library”,即开源神经网络库,其核心代码由 C 编写,从名字就可以看出,其主要面向深度学习领域,助力于用户构建各种不同的神经网络模型。

据官方描述,OpenNN 可用于实现监督学习场景中任何层次的非线性模型,同时还支持各种具有通用近似属性的神经网络设计。

除了模型的多层支持外,OpenNN 最主要优势还在于强大的性能表现。具体来说就是,OpenNN 能够通过 C 语言实现的核心代码高效地调节内容使用,通过 OpenMP 库很好地平衡多线程 CPU 调用,以及通过 CUDA 工具对 GPU 进行加速。

官网:http://www.opennn.net/

7. Oryx 2:重新设计了 Lambda 架构

开发者必备:基于Linux生态的十大AI开源框架盘点

Oryx 2 是 Oryx 项目的 2.0 版,前身名为 Myrrix,后来被大数据公司 Cloudera 收购,才改名为 Oryx。

Oryx 2.0 关注于大规模机器学习/预测分析基础框架的实时表现,它基于 Apache Spark 和 Apache Kafka 框架开发,并重新设计了 Lambda 架构,使得层次之间的复用性更强。

2. 0 版相比之前实现了更多算法,包括 ALS 协同过滤、随机森林、以及K-means 等。

官网:http://oryx.io/

8. OpenCyc:全球最庞大、最完备的通用型知识库与常识推理引擎

开发者必备:基于Linux生态的十大AI开源框架盘点

OpenCyc 是 Cycorp 公司推出的一个基于 Cyc 的开源版本,而 Cyc 是目前全球最庞大、最完备的通用型知识库与常识推理引擎。

OpenCyc 包含数十万个精心组织的 Cyc 词条。Cycorp 公司不但免费提供 OpenCyc,同时也鼓励开发者基于 OpenCyc 开发针对于特定应用领域的分支版本。

目前,OpenCyc 已经被成功应用在大数据建模、语言数据整合、智能文本理解、特定领域的专家系统建模和人工智能游戏。

官网:http://www.cyc.com/platform/opencyc/

9. Apache SystemML:专注于大数据分析的开源机器学习平台

开发者必备:基于Linux生态的十大AI开源框架盘点

SystemML 是一个利用机器学习算法进行大数据分析的开源 AI 平台,其主要特点是支持R语言和 Python 的语法,专注于大数据分析领域,以及专门为高阶数学计算设计。

按照官网的介绍,Apache SystemML 基于 Apache Spark 框架运行,其最大的特点就是能够自动、逐行地评估数据,并根据评估结果确定用户的代码应该直接运行在驱动器上还是运行在 Apache Spark 集群上。

除了 Apache Spark 之外,SystemML 还支持 Apache Hadoop、Jupyter 和 Apache Zeppelin 等多个平台。目前,SystemML 技术已经成功应用在交通、航空和金融等多个领域。

官网:http://systemml.apache.org/

10. NuPIC:基于层级实时存储算法的机器智能平台

开发者必备:基于Linux生态的十大AI开源框架盘点

NuPIC 是一个与众不同的开源机器智能平台,它基于一种大脑皮层理论,即“层级实时存储算法”(Heirarchical Temporary Memory,HTM)。NuPIC 聚焦于分析实时数据流,可以通过学习数据之间基于时间的状态变化,对未知数据进行预测,并揭示其中的非常规特性。

NuPIC 关键的功能特性包括:

1) 持续的在线学习:NuPIC 模型可以持续根据快速变化的数据流进行实时调整;

2) 时间和空间分析:像人脑一样,NuPIC 可以同时模拟时间和空间的变化;

3) 实时的数据流分析:智能化的数据分析不会随着数据量的增加而改变;

4) 预测和建模:通过通用性的大脑皮层算法,对数据进行预测、建模和学习;

5) 强大的异常检测能力:实时检测数据流的扰动,不依靠僵化的阈值设置和过时的算法;

6) 层级实时存储算法:支持全新的 HTM 计算架构。

官网:http://numenta.org/

由于 2016 仅仅是人工智能走向主流的元年,未来随着技术的进一步发展和革新,势必会出现更多、更丰富的开发工具。这里值得注意的一点是:工具的意义不仅在于解决了日常研发中遇到的各种问题,更在于降低了开发的难度,引导了更多人投入到人工智能的研发之中。雷锋网

 

来源:https://www.kzwr.com/article/339762

Kodi 中文版开源多媒体影音中心播放器

如果你是个高清电影爱好者,你一定会考虑如何将客厅的电脑打造成一台强大的家庭影院影音播放中心!然而,简单地接上电脑+键盘鼠标,对着电视上极小的窗口和字体操作半天绝对是一个“糟糕麻烦”的体验。

Kodi (原名 XBMC) 是一款经典免费开源、跨平台且极其强大专业的多媒体影音中心软件播放器,包含了专业的影音内容管理以及解码播放功能一体,提供适合在电视/投影/大屏幕上显示的全屏界面,无线手机遥控操作方式,以及功能相当丰富的插件扩展,绝对是打造家庭影院 (影音中心) 和私人电影库的必备神器!

Kodi - 用更优雅专业的方式来播放和管理电影视频音乐

Kodi 能带给你更优雅、舒适的观影体验,可以说是目前同类软件中当之无愧的 No·1。首先,免费开源跨平台+配置要求低的特性让 Kodi 不仅能在 Windows、Mac、Linux 电脑上使用,甚至在 Android、iOS 手机/平板以及像「树莓派」这样的微型电脑或很多安卓机顶盒(网络播放器)上流畅运行,兼容性和适用范围极广。

 

其次,Kodi 是一个万能格式高清播放器,支持解码播放几乎所有流行的音频和视频格式,3D、4K 高清什么的都没问题。它集电影视频、音乐、图片管理和播放于一身,不仅能读取本机硬盘、移动硬盘的影音内容,最重要的是它还能通过局域网播放和管理其他电脑、NAS (网络存储服务器) 里的内容。这使得任何人都能轻松将手头上的电脑设备变成客厅中强大无比的网络影音播放机。

 

再次,Kodi 专为大电视、大尺寸屏幕和投影优化的大字体全屏界面、可以通过手机 APP 实现无线遥控控制、支持 AirPlay / DLNA 无线投射串流等功能特性也让其更加实用方便。

 

不过,看到这里你可能还觉得它比起普通的播放器没什么特别之处,其实 Kodi 真正的亮点主要还是在于它丰富强大的插件扩展。

贴心强大的插件功能(自动下载电影字幕 / 更新电影封面和介绍信息等)

不夸张地说,丰富强大的插件才是 Kodi 之所以被称为神器的最主要的原因!得益于免费与开源的策略,全球无数开发者为 Kodi 制作了大量实用的插件,这些插件不仅让你的影音中心拥有更多新功能,最重要的是,它能让你看电影的流程变得更加傻瓜便捷!

举个例子,我们从 BT 下载的电影经常都是一串英文命名,辨别起来十分困难,手动改名字实在是麻烦。Kodi 可以通过不同的「刮削器」插件“自动化”地从豆瓣、时光网等国内外网站中匹配并下载电影的介绍信息 (包括电影名称、剧情介绍、导演、演员、封面图片),让你的视频库看起来超级详细漂亮,简直就像一个专业的视频网站,点播起来简直不能更舒服了!而这一切都是靠刮削器自动联网完成的。

 

另外,通过安装不同的「字幕插件」,还可以让 Kodi 播放电影时自动从不同的字幕网站中搜索匹配并下载字幕,这点对懒人来说就一句话——太 TM 爽了!再也不用为找字幕下载而发愁了。当然,Kodi 能做的事情远不止如此,它的插件库简直就像一个宝库,你总能在里面找到更多实用的扩展功能,譬如电视直播、在线音乐/视频点播、百度云网盘播放、以及各种换肤等等。

因此你完全可以根据自己的需求和喜好,选用不同的插件,配置打造出最适合自己使用的私人影音中心。相信我,只要你体验过 Kodi,你绝对不想回到以前对着电视上极小的字体操作半天,还要到处找字幕的“原始低效”的观影方式了。

Kodi (XBMC) 设置与使用入门教程

首先我们根据设备的操作系统下载相应版本的 Kodi 应用进行安装。目前,Kodi 支持 Windows、Mac、Linux 以及  Android、iOS (需越狱)。另外,还有一些专门用于运行 Kodi 的 Linux 整合版操作系统,启动后整个系统就是 Kodi,适合那些专用做播放器的场合。这些衍生系统常见的有 Kodibuntu (Ubuntu 与 Kodi 的整合版系统,PC适用)、OSMC (原 Raspbmc,整合 Debian 与 Kodi,树莓派适用) 等,大家可以根据需求选择。不同版本的 Kodi 的设置和使用方法均大同小异,部分插件也是通用的,大家可以参考下面的教程。

Kodi 设置成中文界面的方法 (解决显示乱码问题)

默认情况下,新安装好的 Kodi 启动后是英文版的界面。但事实上,Kodi 包含多国语言 (包含简繁体中文版),我们可以设置改回简体中文界面。不过,很多人都遇到修改 Kodi 的语言为中文之后整个界面显示乱码的问题,正确的设置方法如下:

  1. 启动 Kodi,进入 System -> Settings -> Appearance -> Skin,将其中的 Fonts 修改成 Arial Based (这是必须的,也是第一步首先要做的步骤,否则就会显示乱码)
  2. 然后再进入 System -> Settings -> International -> Language,选择 Chinese (Simple) 确定
  3. 进入 系统->设置->视频->字幕 “首选字幕语言” 以及“下载字幕语言”均选择 Chinese (Simple)

Kodi 怎样添加本机和网络上的电影(视频)、音乐、图片目录?

Kodi 可以添加本机的文件夹,也可以将局域网中其他电脑 / NAS 中的共享文件夹添加进来。也就是说,你可以非常方便地在客厅的 Kodi 中播放寝室电脑里或 NAS 中下载好的电影视频!加上 Kodi 支持各种平台,因此,你可以选用「安卓机顶盒」、「树莓派」、「Mac Mini」、笔记本或组装一台小型 Windows 电脑 (HTPC 迷你主机) 放在客厅用来做专用播放机。

添加视频源的方法如下:依次点击 视频 -> 文件 -> 添加视频... -> 浏览,可以看到你可以添加本机硬盘的目录,也能添加 SMB (Windows共享) 和 NFS (Mac 或 Linux 使用的共享协议) 的网络路径,在“添加网络位置...”选项里还能添加 HTTP、FTP、WebDAV 等网络路径。

 

Kodi 能自动搜索出某些局域网的共享目录,如果它找不到的话,那就需要手动指定一下了。如果共享需要用户名密码的话还是要正确输入的。选择好电影所在的文件夹后,便会出现如下图的窗口,nfs://xxxx 那个是我的 NAS 的 IP 和电影文件所在的文件夹路径,底部可以为这个“视频源”命名,然后确定下一步。

 

在最后一步时,我们会看到 Kodi 弹出「设置内容」的窗口,这里可以设置该目录包含电影、剧集、音乐哪种内容,而右边还有一个「选择刮削器」的列表。这个刮削器(插件)是 Kodi 的一大特色,下面我们将会介绍什么是刮削器,并介绍怎么安装 Kodi 的插件。

Kodi 安装电影刮削器插件教程 - 自动联网下载电影海报与简介信息 (豆瓣/时光网)

Kodi 最为强大之处便是支持各种第三方插件,而且插件数量巨多,可以实现看电影几乎所有的周边功能。其中「刮削器」插件可以让 Kodi 匹配目录中的影音文件,并自动从网上下载对应的图文信息对它们进行补充,让你的影音库显得更加“精美专业”。下面以安装「豆瓣电影刮削器」为例子作为介绍吧:

 

如上图,在左边的「该目录包含」一列下,点击上下箭头按钮为目录设置成「电影」类别,这时右边就会列出可用的刮削器了,不过 Kodi 自带的这两对我们都没啥用,点击「获取更多...」,然后 Kodi 就会从它的网上插件库中搜索可下载的刮削器了,其中 douban(豆瓣) 或 MTime(时光网) 就是咱们需要的,按喜好选择即可。其他的大多数是英文的网站,并没有中文信息。

 

不过在截稿时,我发现豆瓣刮削器无法获取电影封面图片,时光网刮削器则无问题,大家可以自己试试。选择之后,点击「安装」即可。之后我们就能回到目录的「设置内容」窗口来启用这个刮削器了。

 

应用了刮削器之后,Kodi 便会扫描目录下的文件,并从网上下载对应的电影信息,如果文件较多的话需要一定的时间,待电影信息更新完毕之后,我们的电影库就变得非常酷了!如下图:

 

我们不仅可以在点播前看看电影简介、海报、预告片,还能按照电影类型、年份之类的进行分类筛选。如果日后文件有增删改动,或者某个电影匹配不出来或匹配错的话也可以手动查询进行修改。另外,除了电影之外,「音乐」同样也有刮削器可以使用,自动下载音乐专辑封面什么的也是一样的,大家可以去试试。

安装 Kodi 电影中文字幕下载插件和更多其他中文插件

在 Kodi 中,默认已经提供了一个联网的「在线插件库」可以供你下载各种各样的插件了。我们可以在 “系统->插件->从库安装” 的列表里面浏览。

 

库里有各种类型的插件可供下载,如下图,插件也是分类放置的,大家可以自己挖掘一下。其中「信息提供者」一类就是上面提到的「刮削器」了,从这个入口进来安装其实也是一样的。不过,你会发现,默认的插件库大多都是英文内容的插件,主要是因为 Kodi 官方插件库的维护者都是老外。而「字幕」一类里原本唯一能支持中文字幕下载的 “Shooter” (射手网) 插件又因网站的关停已经不可用了,所以我们必须另寻办法。

好在 Kodi 足够的开放,除了 Kodi 自带的插件库外,我们还可以自己添加由国人维护的「Kodi 中文插件库」,这些中文插件库里面就包含了各种适合国情的中文插件,其中就有一些中文字幕插件了,当然还有些其他的福利。下面,我们就来说说怎样为 Kodi 添加中文的插件库吧。

Kodi 添加中文插件库安装教程:

  1. 下载最新的 Kodi 中文插件库安装文件,目前有两个中文插件库可以选择,分别是「Chinese Add-ons Repository - repository.xbmc-addons-chinese.zip」和「HDPFans 中文插件库 - repository.hdpfans.xbmc-addons-chinese.zip」。不同的库里面提供了不同的插件,推荐大家把这两个库都装上吧,日后想安装什么插件也方便一些。
  2. 注意文件下载回去后不要解压,如果是安装到手机/平板或电视盒上的 Kodi,请把文件拷贝到该设备中。
  3. 启动 Kodi,进入 “系统->插件”,这次要点击「从 ZIP 文件安装」,然后选择刚才下载的 zip 文件,待 Kodi 更新完毕,对应的插件库即安装完成。
  4. 再次进入 “系统->插件->从库安装”,此时便会在库列表中看到多出新安装的库了,如下图,多出的Chinese Add-ons 和 HDPfans 中文插件库就是我刚安装上去的。(最下面那个 Kodi Add-on repository 是 Kodi 官方自带的英文插件库)。

“Chinese Add-ons” 中文库为例,点击进入后,选择「字幕」一类,就能看到 163sub、Sub HD、Subom、zimuku 字幕库等字幕网站的插件了,按喜欢选择安装即可。这个中文插件库里还有很多实用的插件,譬如豆瓣电视剧刮削器、优酷视频、Bilibili哔哩哔哩、爱奇艺、乐视、CNTV 电视直播、搜狐视频等视频插件以及 一听音乐、酷狗、酷我音乐盒、百度、豆瓣电台等音乐插件,还算比较丰富。

而“HDPFans 中文插件库”里面则提供了 MyCloud (百度云、115网盘、迅雷离线等网盘视频图片音乐播放器器)、HDP电视直播、斗鱼直播、115影库、HDP 优酷高清、HDP 公开课、百度云视频等等插件。两个插件库的内容说多不多说少不少,大家根据自己的兴趣去试用吧。

说回 Kodi 的字幕搜索插件,在成功安装后,只需在播放界面中点击右下方的第一个「字幕」图标,选择下载,即能联网进行字幕搜索,即会自动下载并加载显示,总体使用体验非常的方便快捷。而且往往还有多个不同版本的字幕可供选择。

反正,比起平时要到电脑上开启浏览器去访问字幕网站,搜索、下载、解压、拷贝等繁杂的步骤,Kodi + 字幕插件的方式简直是方便到极点。

AirPlay 和 DLNA 无线串流投影以及开启方法

除了可以播放电脑和 NAS 上的视频音乐外, Kodi 还有一个非常好用的功能—— AirPlay 和 UPnP / DLNA 支持。 AirPlay 是苹果的无线音乐视频投射技术,原本需要购买 AppleTV 才能享受这个功能,而利用 Kodi 则可以完全免费实现。

AirPlay 可以将 iPhone / iPad 上的视频或音乐通过 WiFi 直接串流到 Kodi 上播放,如果你把 Kodi 装在客厅大电视和音响上,那么你一定会深深感到这个技术是多么的方便,它能让你手机平板的影音内容轻松跨屏播放。DLNA 也是类似的技术,Android 和 Windows 等设备只能用它,个人认为从易用性和方便性,还是苹果的 AirPlay 更胜一筹。

Kodi 默认并没有启动 AirPlay / DLNA 的支持,需要手动启用。首先进入“系统->服务->ZeroConf”,打开「向其他系统声明服务」的选项。如果提示“启动 ZeroConf 失败”的错误,请在安装了苹果 iTunes 软件后再试。在成功开启“向其他系统声明服务”之后,进入“系统->服务->AirPlay”,允许「启用 AirPlay 支持」即可。(另外,“UPnP / DLNA” 也可以在设置里开启)

不过,Kodi 的 AirPlay 功能仅能用于播放视频和音乐,无法实现屏幕镜像和玩游戏等高级功能。但大多时候这已经够用了,手边有苹果设备的朋友不妨玩一玩吧。

Kodi for Android / iOS 手机版、平板版

Kodi 除了 PC、Mac 和 Linux 的桌面版应用外,同时也提供了 iOS 以及 Android 版,可在手机和平板上运行。它们的界面和操作几乎和 PC 版完全一致,就不多做介绍了,只不过,iOS 版的 Kodi 需要越狱后才能安装。

Kodi Android 安卓版截图

Kodi 同样可以轻松将你的平板或手机变成一个强劲的多媒体中心!当然, 最合适不过的还是在各种安卓电视机顶盒上安装 Kodi 了,绝对能让你的盒子的功能提升一个级别!应该各大盒子的论坛都会有相应的教程吧。

Kodi 手机无线遥控器 APP

为了让 Kodi 更适合在客厅、影音室等场合方便地使用,Kodi 不仅支持很多硬件的遥控器,而且官方还提供了免费的 iOS 和 Android 的远程控制 APP,可以将手机、平板变成 Kodi 的无线遥控器!这个比起拿着鼠标在沙发上的使用体验要强太多了,你甚至还能直接在手机上看到你的影音库并进行选片播放。

安装好 Kodi 的遥控器 APP 之后,只需填写 Kodi 所在的正确 IP 地址和端口号即可连接使用。另外,Kodi 其实还可以通过 WEB 进行异地远程控制,不过个人感觉有些鸡肋,就不多介绍了。一般家里使用,遥控器足以应付自如。

总结:

Kodi 完全免费而且开源,集播放、管理于一体,本身播放能力优异,还可借由各种插件增强功能,可配置性强,能根据自己的需要和喜爱,轻松地将电脑变成一台超级好用的专属网络影音播放机。

对于打算 DIY HTPC、搭建家庭影院以及高清电影爱好者而言,Kodi 是一款绝对不应错过的多媒体中心应用。它的强大、方便之处绝能让你心动!当你用过 Kodi 之后,你一定会爱上他……

 

来源:https://www.iplaysoft.com/kodi.html