{"id":106291,"date":"2022-02-25T07:00:00","date_gmt":"2022-02-25T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=106291"},"modified":"2022-02-25T07:00:17","modified_gmt":"2022-02-25T15:00:17","slug":"20220225-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20220225-00\/?p=106291","title":{"rendered":"How can I monitor changes to the reference count of a C++\/WinRT object?"},"content":{"rendered":"<p>Say you&#8217;re debugging your C++\/WinRT object and you want to keep an eye on its reference count, perhaps because you&#8217;re tracking down a memory leak. How can you do that?<\/p>\n<p>For concreteness, let&#8217;s say we&#8217;ve got these objects.<\/p>\n<pre>\/\/ A local object without a projection\r\nstruct Faucet : winrt::implements&lt;Faucet, IFaucet&gt;\r\n{\r\n    bool is_dripping = false;\r\n\r\n    Faucet()\r\n    {\r\n        ... construct the faucet ...\r\n    }\r\n\r\n    ... other methods ...\r\n};\r\n\r\n\/\/ A projected class\r\nnamespace winrt::Fixtures::implementation\r\n{\r\n    struct Lamp : LampT&lt;Lamp&gt;\r\n    {\r\n        bool is_on = false;\r\n\r\n        Lamp()\r\n        {\r\n            ... construct the lamp ...\r\n        }\r\n\r\n        ... other methods ...\r\n    };\r\n}\r\n<\/pre>\n<p>If you are the caller of <code>make_self<\/code>, you can inspect that result to find the reference count.<\/p>\n<pre>auto faucet = winrt::make_self&lt;Faucet&gt;();\r\nauto lamp = winrt::make_self&lt;implementation::Lamp&gt;();\r\n<\/pre>\n<p>For our purposes, <code>make_self<\/code> is convenient because it gives you a pointer to the implementation class, which makes it easy to extract the reference count. You can see it in the debugger:<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"=0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td>Name<\/td>\n<td>Value<\/td>\n<\/tr>\n<tr>\n<td>\u25e2 faucet<\/td>\n<td>0x00d4bab8 {&#8230;}<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u25e2 [winrt::impl::heap_implements&lt;Faucet&gt;]<\/td>\n<td>{&#8230;}<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u2003\u25e2 Faucet<\/td>\n<td>{&#8230;}<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u2003\u2003\u2003\u25e2 winrt::implements&lt;Faucet, IFaucet&gt;<\/td>\n<td>{&#8230;}<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u2003\u2003\u2003\u25b6 winrt::impl::producers_base&lt;Faucet, std::tuple&lt;IFaucet&gt; &gt;<\/td>\n<td>{&#8230;}<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u2003\u2003\u2003\u25e2 winrt::impl::root_implements&lt;Faucet, std::tuple&lt;IFaucet&gt; &gt;<\/td>\n<td>{m_references=0x00000001 }<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u2003\u2003\u2003\u2003\u2003 winrt::impl::root_implements_composing_outer&lt;0&gt;<\/td>\n<td>{&#8230;}<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u2003\u2003\u2003\u2003\u2003 winrt::impl::root_implements_composable_inner&lt;Faucet, 0&gt;<\/td>\n<td>{&#8230;}<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u2003\u2003\u2003\u2003\u2003 winrt::impl::module_lock_updater&lt;1&gt;<\/td>\n<td>{&#8230;}<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u2003\u2003\u2003\u2003\u2003 __vfptr<\/td>\n<td>0x004b4464 {&#8230;}<\/td>\n<\/tr>\n<tr style=\"background-color: #ffd1dc;\">\n<td>\u2003\u2003\u2003\u2003\u2003\u2003 m_references<\/td>\n<td>0x00000001 \u2190<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u25b6 IUnknown<\/td>\n<td>{&#8230;}<\/td>\n<\/tr>\n<tr>\n<td>\u2003\u25b6 [Raw View]<\/td>\n<td>{m_ptr=0x00d4bab8 {&#8230;} }<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>You get a similar view for <code>lamp<\/code>.<\/p>\n<p>From here, you can right-click the <code>m_references<\/code> and say <i>Break When Value Changes<\/i>.<\/p>\n<p>If you are more of a roll-up-your-sleeves kind of person, you can extract the address of that reference count variable from the Immediate window:<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"=0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td><code>&amp;faucet.m_ptr-&gt;m_references<br \/>\n        0x00d4babc 0x00000001<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>And then you can create a data breakpoint that triggers when the reference count changes.<\/p>\n<p>If you&#8217;re not so lucky and the object was created via projection or <code>make<\/code>, then what comes out is an interface pointer, not a pointer to the concrete object. So how do you get a pointer to the concrete object?<\/p>\n<p>My trick is to set a breakpoint on the constructor. In the constructor, you have the <code>this<\/code> pointer, and you can follow the same cookbook above to get to the <code>m_references<\/code>.<\/p>\n<p>If you&#8217;re really unlucky, the constructor was optimized out. You can ask the compiler not to optimize out the constructor by marking it as <code>noinline<\/code>.<\/p>\n<pre>    \/\/ or __attribute__((noinline)) if that's what your compiler prefers\r\n    <span style=\"color: blue;\">__declspec(noinline)<\/span> Faucet()\r\n    {\r\n        ... construct the faucet ...\r\n    }\r\n<\/pre>\n<p>The last wrinkle is that you may see a write to <code>m_references<\/code> that comes from <code>make_<wbr \/>weak_<wbr \/>ref<\/code> instead of the usual <code>AddRef<\/code> and <code>Release<\/code>. C++\/WinRT uses <a title=\"How WRL squeezes a weak reference and a reference count into a single integer\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200817-00\/?p=104089\"> the same trick that WRL uses to squeeze a weak reference and a reference count into a single integer<\/a>: If no weak reference has been created, then the <code>m_references<\/code> is the actual reference count. But once a weak reference is created, then <code>m_references<\/code> becomes a pointer to the weak reference, and the reference count moves into the weak reference.<\/p>\n<p>When that happens, you want to double-click the call stack entry for <code>make_<wbr \/>weak_<wbr \/>ref<\/code>, expand the <code>weak_ref<\/code> variable, find the <code>m_strong<\/code> and do another <i>Break When Value Changes<\/i>. (The corresponding immediate expression is <code>&amp;weak_ref.<wbr \/>m_ptr-&gt;<wbr \/>m_strong<\/code>.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A little cookbook.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-106291","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A little cookbook.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106291","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=106291"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106291\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=106291"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=106291"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=106291"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}