File 6131-erts-Fix-proc-bin-writable-trace-fixup.patch of Package erlang

From 00b36d46c8b8780960f9dbc88fbf1441ba236f8a Mon Sep 17 00:00:00 2001
From: Lukas Larsson <lukas@erlang.org>
Date: Mon, 7 Feb 2022 17:43:14 +0100
Subject: [PATCH 2/2] erts: Fix proc bin writable trace fixup

When creating a new proc bin because tracing has removed the
writable flag from the proc bin, we must make sure to also
create a new sub binary if the sub binary is on the mature
or old heap. When this is not done, the subbinary can be
promoted to the old heap without the proc bin also being there.

Bug was introduced in #5195, aka e16e5458c37a649b
---
 erts/emulator/beam/erl_bits.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index 45e522a3e8..4ca63fb1f4 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -1729,18 +1729,31 @@ erts_bs_private_append_checked(Process* p, Eterm bin, Uint build_size_in_bits, U
 	     */
 	    Binary* bptr = erts_bin_nrml_alloc(new_size);
             ProcBin* new_pb;
+            Uint sz = PROC_BIN_SIZE;
 
             sys_memcpy(bptr->orig_bytes, binp->orig_bytes, binp->orig_size);
 
-            new_pb = (ProcBin*) HeapFragOnlyAlloc(p, PROC_BIN_SIZE);
+            /* If the subbinary is on the mature or old heap, we need to also move it */
+            if (ErtsInArea(sb, OLD_HEAP(p), ((char *)OLD_HTOP(p)) - ((char *)OLD_HEAP(p))) ||
+                ErtsInArea(sb, HEAP_START(p), ((char *)HIGH_WATER(p)) - ((char *)HEAP_START(p)))) {
+                sz += ERL_SUB_BIN_SIZE;
+            }
+
+            new_pb = (ProcBin*) HeapFragOnlyAlloc(p, sz);
             new_pb->thing_word = HEADER_PROC_BIN;
             new_pb->size = pb->size;
             new_pb->val = bptr;
             new_pb->bytes = (byte *) bptr->orig_bytes;
             new_pb->next = p->wrt_bins;
             p->wrt_bins = (struct erl_off_heap_header*) new_pb;
-            sb->orig = make_binary(new_pb);
             pb = new_pb;
+            if (sz != PROC_BIN_SIZE) {
+                ErlSubBin *new_sb = (ErlSubBin*)(new_pb+1);
+                sys_memcpy(new_sb, sb, sizeof(*new_sb));
+                sb = new_sb;
+                bin = make_binary(sb);
+            }
+            sb->orig = make_binary(new_pb);
 	}
     }
     pb->flags = PB_IS_WRITABLE | PB_ACTIVE_WRITER;
-- 
2.34.1

openSUSE Build Service is sponsored by