File 0234-erts-Improve-pcre-debug-yield-coverage.patch of Package erlang
From 812f68b4e584eec18e0ce9a2a8ce8c69d77d1e35 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Wed, 17 Dec 2025 16:09:27 +0100
Subject: [PATCH 4/5] erts: Improve pcre debug yield coverage
Use 64-bit counters to not wrap
---
erts/emulator/beam/erl_bif_info.c | 26 ++++++++++++++++----------
erts/emulator/pcre/pcre2_match.c | 8 ++++----
2 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 41b5391423..ebf03797b9 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -24,6 +24,7 @@
# include "config.h"
#endif
+#include <stdint.h>
#define ERTS_WANT_MEM_MAPPERS
#include "sys.h"
#include "erl_vm.h"
@@ -4483,23 +4484,28 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
else if (ERTS_IS_ATOM_STR("re_yield_coverage", BIF_ARG_1)) {
#ifdef DEBUG
extern const int erts_dbg_pcre_cost_chk_lines[];
- extern int erts_dbg_pcre_cost_chk_visits[];
- extern int erts_dbg_pcre_cost_chk_yields[];
+ extern uint64_t erts_dbg_pcre_cost_chk_visits[];
+ extern uint64_t erts_dbg_pcre_cost_chk_yields[];
extern const int erts_dbg_pcre_cost_chk_cnt;
- const Uint hsz = (2 + 1 + 3) * erts_dbg_pcre_cost_chk_cnt;
+ const Uint hsz = ((2 + 1+3 + 2*ERTS_MAX_UINT64_HEAP_SIZE)
+ * erts_dbg_pcre_cost_chk_cnt);
Eterm *hp = HAlloc(BIF_P, hsz);
Eterm *hp_end = hp + hsz;
Eterm list = NIL;
for (int i=erts_dbg_pcre_cost_chk_cnt-1; i>=0; i--) {
- Eterm tuple = TUPLE3(hp,
- make_small(erts_dbg_pcre_cost_chk_lines[i]),
- make_small(erts_dbg_pcre_cost_chk_visits[i]),
- make_small(erts_dbg_pcre_cost_chk_yields[i]));
+ Eterm line = make_small(erts_dbg_pcre_cost_chk_lines[i]);
+ Eterm visits = erts_bld_uint64(&hp, NULL, erts_dbg_pcre_cost_chk_visits[i]);
+ Eterm yields = erts_bld_uint64(&hp, NULL, erts_dbg_pcre_cost_chk_yields[i]);
+ Eterm tuple = TUPLE3(hp, line, visits, yields);
hp += 1+3;
list = CONS(hp, tuple, list);
hp += 2;
+
+ erts_dbg_pcre_cost_chk_visits[i] = 0;
+ erts_dbg_pcre_cost_chk_yields[i] = 0;
}
- ASSERT(hp == hp_end);
+ ERTS_ASSERT(hp <= hp_end);
+ HRelease(BIF_P, hp_end, hp);
return list;
#else
return am_undefined;
@@ -5121,7 +5127,7 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
else if (ERTS_IS_ATOM_STR("re_loop_limit", BIF_ARG_1)) {
/* Used by re_SUITE (stdlib) */
Uint max_loops;
- if (is_atom(BIF_ARG_2) && ERTS_IS_ATOM_STR("default", BIF_ARG_2)) {
+ if (ERTS_IS_ATOM_STR("default", BIF_ARG_2)) {
max_loops = erts_re_set_loop_limit(-1);
BIF_RET(make_small(max_loops));
} else if (term_to_Uint(BIF_ARG_2, &max_loops) != 0) {
@@ -5132,7 +5138,7 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
else if (ERTS_IS_ATOM_STR("unicode_loop_limit", BIF_ARG_1)) {
/* Used by unicode_SUITE (stdlib) */
Uint max_loops;
- if (is_atom(BIF_ARG_2) && ERTS_IS_ATOM_STR("default", BIF_ARG_2)) {
+ if (ERTS_IS_ATOM_STR("default", BIF_ARG_2)) {
max_loops = erts_unicode_set_loop_limit(-1);
BIF_RET(make_small(max_loops));
} else if (term_to_Uint(BIF_ARG_2, &max_loops) != 0) {
diff --git a/erts/emulator/pcre/pcre2_match.c b/erts/emulator/pcre/pcre2_match.c
index 9f6218a5a4..75c45fa71a 100644
--- a/erts/emulator/pcre/pcre2_match.c
+++ b/erts/emulator/pcre/pcre2_match.c
@@ -258,12 +258,12 @@ for (i = 0, Q = match_data->heapframes;
const int erts_dbg_pcre_cost_chk_lines[] = {
#include "pcre2_match_yield_coverage.gen.h"
};
-int erts_dbg_pcre_cost_chk_visits[ERLANG_YIELD_POINT_CNT];
-int erts_dbg_pcre_cost_chk_yields[ERLANG_YIELD_POINT_CNT];
+uint64_t erts_dbg_pcre_cost_chk_visits[ERLANG_YIELD_POINT_CNT];
+uint64_t erts_dbg_pcre_cost_chk_yields[ERLANG_YIELD_POINT_CNT];
const int erts_dbg_pcre_cost_chk_cnt = ERLANG_YIELD_POINT_CNT;
-# define DBG_COST_CHK_VISIT() ++erts_dbg_pcre_cost_chk_visits[NAME_CAT(ERLANG_YIELD_POINT_,__LINE__)]
-# define DBG_COST_CHK_YIELD() ++erts_dbg_pcre_cost_chk_yields[NAME_CAT(ERLANG_YIELD_POINT_,__LINE__)]
+# define DBG_COST_CHK_VISIT() ++(erts_dbg_pcre_cost_chk_visits[NAME_CAT(ERLANG_YIELD_POINT_,__LINE__)])
+# define DBG_COST_CHK_YIELD() ++(erts_dbg_pcre_cost_chk_yields[NAME_CAT(ERLANG_YIELD_POINT_,__LINE__)])
# define DBG_FAKE_COST_CHK() (DBG_COST_CHK_VISIT(), DBG_COST_CHK_YIELD())
#else // !DEBUG
# define DBG_COST_CHK_VISIT()
--
2.51.0