Setting Breakpoints on All Class Methods

In a recent video John Robbins (probably the world’s leading debugging expert) made a public request of his audience: write a VS addin that enables setting function breakpoints by partial name matches. That is, let the user type C*::M* in some input dialog, and breakpoints would be set at CMyWnd::Move() and in Cookie::Monster() alike.

Well Naveen did pick up the gauntlet and wrote a nice addin to do exactly that. It even goes as far as regular expressions.

Both the original challenge and the given addin relate to managed code only – and it occurred to me this may be the first example in recorded history of a debugging goodie that’s available to native devs before managed devs.   Windbg has had the bm command forever, and while VS does not get quite there  – a while ago Habib Heydarian posted about an undocumented-VS trick that goes a major part of the way:

In the breakpoints window (Ctrl+B) you can type ‘YoueClassName::*’ to simultaneously set breakpoints to all class methods. This was useful to me recently when trying to find the first entry point to a module, and surely it would yet come handy in many other scenarios. In response to my email question, Habib Heydarian confirmed that (a) it is indeed undocumented and as such unsupported – so YMMV, (b) there isn’t any non trivial wildcard pattern matching available yet.  In response to another email question I learnt from John Robbins that  he checked with the expression evaluator developers and they don’t support any form of wildcards for .NET code either. However, it’s on their list of features for Dev 11.  Thus, the brief (and utterly insignificant) favoring of native over managed devs is about to come to an end.

std::vector of Aligned Elements

Update: answers to some questions raised below are available in a newer post.

Fact (1):

Functions cannot accept aligned types by value. That is really a fact of nature, but it can make sense:  the function’s stack frame can be located anywhere in memory, and so a hypothetical aligned argument passed by value cannot be passed at a fixed offset relative to the frame base. There would be no sane way for the function to reference that argument – unless some compiler writer out there is willing to pad every stack frame with some slack, generate function prologues that would take ebp modulo the desired alignment, fiddle with it to deduce the aligned argument location by some convention etc etc etc. Let’s not even start to imagine stack frame cleanup.

Fact (2):

Ever since MMX, and more pronouncedly  since SSE, data alignment is a major, major performance boost opportunity for mathematical code. In games and game-like apps, practically every mathematical object (matrices, vectors, and thus every object that holds them as members) are aligned on 16 byte boundaries.

Fact (3):

In VC++, when you try and instantiate an STL vector of aligned types you get slapped by the compiler:

error C2719: '_Val': formal parameter with __declspec(align('16')) won't be aligned

The reason is that the  implementation of std::vector::resize has the signature -

void resize(size_type _Count, _Elem _Ch);

That is, it accepts an element of the contained type by value. Semantically – resize pads the existing buffer with copies of _Ch  as needed to get to size _Count.

Corollary:

MS’s std::vector is pretty close to useless.

I wasn’t as decisive until recently, when several things happened: (1) I discovered gcc’s implementation does not suffer from the same issue, so it’s nothing inherent in the c++ standard. (2) I manually modified vector::resize’s signature to accept a const reference, and the code compiled cleanly and ran well. (3) Most importantly, I mailed Stephan T. Lavavej, Microsoft’s own STL grand master, and asked him whether I was missing something.    His response was:

I filed internal bug number Dev10#891686 about this.  There’s a reason that our resize() is currently taking T by value – it guards against being given one of the vector’s own elements (which is perfectly legal).  We’ll investigate changing this in VC11, but we’d have to make nontrivial changes to resize() and possibly other places throughout <vector>.

Note that header hacking is unsupported.

Frankly, I don’t fully understand this. The only case I can see when you might need to guard against being given one of the vector’s own elements is when that element is potentially changed by resize’s padding itself. It might happen when your vector buffer holds some slack, you pass _Ch from that slack, and resize into that very slack space, e.g.:

std::vector<CWhateva> v;
v.resize(100);
v.resize(50); // v's storage capacity is still 100
v.resize(100, v[80]); // when _SECURE_SCL is off, there would be no runtime checks and this may run.

Indeed if v[80] is accepted by ref, even const, it would be overwritten in the last line. I don’t see an inherent problem here, as it seems it should be overwritten by a copy of itself – but I can understand the feeling that overwriting an object with itself might be sensitive. (anyone has a concrete example?).

Then again, maybe he meant something different altogether.

Most of all, I gotta say I was mightily impressed with the speed and seriousness of MS’s replies.  I’m developing quite an email-CHUTZPA lately (more in coming posts), and am always flattered to get responses from busy people.  MS does deserve some kudos there – before realizing Stephen was the right address for this inquiry I mailed the almighty Herb Sutter himself, and got similarly swift and informative responses.