<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Rambling Comments</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/" />
    <link rel="self" type="application/atom+xml" href="http://www.lenholgate.com/blog/atom.xml" />
    <id>tag:www.lenholgate.com,2010-12-10:/blog//12</id>
    <updated>2011-06-23T10:09:54Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 5.12</generator>

<entry>
    <title>Alternative call stack capturing</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2008/09/alternative-call-stack-capturing.html" />
    <id>tag:www.socketframework.com,2008:/blog//12.864</id>

    <published>2008-09-25T08:34:31Z</published>
    <updated>2011-06-23T10:09:54Z</updated>

    <summary>I&apos;ve just stumbled on these blog posts, by Maciej Sinilo, a game developer. He&apos;s written a memory allocation monitoring tool and mentions that using RtlCaptureStackBackTrace() is a faster (if undocumented) way to capture a call stack. This is interesting to...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Lock Explorer" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>I've just stumbled on <a href="http://msinilo.pl/blog/?cat=7">these blog posts</a>, by Maciej Sinilo, a game developer. He's written a memory allocation monitoring tool and <a href="http://msinilo.pl/blog/?p=40 ">mentions</a> that using <code>RtlCaptureStackBackTrace()</code> is a faster (if undocumented) way to capture a call stack. This is interesting to me as the call stack capture code in my debugging tools (<a href="http://www.lenholgate.com/archives/000643.html">deadlock detection</a>, timeshifter, <a href="http://www.lenholgate.com/archives/000648.html">tickshifter</a>, etc.) is pretty slow when using <code>StackWalk64()</code>. It's also interesting that he seems to store and sort stacks by CRC which is similar to what I do in my tools.  </p>

<p>This entry's really just so that I don't forget where I found the link...</p>

<p>Oh, and this <a href="http://www.gamasutra.com/view/feature/1430/monitoring_your_pcs_memory_usage_.php">link</a> is really useful to, though I've already been bitten by and fixed most of the issues that are mentioned.</p>

Updated: Link to the docs for <code>RtlCaptureStackBackTrace()</code> is <a href="http://msdn.microsoft.com/en-us/library/bb204633(VS.85).aspx">here</a>; thanks Barry.]]>
        
    </content>
</entry>

<entry>
    <title>More on the CLR startup change</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2008/05/more-on-the-clr-startup-change.html" />
    <id>tag:www.socketframework.com,2008:/blog//12.835</id>

    <published>2008-05-06T14:37:00Z</published>
    <updated>2011-06-23T10:12:58Z</updated>

    <summary>Last week I mentioned that some of my tests for my Win32 Debug API class had suddenly started failing. It seems that I was right and the changes are due to some .Net fixes that have been rolled out recently....</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>Last week I mentioned that some of my tests for my Win32 Debug API class had <a href="http://www.lenholgate.com/archives/000780.html">suddenly started failing</a>. It seems that I was right and the changes are due to some .Net fixes that have been rolled out recently. The code runs and the tests pass if I run on a clean instal Vista x64 VM and fail on my day to day development box. </p>

It seems that my plan to "stick a breakpoint in mscoree.dll's _CorExeMain()" wasn't such a good idea after all. With the new updates installed and with an x64 process using the Win32 debug API to run a CLR 1.0 or 1.1 app (x86) the breakpoint in mscoree.dll's _CorExeMain() never gets hit. Luckilly switching to sticking a breakpoint in mscorwks.dll's _CorExeMain() instead seems to work on both x86 and x64, running either x86 or x64 (where appropriate) CLR apps and on both a clean install of Vista and on patched systems. So, now if the app we're launching is a CLR app we ignore the start address entirely and use mscorwks.dll's _CorExeMain() as our start address. This seems to give a reliable way to halt a CLR app after it has started up, when it's in a stable state, and before it starts to do anything. Just what I need to inject my code.]]>
        
    </content>
</entry>

<entry>
    <title>WOW64 Win32 DebugAPI CLR application startup change</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2008/05/wow64-win32-debugapi-clr-application-startup-change.html" />
    <id>tag:www.socketframework.com,2008:/blog//12.833</id>

    <published>2008-05-01T15:43:42Z</published>
    <updated>2011-06-23T10:21:24Z</updated>

    <summary>Back in October 2007 I sumarised my findings from getting my Win32 DebugAPI based debug engine working on x64. One of the strange things that I found at the time was this: When running a CLR app under the Win32...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Geek Speak" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>Back in October 2007 I <a href="http://www.lenholgate.com/archives/000727.html">sumarised my findings</a> from getting my Win32 DebugAPI based debug engine working on x64. One of the strange things that I found at the time was this:</p>

<p><i>When running a CLR app under the Win32 debug interface you only ever seem to hit the native entry point if you're running under WOW64. In all other situations you don't hit the native entry point ever. If you rely on it to pause your debug tools once the process is completely loaded and ready to roll then you need to stick a break point in _CorExeMain in mscoree.dll. What's more, if you're on x64 you might not even be able to access the native entry point's memory...</i></p>

Well, that seems to have changed... Upon running up my "Debug Tools" test harness a couple of days ago I found I had some test failures when launching CLR 1.0 apps for debug from a Win32 debugger running on an x64 system. On my system only CLR 2.0 apps run as native x64, so, in effect the Win32 debugger was launching a Win32 CLR application whilst running under the WOW64 layer. The behaviour now seems to be identical to running a Win32 CLR application from a Win32 debugger on an x86 system; which, I suppose, is good. The downside is that I've no idea when this change was rolled out and I now have no sure fire way of building a VM box with the old style behaviour to see if I can write some code that works with box fixed and unfixed CLR start up semantics. I guess I can try a clean install of Vista x64...]]>
        
    </content>
</entry>

<entry>
    <title>Summary of x64 Win32 Debug API issues</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2007/10/summary-of-x64-win32-debug-api-issues.html" />
    <id>tag:www.socketframework.com,2007:/blog//12.780</id>

    <published>2007-10-04T07:41:35Z</published>
    <updated>2010-12-27T22:00:36Z</updated>

    <summary>I&apos;ve finished porting my debugging tools support libraries to x64 now and thought it was worth putting up a summary of the issues that I&apos;ve noticed: A 32bit exe can&apos;t start a 64bit exe for debugging - pretty obvious really....</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="x64" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>I've finished porting my debugging tools support libraries to x64 now and thought it was worth putting up a summary of the issues that I've noticed:<br />
</p><ul>
<li>A 32bit exe can't start a 64bit exe for debugging - pretty obvious really.</li><br />
<li>When a 64bit debugger is running a 32bit debugee the debugger seems to get TWO "loader breakpoints" one when the 64bit dlls are loaded and a second when the 32bit dlls have been loaded.</li><br />
<li>In a 32bit debugger running on WOW64 a call to <code>DebugSetProcessKillOnExit()</code> succeeds but doesn't seem to do what it's supposed to do.</li><br />
<li>When a CLR process is started on an x64 machine you can't rely on the image type of the stub to tell you if it will be a native x64 process or an x86 process; the stub for a .Net 2.0 process can be x86 yet can still cause a native x64 CLR host to run the app...</li><br />
<li>When running a CLR app under the Win32 debug interface you only ever seem to hit the native entry point if you're running under WOW64. In all other situations you don't hit the native entry point ever. If you rely on it to pause your debug tools once the process is completely loaded and ready to roll then you need to stick a break point in <code>_CorExeMain</code> in <code>mscoree.dll</code>. What's more, if you're on x64 you might not even be able to access the native entry point's memory...</li><br />
<li>When injecting a dll into a process using the "Richter" thread calls <code>LoadLibrary()</code> approach remember that a) the dll image type (x86/x64) must match the process image type and b) if you're injecting into a 32bit process from a 64bit process you'll need to enumerate the modules in the 32bit process to get the <code>HMODULE</code> to <code>Kernel32.dll</code> so that you're function pointer to <code>LoadLibrary()</code> is offset correctly...</li>
</ul>
And now to update the tools themselves so that they run as 32bit processes with 64bit processes stored as resources (along with the 32bit and 64bit injection dlls) so that they can switch over to 64bit if appropriate and can run natively on 32bit and 64bit OSs and inject into either 32bit or 64bit targets...]]>
        
    </content>
</entry>

<entry>
    <title>WOW64 Win32 DebugAPI and managed code</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2007/10/wow64-win32-debugapi-and-managed-code.html" />
    <id>tag:www.socketframework.com,2007:/blog//12.778</id>

    <published>2007-10-02T08:48:28Z</published>
    <updated>2010-12-27T21:59:02Z</updated>

    <summary>It seems that I&apos;ve located the &quot;issues&quot; in my Debug Tools library. This library is used in my TickShifter (time control) tool and my native Win32 Deadlock Detection tool. Due to how I wanted to control the debugged processes start...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="x64" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>It seems that I've located the "issues" in my Debug Tools library. This library is used in my <a href="http://www.lenholgate.com/archives/000648.html">TickShifter</a> (time control) tool and my <a href="http://www.lenholgate.com/archives/000643.html">native Win32 Deadlock Detection tool</a>. Due to how I wanted to control the debugged processes start up and how I needed to halt the debugged process at a particular time there were some hoops that I found I had to jump through. Those hoops have changed shape; either because of differences between Vista and XP or due to x64 and the WOW64 layer, I'm not sure which yet.</p>

<p>Anyway, when starting a native process under the Debug API it was always easy enough to set a break point in the process' entry point and halt the debugger at that point so that I could inject code and fiddle around. On XP I found that managed processes never hit the native entry point that's written into the PE file and so I had to spot that the process was managed and shove a break point into <code>_CorExeMain</code> in <code>mscoree.dll</code> as that was the nearest alternative. Under x64 using .Net 2.0 I still have to do this (and what's more the entry point in the PE isn't in writable memory, so perhaps it's an offset to a managed entry point...). However, when running with .Net 1.0 or .Net 1.1 on x64 I end up with the WOW64 layer coming to life (which complicates matters a little) and the native entry point IS hit as you'd expect... An added complication is that I can't just use the code that assumes that the native entry point wont be hit and ignore it if it is because under WOW64 I start getting notifications from other threads before my managed entry point is hit and I need to gain control before other threads are running...</p>

<p>Fun, fun, fun... The good news is that I know what's going on now and I expect I can build in some checks that will work out how to take control of the processes that are being started up. I don't really want to look at the managed debug api just yet as that's not really what I need...</p>

Now I just need to work out how to programatically disable the "program has stopped working, dialog" which pops up when my application under test exits due to an exception as my debugger is in control and I don't want windows trying to do 'clever' things for me... And, of course, it's all different under a Win32 build on x64...]]>
        
    </content>
</entry>

<entry>
    <title>x64 Debugger, ExceptionCode == 0x4000001f</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2007/10/x64-debugger-exceptioncode-0x4000001f.html" />
    <id>tag:www.socketframework.com,2007:/blog//12.777</id>

    <published>2007-10-01T12:50:33Z</published>
    <updated>2010-12-27T19:40:53Z</updated>

    <summary><![CDATA[I should be finishing some docs for the x64 release of The&nbsp;Server&nbsp;Framework... But this is more interesting... When running my Win32 debugging code on x64, this time when compiled natively as x64 code and when debugging an x64 CLR process,...]]></summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="x64" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>I should be finishing some docs for the x64 release of <a href="http://www.serverframework.com/">The&nbsp;Server&nbsp;Framework</a>... But this is more interesting...</p>

<p>When running my Win32 debugging code on x64, this time when compiled natively as x64 code and when debugging an x64 CLR process, I've been getting an 'unexpected' ExceptionCode in an <code>EXCEPTION_DEBUG_EVENT</code>. The code is 0x4000001f and, after some searching around, it seems that it's a <code>STATUS_WX86_BREAKPOINT</code> event and I sometimes get these instead of <code>EXCEPTION_BREAKPOINT</code> events...</p>

This is a bit of a surprise, some breakpoints that I've set generate the expected debug event and some generate the 0x4000001f one... This isn't too bad to handle in code except for the fact that I'm getting one of these debug events generated for a break point that I havent set and know nothing about...]]>
        
    </content>
</entry>

<entry>
    <title>DebugSetProcessKillOnExit and Win32 processes on x64</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2007/10/debugsetprocesskillonexit-and-win32-processes-on-x64.html" />
    <id>tag:www.socketframework.com,2007:/blog//12.776</id>

    <published>2007-10-01T09:55:03Z</published>
    <updated>2010-12-27T19:40:36Z</updated>

    <summary>I spent a little time looking at an x64 port of my debugging tools library at the weekend. Since this requires me to set breakpoints and manipulate process memory and image files and all sorts I expected it to be...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="x64" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>I spent a little time looking at an x64 port of my debugging tools library at the weekend. Since this requires me to set breakpoints and manipulate process memory and image files and all sorts I expected it to be a little more complex to port than the higher level sockets code and the bulk of my Win32 code. So far things are going reasonably well, but I've just come across a strangeness with <code>DebugSetProcessKillOnExit(TRUE)</code> in an x86 debugger that's running an x86 process on an x64 machine. It seems like when the debug thread terminates the debugged process doesn't get terminated, it should do, but it doesn't... :(</p>

<p>What's more, changing my code to terminate the process forcibly, with <code>TerminateProcess()</code> if my wait for the debugged process to terminate cleanly times out also fails... The call to <code>TerminateProcess()</code> returns without error but the process is still alive and remains that way until the debugger process itself terminates...</p>

My current best guess is that my code is subtly broken and there's a race condition being exposed on my x64 box that never shows up (the tests don't fail) on my x86 box...]]>
        
    </content>
</entry>

<entry>
    <title>Bug in my debugger code, and hence also in TickShifter</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2007/03/bug-in-my-debugger-code-and-hence-also-in-tickshifter.html" />
    <id>tag:www.socketframework.com,2007:/blog//12.733</id>

    <published>2007-03-05T05:52:34Z</published>
    <updated>2011-06-23T10:21:31Z</updated>

    <summary>Back in April 2006 I posted a copy of TickShifter, see here for details. It seems that there was a bug in my Win32 debugger code on which TickShifter is built. The bug was that we failed to &quot;forget about&quot;...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>Back in April 2006 I posted a copy of TickShifter, see <a href="http://www.lenholgate.com/archives/000648.html">here</a> for details. It seems that there was a bug in my Win32 debugger code on which TickShifter is built. The bug was that we failed to "forget about" dlls that were unloaded... Because we failed to forget about them it was possible for the debugger code to try and do something with addresses in these dlls that were no longer loaded and this would cause a C++ exception on the debugger thread when our call to <code>ReadProcessMemory()</code> failed and this caused all sorts of problems... </p>

<p>The end result of this is that if you try and run TickShifter on an executable that happens to load and then unload a dll during process start up then it probably wont work very well... Internet Explorer is one such executable...</p>

I've fixed the bug, I'll release a new version of TickShifter shortly.]]>
        
    </content>
</entry>

<entry>
    <title>Deadlock detection tool design change for Vista?</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2006/07/deadlock-detection-tool-design-change-for-vista.html" />
    <id>tag:www.socketframework.com,2006:/blog//12.710</id>

    <published>2006-07-12T07:54:17Z</published>
    <updated>2011-07-07T07:21:00Z</updated>

    <summary>It seems that Vista contains lots of interesting new Win32 API calls and some of these provide built in support for deadlock detection... I guess my deadlock detection tool can operate differently on Vista then......</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Geek Speak" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Lock Explorer" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[It seems that Vista contains lots of interesting new Win32 API calls and some of these provide <a href="http://www.bluebytesoftware.com/blog/PermaLink,guid,7a2e54d1-a829-42b7-8059-b3e030da35c1.aspx">built in support for deadlock detection</a>... I guess my <a href="http://www.lockexplorer.com" target="_blank">deadlock detection tool</a> can operate differently on Vista then...]]>
        
    </content>
</entry>

<entry>
    <title>Mock32, parameterize from below</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2006/05/mock32-parameterize-from-below.html" />
    <id>tag:www.socketframework.com,2006:/blog//12.708</id>

    <published>2006-05-12T06:07:26Z</published>
    <updated>2010-12-27T08:19:56Z</updated>

    <summary>It&apos;s funny how potential product ideas beget other potential product ideas and the thing that you eventually end up with as a product for sale is often far from the original product idea and the code that you started to...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        It&apos;s funny how potential product ideas beget other potential product ideas and the thing that you eventually end up with as a product for sale is often far from the original product idea and the code that you started to write... I&apos;m not even there yet and I&apos;m on my third wave of product idea focus. Right now I&apos;m working towards getting some developer tools out there to help people write better systems. This is the API hooking stuff that I&apos;ve blathered on about in the past. The original product idea that started it all was a niche market testing tool that was too big an idea for me to focus on it to start with. Part of that tool required mocking out of Win32 API calls to allow for controlled testing of the target and so the wildly ambitious product 1 gave birth to the slightly more focused product 2.
        <![CDATA[<p>Product 2 became a bit bogged down in the detail. It's a much more generic tool than either product 1 or product 3 and as such it presented several problems that I wasn't ready to face and so I moved on to product 3. Product 3 is the suite of API hooking based debugger tools. These are much easier to understand from a 'who's my market' point of view than product 2, though not as niche as product 1. The handy thing is that they're built on much of the support code that was required for product 2. Anyway, enough of the family tree, I've decided to talk about product 2 for a change.</p>

<p>Product 2 was something that I, rather grandly, named Mock32. The idea being that you could use it to do things like this:</p>
<pre class="brush: cpp gutter: false">   CMockEvent mock;

   mock.Expect(_T("CreateEvent"))
      .Taking(_T("lpEventAttributes"), CNullPointer())
      .Taking(_T("bManualReset"), CFunctionCallData(FALSE))
      .Taking(_T("bInitialState"), CFunctionCallData(FALSE))
      .Taking(_T("lpName"), CNullPointer());                   // Should be able to specify returning 'index 1'
                                                               // or extract the return value?
   mock.Expect(_T("CloseHandle"))
      .Taking(_T("hObject"), CFunctionCallData())              // Should be able to pass 'index 1'
      .Returning(_T("hObject"), CFunctionCallData())
      .Returning(CFunctionCallData(TRUE))
      .LastError(ERROR_SUCCESS);

   {
      CAutoResetEvent event;
   }

   THROW_ON_FAILURE(functionName, true == mock.Verify());
</pre>
<p>And test the lowest level of your code by using mocking and dependency injection techniques to replace and control parts of the Win32 API.</p>

<p>It works. The code above and much more are now part of my Win32Tools test harness suite. My problem was one of moving the workingish code to a product and dealing with the questions of licensing and whatever. It was clear, at the time, that although I could use this stuff it wasn't necessarily easy for anyone else to use; what's more, I'm not even sure that anyone else would want to test at this level...</p>

<p>The more useful tests being ones where you have the mock fail a call which is often complex to force a failure in unexceptional conditions...</p>
<pre class="brush: cpp gutter: false">   CMockEvent mock;
  
   mock.Expect(_T("CreateEvent"));
  
   mock.Expect(_T("SetEvent"));
  
   mock.ExpectAndReturn(_T("SetEvent"))
      .Returning(CFunctionCallData(FALSE))
      .LastError(ERROR_NOT_ENOUGH_MEMORY);
  
   mock.Expect(_T("CloseHandle"));
  
   {
      CEvent event(0, CEvent::AutoReset, CEvent::NonSignaled);
  
      event.Set();
  
      THROW_ON_NO_EXCEPTION(functionName, event.Set);
   }
  
   THROW_ON_FAILURE(functionName, true == mock.Verify());
</pre>
<p>The way the mock is set up above it causes the second call to <code>::SetEvent()</code> that is made to fail and return <code>FALSE</code> with a lastError of <code>ERROR_NOT_ENOUGH_MEMORY</code>. This allows us to force execution of the error handling code path in the class under development; something that would otherwise be extremely difficult to do.</p>

<p>This is the code that I originally developed my <a href="http://www.lenholgate.com/archives/000417.html">code generator</a> for. The code generator can generate much of the code that is required to mock an API by simply running it on the appropriate section of a windows header file. </p>

<p>This is also the code that <a href="http://weblogs.asp.net/rosherove/archive/2005/06/18/413674.aspx">Roy Osherove's comments</a> convinced me to change from a purely log based mock system to one which used expectations. You'll note the JMockesque style of the mock setup. This was well worth doing and moved the code slightly nearer to being something that someone other than me would find useful.</p>

I paused development due to the sheer scale of the work involved. Sure I needn't focus on the whole of the Win32 API to start with but at present the code generator needs adjustments almost every time I decide to add new set of mock functions and the expectations need a lot of work before they'll be as useful as I want them to be. It's unfortunate that the mocks can't "fail fast" in the same way that JMock can; if we detect an expectation failure in an API call there's nothing we can do about it until the call returns. Throwing an exception is a no-no as the Win32 API doesn't do that. Dumping the user in the debugger with an <code>int 3</code> is less than useful in a test. Hence the need for an explicit verification call; this design was still a work in progress when I pressed the pause button on the project. Still, the work was a useful step towards my current product ideas and there's nothing to stop me going back to it in the future as and when I get the time and inclination.]]>
    </content>
</entry>

<entry>
    <title>The thread hijack exercise was a waste of time</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2006/05/the-thread-hijack-exercise-was-a-waste-of-time.html" />
    <id>tag:www.socketframework.com,2006:/blog//12.707</id>

    <published>2006-05-09T07:26:17Z</published>
    <updated>2010-12-27T08:18:41Z</updated>

    <summary>A few weeks ago I wrote about hijacking threads. The principle was good, the code worked but the reason I needed it was flawed so the exercise was a failure. I assumed that it was likely to be a failure...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>A few weeks ago I wrote about <a href="http://www.lenholgate.com/archives/000652.html">hijacking threads</a>. The principle was good, the code worked but the reason I needed it was flawed so the exercise was a failure. I assumed that it was likely to be a failure when I set out though, so it's more a confirmation that I need to do things properly rather than hackily...</p>

The idea was the try and outsmart the Windows program loader. My API hooking tools currently hook the target process when it gets to a point where it has started up but no 'user' code has run. Well, that's not strictly true, any user code that's invoked from the <code>DllMain()</code> of any DLLs loaded has been run, likewise, any code executed as part of a module's static initialisation has also run. The point at which I hook is safe, reliable but fractionally too late for all some potential scenarios.]]>
        <![CDATA[<p>The solution to my problem, I think, is to switch to kernel mode hooking so that I put some hooks in before I start the process and then have complete control over the process startup. That involves getting dirty with drivers though and I don't fancy that quite yet - so I tried the hackier solution...</p>

<p>The idea was that I'd hijack the loader thread as it was loading dlls and (ok, ok, I can see you all rolling your eyes! I did say that I expected this plan to fail didn't I!). Well, since my Win32 Debug API framework allows some fine grained control over the target process so I could at least try. I tried, it failed as expected. Injecting a DLL into a process after kernel32.dll has loaded but before the rest of the dlls load is possible but unreliable; things "go boom" sometimes (rarely, but it happens, ah the advantage of unit tests that you can run over and over again ...). </p>

So, it looks like I'll have to delve into kernel level hooking after all, but not yet. I don't actually need this functionality right now it was just a diversion for whilst I couldn't focus on the real work at hand...]]>
    </content>
</entry>

<entry>
    <title>Hijacking a thread in another process</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2006/04/hijacking-a-thread-in-another-process.html" />
    <id>tag:www.socketframework.com,2006:/blog//12.705</id>

    <published>2006-04-17T18:46:56Z</published>
    <updated>2010-12-27T08:16:45Z</updated>

    <summary>My API hooking currently relies on creating a block of memory in the target process to hold the string that you need to pass to LoadLibraryW() and then calling CreateRemoteThread() and passing the address of LoadLibraryW() as the thread start...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[My API hooking currently relies on creating a block of memory in the target process to hold the string that you need to pass to <code>LoadLibraryW()</code> and then calling <code>CreateRemoteThread()</code> and passing the address of <code>LoadLibraryW()</code> as the thread start address and the address of our block of memory as the thread parameter. It works well and even allows you to know if the operation worked, by waiting for the remote thread to terminate and then examining its exit code. However, there are times when you might not want (or be able to) create a thread in the target process and for those situations something else is called for...]]>
        <![CDATA[<p>My latest bit of exploratory code is based on "<a href="http://www.catch22.net/source/files/InjectThread.c">InjectThread.c</a>" which I found on <a href="http://www.catch22.net/">www.catch22.net</a>. The general idea being that rather than starting a new thread in the target process you hijack an existing thread, change the next instruction that it's going to execute to one of yours and then have your code return back to where the code was prior to your interference. The sample does this by copying code and data onto the target's stack, this will likely fail if <a href="http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2mempr.mspx">DEP</a> is enabled but I expect that if the code were placed in a piece of remotely allocated memory with the correct permissions then everything would be good...</p>

<p>My first stumbling block was that the example code didn't work; well, that's not strictly true, it worked in a release build but not in a debug build. I spent a while fiddling with the settings that made a release build different to a debug build and couldn't work out what was causing the problem so I looked at the compiler output...</p>

<p>I'm not especially clever at assembly language programming. I understand the general concepts and I can read and understand simple code but I don't write a great deal; there simply isn't the need in my line of work and although I've bought several books in the past I've never found the time to study them. This API hooking project has had me reading more assembly than I have in a while; many of the pieces of sample code that I found originally used inline assembly for hook functions, etc. This was useful as my I needed to view (and understand) the disassembly of the release and debug builds of the injected code to work out what was going on...</p>

<p>The disassembly clearly showed the problem, which was that the debug build was inserting some stack checking code in the epilogue of the injected function and, well, it didn't like the fact that we were messing with the stack... Since I still use VC6 for most of my work and since this stack checking is part of VC6's <a href="http://msdn2.microsoft.com/en-US/library/hddybs7t.aspx">/GZ</a> compiler option and the other bits are useful so I didn't want to turn it off. I hoped that <code><a href="http://msdn2.microsoft.com/en-us/library/h5w10wxs(VS.80).aspx">__declspec(naked)</a></code> might help, but it didn't seem to... For now, I've decided that the easiest fix was to simply use the code that the compiler generated for the release build. My injected code is likely to be simple and remain stable so I simply compiled it as a release build and then created an array of bytes with the code bytes from the disassembly window. </p>

<pre class="brush: cpp gutter: false">// Note that we don't actually use this function as only the release build works
// due to the fact that the debug build is built with /GZ which adds stack 
// checks to the epilogue of the function and these go bang when injected...
     
void WINAPI InjProc(INJDATA *pInjData)
{
   pInjData-&gt;pfnLoadLibrary(pInjData-&gt;szText);
}
  
// This is the code that InjProc generates in a release build. We inject this
// directly rather than copying from the function pointer to get the generated
// code...
  
static const BYTE s_code[] = 
{
   0x55,                // push        ebp
   0x8B, 0xEC,          // mov         ebp,esp
   0x8B, 0x45, 0x08,    // mov         eax,dword ptr [pInjData]
   0x83, 0xC0, 0x04,    // add         eax,4
   0x50,                // push        eax
   0x8B, 0x4D, 0x08,    // mov         ecx,dword ptr [pInjData]
   0xFF, 0x11,          // call        dword ptr [ecx]
   0x5D,                // pop         ebp
   0xC2, 0x04, 0x00     // ret         4
};
</pre>

<p>Then, rather copying the code from the address of the function (as the original sample does) I simply pass the hard-coded array of bytes in...</p>

<pre class="brush: cpp gutter: false">   INJDATA injData;
  
   injData.pfnLoadLibrary = LoadLibraryA;
   strcpy(injData.szText, "TestDll.dll");
  
   CThreadHijacker hijacker(
      hProcess,
      hThread,
      (CThreadHijacker::PINJCODE)(void*)s_code, 
      sizeof(s_code), 
      &amp;injData, 
      sizeof(injData));
</pre>

It's a bit of a hack, but it works and means that my thread hijacking code can be used in a debug build...]]>
    </content>
</entry>

<entry>
    <title>I love it when a plan comes together</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2006/04/i-love-it-when-a-plan-comes-together.html" />
    <id>tag:www.socketframework.com,2006:/blog//12.703</id>

    <published>2006-04-14T20:10:51Z</published>
    <updated>2010-12-27T08:16:08Z</updated>

    <summary>Discovering and then fixing the problem that prevented my tools from running on themselves planted a seed of an idea in my mind. My APIHook library and any code that used it died horribly under leak testing tools such as...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[Discovering and then fixing the <a href="http://www.lenholgate.com/archives/000649.html">problem</a> that prevented my tools from running on themselves planted a seed of an idea in my mind. My APIHook library and any code that used it died horribly under leak testing tools such as Purify and BoundsChecker. I'd put it down to me trying to be too clever but not being clever enough and ignored it but it's a pain to have code that you can't polish. Solving the problem of the "wrong address" suggested to me that perhaps these other tools were causing similar problems. It's most likely that they both operate in a similar fashion to my tools (at the API interception level) and since my "fix" was specific to my hooking technique (I hacked the fix into my hook for <code>GetProcAddress()</code>) it made sense that if I could find a more generic solution I might fix the code so that it worked when running under any tool that hooked APIs...]]>
        <![CDATA[<p>The problem was this; any tool that hooks an API using IAT patching most probably also hooks <code>LoadLibrary()</code> and <code>GetProcAddress()</code>; it needs to so that it can make sure the whole process is hooked and that the whole process has the same view of the addresses of the APIs that it has hooked. My DLL injection API hooking technique (well, Jeffrey Richter's really), relies on being able to create a remote thread in the target process and have that thread run <code>LoadLibrary()</code> to load a DLL into that process. The crashes I was experiencing were due to the fact that the address I was getting for <code>LoadLibrary()</code> was the address of a hook which was specific to my tool's process rather than being the real address in Kernel32.dll which is the same in all processes... My <a href="http://www.lenholgate.com/archives/000649.html">first attempt</a> at fixing this was a hack that would only work with my own hooks.</p>

<p>The usual way to obtain the address of a function within a dll is to call <code>GetProcAddress()</code>, however, since we <i>must</i> get the <i>real</i> address of <code>LoadLibrary()</code> and since we must assume that both <code>LoadLibrary()</code> and <code>GetProcAddress()</code> have already been patched by the time we try to obtain the address we need to avoid <code>GetProcAddress()</code> and, instead, do things the hard way.</p>

<p>So, how do you find the address of an exported function from a DLL if you can't use the normal means? Step one is map the DLL into memory as a normal file. Once you've done this you can pick apart the PE file format (the format used for all Windows DLL and EXE files) and walk the various structures until you have the address that you need. Luckilly the "hard way" isn't really that hard; especially since Matt Pietrek has <a href="http://msdn.microsoft.com/msdnmag/issues/02/02/PE/default.aspx">written a great article</a> on the PE file format, and even more especially since that article comes with code that dumps PE files. </p>

<p>The resulting piece of code that works out the address of a function within a module is as follows:</p>

<pre class="brush: cpp gutter: false">DWORD CRawImage::GetExportedProcRVA(
   const _tstring &amp;name) const
{
   const string narrowName = CStringConverter::TtoA(name);

   const DWORD exportsStartRVA = m_pNTHeader-&gt;OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
   const DWORD exportsEndRVA = exportsStartRVA + m_pNTHeader-&gt;OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;

   IMAGE_EXPORT_DIRECTORY *pExports = reinterpret_cast&lt;IMAGE_EXPORT_DIRECTORY*&gt;(GetPtrFromRVA(exportsStartRVA, m_pNTHeader, m_pImageBase));

   DWORD *pFunctions = reinterpret_cast&lt;DWORD*&gt;(GetPtrFromRVA(pExports-&gt;AddressOfFunctions, m_pNTHeader, m_pImageBase));
   WORD *pOrdinals =	reinterpret_cast&lt;WORD *&gt;(GetPtrFromRVA(pExports-&gt;AddressOfNameOrdinals, m_pNTHeader, m_pImageBase));
   DWORD *pFuncNames =  reinterpret_cast&lt;DWORD*&gt;(GetPtrFromRVA(pExports-&gt;AddressOfNames, m_pNTHeader, m_pImageBase));

   for (size_t i = 0; i &lt; pExports-&gt;NumberOfFunctions; ++i)
   {
      const DWORD entryPointRVA = *(pFunctions + i);

      if (entryPointRVA != 0)       // Skip over gaps in exported function ordinals
      {
         // Look for a name

         for (size_t j = 0; j &lt; pExports-&gt;NumberOfNames; ++j)
         {
            if (pOrdinals[j] == i)
            {
               if (narrowName == reinterpret_cast&lt;char*&gt;(GetPtrFromRVA(pFuncNames[j], m_pNTHeader, m_pImageBase)))
               {
                  // We dont handle forwarders...

                  return entryPointRVA;
               }
            }
         }
      }
   }

   return 0;
}</pre>

<p>Note that this only returns the RVA (relative virtual address) of the function. We actually want the address relative to the load address of Kernel32.dll rather than relative to where we mapped our view of Kernel32.dll to be able to walk its PE format...</p>

<p>The following provides the address when given a handle to a properly loaded module...</p>

<pre class="brush: cpp gutter: false">FARPROC CRawImage::GetExportedProcAddressInModule(
   HMODULE hModule,
   const _tstring &amp;name) const
{
   FARPROC pProc = 0;

   const DWORD rva = GetExportedProcRVA(name);

   if (rva)
   {
      pProc = reinterpret_cast&lt;FARPROC&gt;(reinterpret_cast&lt;DWORD&gt;(hModule) + rva);
   }

   return pProc;
}
</pre>

<p>So now that I'm free from using a potentially compromised <code>GetProcAddress()</code> and can locate the address of <code>LoadLibrary()</code> myself I can remove the hacky fix that I put in to my hooking code. Once the code was adjusted and the tests passed I built the whole lot under the tools that were causing problems and everything worked nicely. </p>

I love it when a plan comes together...]]>
    </content>
</entry>

<entry>
    <title>Tools, debug thyselves</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2006/04/tools-debug-thyselves.html" />
    <id>tag:www.socketframework.com,2006:/blog//12.702</id>

    <published>2006-04-12T07:31:47Z</published>
    <updated>2011-06-23T10:21:37Z</updated>

    <summary>One of the first things that I tried to do with the latest release of my TickShifter tool was to run it on itself. Of course, that didn&apos;t work. There are several reasons why the tool might have had problems...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[<p>One of the first things that I tried to do with the latest release of my <a href="http://www.lenholgate.com/archives/000648.html">TickShifter</a> tool was to run it on itself. Of course, that didn't work.</p>

<p>There are several reasons why the tool might have had problems running on itself but I thought I'd addressed most of them when I dealt with the issues around getting multiple copies of the tool running at the same time. The problems there were mostly around the names that I used for the named kernel objects that were required; the control program communicates with the dll that it injects so that it can control the dll's operation and collect data. This communication requires some named objects, pipes, shared memory, events, etc, so that the dll can correctly hook up with the control program. Initially these names were fixed and that meant that only one instance of the tool could run at a time, adding the process Id of the running instance of the tool to the names fixed that little problem.</p>

So, I was pretty sure that it wasn't anything to do with kernel object naming and <a href="http://www.sysinternals.com/">SysInternals</a> <a href="http://www.sysinternals.com/Utilities/ProcessExplorer.html">Process Explorer</a> showed me that I was correct in this, so what was the problem?
]]>
        <![CDATA[<p>The tools all use API hooking to do their work. The control program, the bit of the tool that you see and interact with, injects a dll into the target program and this dll hooks specific APIs within the target program and communicates back with the control program. The API hooking code is pretty standard stuff, based on the design that's straight out of Richter's books. Part of this design ensures that when each new dll is loaded into the target process it's hooked correctly. This requires that the code that does the hooking of your target APIs also hooks <code>LoadLibrary()</code> so that it can hook all newly loaded dlls and <code>GetProcAddress()</code> so that it can lie about function addresses to anyone that asks.</p>

<p>The problem I had was that to inject the dll into the target process the control program needs to find out the address of <code>LoadLibrary()</code> in itself and, since it's implemented in Kernel32.dll, and that's always loaded in the same place in all processes, that address is the same in the target process. The result of this is used in the call to create a remote thread in the target process and this remote thread loads the dll into the target. My problem was that in the tool that was running under a tool, the address that I was getting back from <code>GetProcAddress()</code> for <code>LoadLibrary()</code> was the address of the hooked function in the tool process and not the address of the real function in Kernel32. Since the hooked function only existed in the hooked tool and not in the target process the target process died with an access violation when the remote thread tried to call <code>LoadLibrary()</code>. </p>

<p>It's a fairly obvious problem once you realise what's going on. Of course getting to that realisation stage took a while. Debugging debuggers that inject code into target processes isn't the simplest thing in the world and I ended up doing it the "<a href="http://www.lenholgate.com/archives/000539.html">old fashioned way</a>" with <code>OutputDebugString()</code>. This also wasn't as easy as it could have been because my tool, the control program, is a Win32 debugger and, as such, it receives the <code>OutputDebugString()</code> output from all of its child processes.  So, to see that child process output I needed to have the debugger call <code>OutputDebugString()</code> on the strings that it was passed via the <code>EXCEPTION<em>DEBUG</em>INFO</code> structure...</p>

<p>Once I'd located the problem, solving it took a little while. The obvious solution is to simply provide the real address when required. Unfortunately, possibly due to my design, that's a little harder than it should be. When I fixed the code so that it worked with the tool that had been hooked by another tool the tool that wasn't hooked stopped working... Eventually I figured it out and the latest, as yet unreleased, version of <a href="http://www.lenholgate.com/archives/000648.html">TickShifter</a> can now shift the ticks on an instance of itself which can shift the ticks on an instance of itself, etc... </p>

This is handy as it means that I could now run my <a href="http://www.lenholgate.com/archives/000643.html">deadlock detection tool</a> on the other tools whilst I'm developing them, should I need to do so!
]]>
    </content>
</entry>

<entry>
    <title>TickShifter v0.2</title>
    <link rel="alternate" type="text/html" href="http://www.lenholgate.com/blog/2006/04/tickshifter-v02.html" />
    <id>tag:www.socketframework.com,2006:/blog//12.701</id>

    <published>2006-04-09T20:49:28Z</published>
    <updated>2011-06-23T10:15:38Z</updated>

    <summary>As I mentioned a while back, I&apos;ve been working on adding rudimentary GUIs to my debugging and testing tools. In fact, both the deadlock detection tool and the time shifting tool are both functional enough for real world use but...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Debugging Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-us" xml:base="http://www.lenholgate.com/blog/">
        <![CDATA[As I mentioned a <a href="http://www.lenholgate.com/archives/000643.html">while back</a>, I've been working on adding rudimentary GUIs to my debugging and testing tools. In fact, both the <a href="http://www.lenholgate.com/archives/000489.html">deadlock detection tool</a> and the <a href="http://www.lenholgate.com/archives/000576.html">time shifting tool</a> are both functional enough for real world use but the command line interfaces make them harder to use than they need to be. I'm not yet 100% sure of the form that the final GUI should take, but I've pressed on with my initial GUI development to produce a reasonably complete GUI for the cut down, demonstration tool, <a href="http://www.lenholgate.com/archives/000647.html">TickShifter</a>.]]>
        <![CDATA[<p>The GUI version of the tool accepts the same command line arguments as the console mode version that I wrote about <a href="http://www.lenholgate.com/archives/000647.html">here</a>. It also accepts an additional argument of <code>-launch</code> which, when used with <code>-exe</code> will cause the target process to be started automatically. Without <code>-launch</code> the command line arguments simply allow you to "automatically fill in" some of the required input data.</p>

<p>The GUI is fairly simple.</p>

<p><a href="http://www.lenholgate.com/blog/assets_c/2010/12/TickShifter-28.html" onclick="window.open('http://www.lenholgate.com/blog/assets_c/2010/12/TickShifter-28.html','popup','width=833,height=448,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.lenholgate.com/blog/assets_c/2010/12/TickShifter-thumb-500x268-28.png" width="500" height="268" alt="TickShifter.png" class="mt-image-none" style="" /></a></p>

<p>Simply browse for, or type in, a target process, select how you want to adjust the results of its calls to <code>GetTickCount()</code> and hit the "Launch" button.</p>

<p><a href="http://www.lenholgate.com/blog/assets_c/2010/12/TickShifterShifting-31.html" onclick="window.open('http://www.lenholgate.com/blog/assets_c/2010/12/TickShifterShifting-31.html','popup','width=1126,height=546,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.lenholgate.com/blog/assets_c/2010/12/TickShifterShifting-thumb-500x242-31.png" width="500" height="242" alt="TickShifterShifting.png" class="mt-image-none" style="" /></a></p>

<p>Once you're running a process under the tool you'll see the "session" listed in the sessions list. A session is a collection of data from one or more processes under test. Each time you hit the "Launch" button you create a new session. Viewing the session data shows you the processes that were monitored during the session. If the process that you launched didn't launch any child processes then this dialog will simply list one process. The multiple-process support isn't especially useful for the simple TickShifter tool (but then it is just a minimal example of how the tools work!), it's much more useful for the Deadlock detection tool as it allows deadlock detection to operate on named kernel objects across processes rather than simply within a single process.</p>

<p><a href="http://www.lenholgate.com/blog/assets_c/2010/12/TickShifterSession-34.html" onclick="window.open('http://www.lenholgate.com/blog/assets_c/2010/12/TickShifterSession-34.html','popup','width=1102,height=683,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.lenholgate.com/blog/assets_c/2010/12/TickShifterSession-thumb-500x309-34.png" width="500" height="309" alt="TickShifterSession.png" class="mt-image-none" style="" /></a></p>

<p>From the session display you can navigate to each individual process. The TickShifter GUI simply displays all of the calls that the process has made to <code>GetTickCount()</code> more complex tools might show a tab for each lock that's accessed by the process, another tab for each thread, another showing the overall ordering of lock access within the process, etc. The number next to each entry is the location that the call occurred at. Clicking on the location takes you to a call stack display.</p>

<p><a href="http://www.lenholgate.com/blog/assets_c/2010/12/TickShifterCallStack-37.html" onclick="window.open('http://www.lenholgate.com/blog/assets_c/2010/12/TickShifterCallStack-37.html','popup','width=1079,height=660,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.lenholgate.com/blog/assets_c/2010/12/TickShifterCallStack-thumb-500x305-37.png" width="500" height="305" alt="TickShifterCallStack.png" class="mt-image-none" style="" /></a></p>

<p>And that's about it. If you come across buttons that never become enabled that's because the code isn't finished. Likewise the "namespace" removal stuff doesn't yet work; once it does it will allow you to make the call stack display easier to read by being able to specify namespaces that you'd like stripped from function names.</p>

<p>I quite expect that this will fail to work on your machine, but I'd like to know if it does so that I can fix it! Comments and suggestions welcome, as always.</p>

TickShifter v0.2 can be downloaded from <a href="http://www.lenholgate.com/zips/TickShifter-0.2.zip" onclick="_gaq.push(['_trackEvent', 'Downloads', 'TickShifter-0.2.zip']);">here</a>. You can use the sample projects that I provided with v0.1 to see it in action.]]>
    </content>
</entry>

</feed>



