簡體   English   中英

使用 natvis 的圓形雙鏈表可視化

[英]Circular Double Linked list visualization using natvis

我想為雙鏈表編寫一個natvis 可視化工具。 列表沒有存儲計數節點,簡單的方法效果不佳,因為擴展永遠不會停止(next 永遠不會為空,列表的最后一項指向列表根)。

<Type Name="TListBidir&lt;*&gt;">
    <Expand>
        <LinkedListItems>
            <HeadPointer>next</HeadPointer>
            <NextPointer>next</NextPointer>
            <ValueNode>($T1 *)this</ValueNode>
        </LinkedListItems>
    </Expand>
</Type>

我希望我能夠在 NextPointer 中添加一個 Condition 屬性,將它與列表頭進行比較,但是由於 NextPoint 在節點的上下文中被評估,我不知道將它與什么進行比較:

<NextPointer Condition="next!=XXXXXXXXX">next</NextPointer>

這是以前(2010 年)可視化工具的樣子,使用跳過指令,因為#list 正在自動處理

#list可以防止無限遍歷,並且可以優雅地處理循環列表。 此外,您可以使用skip:表達式來表示不應報告的哨兵節點。 雖然名字暗示節點會被跳過,但它實際上會導致遍歷停止,所以如果你的哨兵節點是第一個你應該在它之后開始遍歷。

TListBidir<*,*,*>{
    children
    (
      #list(
        head: ((($T2 *)&$c)->next),
        next: next,
        skip : &($c)
      ): (($T1 *)(&$e))
    )
}

我如何在 natvis 中向調試器解釋它一旦再次到達根元素就應該停止擴展列表?

我有一個類似的問題,不是循環列表,而是最后一個指向自身的哨兵節點,並提出了一個可能適合您需求的有趣解決方案:您可以使用三元運算符來偽造一個真正的終止。 <NextPointer>的表達式可以是您可以用普通 C 編寫的任何內容,因此您可以在其中進行真正的計算(但遺憾的是,沒有遞歸)。

(請注意,不允許將Condition屬性放在<NextPointer> ,因此三元運算符是在那里完成條件的唯一方法。)

所以在我的情況下,列表是這樣終止的:

<LinkedListItems>
    <HeadPointer>this</HeadPointer>
    <NextPointer>next != this ? next : 0</NextPointer>
    <ValueNode>items</ValueNode>
</LinkedListItems>

在您的情況下,如果每個節點都有一個指向其容器的指針,您可以使用它來與頭節點進行比較:

<LinkedListItems>
    <HeadPointer>container-&gt;head</HeadPointer>
    <NextPointer>next != container-&gt;head ? next : 0</NextPointer>
    <ValueNode>items</ValueNode>
</LinkedListItems>

或者,沒有&gt; 實體並用更傳統的 C 編寫,這相當於:

next != container->head ? next : NULL

但是,如果您沒有某種container反向指針,那么您可能不走運,因為無法通過僅查看循環鏈表中的單個節點來回答它是否有效地“最后”節點。

您可以使用CustomListItems元素執行此操作:

<CustomListItems>
    <Variable Name="orig_head" InitialValue="head"/>
    <Variable Name="iter" InitialValue="first_elem"/>
    <Loop>
        <Break Condition="iter == orig_head || iter == 0"/>
        <Item>*iter</Item>
        <Exec>iter = iter-&gt;next_elem</Exec>
    </Loop>
</CustomListItems>

CustomListItems允許您將頭部保存在一個變量中,以便在遍歷列表時可以使用它。 如果您的頭部具有不同的類型,那么您需要將列表節點轉換為節點類型。

natvis 框架目前不支持沒有提供計數的循環鏈表。 如果您提供計數,它應該可以工作。 但是,如果沒有計數,就沒有什么好方法可以阻止擴張永遠持續下去。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM