Archive

Posts Tagged ‘debug’

How to Build a Debug Enabled Erlang RunTime System

May 7th, 2010 1 comment

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: How to Build a Debug Enabled Erlang RunTime System

很多朋友在问如何调试Erlang的驱动代码等等,其实otp源码下的INSTALL.md写的很清楚, 摘抄下:
How to Build a Debug Enabled Erlang RunTime System
————————————————–

After completing all the normal building steps described above a debug
enabled runtime system can be built. To do this you have to change
directory to `$ERL_TOP/erts/emulator`.
注:一定要注意这句话, 假设你现在在otp源码目录下,正常编译好了, export ERL_TOP=`pwd` 然后进入erts/emulator目录下

In this directory execute:

$ make debug FLAVOR=$FLAVOR

where `$FLAVOR` is either `plain` or `smp`. The flavor options will
produce a beam.debug and beam.smp.debug executable respectively. The
files are installed along side with the normal (opt) versions `beam.smp`
and `beam`.

To start the debug enabled runtime system execute:

$ $ERL_TOP/bin/cerl -debug

The debug enabled runtime system features lock violation checking,
assert checking and various sanity checks to help a developer ensure
correctness. Some of these features can be enabled on a normal beam
using appropriate configure options.

There are other types of runtime systems that can be built as well
using the similar steps just described.

$ make $TYPE FLAVOR=$FLAVOR

where `$TYPE` is `opt`, `gcov`, `gprof`, `debug`, `valgrind`, or `lcnt`.
These different beam types are useful for debugging and profiling
purposes.

祝玩的开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: , ,

escript的高级特性

November 25th, 2009 7 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: escript的高级特性

escript Erlang scripting support, 可以让erl模块转身变成unix script来使用,大大方便用户,具体的使用参看otp文档。我这里要演示的是些比较被忽视的高级特性:

首先crack erts/etc/common/escript.c:33 static int debug = 1; 让之显示调用参数。

root@nd-desktop:~# cat >factorial
[color=red]#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname factorial -mnesia debug verbose[/color]
main([String]) ->
try
N = list_to_integer(String),
F = fac(N),
io:format("factorial ~w = ~w\n", [N,F])
catch
_:_ ->
usage()
end;
main(_) ->
usage().

usage() ->
io:format("usage: factorial integer\n"),
halt(1).

fac(0) -> 1;
fac(N) -> N * fac(N-1).

CTRL+D

root@nd-desktop:~# chmod +x factorial
root@nd-desktop:~# ./factorial  10

[color=red]erl +B -boot start_clean -noshell -smp enable -sname factorial -mnesia debug verbose -run escript start -extra ./factorial 10[/color]
factorial 10 = 3628800

特性1:

摘抄文档。。。
On the third line (or second line depending on the presence of the Emacs directive), it is possible to give arguments to the emulator, such as

%%! -smp enable -sname factorial -mnesia debug verbose

Such an argument line must start with %%! and the rest of the line will interpreted as arguments to the emulator.

我们可以看到 这些选项被传递给了 erl

特性2:
-mode(compile).

这个选项是在escript.erl这个模块处理的。默认情况下 escript是被解释执行的,如果你的脚本很复杂,那么效率估计会是瓶颈。这种情况下, 你可以通过这个选项来让escript来先编译你的模块成opcode, 在vm里面运行。

特性3:
-d 选项 用来调试script的
-c 编译执行
-i 解释执行
-s 只检查不执行
root@nd-desktop:~# escript -d ./factorial 10
我们就可以看到 调试界面如下图
escript_debug

特性4:
可以把一个beam文件作为script

root@nd-desktop:/usr/src# cat hello.erl
-module(hello).
-export([start/0,main/1]).

main(_)->
start().

start()->
io:format("hello world~n",[]).
root@nd-desktop:/usr/src# erlc hello.erl
root@nd-desktop:/usr/src# cat >hello
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname factorial -mnesia debug verbose

CTRL+D

root@nd-desktop:/usr/src# cat hello.beam >>hello
root@nd-desktop:/usr/src# chmod +x hello
root@nd-desktop:/usr/src# ./hello
hello world

特性5:
可以把一个zip文件作为script

root@nd-desktop:/usr/src# cat hello.erl
-module(hello).
-export([start/0,main/1]).

main(_)->
start().

start()->
io:format("hello world, fac(10)=~w ~n",[fac:fac(10)]).
root@nd-desktop:/usr/src# cat fac.erl
-module(fac).
-export([fac/1]).

fac(0) ->
1;
fac(N) -> N * fac(N-1).
root@nd-desktop:/usr/src# erlc *.erl
root@nd-desktop:/usr/src# erl
Erlang R13B03 (erts-5.7.4)
[smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
1> zip:zip("hello.zip", ["hello.beam", "fac.beam"]).
{ok,"hello.zip"}
2>
root@nd-desktop:/usr/src# cat >hello
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname factorial -mnesia debug verbose -escript main hello

CTRL+D

root@nd-desktop:/usr/src# cat hello.zip >>hello
root@nd-desktop:/usr/src# chmod +x hello
root@nd-desktop:/usr/src# ./hello
hello world, fac(10)=3628800

特性6:
在独立的包里面 把escript伪装成我们的应用程序

root@nd-desktop:/usr/src# cat >hello.escript
-module(hello).
-export([start/0,main/1]).

main(_)->
start().

start()->
io:format("hello world~n",[]).

CTRL+D

root@nd-desktop:/usr/src#  cp `which escript` hello
root@nd-desktop:/usr/src# ./hello
hello world

规则是 escript 改名成xxxx 执行xxxx的时候 实际上要读取的脚本是 xxxx.escript

综述: escript是很强大的 未来的erlang standalone全靠它。

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: , , , ,

如何用gdb调试erlang运行期(高级)

October 11th, 2009 4 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 如何用gdb调试erlang运行期(高级)

前些天在erlang的源码里面闲逛的时候发现了 bin目录下的cerl,一看原来是个调试的高级货。

我之前写过一篇文章http://mryufeng.javaeye.com/blog/113852 如何调试erlang 但是这是土八路的方法, cerl才是现代化工业。

# This is a script to start Erlang/OTP for debugging. PATH is set to
# include this script so if slave nodes are started they will use this
# script as well.
#
# usage: cerl [ OPTIONS ] [ ARGS ]
#
# The OPTIONS are
#
# -rootdir $MYROOTDIR
# Run an installed emulator built from this source
# -debug Run debug compiled emulator
# -gdb Run the debug compiled emulator in emacs and gdb.
# You have to start beam in gdb using “run”.
# -break F Run the debug compiled emulator in emacs and gdb and set break.
# The session is started, i.e. “run” is already don for you.
# -xxgdb FIXME currently disabled
# -purify Run emulator compiled for purify
# -quantify Run emulator compiled for quantify
# -purecov Run emulator compiled for purecov
# -gcov Run emulator compiled for gcov
# -valgrind Run emulator compiled for valgrind
# -lcnt Run emulator compiled for lock counting
# -nox Unset the DISPLAY variable to disable us of X Windows
#

要使用cerl 我们最好准备个调试版本的erlang。R13B 修正了些编译错误,可以编译出debug版本的系统:./configure && make TYPE=debug && make

这样就生成了个beam.debug的运行期。

我们要调试的时候 就可以在otp的binx目录下运行 cerl -debug -gdb -break main

这时候cerl自动会加载 emacs 启动 gud, 整个过程都是自动的。但是这个脚本有点小问题, gud模型下没有把源码和当前对应的调试对应起来。可以通过以下方式修正:

yu-fengdemacbook-2:bin yufeng$ diff cerl cerl2
284c284
<     exec $EMACS --eval "(progn (gdb \"gdb $EMU\") $gdbcmd)"
---
>     exec $EMACS --eval "(progn (gdb \"gdb --annotate=3  $EMU\") $gdbcmd)"

具体的操作和界面可以参照这篇文章:
http://www.nabble.com/printing-of-Eterm%27s-from-gdb-td19240493.html

在调试的时候 我们会希望查看 eterm的值,但是由于eterm的格式非常复杂, gdb的print什么的无法满足我们的需求。 otp开发团队于是开发出了一套方法来减轻我们的负担:

1. erts/etc/unix/etp-commands 这是gdb的脚本 包含了几十个etp方法,而且文档非常详细。

2. 源码里面的 pp, ps等函数, 这些函数是专门为gdb调试开发的。 可以用gdb的 call pp(xxx)来调用。

有了这些工具 调试和研究erts变成了一件很快乐的事情!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: , , , ,