.natvis的文件來問題總結 .natvis的文件來

VS調試STL問題總結

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Packages\Debugger\Visualizers

https://www.cnblogs.com/hujichen/p/5997310.html

https://blog.csdn.net/u011251225/article/details/78669410

---恢復內容開始---

  以前寫代碼總覺用自己寫的東西比較牛逼,vector?stack?爲什麼不自己實現。後來才認識到這是個幼稚的想法!首先每次都自己實現是一種重複勞動;其次,自己寫的話很難保證沒有bug;效率往往也不如STL。STL的優勢不在此贅述,最近使用STL的時候發現調試時,監視器中的內容不忍直視,亂七八糟的,經過一番瞭解才慢慢發現問題所在。在這裏總結一下,也希望能幫到遇到同樣問題的同學。

  首先貼出來,我用的vs2015社區版 update3 調試代碼時遇到的問題。item_vec的聲明如下:

  vector<string> item_vec;

  當我想查看一下item_vec中的內容時,watch中的內容如下:

  看到這個,我的內心基本是崩潰的,這還看個毛線啊。回過頭來想想,爲什麼vs顯示的是這些“亂七八糟”的東西?因爲這些正是vector對象的成員。想想一下,vs在提供調試的時候,我們查看一對象a,vs就應該給我顯示對象a的成員和值,那我想查看vector的內容時,vs就應該像上面這樣顯示,沒有問題。但是回想以前使用stl,調試時顯示的好像不是這種東西,問題出在哪裏?

  一番查找之後,瞭解到這個屬於vs可視化調試的內容。可視化調試大概就是區別於gdb,提供可視化調試界面的功能。強大的vs在想,我怎麼爲STL提供給友好的可視界面,那我爲STL單獨設置一種顯示行不行,vector對象顯示size, capacity, vector中的所有元素列表等等。這樣這個問題貌似就解決了!!!

  然而這個問題並沒有這麼簡單,這樣做只能解決STL的顯示問題,如果用戶自己實現了STL功能,或者自己使用了更適合自己的第三方類庫,這個時候STL類的定義都完全不一樣了,vs就沒有辦法顯示了。推而廣之,如果任意一個用戶定義的類,而且這個類和STL中的類一樣複雜,並且調試的時候經常需要查看這個類的對象的狀態,這個時候vs就無法滿足要求的。仔細一想這個問題就不能用上面的方案解決。所以微軟提供了更牛叉的解決方案:用戶自定義顯示。

  大概的想法是這樣的,“我定義的類我做主”,vs提供一種工具,讓你自己來決定怎麼在調試的時候顯示這個類的對象。具體可以訪問:https://msdn.microsoft.com/zh-cn/library/jj620914.aspx。簡而言之就是,你可以使用一種.natvis的文件來定義一個類的對象在調試時的顯示。大概的定義方式如下:

1

2

3

4

5

6

7

8

9

10

11

<Type Name="std::vector<*>">

    <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>

    <Expand>

        <Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>

        <Item Name="[capacity]" ExcludeView="simple">_Myend -_Myfirst</Item>

        <ArrayItems>

            <Size>_Mylast - _Myfirst</Size>

            <ValuePointer>_Myfirst</ValuePointer>

        </ArrayItems>

    </Expand>

</Type>                           

  這個是微軟給出的樣例,在vs2013中用來定義vector的顯示形式,大概的效果如下:

  厲害了我的哥,這個就舒服很多嘛!參考微軟官方的指南,你就可以爲自己的類定義你想要的顯示形式。這樣就在調試代碼的時候就不用加一些爲了查看某些值而寫一些額外的代碼了。

  vs在安裝時,STL中的類都有默認的顯示方案,大概就是上面這張圖中的效果。

  上面講的是vs自定義類顯示的原理,那爲什麼我的vs還會有顯示問題,不是有默認的顯示嗎?其實這是vs 社區版update3的一個bug,參考這個鏈接:https://connect.microsoft.com/VisualStudio/feedback/details/1676171/change-in-c-stl-container-implementation-causes-debug-visualizer-error。bug產生的原因如下:.natvis文件時XML文件,所以正常是需要加上驗證的,這個驗證文件在C:\Program Files (x86)\Microsoft Visual Studio 14.0\Xml\Schemas\1033\natvis.xsd。但是vs2015社區版update3的這個文件不知道爲什麼使用的是vs2015RTM版本的xsd文件。導致,vs默認的stl.natvis文件中的一些定義不無通過驗證,相應的內容就無法生效,在vs看來相應的內容就只能用raw_data的形式顯示。這個問題會在下個版本中解決,目前只能等。上面的連接中有人提到了一種解決的偏方,有興趣的同學可以嘗試一下,我的vs下沒有偏方中描述的文件,所以沒辦法用。

  

  最後再說一說遇到這種現實問題應該怎麼去確認問題的原因,如果下次vs再有這種bug,你也可以自己嘗試去確認bug的原因。

  在vs中可以設置以原始數據的形式查看。“工具”->“選項”->“調試”->“常規”下可以設置“在變量窗口中顯示對象的原始數據”,如果希望.natvis生效,需要把這一項取消。

  在查看STL(以vector爲例)對象時,可以查看output窗口,如果.natvis文件解析異常,會報錯。在修改了.natvis文件後可以在watch窗口中執行.natvisreload命令重新加在.natvis文件。

  也可以爲項目添加.natvis文件,該.natvis文件只會在該項目中生效,並且,修改該.natvis文件會立即生效。參考https://www.zhihu.com/question/41286979。

  關於stl.natvis文件,如果需要修改stl.natvis,請注意vs使用的stl版本,不同版本stl對容器元素的聲明會不一樣,如通用的vector顯示:

  vs2013:

複製代碼

<Type Name="std::vector&lt;*&gt;" Priority="MediumLow">
    <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
    <Expand>
        <Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
        <ArrayItems>
            <Size>_Mylast - _Myfirst</Size>
            <ValuePointer>_Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
 </Type>

複製代碼

  vs2015:

複製代碼

<Type Name="std::vector&lt;*&gt;">
    <DisplayString>{{ size={_Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst} }}</DisplayString>
    <Expand>
        <Item Name="[capacity]" ExcludeView="simple">_Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst</Item>
        <Item Name="[allocator]" ExcludeView="simple">_Mypair</Item>
        <ArrayItems>
              <Size>_Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst</Size>
            <ValuePointer>_Mypair._Myval2._Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
</Type>

複製代碼

 

  最後的最後,如果是想vs2015社區版update3這樣的bug,暫時無法修復時。在watch窗口item_vec[0]會失敗,可以使用"&(item_vec.operator[](0)),n",這個表達式可以查看vector中n個元素。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章