File 1287-debugger-Fix-broken-int-no_break-Mod.patch of Package erlang
From 883adc9864f5d7ad6b9d35fbceeb542b87c5482c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Tue, 13 Jun 2023 07:21:53 +0200
Subject: [PATCH] debugger: Fix broken `int:no_break(Mod)`
Closes #7336
---
lib/debugger/src/dbg_icmd.erl | 3 +-
lib/debugger/test/int_break_SUITE.erl | 89 ++++++++++++++++++++++-----
2 files changed, 74 insertions(+), 18 deletions(-)
diff --git a/lib/debugger/src/dbg_icmd.erl b/lib/debugger/src/dbg_icmd.erl
index 0eb258567f..8f96d8f10f 100644
--- a/lib/debugger/src/dbg_icmd.erl
+++ b/lib/debugger/src/dbg_icmd.erl
@@ -291,7 +291,8 @@ handle_int_msg({break_options, Break}, _Status, _Bs, _Ieval) ->
handle_int_msg(no_break, _Status, _Bs, _Ieval) ->
put(breakpoints, []);
handle_int_msg({no_break,M}, _Status, _Bs, _Ieval) ->
- put(breakpoints, [ML || {Mod,_L}=ML <- get(breakpoints), Mod=/=M]);
+ put(breakpoints, [B || {{Mod,_L},_Flags}=B <- get(breakpoints),
+ Mod =/= M]);
handle_int_msg(stop, exit_at, _Bs, _Ieval) ->
erlang:exit(normal).
diff --git a/lib/debugger/test/int_break_SUITE.erl b/lib/debugger/test/int_break_SUITE.erl
index 9894c27b81..e3c4ef7386 100644
--- a/lib/debugger/test/int_break_SUITE.erl
+++ b/lib/debugger/test/int_break_SUITE.erl
@@ -24,10 +24,10 @@
-include_lib("common_test/include/ct.hrl").
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
- basic/1,cleanup/1]).
+ basic/1,delete_breakpoints/1]).
-export([auto_attach/1]).
@@ -35,10 +35,10 @@ suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap,{minutes,1}}].
-all() ->
- [basic, cleanup].
+all() ->
+ [basic,delete_breakpoints].
-groups() ->
+groups() ->
[].
init_per_suite(Config) ->
@@ -63,27 +63,27 @@ init_per_testcase(_Case, Config) ->
end_per_testcase(_Case, _Config) ->
ok = io:format("Interpreted modules: ~p", [int:interpreted()]),
+ ok = int:auto_attach(false),
+ ok = int:no_break(),
+ ok = int:clear(),
ok.
-%% Tests setting a few break points.
-basic(Config) when list(Config) ->
+%% Test auto_attach functions and setting breakpoints.
+basic(_Config) ->
int:auto_attach([init], {?MODULE,auto_attach}),
S1 = [] = ordsets1:new_set(),
- ok = i:ib(ordsets1, 86),
+ ok = i:ib(ordsets1, 86), %Set one breakpoint.
S2 = [xxx] = ordsets1:add_element(xxx, S1),
S3 = [xxx,y] = ordsets1:add_element(y, S2),
- ok = i:ib(ordsets1, union, 2),
+ ok = i:ib(ordsets1, union, 2), %Set five breakpoints.
[xxx,y,z] = ordsets1:union(S3, [z]),
- All = [{{ordsets1,86}, _}, {{ordsets1,_},_}|_] = lists:sort(int:all_breaks()),
+ All = lists:sort(int:all_breaks()),
+ [{{ordsets1,86}, _}, {{ordsets1,_},_}|_] = All,
+ 6 = length(All),
[] = lists:sort(int:all_breaks(foobar)),
All = lists:sort(int:all_breaks(ordsets1)),
ok.
-%% Make sure that the auto-attach flag is turned off.
-cleanup(Config) when list(Config) ->
- int:auto_attach(false),
- ok.
-
auto_attach(Pid) ->
{ok, Meta} = int:attached(Pid),
io:format("Pid = ~p; Meta = ~p", [Pid,Meta]),
@@ -102,11 +102,66 @@ attach_cmd({Meta,{break_at,ordsets1,36,2}}, _Pid, Meta) ->
int:meta(Meta, continue);
attach_cmd({Meta,{break_at,ordsets1,87,_}}, _Pid, Meta) ->
int:meta(Meta, continue);
-attach_cmd({Meta,{break_at,ordsets1,89,_}}, _Pid, Meta) ->
- int:meta(Meta, continue);
attach_cmd({Meta,{break_at,ordsets1,Line,_}}, _Pid, Meta) when 107 =< Line, Line =< 115 ->
int:meta(Meta, finish);
attach_cmd({Meta,{break_at,_Mod,_Line,_Other}}=Cmd, _Pid, Meta) ->
io:format("attached: no action for ~p", [Cmd]);
attach_cmd(_, _Pid, _Meta) ->
ok.
+
+%% Test that deleting breakpoints works.
+delete_breakpoints(_Config) ->
+ Mod = ordsets1,
+
+ %% Testing deleting all breakpoints in all modules.
+ ok = i:ib(Mod, intersection, 2), %Set five breakpoints.
+ 5 = num_breaks(),
+ ok = int:no_break(),
+ 0 = num_breaks(),
+ [b] = Mod:intersection([a,b,c], [b,d,e]),
+
+ %% Set 10 breakpoints.
+ ok = i:ib(Mod, 89), %One breakpoint.
+ 1 = num_breaks(),
+ ok = i:ib(Mod, union, 2), %Five breakpoints.
+ 6 = num_breaks(),
+ ok = i:ib(Mod, del_element, 2), %Four breakpoints.
+ 10 = num_breaks(),
+
+ %% Make sure that all breakpoints remain when deleting breakpoints
+ %% for another (non-existing) module.
+ ok = int:no_break(foobar),
+ [] = int:all_breaks(foobar),
+ 10 = num_breaks(),
+
+ %% Delete the breakpoint in ordsets1:add_element/2, line 89,
+ %% and testing calling it. If the breakpoint has not been removed
+ %% the call will hang and the test case will fail with a timetrap
+ %% timeout.
+ ok = int:delete_break(Mod, 89),
+ 9 = num_breaks(),
+ [x] = Mod:add_element(x, []),
+
+ %% Delete all breakpoints in ordsets1:del_element/2.
+ ok = int:del_break_in(Mod, del_element, 2),
+ 5 = num_breaks(),
+ [a,b,d,e] = Mod:del_element(c, [a,b,c,d,e]),
+
+ %% GH-7336: Deleting all breakpoints for a module didn't work.
+ ok = int:no_break(Mod),
+ [] = int:all_breaks(Mod),
+ [] = int:all_breaks(),
+
+ %% All breakpoints should now be removed.
+ [x] = Mod:add_element(x, []),
+ [a,b,d,e] = Mod:del_element(c, [a,b,c,d,e]),
+ [a,b,c] = Mod:union([a,c], [a,b]),
+
+ ok.
+
+%% Return the number of breakpoints in the ordsets1 module.
+num_breaks() ->
+ %% Assumption: There are breakpoints only in the ordsets1 module.
+ Breaks = lists:sort(int:all_breaks()),
+ Breaks = lists:sort(int:all_breaks(ordsets1)),
+ length(Breaks).
--
2.35.3