Forcing VC++ Debugger to Display Pointers as Arrays

C++, Development 17 Comments

I’m going to risk being called a dunce for not picking up on this until now, because I think there are probably other people with this annoying problem too. When you’re debugging in VC++, by default raw pointers only display a single item when you expand them, like this:

Now, if you know this pointer is actually a series of items and not just one, you really want to inspect them all - you can add array indices (pFoo[n]) but this is awkward if you want to browse rather than cherry-pick single items. I’ve sometimes used the ‘memory’ view to get around this, which is especially useful if you’re looking at an array of bytes, but arrays of floating point values aren’t that readable via the memory view.

The way to force VC++ to display raw pointers as arrays is to add ‘,n’ to the end of the watch expression, like this:

And if you want to skip a bunch of items, just use pointer arithmetic as usual, such as (pFoo + 50),100 showing items 50-150.

If you knew this already and think I’m a muppet for only just figuring this out, bully for you (although why didn’t you tell me, you bastard? ;) ). I’m hoping to help the poor saps like me who have found this clunky in the past.

By-value static member variables & XCode debug builds

C++, Development, OGRE, OS X 2 Comments

Well, this had me baffled for a while. I’ve been beavering away on allowing custom, user-supplied memory allocators in Ogre, hopefully for inclusion in the upcoming 1.6, and I came across a very weird problem in OS X. The wrapper for customising regular allocations (ie new/delete as opposed to STL allocations, those are in a different std::allocator compatible class), looks like this:

template <class Alloc>
class AllocatedObject
{
protected:
    static Alloc smAllocPolicy;

Pretty obvious stuff, we clearly redirect new/delete operators via that allocator policy. We then go on to define some default allocators (which can be replaced), something like this:

typedef AllocatedObject<StdAllocPolicy> DefaultAllocatedObject;
typedef DefaultAllocatedObject SomeObjectAlloc;

.. and then in our first-party class definition:

class SomeObject : public SomeObjectAlloc
{

All fairly straight forward - all that typedefing is just a compact way of allowing per-class user configurable allocators while still keeping the type duplication to a minimum. I can also place those typedefs in such a way that they can be easily replaced just by user headers or preprocessor blocks. Now, obviously I need to instantiate that smAllocPolicy member, otherwise I’m in trouble. So, here’s what I initially tried to do, in a cpp:

template <> DefaultAllocationPolicy DefaultAllocatedObject::smAllocPolicy;

Seems ok, right? Again I’ve used the typedefs here so that the instantiation will work even if I changed the basis for the types. This worked fine on Visual C++ 2005, Ubuntu 7.1 and in release mode on OS X. But, in debug mode on OS X, I got this:

ld: Undefined symbols:
__ZN4Ogre15AllocatedObjectINS_14StdAllocPolicyEE13smAllocPolicyE
/Users/steve/projects/Shoggoth/ogre/Mac/Ogre/../build/Ogre.build/Debug/Ogre.build/Objects-normal/ppc/OgreEntity.o reference to undefined __ZN4Ogre15AllocatedObjectINS_14StdAllocPolicyEE13smAllocPolicyE
/usr/bin/libtool: internal link edit command failed

WTF? I double-checked that the .cpp was included in the target, that the .LinkFileList file included the right object file, that ZeroLink was disabled (not that that would have any effect but to delay any link errors until runtime anyway). I tried getting rid of the typedefs and making it explicit, no dice. It had me scratching my head for some time, I was convinced I was instantiating this static and the object file was getting linked, so why the problem? In the end, the solution was to to change the instantiation to this:

template <> DefaultAllocationPolicy DefaultAllocatedObject::smAllocPolicy = DefaultAllocationPolicy();

I’m really not sure why in debug mode I was forced to include an explicit construction & assignment of this policy class rather than it being constructed by value in place, as seems to have happened with the other compilers and indeed in release mode under OS X. I usually don’t hold complex types statically by value, so usually I’d have an explicit initialisation in code like this to init pointers to 0 or numerics to something reasonable, so I wouldn’t have tried this particular thing on OS X before, but I did not expect to have to construct a complex type manually (and copy-construct effectively, although that’s likely to be optimised out). The fact that it worked in release mode and on other compilers makes me wonder how idiosyncratic that behaviour is. Maybe I’m just too tired and need to read Stroustrup again. If anyone has a rational explanation, I’d be glad to hear it.

Moving beyond language

C++, Development 9 Comments

When you’re talking with some programmers, particularly younger ones, you can’t help but run into the ‘great language debate’ at some point or another. That is, that many programmers have a language which they feel is superior to all the others, and they’ll put up a ton of resistence should you suggest that they use something else. It happens in other areas too of course - preferred operating systems, databases, apps etc, but as coders the language issue always tends to come up most, closely followed by IDEs.

I’m increasingly finding myself thoroughly tired of those discussions. Over the years, I’ve used a lot of languages - the main ones in approximate order of ‘first encounter’ (excluding assembly, which I don’t count as comparable): BASIC, C, C++, COBOL, Smalltalk, Visual Basic, Java, Prolog, Javascript, Python, Perl, PHP, C#, Lua, Ruby, Actionscript. At one point in my career, I would have obsessed over things like the verbosity of COBOL and Visual Basic (with all those superfluous Dim, As and line continuation bits), how useful closures are, how C++’s template system exceeds ‘generics’ systems, or Perl’s regular expression integration. But over the years while I still have elements I like and dislike about one language or another, and appreciate it when some ‘nice to have’ features are present, I’ve come to the conclusion that none of it really matters. I reckon I could pick up just about any modern programming language and be productive and content with it, because at the end of the day, language nuances are mostly icing - they don’t fundamentally affect the development process at the macro level at all.

Of course, that’s not to say that you’d want to pick up any random language for a given problem; of course not. Each has its own strengths and weaknesses for particular tasks, and crucially most often that’s not even related to the language itself but rather the surrounding ecosystem; platform / operating system support, availability of libraries and frameworks, performance characteristics at build and runtime, integration with existing software etc. This fact is what makes language allegiance so inappropriate in fact, along with unqualified, generalised statements like ‘language A is so much better than language B’. As engineers, which all good programmers should be at heart, we should recognise that each tool has its strengths and weaknesses.

Personally, if I’m looking to do a system automation tool or other portable scripted system, I’d probably look at Python or Perl, or maybe Ruby (except that I’m not as familiar with it), because they’re suited to that kind of task. If I’m looking to do something very intensive where performance and memory footprint is paramount, C or C++ would likely be a good choice. For an ultra-simple web app, PHP might be fastest, or moving up a little Ruby (on rails) might be good. If I need to make a moderately complex Windows-based tool fast, C# might attract me. If I want to make a more complex portable web app, Java is likely to be my choice. Horses for courses.

I think many programmers expend too much emotional energy on the languages that they like. Languages are just a way of expressing the implementation - they’re the very lowest level consideration of any software project. Sure, it’s what the programmer works with every day so maybe they’re entitled to obsess over it a bit, but in my mind that’s short sighted. Really your choice of language should be based based on the surrounding environmental conditions (like requirements for portability, speed, memory usage, deployment, integration, framework needs etc), not preferance for given syntax, since most syntax elements can be expressed in different ways anyway. Let those needs guide / boundary your choice rather than your language preference.

I think it’s actually far more important to think about all the things that apply regardless of implementation language - things like design, use of patterns & frameworks, use of techniques to improve software quality & maintainability like aspect-oriented programming, dependency injection, test driven development, contract-based programming, iterative agile development, all that good stuff. In the end, all of those considerations will impact the quality and maintainability of your final deliverable far more than what language you used.

In short, I think we should stop loving our languages and see them for what they are - simple tools which should demand no more allegiance than spanners, screwdrivers and hammers. Making software is about so much more than the individual characters we type into an editor, and I think we risk losing sight of what’s really important when we’re geeking out over the language minutae - just making good software. I for one don’t consider myself a C++ coder, or a Java coder, or whatever - I make software, and to do that I use a bunch of different tools depending on the circumstances. I actually think the more flexible you can be about those tools, the better.

Why I don’t need Visual Studio 2008 (yet)

C++, OGRE 9 Comments

Visual C++ Express 2008 came out while I was away I see, which inevitably was going to draw calls for a VS9 version of our SDKs (I always buy the Pro version of Visual Studio myself, but I keep an Express version for testing too).

I’ve always been pretty relaxed about this particular version though, because unlike many previous versions it holds precious little for the native C++ developer. Sure, you can use Vista native controls, which will undoubtedly be useful for some people, and if you’re a purely Windows-targetting .Net user then of course the new features in that area are no doubt going to get you all excited, but for me I can only think of one feature that I really hankered for: multiprocessor builds for all files rather than just projects.

VS8 (aka 2005) does make use of multiple processors, but only between separate projects. If you have a solution with many projects in it, you can get some parallelism there, but typically you’ve got dependencies between projects which forces serialisation. For me, OgreMain was the bottleneck, but once that was built all the plugins and samples could then fire off separately. It helped, but it wasn’t perfect. VS9 introduces fully parallel builds of files which means every project can take advantage of multiple processors.

It’s a fair amount to pay for an upgrade just for that though, so I’d pretty much accepted that I’d leave the upgrade for a while and just live with it. However, the ever-resourceful Paul (tuan kuranes) linked in the Ogre Forum a plugin called MPCL for Visual Studio 2005, which adds fully parallel builds without upgrading. I installed it, and my build time for the OgreMain project (debug only) on my 2-core Core 2 Duo E6750 (2.66Mhz) dropped from 6 mins 45 sec to 4 mins 29 sec - ie shaving a third off the build time. Not double the performance, but not to be sniffed at either.

So that seals it - I won’t be upgrading to VS9 just yet. Those who use VS9 can (as I suspected) use the VS8 OGRE SDK binaries anyway, because the native compiler really didn’t change that much, in marked contrast to VS8. Of course you can only use the MPCL plugin if you use the Pro version of VS so I guess those using Express will upgrade to 9 fairly swiftly, so that’s their path unless they want to use VS9 OGRE SDKs created by third parties (I see those are already springing up - may host those if they work). Anyone reading the OGRE forums regularly already knew about this of course but I just thought I’d post it here too, because being away for 2 weeks I missed it entirely and only picked up on it because someone updated the thread today.

Remote debugging tips

C++, OGRE, Tech 4 Comments

I used to use remote debugging as my primary form of debugging many years ago (we’re talking the early to mid 1990’s now), simply because it was impossible to debug code that was tinkering directly with the VGA registers to do things like Mode X any other way. These days I still find it useful although less frequently - I’ve used it to diagnose full-screen issues that couldn’t easily be tracked via simple log output, and at times I’ve used it to debug server applications (J2EE, via Eclipse that time) where the behaviour could not be replicated anywhere but a super-duper beast of a machine. However, I hadn’t set it up in VS2005 yet.

I have plans to set up a couple of extra machines in the office here in the near future to handle compatibility testing, one AGP machine and one PCIE (and one of them with an embedded GMA chipset hopefully), and I already have my wife’s machine for ATI testing, so it was likely I was going to need it again sometime. It came to a head in that I did some work on sRGB support for OGRE recently as part of a contract project I’m involved with, which worked on my 8800 but is borked on ATI machines in GL for reasons unknown right now. It’s a pain to go backwards and forwards with new binaries using simple logging to diagnose so I decided to get remote debugging set up again.

The basic instructions can be found on the MSDN site. It’s pretty much the same as my experience with older versions, except they’re a bit tighter on security now (but I’m on a small  LAN so I turned all that off and ignored the warnings). However there’s one sticking point - the Visual Studio 2005 Debug CRT. The remote machine won’t have the debug runtime unless it has VC installed (unlikely) so you can’t run full debug builds remotely without getting the debug runtimes installed, or changing the way you build your binaries which is undesirable. The debug runtimes are now (of course) using the side-by-side assembly setup, so you can’t just drop the msvcr80d.dll et al in the local folder, you have to install them (unless you do it as a private assembly which is not ‘officially’ recommended and again requires build changes). Whilst it’s easy to install the release CRT using the redist package, the debug runtime has no redist package because, well, you’re not allowed to redistribute it. Internally for testing it’s allowed but there’s no prebuilt package to help you get it set up.

You can supposedly do it manually from the merge modules by running this on the remote machine:

msiexec /i Microsoft_VC80_DebugCRT_x86.msm

Where the .msm is obtained from your c:\Program Files\Common Files\Merge Modules folder. However, I tried that and it didn’t seem to work - it appeared to set up the appropriate folders in the WinSxS area, but looking at it, it did not appear to follow the redirections to the newer DLL versions set up by VC SP1, probably because the .msm didn’t change with SP1 but the external profiles did. That approach just left me in familiar ‘The application failed to initialise’ territory.

So instead, I built a simple Setup and Deployment Project on my dev machine, added the Debug CRT from Project > Add > Merge Modules, built it and ran the resulting setup program on the remote machine. Hey presto, I can now hit F5 and see OGRE fire up on my wife’s machine across the room, pause, debug and resume it all without moving from my chair. Splendid.