summaryrefslogtreecommitdiff
path: root/lib/kernel/src/erts_debug.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/src/erts_debug.erl')
-rw-r--r--lib/kernel/src/erts_debug.erl64
1 files changed, 34 insertions, 30 deletions
diff --git a/lib/kernel/src/erts_debug.erl b/lib/kernel/src/erts_debug.erl
index a69e74a3c1..9a03dd8d75 100644
--- a/lib/kernel/src/erts_debug.erl
+++ b/lib/kernel/src/erts_debug.erl
@@ -40,6 +40,15 @@
lc_graph/0, lc_graph_to_dot/2, lc_graph_merge/2,
alloc_blocks_size/1]).
+%% Reroutes calls to the given MFA to error_handler:breakpoint/3
+%%
+%% Note that this is potentially unsafe as compiled code may assume that the
+%% targeted function returns a specific type, triggering undefined behavior if
+%% this function were to return something else.
+%%
+%% For reference, the debugger avoids the issue by purging the affected module
+%% and interpreting all functions in the module, ensuring that no assumptions
+%% are made with regard to return or argument types.
-spec breakpoint(MFA, Flag) -> non_neg_integer() when
MFA :: {Module :: module(),
Function :: atom(),
@@ -92,7 +101,7 @@ copy_shared(_) ->
-spec get_internal_state(W) -> term() when
W :: reds_left | node_and_dist_references | monitoring_nodes
- | next_pid | 'DbTable_words' | check_io_debug
+ | next_pid | 'DbTable_words' | check_io_debug | lc_graph
| process_info_args | processes | processes_bif_info
| max_atom_out_cache_index | nbalance | available_internal_state
| force_heap_frags | memory
@@ -517,43 +526,38 @@ alloc_blocks_size_1([], _Type, 0) ->
undefined;
alloc_blocks_size_1([{_Type, false} | Rest], Type, Acc) ->
alloc_blocks_size_1(Rest, Type, Acc);
-alloc_blocks_size_1([{Type, Instances} | Rest], Type, Acc0) ->
- F = fun ({instance, _, L}, Acc) ->
+alloc_blocks_size_1([{_Type, Instances} | Rest], Type, Acc) ->
+ F = fun ({instance, _, L}, Acc0) ->
MBCSPool = case lists:keyfind(mbcs_pool, 1, L) of
{_, Pool} -> Pool;
false -> []
end,
{_,MBCS} = lists:keyfind(mbcs, 1, L),
{_,SBCS} = lists:keyfind(sbcs, 1, L),
- Acc +
- sum_block_sizes(MBCSPool) +
- sum_block_sizes(MBCS) +
- sum_block_sizes(SBCS)
+ Acc1 = sum_block_sizes(MBCSPool, Type, Acc0),
+ Acc2 = sum_block_sizes(MBCS, Type, Acc1),
+ sum_block_sizes(SBCS, Type, Acc2)
end,
- alloc_blocks_size_1(Rest, Type, lists:foldl(F, Acc0, Instances));
-alloc_blocks_size_1([{_Type, Instances} | Rest], Type, Acc0) ->
- F = fun ({instance, _, L}, Acc) ->
- Acc + sum_foreign_sizes(Type, L)
- end,
- alloc_blocks_size_1(Rest, Type, lists:foldl(F, Acc0, Instances));
+ alloc_blocks_size_1(Rest, Type, lists:foldl(F, Acc, Instances));
alloc_blocks_size_1([], _Type, Acc) ->
Acc.
-sum_foreign_sizes(Type, L) ->
- case lists:keyfind(mbcs_pool, 1, L) of
- {_,Pool} ->
- {_,ForeignBlocks} = lists:keyfind(foreign_blocks, 1, Pool),
- case lists:keyfind(Type, 1, ForeignBlocks) of
- {_,TypeSizes} -> sum_block_sizes(TypeSizes);
- false -> 0
- end;
- _ ->
- 0
- end.
+sum_block_sizes([{blocks, List} | Rest], Type, Acc) ->
+ sum_block_sizes(Rest, Type, sum_block_sizes_1(List, Type, Acc));
+sum_block_sizes([_ | Rest], Type, Acc) ->
+ sum_block_sizes(Rest, Type, Acc);
+sum_block_sizes([], _Type, Acc) ->
+ Acc.
+
+sum_block_sizes_1([{Type, L} | Rest], Type, Acc0) ->
+ Acc = lists:foldl(fun({size, Sz,_,_}, Sz0) -> Sz0+Sz;
+ ({size, Sz}, Sz0) -> Sz0+Sz;
+ (_, Sz) -> Sz
+ end, Acc0, L),
+ sum_block_sizes_1(Rest, Type, Acc);
+sum_block_sizes_1([_ | Rest], Type, Acc) ->
+ sum_block_sizes_1(Rest, Type, Acc);
+sum_block_sizes_1([], _Type, Acc) ->
+ Acc.
+
-sum_block_sizes(Blocks) ->
- lists:foldl(
- fun({blocks_size, Sz,_,_}, Sz0) -> Sz0+Sz;
- ({blocks_size, Sz}, Sz0) -> Sz0+Sz;
- (_, Sz) -> Sz
- end, 0, Blocks).