[erlang-questions] Creating a diagnostic memory dump of live erlang VM

Hynek Vychodil vychodil.hynek@REDACTED
Sat Feb 22 12:34:16 CET 2014


Hi,
one of the greatest engineering rules is: If it works, don't touch it. And
I'm far far away to teach anybody how to code but it itches. So I did some
touches here

============

-module(report).

-export([crash_report/0, crash_report/1, make_report/0]).

crash_report() ->
    crash_report("/tmp/erl_crash.dump").

crash_report(FileName) ->
    file:write_file(FileName, make_report()).

make_report() ->
    Date = rfc1123_local_date(),
    Header = iolist_to_binary([<<"=erl_crash_dump:0.2\n">>, Date,
<<"\nSystem version: ">>]),
    Ets = ets_info(),
    [
        Header,
        erlang:system_info(system_version),
        erlang:system_info(info),
        erlang:system_info(procs),
        Ets,
        erlang:system_info(dist),
        <<"=loaded_modules\n">>,
        binary:replace(erlang:system_info(loaded), <<"\n">>, <<"\n=mod:">>,
[global])
        ].

ets_info() ->
    [ets_table_info(T) || T<-ets:all()].

ets_table_info(Table) ->
    Info = ets:info(Table),
    Owner = pid_to_list(proplists:get_value(owner, Info)),
    Name = atom_to_list(proplists:get_value(name, Info)),
    Objects = integer_to_list(proplists:get_value(size, Info)),
    iolist_to_binary([
            <<"=ets:">>, Owner,
            <<"\nTable: ">>, Name,
            <<"\nName: ">>, Name,
            <<"\nObjects: ">>, Objects, $\n
            ]).

rfc1123_local_date() ->
    rfc1123_local_date(os:timestamp()).

rfc1123_local_date({A, B, C}) ->
    rfc1123_local_date(calendar:now_to_local_time({A, B, C}));
rfc1123_local_date({{YYYY, MM, DD}, {Hour, Min, Sec}}) ->
    DayNumber = calendar:day_of_the_week({YYYY, MM, DD}),
    io_lib:format(
        "~s, ~2.2.0w ~3.s ~4.4.0w ~2.2.0w:~2.2.0w:~2.2.0w GMT",
        [httpd_util:day(DayNumber), DD, httpd_util:month(MM), YYYY, Hour,
Min, Sec]
        );
rfc1123_local_date(Epoch) when erlang:is_integer(Epoch) ->

rfc1123_local_date(calendar:gregorian_seconds_to_datetime(Epoch+62167219200)).

==========

No wonder they are telling Erlang has bad string support if they see code
like previous. I think iolist is one of most powerful structures for
manipulating strings and one of strengths of Erlang so we should use it and
use it well. Converting list or iolist to binary over and over again is
very bad idea. It is very slow and doesn't saves any memory until GC
occurs. These two calls to iolist_to_binary/1 in code above is unnecessary
but shows the idea. Call it early when make string which you are not
intended to touch and is big enough to save memory but most importantly
never ever call it again until you have a very good reason to do. It would
make unnecessary copying. Let Erlang io subsystem do the rest.

Sorry for this rant but it was itchy
With best regards
    Hynek Vychodil


On Fri, Feb 21, 2014 at 4:47 AM, Matthew Evans <mattevans123@REDACTED>wrote:

> Hi,
>
> I took it on myself to write a little module. This will produce a crash
> report that will display most of the important data that can be loaded into
> the crash dump viewer. From Erlang run report:crash_report().
>
> The crash dump goes to /tmp/erl_crash.dump and can be viewed from Erlang
> via your browser when you run crashdump_viewer:start(). from your Erlang
> shell.
>
> =========
>
> -module(report).
>
> -export([crash_report/0]).
>
> crash_report() ->
>     Date = erlang:list_to_binary(rfc1123_local_date()),
>     Header =
> binary:list_to_bin([<<"=erl_crash_dump:0.2\n">>,Date,<<"\nSystem version:
> ">>]),
>     Ets = ets_info(),
>     Report =
> binary:list_to_bin([Header,erlang:list_to_binary(erlang:system_info(system_version)),erlang:system_info(info),erlang:system_info(procs),Ets,erlang:system_info(dist),
>
> <<"=loaded_modules\n">>,binary:replace(erlang:system_info(loaded),<<"\n">>,<<"\n=mod:">>,[global])]),
>     file:write_file("/tmp/erl_crash.dump",Report).
>
> ets_info() ->
>     binary:list_to_bin([ets_table_info(T)||T<-ets:all()]).
>
> ets_table_info(Table) ->
>     Info = ets:info(Table),
>     Owner =
> erlang:list_to_binary(erlang:pid_to_list(proplists:get_value(owner,Info))),
>     TableN =
> erlang:list_to_binary(erlang:atom_to_list(proplists:get_value(name,Info))),
>     Name =
> erlang:list_to_binary(erlang:atom_to_list(proplists:get_value(name,Info))),
>     Objects =
> erlang:list_to_binary(erlang:integer_to_list(proplists:get_value(size,Info))),
>     binary:list_to_bin([<<"=ets:">>,Owner,<<"\nTable:
> ">>,TableN,<<"\nName: ">>,Name,<<"\nObjects: ">>,Objects,<<"\n">>]).
>
> rfc1123_local_date() ->
>     rfc1123_local_date(os:timestamp()).
> rfc1123_local_date({A,B,C}) ->
>     rfc1123_local_date(calendar:now_to_local_time({A,B,C}));
> rfc1123_local_date({{YYYY,MM,DD},{Hour,Min,Sec}}) ->
>     DayNumber = calendar:day_of_the_week({YYYY,MM,DD}),
>     lists:flatten(
>         io_lib:format("~s, ~2.2.0w ~3.s ~4.4.0w ~2.2.0w:~2.2.0w:~2.2.0w
> GMT",
>
> [httpd_util:day(DayNumber),DD,httpd_util:month(MM),YYYY,Hour,Min,Sec]));
> rfc1123_local_date(Epoch) when erlang:is_integer(Epoch) ->
>
> rfc1123_local_date(calendar:gregorian_seconds_to_datetime(Epoch+62167219200)).
>
>
> ------------------------------
> From: vladdu55@REDACTED
> Date: Thu, 20 Feb 2014 10:30:39 +0100
> To: mabrek@REDACTED
> CC: erlang-questions@REDACTED
> Subject: Re: [erlang-questions] Creating a diagnostic memory dump of live
> erlang VM
>
>
> Hi,
>
> On Thu, Feb 20, 2014 at 9:26 AM, Anton Lebedevich <mabrek@REDACTED>wrote:
>
> Another thing which I missed a lot after converting from java to erlang
> is a thread dump. It turned out that it's possible to get all
> stacktraces for all processes (even with function arguments) via
> erlang:system_info(procs).
>
> It returns them as text so it's better to dump it to file immediately:
> file:write_file("/tmp/procs.txt",erlang:system_info(procs)).
>
> Format of these traces is quite interesting (undocumented) the best
> description I found is in the mailing list
> http://erlang.org/pipermail/erlang-questions/2012-November/070609.html
>
>
> I might just as well ask the obvious question: why is not this information
> available even as normal Erlang terms, so that one doesn't need to parse
> it? When writing a crash dump, it doesn't matter, but if it should be used
> at runtime it's a pain to parse it... This applies to the other results
> from system_info/1 that are dumped as text.
>
> regards,
> Vlad
>
>
> _______________________________________________ erlang-questions mailing
> list erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140222/ee87f98e/attachment.htm>


More information about the erlang-questions mailing list