forked from erlang/otp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalgrind_beamasm_update.escript
executable file
·84 lines (77 loc) · 3.22 KB
/
valgrind_beamasm_update.escript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env escript
-mode(compile).
main([VGFile,PerfFile]) ->
{ok, Perf} = file:read_file(PerfFile),
{ok, VG} = file:read_file(VGFile),
file:write_file(VGFile,update_vg(VG, parse_perf(Perf))).
parse_perf(Perf) ->
%% Example: 0x409b1c0 84 $global::arith_compare_shared
lists:foldl(
fun(<<>>, Acc) ->
Acc;
(Line, Acc) ->
[<<"0x",Base/binary>>, Size, Name] = string:split(Line," ",all),
Acc#{ binary_to_integer(Base, 16) =>
{binary_to_integer(Size, 16), Name}}
end,#{},string:split(Perf,"\n",all)).
update_vg(VG, Perf) ->
%% Check if regular log file
case re:run(VG,"(?:by|at) 0x([0-9A-F]+): (\\?\\?\\?)",[global]) of
{match, Matches} ->
lists:foldl(
fun(Match, File) ->
[_,Base, Replace] = Match,
case find_replacement(binary_to_integer(binary:part(VG,Base),16), Perf) of
undefined ->
File;
Replacement ->
replace(File,Replace,Replacement)
end
end, VG,
%% Run replacements in reverse in order to not invalidate
%% the positions as we update the contents.
lists:reverse(Matches));
_ ->
%% Check if xml log file
case re:run(VG,"(<ip>0x([0-9A-F]+)</ip>)",[global]) of
{match, Matches} ->
lists:foldl(
fun(Match, File) ->
[_,Replace,Base] = Match,
case find_replacement(binary_to_integer(binary:part(VG,Base),16), Perf) of
undefined ->
File;
Replacement ->
Xml = ["<ip>0x",binary:part(VG,Base),"</ip>\n"
" <obj>JIT code</obj>\n"
" <fn>",Replacement,"</fn>\n"
" <dir></dir>\n"
" <file></file>\n"
" <line></line>"],
replace(File,Replace,Xml)
end
end, VG,
%% Run replacements in reverse in order to not invalidate
%% the positions as we update the contents.
lists:reverse(Matches));
_ ->
VG
end
end.
find_replacement(Addr, Perf) when is_map(Perf) ->
find_replacement(Addr, maps:iterator(Perf));
find_replacement(Addr, Iter) ->
case maps:next(Iter) of
{Base,{Size,Str},Next} ->
if Base =< Addr andalso Addr < Base + Size ->
[Str,"+",integer_to_list(Addr - Base, 16)];
true ->
find_replacement(Addr,Next)
end;
none ->
undefined
end.
replace(Bin,{Start,Len},What) ->
[string:slice(Bin,0,Start),
What,
string:slice(Bin,Start+Len)].