File 0487-cdv-Handle-multiple-Yc-lines-refering-to-the-same-re.patch of Package erlang

From c9c1efe3815a49eb59ef62e8319cd9f6ea6c67d8 Mon Sep 17 00:00:00 2001
From: Siri Hansen <siri@erlang.org>
Date: Mon, 29 Oct 2018 16:12:01 +0100
Subject: [PATCH 2/2] [cdv] Handle multiple "Yc" lines refering to the same
 refc binary

Usually, sub binaries are implemented as special sub binary terms
("Ys" lines). But if a sub binary is sent to another process, sub
binaries will be eliminated and incorporated into the ProcBin ("Yc"
line), and when that happens there can be several "Yc" lines that
refer to the same underlying binary object. Make sure that that the
crash dump viewer can handle multiple "Yc" lines referring to the same
binary object.
---
 lib/observer/src/crashdump_viewer.erl        |  4 ++--
 lib/observer/test/crashdump_helper.erl       | 18 ++++++++++++++++++
 lib/observer/test/crashdump_viewer_SUITE.erl |  7 +++++++
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index 41a569c2bf..af4e2f1dda 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -2802,12 +2802,12 @@ parse_heap_term("Yc"++Line0, Addr, DecodeOpts, D0) ->	%Reference-counted binary.
             SymbolicBin = {'#CDVBin',Start},
             Term = cdvbin(Offset, Sz, SymbolicBin),
             D1 = gb_trees:insert(Addr, Term, D0),
-            D = gb_trees:insert(Binp, SymbolicBin, D1),
+            D = gb_trees:enter(Binp, SymbolicBin, D1),
             {Term,Line,D};
         [] ->
             Term = '#CDVNonexistingBinary',
             D1 = gb_trees:insert(Addr, Term, D0),
-            D = gb_trees:insert(Binp, Term, D1),
+            D = gb_trees:enter(Binp, Term, D1),
             {Term,Line,D}
     end;
 parse_heap_term("Ys"++Line0, Addr, DecodeOpts, D0) ->	%Sub binary.
diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl
index d8f4e046ae..315116fab7 100644
--- a/lib/observer/test/crashdump_helper.erl
+++ b/lib/observer/test/crashdump_helper.erl
@@ -62,6 +62,7 @@ n1_proc(Creator,_N2,Pid2,Port2,_L) ->
     put(ref,Ref),
     put(pid,Pid),
     put(bin,Bin),
+    put(proc_bins,create_proc_bins()),
     put(bins,create_binaries()),
     put(sub_bin,SubBin),
     put(sub_bins,create_sub_binaries(get(bins))),
@@ -117,6 +118,23 @@ create_sub_binary(Bin, Start, LenSub) ->
     <<_:Start/bytes,Sub:Len/bytes,_/bytes>> = Bin,
     Sub.
 
+create_proc_bins() ->
+    Parent = self(),
+    Pid =
+        spawn(
+          fun() ->
+                  %% Just reverse the list here, so this binary is not
+                  %% confused with the one created in n1_proc/5 above,
+                  %% which is used for testing truncation (see
+                  %% crashdump_viewer_SUITE:truncate_dump_binary/1)
+                  Bin = list_to_binary(lists:reverse(lists:seq(1, 255))),
+                  <<A:65/bytes,B:65/bytes,C/bytes>> = Bin,
+                  Parent ! {self(),{A,B,C}}
+          end),
+    receive
+        {Pid,ProcBins} -> ProcBins
+    end.
+
 %%%
 %%% Test dumping of maps. Dumping of maps only from OTP 20.2.
 %%%
diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl
index 864454cdff..25368da734 100644
--- a/lib/observer/test/crashdump_viewer_SUITE.erl
+++ b/lib/observer/test/crashdump_viewer_SUITE.erl
@@ -399,6 +399,13 @@ special(File,Procs) ->
 		crashdump_viewer:expand_binary({SOffset,SSize,SPos}),
 	    io:format("  expand binary ok",[]),
 
+            ProcBins = proplists:get_value(proc_bins,Dict),
+            {['#CDVBin',0,65,ProcBin],
+             ['#CDVBin',65,65,ProcBin],
+             ['#CDVBin',130,125,ProcBin]} = ProcBins,
+            io:format("  ProcBins ok",[]),
+
+
             Binaries = crashdump_helper:create_binaries(),
             verify_binaries(Binaries, proplists:get_value(bins,Dict)),
 	    io:format("  binaries ok",[]),
-- 
2.16.4