diff options
Diffstat (limited to 'lib/observer/src/crashdump_viewer.erl')
-rw-r--r-- | lib/observer/src/crashdump_viewer.erl | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl index 0534ead50e..b01c3a1bac 100644 --- a/lib/observer/src/crashdump_viewer.erl +++ b/lib/observer/src/crashdump_viewer.erl @@ -86,6 +86,7 @@ -define(max_line_size,100). % max number of bytes (i.e. characters) the % line_head/1 function can return -define(not_available,"N/A"). +-define(binary_size_progress_limit,10000). %% All possible tags - use macros in order to avoid misspelling in the code @@ -307,6 +308,7 @@ init([]) -> ets:new(cdv_dump_index_table,[ordered_set,named_table,public]), ets:new(cdv_reg_proc_table,[ordered_set,named_table,public]), ets:new(cdv_binary_index_table,[ordered_set,named_table,public]), + ets:new(cdv_heap_file_chars,[ordered_set,named_table,public]), {ok, #state{}}. %%-------------------------------------------------------------------- @@ -849,7 +851,12 @@ indexify(Fd,AddrAdj,Bin,N) -> _ -> insert_index(Tag,Id,NewPos) end, - put_last_tag(Tag,Id), + case put_last_tag(Tag,Id) of + {?proc_heap,LastId} -> + [{_,LastPos}] = lookup_index(?proc_heap,LastId), + ets:insert(cdv_heap_file_chars,{LastId,N+Start+1-LastPos}); + _ -> ok + end, indexify(Fd,AddrAdj,Rest,N1); nomatch -> case progress_read(Fd) of @@ -1485,6 +1492,8 @@ parse_dictionary(Line0, BinAddrAdj, D) -> read_heap(Fd,Pid,BinAddrAdj,Dict0) -> case lookup_index(?proc_heap,Pid) of [{_,Pos}] -> + [{_,Chars}] = ets:lookup(cdv_heap_file_chars,Pid), + init_progress("Reading process heap",Chars), pos_bof(Fd,Pos), read_heap(BinAddrAdj,Dict0); [] -> @@ -1495,13 +1504,16 @@ read_heap(BinAddrAdj,Dict0) -> %% This function is never called if the dump is truncated in {?proc_heap,Pid} case get(fd) of end_of_heap -> + end_progress(), Dict0; Fd -> case bytes(Fd) of "=" ++ _next_tag -> + end_progress(), put(fd, end_of_heap), Dict0; Line -> + update_progress(length(Line)+1), Dict = parse(Line,BinAddrAdj,Dict0), read_heap(BinAddrAdj,Dict) end @@ -2664,6 +2676,7 @@ deref_ptr(Ptr, Line, BinAddrAdj, D0) -> put(fd, end_of_heap), deref_ptr(Ptr, Line, BinAddrAdj, D0); L -> + update_progress(length(L)+1), D = parse(L, BinAddrAdj, D0), deref_ptr(Ptr, Line, BinAddrAdj, D) end @@ -2731,7 +2744,7 @@ get_label([H|T], Acc) -> get_binary(Line0) -> case get_hex(Line0) of {N,":"++Line} -> - do_get_binary(N, Line, []); + do_get_binary(N, Line, [], false); _ -> {'#CDVTruncatedBinary',[]} end. @@ -2739,17 +2752,23 @@ get_binary(Line0) -> get_binary(Offset,Size,Line0) -> case get_hex(Line0) of {_N,":"++Line} -> - do_get_binary(Size, lists:sublist(Line,(Offset*2)+1,Size*2), []); + Progress = Size>?binary_size_progress_limit, + Progress andalso init_progress("Reading binary",Size), + do_get_binary(Size, lists:sublist(Line,(Offset*2)+1,Size*2), [], + Progress); _ -> {'#CDVTruncatedBinary',[]} end. -do_get_binary(0, Line, Acc) -> +do_get_binary(0, Line, Acc, Progress) -> + Progress andalso end_progress(), {list_to_binary(lists:reverse(Acc)),Line}; -do_get_binary(N, [A,B|Line], Acc) -> +do_get_binary(N, [A,B|Line], Acc, Progress) -> Byte = (get_hex_digit(A) bsl 4) bor get_hex_digit(B), - do_get_binary(N-1, Line, [Byte|Acc]); -do_get_binary(_N, [], _Acc) -> + Progress andalso update_progress(), + do_get_binary(N-1, Line, [Byte|Acc], Progress); +do_get_binary(_N, [], _Acc, Progress) -> + Progress andalso end_progress(), {'#CDVTruncatedBinary',[]}. cdvbin(Offset,Size,{'#CDVBin',Pos}) -> @@ -2766,7 +2785,8 @@ cdvbin(_,_,'#CDVNonexistingBinary') -> reset_tables() -> ets:delete_all_objects(cdv_dump_index_table), ets:delete_all_objects(cdv_reg_proc_table), - ets:delete_all_objects(cdv_binary_index_table). + ets:delete_all_objects(cdv_binary_index_table), + ets:delete_all_objects(cdv_heap_file_chars). insert_index(Tag,Id,Pos) -> ets:insert(cdv_dump_index_table,{{Tag,Pos},Id}). |