<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>luminance &#187; C++</title>
	<atom:link href="http://www.luminance.org/tag/c/feed" rel="self" type="application/rss+xml" />
	<link>http://www.luminance.org/blog</link>
	<description>Programming and Game Development - Kevin Gadd&#039;s Blog</description>
	<lastBuildDate>Sun, 02 Oct 2011 00:15:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Copying pixels from a pointer to an XNA Texture2D</title>
		<link>http://www.luminance.org/blog/code/2011/10/01/copying-pixels-from-a-pointer-to-an-xna-texture2d</link>
		<comments>http://www.luminance.org/blog/code/2011/10/01/copying-pixels-from-a-pointer-to-an-xna-texture2d#comments</comments>
		<pubDate>Sun, 02 Oct 2011 00:15:58 +0000</pubDate>
		<dc:creator>Kael</dc:creator>
				<category><![CDATA[AltDevBlogADay]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Awesomium]]></category>
		<category><![CDATA[berkelium]]></category>
		<category><![CDATA[blasphemy]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[xna]]></category>

		<guid isPermaLink="false">http://www.luminance.org/blog/?p=1033</guid>
		<description><![CDATA[In the XNA framework, the only way to load pixel data into a texture is to provide it in the form of a .NET Array. In most cases, this isn&#8217;t a problem &#8211; you can specify an offset into the array, and the array can be of any type. However, if you&#8217;re using a library [...]]]></description>
			<content:encoded><![CDATA[<p>In the XNA framework, the only way to load pixel data into a texture is to provide it in the form of a .NET Array. In most cases, this isn&#8217;t a problem &#8211; you can specify an offset into the array, and the array can be of any type. However, if you&#8217;re using a library like <a href="http://awesomium.com/">Awesomium</a> or <a href="http://berkelium.org/">Berkelium</a>, you will end up with large blocks of pixel data in the form of a pointer. The only way to turn this into an array is to manually allocate an array of the appropriate size and copy the pixels over every time they change. Not only does this waste memory, but it&#8217;s relatively expensive.</p>
<p>In this post I&#8217;ll show you a (fairly evil) way to copy pixel data directly from a pointer into an XNA texture using C#, PInvoke, and some knowledge of XNA internals.</p>
<p>The first step is to understand how XNA&#8217;s <tt>Texture2D.SetData</tt> method works normally. I opened it up in <a href="http://wiki.sharpdevelop.net/ILSpy.ashx">ILSpy</a>, a free .NET decompiler.<br />
Looking at the three overloads of <tt>SetData</tt> reveals that they all call into a private method called <tt>CopyData</tt>, with this signature:</p>
<pre>private unsafe void CopyData&lt;T&gt;(int level, Rectangle? rect, T[] data, int startIndex, int elementCount, uint options, [MarshalAs(UnmanagedType.U1)] bool isSetting) where T : struct</pre>
<p>The method is large and complicated, and parts of it don&#8217;t decompile into readable, valid C#. But we can understand what it does and how it does it with some research and careful examination of the decompiled code.</p>
<p>The first part of the function spends a bunch of time validating all the provided arguments. It ensures that the texture being modified isn&#8217;t active as a render target or attached to one of the device&#8217;s texture samplers, and validates other parameters like the size of the texture and the size of the data provided.</p>
<p>However, you start to see rather confusing code like this in the disassembly:</p>
<pre>	_D3DSURFACE_DESC d3DSURFACE_DESC;
	initblk(ref d3DSURFACE_DESC, 0, 32);
	IDirect3DTexture9* ptr = this.pComPtr;
	int num3 = calli(System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall)(System.IntPtr,System.UInt32,_D3DSURFACE_DESC*), ptr, level, ref d3DSURFACE_DESC, *(*(int*)ptr + 68));
	if (num3 < 0)
	{
		throw GraphicsHelpers.GetExceptionFromResult(num3);
	}</pre>
<p>If you know enough about .NET bytecode (CIL/MSIL), it may be easier to understand what's going on here. Bytecodes that couldn't be mapped to C# constructs were basically spit out directly as if those bytecodes were functions. This is happening because XNA is mostly written in C++/CLI, not C#.</p>
<p>First, the <tt><a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.initblk.aspx">initblk opcode</a></tt> is used to zero-initialize the contents of a new <tt>D3DSURFACE_DESC</tt> structure. This is equivalent to doing a <tt>memset</tt> in native C/C++.</pre>
<p>Next, the <tt><a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.calli.aspx">calli</a></tt> opcode is used. Essentially, this opcode allows you to invoke a native function directly, given a function pointer and knowledge of the function&#8217;s signature. All of the decompiled code here is essentially describing the signature of the function and then providing arguments for it. You&#8217;ll probably never see this generated by C# code, but it&#8217;s used often in C++/CLI to invoke native functions &#8211; and in this case, it&#8217;s being used to invoke a method of a COM interface.</p>
<p>How can you tell it&#8217;s being used to invoke a method of a COM interface? There are a few clues here:<br />
First, we notice that <tt>ptr</tt> contains a pointer of type <tt>IDirect3DTexture9</tt> &#8211; a COM interface. Second, we can look at the argument list to the <tt>calli</tt> instruction:</p>
<pre>System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall)(System.IntPtr,System.UInt32,_D3DSURFACE_DESC*), ptr, level, ref d3DSURFACE_DESC, *(*(int*)ptr + 68));</pre>
<p>First we have the return type of the function &#8211; <tt>System.Int32</tt>. Next, two modifiers that notify the compiler about the nature of the function &#8211; it&#8217;s a <tt>stdcall</tt>, and the return type is a C++ &#8216;<tt>long</tt>&#8216; with the semantics that implies. This doesn&#8217;t really matter much to us at the moment, but it&#8217;s good to understand the basics.<br />
Next, the argument types for the function are provided: <tt>System.IntPtr</tt>, <tt>System.UInt32</tt>, and a <tt>D3DSURFACE_DESC *</tt>.</p>
<p>Given this information, we now know the signature of the function being called, so we could write an equivalent delegate if we wanted. The decompilation doesn&#8217;t tell us the name of the function, but given the name of the interface (<tt>IDirect3DTexture9</tt>) and the argument list, we can check that interface&#8217;s documentation on MSDN and try to figure out which function it is.</p>
<p>Finally, let&#8217;s look at the actual arguments being passed when invoking the function:</p>
<pre>ptr, level, ref d3DSURFACE_DESC, *(*(int*)ptr + 68)</pre>
<p>First, we see the first three arguments are of the appropriate type for the function&#8217;s signature and their values make sense. There&#8217;s a fourth argument, though, and it looks funny &#8211; in fact, it looks like the decompiler didn&#8217;t quite make sense of it. What is that?</p>
<p>Well, we know that <tt>ptr</tt> is a pointer to an <tt>IDirect3DTexture9</tt>. First, the code is dereferencing the pointer. If you know enough about COM, you will realize that dereferencing a pointer to a COM interface will allow you to <b>access that interface&#8217;s vtable</b>. The vtable contains pointers to each function provided by the interface, which allows you to invoke those functions on a given instance.<br />
Given that the code is dereferencing the interface pointer and then adding an offset to it, we can now infer that it&#8217;s pulling a specific function out of the interface&#8217;s VTable. Again, we can&#8217;t immediately tell which function, but we have a lot of information here that we could use to figure it out.</p>
<p>This makes it pretty clear that a COM function is being called on the interface, because we can see the function pointer being pulled out of the COM vtable and passed to the <tt>calli</tt> instruction, along with a function signature and argument types that seem like a perfect fit for a COM method (<tt>HRESULT</tt> return value, first argument is the interface pointer).</p>
<p>At this point, we could dig through the vtable and find our way to the necessary method calls to lock the texture and get a pointer to its pixels. Then we could do any necessary pixel format conversion, etc while copying from our buffer to the texture. However, there&#8217;s an easier solution!</p>
<p>If you read through the code for the method, in certain code paths, it makes use of a D3DX function called <tt><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb172904%28v=vs.85%29.aspx">D3DXLoadSurfaceFromSurface</a></tt>. It&#8217;s a pretty useful function &#8211; it can convert pixel formats, resample textures, and even handle DXTC compression. And if you look through the documentation, there&#8217;s <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb172902%28v=VS.85%29.aspx">a version of this function that can take a pointer as a source instead of another surface</a> &#8211; making it perfect for our needs. We just have to find a way to call that function and hand it our image data pointer and D3DX will handle any necessary pixel format conversion and copy our pixel data to the texture.</p>
<p>Now, to call the function. First, we need to get ourselves an interface pointer. If we&#8217;re willing to use reflection, this is quite simple &#8211; we can get ourselves a reference to the <tt>pComPtr</tt> field we see used in the disassembly and use that reference to get the interface pointer for a given texture, like so:</p>
<pre>public static class TextureUtils {
  internal static FieldInfo pComPtr;

  static TextureUtils () {
    pComPtr = typeof(Texture2D).GetField("pComPtr", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
  }

  public static unsafe void* GetIDirect3DTexture9 (this Texture2D texture) {
    return Pointer.Unbox(pComPtr.GetValue(texture));
  }</pre>
<p>Next, we can set up the necessary P/Invoke skeleton to be able to invoke the D3DX function. We need two enumerations, a struct, and finally the function itself:</p>
<pre>
// Some enumeration members omitted for readability
public enum D3DFORMAT : uint {
    UNKNOWN              =  0,

    R8G8B8               = 20,
    A8R8G8B8             = 21,
    X8R8G8B8             = 22,
    A8B8G8R8             = 32,
    X8B8G8R8             = 33,
}

[Flags]
public enum D3DX_FILTER : uint {
    DEFAULT              = 0xFFFFFFFF,
    NONE                 = 0x00000001,
    POINT                = 0x00000002,
    LINEAR               = 0x00000003,
}

[StructLayout(LayoutKind.Sequential)]
public struct RECT {
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

// Note that we need to be careful to use the same exact version of D3DX that XNA uses.
[DllImport("d3dx9_41.dll")]
private static unsafe extern int D3DXLoadSurfaceFromMemory (
    void* pDestSurface, void* pDestPalette, RECT* pDestRect,
    void* pSrcMemory, D3DFORMAT srcFormat, uint srcPitch,
    void* pSrcPalette, RECT* pSrcRect,
    D3DX_FILTER filter, uint colorKey
);</pre>
<p>At this point, however, you might have realized the problem: This function takes a pointer to an <tt>IDirect3DSurface9</tt>, not an <tt>IDirect3DTexture9</tt>. How do we go from a Texture to a Surface? Well, the MSDN documentation shows that there&#8217;s a convenient method that will give us the surface pointer for a given mip level of a texture: <a href="http://msdn.microsoft.com/en-us/library/bb205912%28VS.85%29.aspx">GetSurfaceLevel</a>. But given that all we have is a <tt>void *</tt>, how can we call it? There are a few ways, of course &#8211; you could write a tiny C++ library to do the work, or you could add a reference to the Managed DirectX libraries, or something like that. But we&#8217;re going to do it the way they do it in C &#8211; with pointers!</p>
<p>To make sure we&#8217;re on the right track, we can first dig through the disassembly of <tt>CopyData</tt> to find the spot where it calls <tt>GetSurfaceLevel</tt>. Since we know the argument types and return type, it&#8217;s not too hard to find:</p>
<pre>IDirect3DSurface9* ptr3;
IDirect3DTexture9* ptr4;
num5 = calli(System.Int32 modopt(System.Runtime.CompilerServices.IsLong) modopt(System.Runtime.CompilerServices.CallConvStdcall)(System.IntPtr,System.UInt32,IDirect3DSurface9**), ptr4, 0, ref ptr3, *(*(int*)ptr4 + 72));
if (num5 >= 0) {</pre>
<p>With what we know about COM method invocations, we can tell this is invoking a method of <tt>IDirect3DTexture9</tt> with an integer parameter (0) and a pointer-to-pointer parameter of type <tt>IDirect3DSurface9</tt>. This is definitely <tt>GetSurfaceLevel</tt>. This not only tells us what the right signature for the function looks like, but it also tells us where in the interface&#8217;s VTable we can find a pointer to the function in order to call it. So, armed with this knowledge, we can write some terrifying unsafe code to pull the function pointer out of the VTable:</p>
<pre>
// This could be written better, probably. I'm lazy.
public static unsafe void* AccessVTable (void* pInterface, uint offsetInBytes) {
    void* pVTable = (*(void**)pInterface);
    return *((void**)((ulong)pVTable + offsetInBytes));
}</pre>
<p>And, using that function along with an appropriate delegate type, we can put these pieces together to get a surface pointer:</p>
<pre>internal unsafe delegate int GetSurfaceLevelDelegate (void* pTexture, uint iLevel, void** pSurface);

public static class VTables {
    public static class IDirect3DTexture9 {
        public const uint GetSurfaceLevel = 72;
    }
}

public static unsafe void* GetSurfaceLevel (this Texture2D texture, int level) {
    void* pTexture = texture.GetIDirect3DTexture9();
    void* pGetSurfaceLevel = AccessVTable(pTexture, VTables.IDirect3DTexture9.GetSurfaceLevel);
    void* pSurface;

    var getSurfaceLevel = (GetSurfaceLevelDelegate)Marshal.GetDelegateForFunctionPointer(
        new IntPtr(pGetSurfaceLevel), typeof(GetSurfaceLevelDelegate)
    );

    var rv = getSurfaceLevel(pTexture, 0, &#038;pSurface);
    if (rv == 0)
        return pSurface;
    else
        throw new COMException("GetSurfaceLevel failed", rv);
}</pre>
<p>We use the marshalling API to turn the function pointer into a callable delegate with the appropriate signature, and then call it in order to get ourselves an interface pointer. Now, we&#8217;re finally ready to call D3DX! Let&#8217;s wrap this magic up with a helpful function:</p>
<pre>public static unsafe void SetData (
    this Texture2D texture, int level, void* pData,
    int width, int height, uint pitch,
    D3DFORMAT pixelFormat
) {
    var rect = new RECT {
        Top = 0,
        Left = 0,
        Right = width,
        Bottom = height
    };

    void* pSurface = GetSurfaceLevel(texture, level);

    try {
        var rv = D3DXLoadSurfaceFromMemory(pSurface, null, &#038;rect, pData, pixelFormat, pitch, null, &#038;rect, D3DX_FILTER.NONE, 0);
        if (rv != 0)
            throw new COMException("D3DXLoadSurfaceFromMemory failed", rv);
    } finally {
        Release(pSurface);
    }
}</pre>
<p>You&#8217;ll note that we&#8217;re also ensuring that we decrement the reference count on the surface after we&#8217;re done with it so it doesn&#8217;t leak. To do this, we wrote a quick helper function:</p>
<pre>internal unsafe delegate uint ReleaseDelegate (void* pObj);

public static class VTables {
    public static class IUnknown {
        public const uint Release = 8;
    }
}

public static unsafe uint Release (void* pObj) {
    void* pRelease = AccessVTable(pObj, VTables.IUnknown.Release);
    var release = (ReleaseDelegate)Marshal.GetDelegateForFunctionPointer(new IntPtr(pRelease), typeof(ReleaseDelegate));

    return release(pObj);
}</pre>
<p>And now, after all that hard work, copying pixel data from an Awesomium WebView into an XNA texture is as simple as this:</p>
<pre>var rb = WebView.Render();
WebViewTexture = new Texture2D(GraphicsDevice, rb.Width, rb.Height, false, SurfaceFormat.Color);
WebViewTexture.SetData(0, rb.Buffer.ToPointer(), rb.Width, rb.Height, (uint)rb.Rowspan, D3DFORMAT.A8R8G8B8);</pre>
<p>If you&#8217;d like to use this for yourself, you can <a href="https://github.com/kevingadd/Fracture/blob/master/Squared/RenderLib/Evil.cs">download it in a ready-to-use form from my GitHub repository</a>. Hope it&#8217;s helpful!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.luminance.org/blog/code/2011/10/01/copying-pixels-from-a-pointer-to-an-xna-texture2d/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>In-Depth Python/CPython crash debugging with Visual C++</title>
		<link>http://www.luminance.org/blog/code/2009/06/07/in-depth-pythoncpython-crash-debugging-with-visual-c</link>
		<comments>http://www.luminance.org/blog/code/2009/06/07/in-depth-pythoncpython-crash-debugging-with-visual-c#comments</comments>
		<pubDate>Sun, 07 Jun 2009 17:00:33 +0000</pubDate>
		<dc:creator>Kael</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[cpython]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.luminance.org/?p=371</guid>
		<description><![CDATA[If you do a lot of work with Python&#8217;s standard C implementation, CPython, there&#8217;s a chance that you&#8217;ll run into issues that will actually crash python.exe. If you&#8217;re writing extensions for python in C/C++ (.pyd files), it&#8217;s likely that some of those crashes are the result of your code. Naturally, if your C++ caused python.exe [...]]]></description>
			<content:encoded><![CDATA[<p><span style="float: right"><script src="http://www.reddit.com/button.js?t=2&amp;url=http://www.luminance.org/code/2009/06/07/in-depth-cpython-debugging-with-visual-c" type="text/javascript"></script></span></p>
<p>If you do a lot of work with Python&#8217;s standard C implementation, CPython, there&#8217;s a chance that you&#8217;ll run into issues that will actually crash python.exe. If you&#8217;re writing extensions for python in C/C++ (.pyd files), it&#8217;s likely that some of those crashes are the result of your code. Naturally, if your C++ caused python.exe to crash, you&#8217;re going to attach a debugger and take a look.</p>
<p>If the problem is in your code, often it&#8217;s simple to see it &#8211; just look at your argument values and data structures. But what if the problem exists outside your code, and somewhere in python? All you have in the debugger are a bunch of PyObject * values; Visual C++ or WinDBG won&#8217;t do much to help you work with them. Faced with this, your best options are usually to add debugging code to your python &#8211; print statements, assertions, etc. Eventually, you might be able to puzzle out the problem and a solution.</p>
<p>But as it turns out, PyObject doesn&#8217;t have to be a black box. If you&#8217;re using Visual C++, you have all the tools you need to dig around inside of CPython &#8211; even if you just caught an unhandled exception.</p>
<p>For this to work, you&#8217;ll need a recent version of Visual C++, along with debug symbols for python25.dll. You also need debug symbols for your C/C++ extension (the .pyd). Once you&#8217;ve got all this, attach the visual C++ debugger to your application, and either set a breakpoint in your code, or wait for an unhandled exception.</p>
<p>Once you&#8217;re paused in the debugger, inside your code, you&#8217;re ready to get to work. Let&#8217;s use a hypothetical example. We&#8217;ve got a simple object, written in C, with a method exposed to python called &#8216;print&#8217;. The function we wrote in C to handle the method is called MyPrint:</p>
<pre>void MyPrint(PyObject * self, PyObject * args) {
    const char *text;

    if (!PyArg_ParseTuple(args, "s", &amp;text))
        return NULL;

    int result = printf("%s", text);

    return Py_BuildValue("i", result);
}</pre>
<p>The function is simple &#8211; we take a single argument from the python dict (args), convert it to a string, and call printf to print it to standard output. Then we return printf&#8217;s return value (the number of characters written) as a python int.</p>
<p>So, let&#8217;s suppose that MyPrint crashes. We&#8217;re now sitting in the debugger, and staring at a couple opaque PyObject * pointers. If we&#8217;re lucky, we got past the ParseTuple call and the &#8216;text&#8217; pointer is valid too. Unfortunately, the debugger isn&#8217;t going to be very helpful. If you look at &#8216;self&#8217; and &#8216;args&#8217; in the Locals or Watch windows, you&#8217;re going to see something like this:</p>
<pre>args     0x1179a650 {ob_refcnt=3 ob_type=0x023706a0}</pre>
<p>We can see a reference count, and a pointer to the object&#8217;s type structure, but that&#8217;s about it. There are a few useful things in the type structure, like the name of the type, but that&#8217;s it. The same goes for &#8216;args&#8217; &#8211; we can&#8217;t see the values inside it. What we really want is to be able to look at MyPrint&#8217;s arguments, to see what was passed in.</p>
<p>If you look closely, you&#8217;ll notice that the type structure has a field named &#8216;tp_repr&#8217;. If you dig into the CPython documentation, you&#8217;ll realize that tp_repr is a pointer to the repr() function for that object. In python, repr() converts any given object into a string, usable for debugging purposes.</p>
<p>Go ahead and open up Visual C++&#8217;s Immediate window. You&#8217;ll find it under the Debug menu&#8217;s Windows submenu. After it&#8217;s open, type this in:</p>
<pre>args-&gt;ob_type-&gt;tp_repr(args)</pre>
<p>If everything&#8217;s in good shape, you&#8217;ll see output like this appear in the Immediate window:</p>
<pre>0x1196fd88 { ob_refcnt=2 ob_type=0x02370600 }</pre>
<p>You just called repr() on your argument list, and it returned a Python string object. Now we&#8217;re in a bit of a tough situation &#8211; we still don&#8217;t have any way to look at our results. All we have is a Python object. We do, however, know that it&#8217;s a string, and as it turns out, in CPython, this means that the text of the string is directly adjacent to the PyObject structure. Knowing that, we can read the contents of memory to see the string.</p>
<p>Let&#8217;s take the PyObject * we got from repr(), and have visual studio show us the contents of the memory at that address. Type this into the immediate window:</p>
<pre>0x1196fd88,ma</pre>
<p>The &#8216;<strong>,ma</strong>&#8216; is a hint to the Visual Studio Expression Evaluator (used by the Watch and Immediate windows) that it should treat the specified value as a Memory address pointing to ASCII text. It&#8217;ll spit out something like this:</p>
<pre>0x1196fd88  ..... ..6...........(&lt;MyClass object at 0xbaadf00d&gt;)............</pre>
<p>The debugger wrote out the first 64 bytes of memory at that location. The first few bytes are the contents of the PyObject structure, and immediately following them, the contents of the string. From the result of repr(), we can now see that an instance of MyClass was passed to MyPrint, instead of a string. And from the address shown, it looks like it&#8217;s a bad pointer.</p>
<p>This is already useful debugging information we might not have had access to otherwise. But we can go further!</p>
<p>Let&#8217;s suppose that the MyClass object that was passed to us is actually valid. In that case, you&#8217;ll see a repr() that looks innocuous, and have an idea of what the contents of your argument list are. But if your arguments are all objects, repr() won&#8217;t tell you that much about them.</p>
<p>If MyClass looks like this:</p>
<pre>class MyClass:
  def __init__(self, number, name):
    self.__number = number
    self.name = name</pre>
<p>Calling repr() on it won&#8217;t tell us the things we actually care about &#8211; its name and number. We could add a repr() function to MyClass to find this out, if we wanted. But if you&#8217;re trying to debug a rare crash that&#8217;s hard to reproduce, restarting your app to add a repr() function is a dangerous step to take &#8211; you might not see the crash again for hours, days, or weeks.</p>
<p>So, let&#8217;s find out the name and number of the MyClass instance that was passed in.</p>
<p>The first step is to pull the instance out of our argument list. If we wanted, we could just grab the address straight out of the repr() &#8211; but let&#8217;s be SLIGHTLY less evil and do it using the CPython API. Type this into the immediate window:</p>
<pre>{,,python25.dll}PySequence_GetItem(args, 0)</pre>
<p>If everything went well, you&#8217;ll see output like this:</p>
<pre>0xbaadf00d { ob_refcnt=4 ob_type=0x023791010 }</pre>
<p>The expression we just evaluated bears a little explanation: The &#8216;<strong>{,,python25.dll}</strong>&#8216; part of the expression tells the debugger that you want to resolve the following symbol using the module &#8216;<strong>python25.dll</strong>&#8216;. Otherwise, the debugger might not know the identity of PySequence_GetItem, depending on the quality of your loaded symbols. Don&#8217;t ask me why the two commas are there, I have no idea.</p>
<p>So, now that we&#8217;ve successfully called GetItem on our argument list, we have the PyObject * for our MyClass instance. If things worked correctly, it will match what you saw in the result of repr().</p>
<p>Now that we have a MyClass instance, we want to get the name and number. Let&#8217;s get the value of the name attribute:</p>
<pre>((PyObject *)0xbaadf00d)-&gt;ob_type-&gt;tp_getattro( (PyObject *)0xbaadf00d, {,,python25.dll}PyString_FromString("name") )</pre>
<p>There&#8217;s a lot going on here, so let&#8217;s take it apart. First, we tell the debugger to treat the pointer we were given as a PyObject *:</p>
<pre>((PyObject *)0xbaadf00d)</pre>
<p>Then we invoke its &#8216;tp_getattro&#8217; handler, which is the generic getattr() handler for the object. Note that we have to pass in the pointer again, since it takes self as a parameter:</p>
<pre>-&gt;ob_type-&gt;tp_getattro( (PyObject *)0xbaadf00d,</pre>
<p>Then finally, we pass in the name of the attribute we wish to retrieve, as a PyObject. To do this, we create a PyString, using the CPython API:</p>
<pre>{,,python25.dll}PyString_FromString("name") )</pre>
<p>As before, we had to help the debugger find the name.</p>
<p>The getattr call should succeed, and you should get a result:</p>
<pre>0xabcd0123 { ob_refcnt=7 ob_type=0x023792222 }</pre>
<p>Using the tricks we&#8217;ve already learned, we can peek at the name:</p>
<pre>0xabcd0123, ma</pre>
<pre>0xabcd0123  ..... ..6...........Steve..............................</pre>
<p>Great. Given this, we may already have enough information to hunt through our source code, looking for the code that constructs Steve. But let&#8217;s pretend we need the number:</p>
<pre>((PyObject *)0xbaadf00d)-&gt;ob_type-&gt;tp_getattro( (PyObject *)0xbaadf00d, {,,python25.dll}PyString_FromString("number") )</pre>
<pre>0x00000000</pre>
<p>Hm. That didn&#8217;t work. If we remember carefully, MyClass stores the number in an attribute named &#8216;__number&#8217;, not &#8216;number&#8217;. That&#8217;s easy to fix, right?</p>
<pre>((PyObject *)0xbaadf00d)-&gt;ob_type-&gt;tp_getattro( (PyObject *)0xbaadf00d, {,,python25.dll}PyString_FromString("__number") )</pre>
<pre>0x00000000</pre>
<p>No dice. What&#8217;s the problem? If you read the Python documentation, you&#8217;ll find that a double underscore at the beginning of an attribute&#8217;s name gets treated specially by the language, and &#8216;mangled&#8217; in order to protect it from external access. As a result, when we wrote:</p>
<pre>    self.__number = number</pre>
<p>What actually got run was:</p>
<pre>    self._MyClass__number = number</pre>
<p>This results in __number being accessible from inside MyClass, but not outside. Knowing this, we can fix our getattr call:</p>
<pre>((PyObject *)0xbaadf00d)-&gt;ob_type-&gt;tp_getattro( (PyObject *)0xbaadf00d, {,,python25.dll}PyString_FromString("_MyClass__number") )</pre>
<pre>0xdcba3210 { ob_refcnt=5 ob_type=0x023794444 }</pre>
<p>Since number isn&#8217;t likely to be a string, let&#8217;s call repr and see what it is, and for convenience, display the result as a string directly:</p>
<pre>((PyObject *)0xdcba3210)-&gt;ob_type-&gt;tp_repr( (PyObject *)0xdcba3210),ma</pre>
<pre>0xddddaaaa  ..... ..8...........42..............................</pre>
<p>Now we know that MyPrint was called with an instance of MyClass, that was constructed with the name &#8216;Steve&#8217; and the number &#8217;42&#8242;, and we never had to leave the debugger. Our app is still running, so we can keep putting the debugger to use to investigate. If MyClass held references to other objects, we could follow those references until we found the information we were looking for.</p>
<p>If you find yourself working with large python strings in the debugger (for example, the repr() of a complex object), you can use this snippet to see the entire contents of an object&#8217;s repr(), as a C string:</p>
<pre>{,,python25.dll}PyString_AsString(obj-&gt;ob_type-&gt;tp_repr(obj))</pre>
<p>Hopefully the techniques I&#8217;ve shown you will prove useful the next time you&#8217;re trying to figure out a nasty python crash!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.luminance.org/blog/code/2009/06/07/in-depth-pythoncpython-crash-debugging-with-visual-c/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

