How to guarantee unique ID's in SVG generated?

Is there a way to require that all of the ids in generated SVG are unique without manually specifying them?

SVG spec requires that id’s in a document are unique, which is the behavior I expect based on id | Graphviz but this doesn’t happen in practice.

e.g. If I render the pprof example pprof CPU Profile | Graphviz it has multiple <g> tags with identical id’s

I guess the duplicates you’re pointing out are node1 and a_node1? SVG content for anyone following along at home:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 8.1.0 (20230707.0739)
 -->
<!-- Title: [stackcollapse] Pages: 1 -->
<svg width="805pt" height="1208pt"
 viewBox="0.00 0.00 805.25 1208.25" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1204.25)">
<title>[stackcollapse]</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-1204.25 801.25,-1204.25 801.25,4 -4,4"/>
<g id="clust1" class="cluster">
<title>cluster_L</title>
<polygon fill="none" stroke="black" points="8,-1047.75 8,-1192.25 436,-1192.25 436,-1047.75 8,-1047.75"/>
</g>
<!-- File: [stackcollapse] -->
<g id="node1" class="node">
<title>File: [stackcollapse]</title>
<g id="a_node1"><a xlink:title="[stackcollapse]">
<polygon fill="#f8f8f8" stroke="black" points="428.38,-1184.25 15.62,-1184.25 15.62,-1055.75 428.38,-1055.75 428.38,-1184.25"/>
<text text-anchor="start" x="23.62" y="-1165.05" font-family="Helvetica,Arial,sans-serif" font-size="16.00">File: [stackcollapse]</text>
<text text-anchor="start" x="23.62" y="-1129.55" font-family="Helvetica,Arial,sans-serif" font-size="16.00">Showing nodes accounting for 380, 90.48% of 420 total</text>
<text text-anchor="start" x="23.62" y="-1113.05" font-family="Helvetica,Arial,sans-serif" font-size="16.00">Dropped 120 nodes (cum &lt;= 2)</text>
<text text-anchor="start" x="23.62" y="-1096.55" font-family="Helvetica,Arial,sans-serif" font-size="16.00">Showing top 20 nodes out of 110</text>
<text text-anchor="start" x="23.62" y="-1061.05" font-family="Helvetica,Arial,sans-serif" font-size="16.00">See https://git.io/JfYMW for how to read the graph</text>
</a>
</g>
</g>
<!-- N1 -->
<g id="node1" class="node">
<title>N1</title>
<g id="a_node1"><a xlink:title="deflate (384)">
<polygon fill="#edd6d5" stroke="#b20400" points="558.38,-743.75 415.62,-743.75 415.62,-679.5 558.38,-679.5 558.38,-743.75"/>
<text text-anchor="middle" x="487" y="-722.65" font-family="Helvetica,Arial,sans-serif" font-size="18.00">deflate</text>
<text text-anchor="middle" x="487" y="-703.9" font-family="Helvetica,Arial,sans-serif" font-size="18.00">62 (14.76%)</text>
<text text-anchor="middle" x="487" y="-685.15" font-family="Helvetica,Arial,sans-serif" font-size="18.00">of 384 (91.43%)</text>
</a>
</g>
</g>
<!-- N3 -->
<g id="node3" class="node">
<title>N3</title>
<g id="a_node3"><a xlink:title="longest_match (178)">
<polygon fill="#eddad5" stroke="#b22800" points="573.38,-628.5 400.62,-628.5 400.62,-571 573.38,-571 573.38,-628.5"/>
<text text-anchor="middle" x="487" y="-601.7" font-family="Helvetica,Arial,sans-serif" font-size="24.00">longest_match</text>
<text text-anchor="middle" x="487" y="-576.95" font-family="Helvetica,Arial,sans-serif" font-size="24.00">178 (42.38%)</text>
</a>
</g>
</g>
<!-- N1&#45;&gt;N3 -->
<g id="edge5" class="edge">
<title>N1&#45;&gt;N3</title>
<g id="a_edge5"><a xlink:title="deflate &#45;&gt; longest_match (176)">
<path fill="none" stroke="#b22800" stroke-width="3" d="M487,-679.14C487,-667.74 487,-654.69 487,-642.55"/>
<polygon fill="#b22800" stroke="#b22800" stroke-width="3" points="490.5,-642.87 487,-632.87 483.5,-642.87 490.5,-642.87"/>
</a>
</g>
<g id="a_edge5&#45;label"><a xlink:title="deflate &#45;&gt; longest_match (176)">
<text text-anchor="middle" x="500.12" y="-648.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 176</text>
</a>
</g>
</g>
<!-- N4 -->
<g id="node4" class="node">
<title>N4</title>
<g id="a_node4"><a xlink:title="fill_window (102)">
<polygon fill="#edddd5" stroke="#b23d00" points="293.38,-628.5 162.62,-628.5 162.62,-571 293.38,-571 293.38,-628.5"/>
<text text-anchor="middle" x="228" y="-609.3" font-family="Helvetica,Arial,sans-serif" font-size="16.00">fill_window</text>
<text text-anchor="middle" x="228" y="-592.8" font-family="Helvetica,Arial,sans-serif" font-size="16.00">41 (9.76%)</text>
<text text-anchor="middle" x="228" y="-576.3" font-family="Helvetica,Arial,sans-serif" font-size="16.00">of 102 (24.29%)</text>
</a>
</g>
</g>
<!-- N1&#45;&gt;N4 -->
<g id="edge6" class="edge">
<title>N1&#45;&gt;N4</title>
<g id="a_edge6"><a xlink:title="deflate &#45;&gt; fill_window (102)">
<path fill="none" stroke="#b23d00" stroke-width="2" d="M415.2,-680.16C381.03,-665.67 340.14,-648.32 305.29,-633.54"/>
<polygon fill="#b23d00" stroke="#b23d00" stroke-width="2" points="306.3,-630.32 295.73,-629.63 303.57,-636.76 306.3,-630.32"/>
</a>
</g>
<g id="a_edge6&#45;label"><a xlink:title="deflate &#45;&gt; fill_window (102)">
<text text-anchor="middle" x="379.12" y="-648.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 102</text>
</a>
</g>
</g>
<!-- N10 -->
<g id="node10" class="node">
<title>N10</title>
<g id="a_node10"><a xlink:title="ct_tally (13)">
<polygon fill="#edebe9" stroke="#b2a896" points="672.62,-617.75 591.38,-617.75 591.38,-581.75 672.62,-581.75 672.62,-617.75"/>
<text text-anchor="middle" x="632" y="-600.9" font-family="Helvetica,Arial,sans-serif" font-size="13.00">ct_tally</text>
<text text-anchor="middle" x="632" y="-587.4" font-family="Helvetica,Arial,sans-serif" font-size="13.00">13 (3.10%)</text>
</a>
</g>
</g>
<!-- N1&#45;&gt;N10 -->
<g id="edge15" class="edge">
<title>N1&#45;&gt;N10</title>
<g id="a_edge15"><a xlink:title="deflate &#45;&gt; ct_tally (12)">
<path fill="none" stroke="#b2a999" d="M508.28,-679.19C517.15,-667.79 528.2,-655.52 540.25,-646.5 556.43,-634.39 563.87,-637.41 582,-628.5 585.35,-626.85 588.8,-625.09 592.24,-623.28"/>
<polygon fill="#b2a999" stroke="#b2a999" points="593.7,-625.93 600.85,-618.12 590.38,-619.77 593.7,-625.93"/>
</a>
</g>
<g id="a_edge15&#45;label"><a xlink:title="deflate &#45;&gt; ct_tally (12)">
<text text-anchor="middle" x="550.38" y="-648.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 12</text>
</a>
</g>
</g>
<!-- N20 -->
<g id="node20" class="node">
<title>N20</title>
<g id="a_node20"><a xlink:title="flush_block (27)">
<polygon fill="#ede9e5" stroke="#b29979" points="382.75,-617.75 311.25,-617.75 311.25,-581.75 382.75,-581.75 382.75,-617.75"/>
<text text-anchor="middle" x="347" y="-600.4" font-family="Helvetica,Arial,sans-serif" font-size="8.00">flush_block</text>
<text text-anchor="middle" x="347" y="-592.15" font-family="Helvetica,Arial,sans-serif" font-size="8.00">0 of 27 (6.43%)</text>
</a>
</g>
</g>
<!-- N1&#45;&gt;N20 -->
<g id="edge10" class="edge">
<title>N1&#45;&gt;N20</title>
<g id="a_edge10"><a xlink:title="deflate &#45;&gt; flush_block (26)">
<path fill="none" stroke="#b29a7b" d="M456.83,-679.23C445.71,-668.34 432.7,-656.39 420,-646.5 418.18,-645.08 401.13,-634.39 383.97,-623.7"/>
<polygon fill="#b29a7b" stroke="#b29a7b" points="386.4,-620.47 376.06,-618.16 382.71,-626.41 386.4,-620.47"/>
</a>
</g>
<g id="a_edge10&#45;label"><a xlink:title="deflate &#45;&gt; flush_block (26)">
<text text-anchor="middle" x="447.38" y="-648.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 26</text>
</a>
</g>
</g>
<!-- N2 -->
<g id="node2" class="node">
<title>N2</title>
<g id="a_node2"><a xlink:title="gzip (409)">
<polygon fill="#edd5d5" stroke="#b20100" points="527.25,-1138 446.75,-1138 446.75,-1102 527.25,-1102 527.25,-1138"/>
<text text-anchor="middle" x="487" y="-1120.65" font-family="Helvetica,Arial,sans-serif" font-size="8.00">gzip</text>
<text text-anchor="middle" x="487" y="-1112.4" font-family="Helvetica,Arial,sans-serif" font-size="8.00">0 of 409 (97.38%)</text>
</a>
</g>
</g>
<!-- N7 -->
<g id="node7" class="node">
<title>N7</title>
<g id="a_node7"><a xlink:title="entry_SYSCALL_64_after_hwframe (34)">
<polygon fill="#ede8e3" stroke="#b2906a" points="199.12,-305.75 54.88,-305.75 54.88,-269.75 199.12,-269.75 199.12,-305.75"/>
<text text-anchor="middle" x="127" y="-288.4" font-family="Helvetica,Arial,sans-serif" font-size="8.00">entry_SYSCALL_64_after_hwframe</text>
<text text-anchor="middle" x="127" y="-280.15" font-family="Helvetica,Arial,sans-serif" font-size="8.00">0 of 34 (8.10%)</text>
</a>
</g>
</g>
<!-- N2&#45;&gt;N7 -->
<g id="edge20" class="edge">
<title>N2&#45;&gt;N7</title>
<g id="a_edge20"><a xlink:title="gzip &#45;&gt; entry_SYSCALL_64_after_hwframe (4)">
<path fill="none" stroke="#b2b0aa" d="M480.38,-1101.6C473.1,-1084.97 459.75,-1060.6 440,-1047.75 372.19,-1003.65 81,-1068.63 81,-987.75 81,-987.75 81,-987.75 81,-388.5 81,-361.74 94.82,-334.36 107.3,-315.06"/>
<polygon fill="#b2b0aa" stroke="#b2b0aa" points="110.72,-317.26 113.45,-307.02 104.93,-313.33 110.72,-317.26"/>
</a>
</g>
<g id="a_edge20&#45;label"><a xlink:title="gzip &#45;&gt; entry_SYSCALL_64_after_hwframe (4)">
<text text-anchor="middle" x="86.62" y="-705.83" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 4</text>
</a>
</g>
</g>
<!-- N12 -->
<g id="node12" class="node">
<title>N12</title>
<g id="a_node12"><a xlink:title="_start (393)">
<polygon fill="#edd5d5" stroke="#b20300" points="527.25,-1004.75 446.75,-1004.75 446.75,-968.75 527.25,-968.75 527.25,-1004.75"/>
<text text-anchor="middle" x="487" y="-987.4" font-family="Helvetica,Arial,sans-serif" font-size="8.00">_start</text>
<text text-anchor="middle" x="487" y="-979.15" font-family="Helvetica,Arial,sans-serif" font-size="8.00">0 of 393 (93.57%)</text>
</a>
</g>
</g>
<!-- N2&#45;&gt;N12 -->
<g id="edge1" class="edge">
<title>N2&#45;&gt;N12</title>
<g id="a_edge1"><a xlink:title="gzip &#45;&gt; _start (393)">
<path fill="none" stroke="#b20300" stroke-width="5" d="M487,-1101.57C487,-1080.96 487,-1046.22 487,-1020.53"/>
<polygon fill="#b20300" stroke="#b20300" stroke-width="5" points="491.38,-1020.83 487,-1010.83 482.63,-1020.83 491.38,-1020.83"/>
</a>
</g>
<g id="a_edge1&#45;label"><a xlink:title="gzip &#45;&gt; _start (393)">
<text text-anchor="middle" x="500.12" y="-1024.45" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 393</text>
</a>
</g>
</g>
<!-- N16 -->
<g id="node16" class="node">
<title>N16</title>
<g id="a_node16"><a xlink:title="[unknown] (10)">
<polygon fill="#edecea" stroke="#b2ab9d" points="652.75,-729.62 581.25,-729.62 581.25,-693.62 652.75,-693.62 652.75,-729.62"/>
<text text-anchor="middle" x="617" y="-712.27" font-family="Helvetica,Arial,sans-serif" font-size="8.00">[unknown]</text>
<text text-anchor="middle" x="617" y="-704.02" font-family="Helvetica,Arial,sans-serif" font-size="8.00">0 of 10 (2.38%)</text>
</a>
</g>
</g>
<!-- N2&#45;&gt;N16 -->
<g id="edge17" class="edge">
<title>N2&#45;&gt;N16</title>
<g id="a_edge17"><a xlink:title="gzip &#45;&gt; [unknown] (10)">
<path fill="none" stroke="#b2ab9d" d="M511.22,-1101.56C539.66,-1078.86 583,-1036.31 583,-987.75 583,-987.75 583,-987.75 583,-811.75 583,-786.3 593.15,-759.07 602.36,-739.61"/>
<polygon fill="#b2ab9d" stroke="#b2ab9d" points="605.86,-741.43 607.17,-730.92 599.58,-738.32 605.86,-741.43"/>
</a>
</g>
<g id="a_edge17&#45;label"><a xlink:title="gzip &#45;&gt; [unknown] (10)">
<text text-anchor="middle" x="592.38" y="-893.95" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 10</text>
</a>
</g>
</g>
<!-- N18 -->
<g id="node18" class="node">
<title>N18</title>
<g id="a_node18"><a xlink:title="asm_exc_page_fault (5)">
<polygon fill="#edeceb" stroke="#b2afa7" points="725.62,-307.5 620.38,-307.5 620.38,-268 725.62,-268 725.62,-307.5"/>
<text text-anchor="middle" x="673" y="-294" font-family="Helvetica,Arial,sans-serif" font-size="10.00">asm_exc_page_fault</text>
<text text-anchor="middle" x="673" y="-283.5" font-family="Helvetica,Arial,sans-serif" font-size="10.00">1 (0.24%)</text>
<text text-anchor="middle" x="673" y="-273" font-family="Helvetica,Arial,sans-serif" font-size="10.00">of 5 (1.19%)</text>
</a>
</g>
</g>
<!-- N2&#45;&gt;N18 -->
<g id="edge23" class="edge">
<title>N2&#45;&gt;N18</title>
<g id="a_edge23"><a xlink:title="gzip ... asm_exc_page_fault (2)">
<path fill="none" stroke="#b2b1ae" stroke-dasharray="1,5" d="M527.64,-1119.09C609.39,-1116.91 786,-1099.29 786,-987.75 786,-987.75 786,-987.75 786,-388.5 786,-354.76 757.34,-329.71 728.89,-313.15"/>
<polygon fill="#b2b1ae" stroke="#b2b1ae" points="730.73,-309.62 720.29,-307.85 727.36,-315.75 730.73,-309.62"/>
</a>
</g>
<g id="a_edge23&#45;label"><a xlink:title="gzip ... asm_exc_page_fault (2)">
<text text-anchor="middle" x="791.62" y="-705.83" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 2</text>
</a>
</g>
</g>
<!-- N6 -->
<g id="node6" class="node">
<title>N6</title>
<g id="a_node6"><a xlink:title="file_read (62)">
<polygon fill="#ede3db" stroke="#b2682e" points="266,-513.75 190,-513.75 190,-477.75 266,-477.75 266,-513.75"/>
<text text-anchor="middle" x="228" y="-496.4" font-family="Helvetica,Arial,sans-serif" font-size="8.00">file_read</text>
<text text-anchor="middle" x="228" y="-488.15" font-family="Helvetica,Arial,sans-serif" font-size="8.00">0 of 62 (14.76%)</text>
</a>
</g>
</g>
<!-- N4&#45;&gt;N6 -->
<g id="edge7" class="edge">
<title>N4&#45;&gt;N6</title>
<g id="a_edge7"><a xlink:title="fill_window &#45;&gt; file_read (58)">
<path fill="none" stroke="#b26e37" d="M228,-570.61C228,-556.37 228,-539.14 228,-524.9"/>
<polygon fill="#b26e37" stroke="#b26e37" points="231.5,-525.23 228,-515.23 224.5,-525.23 231.5,-525.23"/>
</a>
</g>
<g id="a_edge7&#45;label"><a xlink:title="fill_window &#45;&gt; file_read (58)">
<text text-anchor="middle" x="237.38" y="-539.7" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 58</text>
</a>
</g>
</g>
<!-- N5 -->
<g id="node5" class="node">
<title>N5</title>
<g id="a_node5"><a xlink:title="updcrc (48)">
<polygon fill="#ede6df" stroke="#b27d4c" points="292.62,-420.5 163.38,-420.5 163.38,-358.5 292.62,-358.5 292.62,-420.5"/>
<text text-anchor="middle" x="228" y="-400.35" font-family="Helvetica,Arial,sans-serif" font-size="17.00">updcrc</text>
<text text-anchor="middle" x="228" y="-382.35" font-family="Helvetica,Arial,sans-serif" font-size="17.00">46 (10.95%)</text>
<text text-anchor="middle" x="228" y="-364.35" font-family="Helvetica,Arial,sans-serif" font-size="17.00">of 48 (11.43%)</text>
</a>
</g>
</g>
<!-- N6&#45;&gt;N5 -->
<g id="edge8" class="edge">
<title>N6&#45;&gt;N5</title>
<g id="a_edge8"><a xlink:title="file_read &#45;&gt; updcrc (48)">
<path fill="none" stroke="#b27d4c" d="M228,-477.54C228,-465.04 228,-447.58 228,-431.58"/>
<polygon fill="#b27d4c" stroke="#b27d4c" points="231.5,-431.82 228,-421.82 224.5,-431.82 231.5,-431.82"/>
</a>
</g>
<g id="a_edge8&#45;label"><a xlink:title="file_read &#45;&gt; updcrc (48)">
<text text-anchor="middle" x="237.38" y="-440.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 48</text>
</a>
</g>
</g>
<!-- N6&#45;&gt;N7 -->
<g id="edge13" class="edge">
<title>N6&#45;&gt;N7</title>
<g id="a_edge13"><a xlink:title="file_read ... entry_SYSCALL_64_after_hwframe (14)">
<path fill="none" stroke="#b2a794" stroke-dasharray="1,5" d="M194.49,-477.51C173.55,-464.79 148.18,-445.39 135.25,-420.5 118.35,-387.97 119.35,-344.65 122.48,-316.73"/>
<polygon fill="#b2a794" stroke="#b2a794" points="126.04,-317.5 123.85,-307.13 119.09,-316.6 126.04,-317.5"/>
</a>
</g>
<g id="a_edge13&#45;label"><a xlink:title="file_read ... entry_SYSCALL_64_after_hwframe (14)">
<text text-anchor="middle" x="145.38" y="-383.7" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 14</text>
</a>
</g>
</g>
<!-- N11 -->
<g id="node11" class="node">
<title>N11</title>
<g id="a_node11"><a xlink:title="do_syscall_64 (33)">
<polygon fill="#ede8e3" stroke="#b2916c" points="162.75,-217 91.25,-217 91.25,-181 162.75,-181 162.75,-217"/>
<text text-anchor="middle" x="127" y="-199.65" font-family="Helvetica,Arial,sans-serif" font-size="8.00">do_syscall_64</text>
<text text-anchor="middle" x="127" y="-191.4" font-family="Helvetica,Arial,sans-serif" font-size="8.00">0 of 33 (7.86%)</text>
</a>
</g>
</g>
<!-- N7&#45;&gt;N11 -->
<g id="edge9" class="edge">
<title>N7&#45;&gt;N11</title>
<g id="a_edge9"><a xlink:title="entry_SYSCALL_64_after_hwframe &#45;&gt; do_syscall_64 (33)">
<path fill="none" stroke="#b2916c" d="M127,-269.61C127,-257.81 127,-241.85 127,-228.19"/>
<polygon fill="#b2916c" stroke="#b2916c" points="130.5,-228.4 127,-218.4 123.5,-228.4 130.5,-228.4"/>
</a>
</g>
<g id="a_edge9&#45;label"><a xlink:title="entry_SYSCALL_64_after_hwframe &#45;&gt; do_syscall_64 (33)">
<text text-anchor="middle" x="136.38" y="-236.7" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 33</text>
</a>
</g>
</g>
<!-- N19 -->
<g id="node19" class="node">
<title>N19</title>
<g id="a_node19"><a xlink:title="__x64_sys_read (15)">
<polygon fill="#edebe8" stroke="#b2a692" points="215.88,-130 130.12,-130 130.12,-90.5 215.88,-90.5 215.88,-130"/>
<text text-anchor="middle" x="173" y="-116.5" font-family="Helvetica,Arial,sans-serif" font-size="10.00">__x64_sys_read</text>
<text text-anchor="middle" x="173" y="-106" font-family="Helvetica,Arial,sans-serif" font-size="10.00">1 (0.24%)</text>
<text text-anchor="middle" x="173" y="-95.5" font-family="Helvetica,Arial,sans-serif" font-size="10.00">of 15 (3.57%)</text>
</a>
</g>
</g>
<!-- N7&#45;&gt;N19 -->
<g id="edge26" class="edge">
<title>N7&#45;&gt;N19</title>
<g id="a_edge26"><a xlink:title="entry_SYSCALL_64_after_hwframe &#45;&gt; __x64_sys_read (1)">
<path fill="none" stroke="#b2b2b0" d="M141.73,-269.4C152.18,-256.01 165.45,-236.54 172,-217 180.26,-192.36 179.69,-162.63 177.53,-140.98"/>
<polygon fill="#b2b2b0" stroke="#b2b2b0" points="180.9,-140.69 176.26,-131.17 173.95,-141.51 180.9,-140.69"/>
</a>
</g>
<g id="a_edge26&#45;label"><a xlink:title="entry_SYSCALL_64_after_hwframe &#45;&gt; __x64_sys_read (1)">
<text text-anchor="middle" x="184.62" y="-193.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 1</text>
</a>
</g>
</g>
<!-- N8 -->
<g id="node8" class="node">
<title>N8</title>
<g id="a_node8"><a xlink:title="compress_block (25)">
<polygon fill="#edeae6" stroke="#b29b7d" points="403.38,-520 290.62,-520 290.62,-471.5 403.38,-471.5 403.38,-520"/>
<text text-anchor="middle" x="347" y="-503.65" font-family="Helvetica,Arial,sans-serif" font-size="13.00">compress_block</text>
<text text-anchor="middle" x="347" y="-490.15" font-family="Helvetica,Arial,sans-serif" font-size="13.00">14 (3.33%)</text>
<text text-anchor="middle" x="347" y="-476.65" font-family="Helvetica,Arial,sans-serif" font-size="13.00">of 25 (5.95%)</text>
</a>
</g>
</g>
<!-- N9 -->
<g id="node9" class="node">
<title>N9</title>
<g id="a_node9"><a xlink:title="send_bits (16)">
<polygon fill="#edebe8" stroke="#b2a590" points="407.12,-413.75 310.88,-413.75 310.88,-365.25 407.12,-365.25 407.12,-413.75"/>
<text text-anchor="middle" x="359" y="-397.4" font-family="Helvetica,Arial,sans-serif" font-size="13.00">send_bits</text>
<text text-anchor="middle" x="359" y="-383.9" font-family="Helvetica,Arial,sans-serif" font-size="13.00">13 (3.10%)</text>
<text text-anchor="middle" x="359" y="-370.4" font-family="Helvetica,Arial,sans-serif" font-size="13.00">of 16 (3.81%)</text>
</a>
</g>
</g>
<!-- N8&#45;&gt;N9 -->
<g id="edge16" class="edge">
<title>N8&#45;&gt;N9</title>
<g id="a_edge16"><a xlink:title="compress_block &#45;&gt; send_bits (11)">
<path fill="none" stroke="#b2aa9b" d="M349.72,-471.09C351.3,-457.37 353.32,-439.84 355.07,-424.63"/>
<polygon fill="#b2aa9b" stroke="#b2aa9b" points="358.62,-425.4 356.29,-415.06 351.67,-424.6 358.62,-425.4"/>
</a>
</g>
<g id="a_edge16&#45;label"><a xlink:title="compress_block &#45;&gt; send_bits (11)">
<text text-anchor="middle" x="363.38" y="-440.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 11</text>
</a>
</g>
</g>
<!-- N9&#45;&gt;N7 -->
<g id="edge27" class="edge">
<title>N9&#45;&gt;N7</title>
<g id="a_edge27"><a xlink:title="send_bits ... entry_SYSCALL_64_after_hwframe (1)">
<path fill="none" stroke="#b2b2b0" stroke-dasharray="1,5" d="M315.04,-364.78C310.67,-362.59 306.27,-360.47 302,-358.5 263.48,-340.74 219.07,-323.08 184.63,-309.97"/>
<polygon fill="#b2b2b0" stroke="#b2b2b0" points="186.33,-306.49 175.74,-306.22 183.85,-313.03 186.33,-306.49"/>
</a>
</g>
<g id="a_edge27&#45;label"><a xlink:title="send_bits ... entry_SYSCALL_64_after_hwframe (1)">
<text text-anchor="middle" x="265.62" y="-327.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 1</text>
</a>
</g>
</g>
<!-- N9&#45;&gt;N18 -->
<g id="edge24" class="edge">
<title>N9&#45;&gt;N18</title>
<g id="a_edge24"><a xlink:title="send_bits &#45;&gt; asm_exc_page_fault (2)">
<path fill="none" stroke="#b2b1ae" d="M407.37,-373.13C461.66,-355.89 549.93,-327.85 609.67,-308.87"/>
<polygon fill="#b2b1ae" stroke="#b2b1ae" points="610.64,-311.92 619.11,-305.55 608.52,-305.24 610.64,-311.92"/>
</a>
</g>
<g id="a_edge24&#45;label"><a xlink:title="send_bits &#45;&gt; asm_exc_page_fault (2)">
<text text-anchor="middle" x="559.62" y="-327.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 2</text>
</a>
</g>
</g>
<!-- N14 -->
<g id="node14" class="node">
<title>N14</title>
<g id="a_node14"><a xlink:title="native_write_msr (9)">
<polygon fill="#edecea" stroke="#b2ac9f" points="112.38,-128.25 5.62,-128.25 5.62,-92.25 112.38,-92.25 112.38,-128.25"/>
<text text-anchor="middle" x="59" y="-111.6" font-family="Helvetica,Arial,sans-serif" font-size="12.00">native_write_msr</text>
<text text-anchor="middle" x="59" y="-98.85" font-family="Helvetica,Arial,sans-serif" font-size="12.00">9 (2.14%)</text>
</a>
</g>
</g>
<!-- N11&#45;&gt;N14 -->
<g id="edge18" class="edge">
<title>N11&#45;&gt;N14</title>
<g id="a_edge18"><a xlink:title="do_syscall_64 ... native_write_msr (9)">
<path fill="none" stroke="#b2ac9f" stroke-dasharray="1,5" d="M113.57,-180.86C103.76,-168.35 90.29,-151.17 79.19,-137.01"/>
<polygon fill="#b2ac9f" stroke="#b2ac9f" points="81.56,-135.36 72.64,-129.65 76.05,-139.68 81.56,-135.36"/>
</a>
</g>
<g id="a_edge18&#45;label"><a xlink:title="do_syscall_64 ... native_write_msr (9)">
<text text-anchor="middle" x="105.62" y="-149.7" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 9</text>
</a>
</g>
</g>
<!-- N11&#45;&gt;N19 -->
<g id="edge12" class="edge">
<title>N11&#45;&gt;N19</title>
<g id="a_edge12"><a xlink:title="do_syscall_64 &#45;&gt; __x64_sys_read (14)">
<path fill="none" stroke="#b2a794" d="M136.09,-180.86C142.28,-169.18 150.63,-153.43 157.83,-139.87"/>
<polygon fill="#b2a794" stroke="#b2a794" points="161.22,-141.94 162.81,-131.47 155.03,-138.66 161.22,-141.94"/>
</a>
</g>
<g id="a_edge12&#45;label"><a xlink:title="do_syscall_64 &#45;&gt; __x64_sys_read (14)">
<text text-anchor="middle" x="162.38" y="-149.7" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 14</text>
</a>
</g>
</g>
<!-- N15 -->
<g id="node15" class="node">
<title>N15</title>
<g id="a_node15"><a xlink:title="treat_file (389)">
<polygon fill="#edd5d5" stroke="#b20400" points="527.25,-917.75 446.75,-917.75 446.75,-881.75 527.25,-881.75 527.25,-917.75"/>
<text text-anchor="middle" x="487" y="-900.4" font-family="Helvetica,Arial,sans-serif" font-size="8.00">treat_file</text>
<text text-anchor="middle" x="487" y="-892.15" font-family="Helvetica,Arial,sans-serif" font-size="8.00">0 of 389 (92.62%)</text>
</a>
</g>
</g>
<!-- N12&#45;&gt;N15 -->
<g id="edge2" class="edge">
<title>N12&#45;&gt;N15</title>
<g id="a_edge2"><a xlink:title="_start ... treat_file (389)">
<path fill="none" stroke="#b20400" stroke-width="5" stroke-dasharray="1,5" d="M487,-968.55C487,-958.59 487,-945.72 487,-933.87"/>
<polygon fill="#b20400" stroke="#b20400" stroke-width="5" points="491.38,-934.22 487,-924.22 482.63,-934.22 491.38,-934.22"/>
</a>
</g>
<g id="a_edge2&#45;label"><a xlink:title="_start ... treat_file (389)">
<text text-anchor="middle" x="500.12" y="-937.45" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 389</text>
</a>
</g>
</g>
<!-- N13 -->
<g id="node13" class="node">
<title>N13</title>
<g id="a_node13"><a xlink:title="zip (386)">
<polygon fill="#edd6d5" stroke="#b20400" points="527.25,-830.75 446.75,-830.75 446.75,-794.75 527.25,-794.75 527.25,-830.75"/>
<text text-anchor="middle" x="487" y="-813.4" font-family="Helvetica,Arial,sans-serif" font-size="8.00">zip</text>
<text text-anchor="middle" x="487" y="-805.15" font-family="Helvetica,Arial,sans-serif" font-size="8.00">0 of 386 (91.90%)</text>
</a>
</g>
</g>
<!-- N13&#45;&gt;N1 -->
<g id="edge4" class="edge">
<title>N13&#45;&gt;N1</title>
<g id="a_edge4"><a xlink:title="zip &#45;&gt; deflate (384)">
<path fill="none" stroke="#b20400" stroke-width="5" d="M487,-794.48C487,-784.84 487,-772.31 487,-759.97"/>
<polygon fill="#b20400" stroke="#b20400" stroke-width="5" points="491.38,-760.1 487,-750.1 482.63,-760.1 491.38,-760.1"/>
</a>
</g>
<g id="a_edge4&#45;label"><a xlink:title="zip &#45;&gt; deflate (384)">
<text text-anchor="middle" x="500.12" y="-763.45" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 384</text>
</a>
</g>
</g>
<!-- N13&#45;&gt;N20 -->
<g id="edge28" class="edge">
<title>N13&#45;&gt;N20</title>
<g id="a_edge28"><a xlink:title="zip &#45;&gt; flush_block (1)">
<path fill="none" stroke="#b2b2b0" d="M455.56,-794.45C436.12,-782.4 411.87,-764.75 395.75,-743.75 369.27,-709.25 356.64,-659.45 351.03,-628.64"/>
<polygon fill="#b2b2b0" stroke="#b2b2b0" points="354.32,-628.11 349.21,-618.84 347.42,-629.28 354.32,-628.11"/>
</a>
</g>
<g id="a_edge28&#45;label"><a xlink:title="zip &#45;&gt; flush_block (1)">
<text text-anchor="middle" x="401.62" y="-705.83" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 1</text>
</a>
</g>
</g>
<!-- N15&#45;&gt;N13 -->
<g id="edge3" class="edge">
<title>N15&#45;&gt;N13</title>
<g id="a_edge3"><a xlink:title="treat_file &#45;&gt; zip (386)">
<path fill="none" stroke="#b20400" stroke-width="5" d="M487,-881.55C487,-871.59 487,-858.72 487,-846.87"/>
<polygon fill="#b20400" stroke="#b20400" stroke-width="5" points="491.38,-847.22 487,-837.22 482.63,-847.22 491.38,-847.22"/>
</a>
</g>
<g id="a_edge3&#45;label"><a xlink:title="treat_file &#45;&gt; zip (386)">
<text text-anchor="middle" x="500.12" y="-850.45" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 386</text>
</a>
</g>
</g>
<!-- N16&#45;&gt;N3 -->
<g id="edge22" class="edge">
<title>N16&#45;&gt;N3</title>
<g id="a_edge22"><a xlink:title="[unknown] &#45;&gt; longest_match (2)">
<path fill="none" stroke="#b2b1ae" d="M604.82,-693.2C594.66,-679.47 579.28,-660.39 563,-646.5 558.27,-642.47 553.15,-638.57 547.86,-634.86"/>
<polygon fill="#b2b1ae" stroke="#b2b1ae" points="550.12,-631.49 539.87,-628.81 546.22,-637.3 550.12,-631.49"/>
</a>
</g>
<g id="a_edge22&#45;label"><a xlink:title="[unknown] &#45;&gt; longest_match (2)">
<text text-anchor="middle" x="583.62" y="-648.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 2</text>
</a>
</g>
</g>
<!-- N16&#45;&gt;N8 -->
<g id="edge21" class="edge">
<title>N16&#45;&gt;N8</title>
<g id="a_edge21"><a xlink:title="[unknown] &#45;&gt; compress_block (2)">
<path fill="none" stroke="#b2b1ae" d="M636.37,-693.26C665.23,-665.31 712.96,-609.58 682,-571 649.11,-530.03 502.5,-510.27 414.5,-501.94"/>
<polygon fill="#b2b1ae" stroke="#b2b1ae" points="415.08,-498.39 404.8,-500.95 414.44,-505.36 415.08,-498.39"/>
</a>
</g>
<g id="a_edge21&#45;label"><a xlink:title="[unknown] &#45;&gt; compress_block (2)">
<text text-anchor="middle" x="697.62" y="-593.95" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 2</text>
</a>
</g>
</g>
<!-- N16&#45;&gt;N9 -->
<g id="edge19" class="edge">
<title>N16&#45;&gt;N9</title>
<g id="a_edge19"><a xlink:title="[unknown] &#45;&gt; send_bits (5)">
<path fill="none" stroke="#b2afa7" d="M645.59,-693.31C658.48,-684.7 673.38,-673.56 685,-661.5 713.71,-631.68 726.78,-607.36 707,-571 648.58,-463.61 500.81,-418.06 417.84,-400.44"/>
<polygon fill="#b2afa7" stroke="#b2afa7" points="418.81,-396.86 408.32,-398.28 417.41,-403.71 418.81,-396.86"/>
</a>
</g>
<g id="a_edge19&#45;label"><a xlink:title="[unknown] &#45;&gt; send_bits (5)">
<text text-anchor="middle" x="699.62" y="-539.7" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 5</text>
</a>
</g>
</g>
<!-- N16&#45;&gt;N10 -->
<g id="edge25" class="edge">
<title>N16&#45;&gt;N10</title>
<g id="a_edge25"><a xlink:title="[unknown] &#45;&gt; ct_tally (1)">
<path fill="none" stroke="#b2b2b0" d="M619.34,-693.46C621.7,-676.22 625.36,-649.38 628.14,-629"/>
<polygon fill="#b2b2b0" stroke="#b2b2b0" points="631.74,-629.54 629.62,-619.16 624.8,-628.59 631.74,-629.54"/>
</a>
</g>
<g id="a_edge25&#45;label"><a xlink:title="[unknown] &#45;&gt; ct_tally (1)">
<text text-anchor="middle" x="631.62" y="-648.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 1</text>
</a>
</g>
</g>
<!-- N17 -->
<g id="node17" class="node">
<title>N17</title>
<g id="a_node17"><a xlink:title="page_cache_ra_unbounded (13)">
<polygon fill="#edebe9" stroke="#b2a896" points="240.25,-39.5 105.75,-39.5 105.75,0 240.25,0 240.25,-39.5"/>
<text text-anchor="middle" x="173" y="-26" font-family="Helvetica,Arial,sans-serif" font-size="10.00">page_cache_ra_unbounded</text>
<text text-anchor="middle" x="173" y="-15.5" font-family="Helvetica,Arial,sans-serif" font-size="10.00">2 (0.48%)</text>
<text text-anchor="middle" x="173" y="-5" font-family="Helvetica,Arial,sans-serif" font-size="10.00">of 13 (3.10%)</text>
</a>
</g>
</g>
<!-- N19&#45;&gt;N17 -->
<g id="edge14" class="edge">
<title>N19&#45;&gt;N17</title>
<g id="a_edge14"><a xlink:title="__x64_sys_read ... page_cache_ra_unbounded (13)">
<path fill="none" stroke="#b2a896" stroke-dasharray="1,5" d="M173,-90.05C173,-78.57 173,-63.73 173,-50.73"/>
<polygon fill="#b2a896" stroke="#b2a896" points="176.5,-50.92 173,-40.92 169.5,-50.92 176.5,-50.92"/>
</a>
</g>
<g id="a_edge14&#45;label"><a xlink:title="__x64_sys_read ... page_cache_ra_unbounded (13)">
<text text-anchor="middle" x="182.38" y="-59.2" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 13</text>
</a>
</g>
</g>
<!-- N20&#45;&gt;N8 -->
<g id="edge11" class="edge">
<title>N20&#45;&gt;N8</title>
<g id="a_edge11"><a xlink:title="flush_block &#45;&gt; compress_block (23)">
<path fill="none" stroke="#b29e81" d="M347,-581.45C347,-567.65 347,-547.89 347,-530.92"/>
<polygon fill="#b29e81" stroke="#b29e81" points="350.5,-531.27 347,-521.27 343.5,-531.27 350.5,-531.27"/>
</a>
</g>
<g id="a_edge11&#45;label"><a xlink:title="flush_block &#45;&gt; compress_block (23)">
<text text-anchor="middle" x="356.38" y="-539.7" font-family="Helvetica,Arial,sans-serif" font-size="14.00"> 23</text>
</a>
</g>
</g>
</g>
</svg>

Not sure what the expected behavior is for a subgraph in this position.

I think it is a bug. The documentation for id says:

If no id attribute is provided, then a unique internal id is used. However, this value is unpredictable by the graph writer.

I don’t believe that node1 was a unique internal id.

However, there is an easy work-around - add an id to the one node that does not already have an id and all works as desired - no duplicates.

subgraph cluster_L {
"File: [stackcollapse]" [  id=XYZ   shape=box fontsize=16 label="File: [stackcollapse]\l\lShowing nodes accounting for 380, 90.48% of 420 total\lDropped 120 nodes (cum <= 2)\lShowing top 20 nodes out of 110\l\lSee https://git.io/JfYMW for how to read the graph\l" tooltip="[stackcollapse]"]
}

Whoops, not a bug!
node1 is a unique internal ID. Below is a reduced version, but with all the nodes and IDs renamed. Dot still produces node1 as the ID for the one unnamed node.
The moral of the story is add IDs to all your nodes or use some ID naming scheme other than nodeN.

digraph "[stackcollapse]" {

node [style=filled fillcolor="#f8f8f8"]
subgraph cluster_L { "File: [stackcollapse]" [shape=box fontsize=16 label="File: [stackcollapse]\l\lShowing nodes accounting for 380, 90.48% of 420 total\lDropped 120 nodes (cum <= 2)\lShowing top 20 nodes out of 110\l\lSee https://git.io/JfYMW for how to read the graph\l" tooltip="[stackcollapse]"] }
N2 [label="deflate\n62 (14.76%)\nof 384 (91.43%)" id="FLOWER2" fontsize=18 shape=box tooltip="deflate (384)" color="#b20400" fillcolor="#edd6d5"]
N3 [label="gzip\n0 of 409 (97.38%)" id="FLOWER3" fontsize=8 shape=box tooltip="gzip (409)" color="#b20100" fillcolor="#edd5d5"]

N2 -> N3 [label=" 1" color="#b2b2b0" tooltip="zip -> flush_block (1)" labeltooltip="zip -> flush_block (1)"]
}

Hmm. Not sure we thought about building a dictionary of object IDs like that, to avoid collisions when an input graph mixes explicit SVG IDs and automatically generated IDs. There’s various places where ad-hoc SVG id generation happens in gvrender_core_svg.c so you can see what is happening. It’s tempting to “improve” this, but wonder if it could break existing downstream processors, too.

1 Like

@scnorth Thank you for the insight. I suppose per Hyrum’s Law there could be some downstream breakage but I’m having a hard time imaging where this would be explicitly desirable. Are there any particular processors you have in mind as a concern?
Perhaps a smaller incremental improvement could be a runtime warning that a graph author should not use node* id’s (or if so should set id’s on all nodes).
However current behavior does break my use case (graphviz2drawio) and is contrary to svg spec so I’m interested in contributing an id generation change if that’s something that would be merged.

Yeah, we have probably millions of graphs out there using Graphviz; Hyrum’s law is always a bit of a worry. For particular processors, I think some javascript graphviz editors take the SVG output and parse the IDs to turn them back into which input nodes should be updated when you click on a rendered node. e.g. https://magjac.com/graphviz-visual-editor/, though I’m not totally sure if they use the ID.

@mark I don’t think that’s right, the gve editor is keyed on node name / title. It also has the same problem when exporting SVG of the pprof graph.

@hbmartin You are correct. The correct terminology according to the DOT language is however not node name but node_id (not to be confused with the node attribute id)

1 Like

I’m inclined to agree with @hbmartin. Graphviz should detect this case and skip the colliding IDs when generating its own ones. I don’t think we can say “don’t mix explicit and implicit IDs” or “use a different naming scheme” when an example on our own website violates this.

1 Like

Are you proposing to just bite the bullet and maintain a dictionary of user-defined IDs so we can avoid collisions? (The typical coding style of graphviz would be to cheat a little and use a weird string prefix for system-generated IDs and hope for the best…) though what you are asking seems not that difficult.

Also, just to make sure, these SVG IDs have nothing to do with node names (that are mapped into internal IDs), edge keys, etc. at the cgraph level.

I hadn’t yet thought about the “how”. I was still stuck on the “what”.

The typical coding style of graphviz would be to cheat a little and use a weird string prefix for system-generated IDs and hope for the best

I don’t see how this can ever work robustly. Like symbol mangling, avoiding collisions requires using a function whose range has no overlap with the range of user-derived IDs. The only IDs I am aware of that are indescribable by the user are the empty string and strings with embedded null bytes. Neither of these seem like a workable idea.

You’re right, of course, though also, nothing is absolutely robust. Like in C (and most languages), you can’t use a reserved word as a variable name, either. Yet somehow we carry on.

Using the scheme I described above (incrementing node%d, but skipping any that collide with explicit IDs) where do we fail on robustness?

I don’t quite follow the analogy. In C, the standard clearly tells you which identifiers are reserved. In Graphviz, (AFAIK) there are no reserved IDs. At least id | Graphviz does not document any.