Saturday, January 1, 2011

How I wasted New Year's Eve

Apparently I am blessed with the kind of brain susceptible to nerd sniping (by the way, the answer to that problem is $4/\pi-1/2$; see [Cserti], an elegant approach using discrete Green functions). On New Year's Eve, an ill-considered click brought this problem before my eyes:
Both ends of a thin flexible rod are joined to the same pivot. What is the angle between the rod's ends?
I had not used much of the mathematical technique learned in the university for ten years. I don't like writing. I have other, arguably more important things to do. Oh well.

This problem seems made for a demonstration of variational calculus. Accordingly, I need an expression for the potential energy of a bent rod to vary. The rod being thin, I can apply simple bending theory, which says that the flexural energy of a piece of rod is proportional to the square of its curvature. The shape the rod makes does not depend on the rod's material or length as long as the assumptions of simple bending theory hold. Also the shape will obviously be symmetrical about the line bisecting my angle of interest (I will make this line my $y$ axis). A final observation is that the rod's curvature at the pivot is zero, because the pivot rotates freely and nonzero curvature generates momentum. At this point physics ends and mathematics, as applied by physicists, begins.

Let $\theta$ be the angle between the tangent to the curve and the $x$ axis, and $s$ the natural parameter (i.e. arc length). Using the Frenet's formula $\dot{\bf{t}}=\kappa\bf{n}$ ($\bf{t}$ the tangent unit vector, $\bf{n}$ the normal unit vector, $\kappa$ the curvature), I obtain that $\kappa=\dot{\theta}$, so the main term to vary is $\dot\theta^2$. In addition, I have to constrain the curve's ends to meet; the curve being symmetrical about the $y$ axis, I worry only about the separation of the curve's ends along the $x$ axis: $\int\cos\theta ds=0$. Accordingly I shall vary $$\tag{*}{(*)}\int_{-1}^{1}\dot\phi^2+½\mu^2\cos2\phi ds$$ where I have introduced $\phi=\theta/2$, arbitrarily made the curve's length equal $2$ and where $\mu$ is the Lagrange multiplier. Equating the variation of (*) to zero yields the ODE for $\phi$: $$\dot\phi^2=\mu^2k^{-2}(1-k^2\sin^2\phi)$$ with $k$ a constant of integration. The curve's symmetry and my choice of axes give me the boundary condition $\phi(0)=0$, and I denote $\phi(-1)=\alpha$. The solution to this ODE is the elliptic integral of the first kind: $\mu s=k\,\mathrm{F}(\phi,k)$. Since the curvature at $s=\pm1$ is zero, $k=1/\sin\alpha$. Now I bring into play the end-meeting constraint: $$0=\int_{-1}^{1}\cos2\phi ds=(\mu/k)\int_{-\mu/k}^{\mu/k}2\mathrm{cn}^2u-1 du,$$ whence G&R 5.134.2 produces $$\mathrm{E}(\alpha,k)=(1-½k^2)\,\mathrm{F}(\alpha,k).$$ At this point I have enough equations to solve for $\alpha$ and need not bother about $\mu$ — not surprising considering that $\mu$ is really a dimensional quantity which arises because I fixed the length of the curve. The solution is implicitly determined by $$2\sin^2\alpha\,\mathrm{E}(\alpha,1/\sin\alpha)=(2\sin^2\alpha-1)\,\mathrm{F}(\alpha,1/\sin\alpha).$$ Mathematica fails to find $\alpha$ numerically from this equation, however, so I solved the two equations together to find $\alpha\approx65°21'$. $\alpha$ being one half of the tangent angle to one end of the rod, the angle between the rod's ends is $4\alpha-\pi$, approximately $81°25'$. ■

Wednesday, December 15, 2010

MSBuild goodies

1. Inline tasks: no more creating and managing a separate assembly just to execute a piece of non-trivial code during build process.
2. Property functions: if the piece of code is merely a couple of method calls, it can go anywhere $() can go with the $([Class]::Method()) syntax. There are all kinds of limitations and the list of officially whitelisted methods is rather short — e.g. it does not include AssemblyName.GetAssemblyName — but whitelist checks can be disabled by setting the environment variable MSBUILDENABLEALLPROPERTYFUNCTIONS to 1.

Wednesday, November 10, 2010

Bootstrapper package for Windows Imaging Component

Developers who target .NET 4 and choose to create a proper bootstrapper for their installer have been bit repeatedly by installation failures on Windows XP SP2 and Windows Server 2003. .NET 4 fails to install on these admittedly outdated, but still widespread OSes because it depends on the Windows Imaging Component, which appears in XP SP3, Vista, 7 and 2008 Server and is installed with .NET 3.5 SP1. These OSes increasingly being the majority, Microsoft decided to leave WIC out of the .NET 4 installer in order to reduce the download size, a laudable intention. Since they actually documented this, there is no cause to complain; but why not also provide a bootstrapper package for WIC in the Windows SDK since it began to include packages for .NET 4? Developers usually direct the bootstrapper to download Microsoft files from the home site, so setup size would not increase appreciably.
Anyway. I created a WIC bootstrapper package and tested it on XP SP2, XP SP3 and 7. I also added a dependence on WIC to the .NET 4 packages. No warranty; use at own risk but comments welcome!

Thursday, June 24, 2010

How to use SSL3 instead of TLS in a particular HttpWebRequest

My application has to talk to different hosts over https, and the default setting of ServicePointManager.SecurityProtocol = TLS served me well. The other day, though, I had some NetWare hosts which (as System.Net trace log shows) don't answer the initial TLS handshake message but keep the underlying connection open until it times out, throwing a timeout exception. It seems that Netware's policy regarding unrecognized/invalid requests is not to respond or give any error messages, presumably to reduce attack surface. Very understandable, but this behaviour does not give .NET's built-in TLS-to-SSL3 fallback mechanism a chance to kick in.
I really didn't want to have to degrade the security protocol setting to SSL3 in the whole application for the sake of a few musty Netware hosts, but this ServicePointManager setting is global and there is no way to force a downgrade through HttpWebRequest. Luckily, 'global' has more than one meaning in the .NET world; ServicePointManager settings are actually per-appdomain. This enabled me to work around the problem by creating a separate appdomain set up to use only SSL3, making my data collection object MarshalByRefObject (WebClient and WebRequest are marshal-by-ref too, but better to reduce the number of cross-appdomain calls and avoid marshaling anything more complicated than a string) and creating it there. Worked perfectly combined with a timeout-based detection scheme.

Friday, August 28, 2009

Having your InternalPreserveStackTrace and eating it

This post stems from a discussion of stack trace problems at the CLR team blog.

The problem

When an existing exception is thrown in the normal way with throw e, any stack trace that was recorded in it is overwritten and destroyed. This complicates debugging and logging — the stack trace seen by a top-level handler (which, in a long-running application, must log it and somehow restore the application to operation) is practically useless. Throwing existing exceptions — ones which were previously caught and stored or serialized — is a necessity when doing custom cross-thread invoke, e.g. a custom thread pool. Custom remote call solutions also suffer from this problem.

The known hacksolution

Microsoft's Remoting team encountered the same problem, but they had the advantage of being able to modify the CLR. They introduced the internal Exception._remoteStackTraceString field, which is not overwritten by CLR when an exception is thrown. Exception.StackTrace prepends the contents of this field to the normal stack trace. They also introduced two internal methods on Exception, PrepForRemoting and InternalPreserveStackTrace, which squirrel away the existing stack trace into this field. However, all these members are internal, so they cannot be reliably called by third-party code with similar needs.
It seems that Chris Taylor was the first to discover these internal members. He published a hack which preserves stack trace in an exception by accessing _remoteStackTraceString with Reflection. A more mature version of this hack by Fabrice Marguerie calls InternalPreserveStackTrace (again using Reflection). Later, Brad Wilson ranted on this subject. Brad also mentions that the Reflection team did not use stack trace preservation, but instead introduced the pesky TargetInvocationException (which most everyone has to unwrap and throw the inner exception ASAP to propagate the original exception).

Back to the present

When I mentioned this hack in the discussion at the CLR team blog, CLR team's Mike Magruder pointed out its essential brittleness/hackiness. Mike is, of course, right; I am sure no-one who uses this hack is happy about messing with mscorlib's internals; but the problem has to be dealt with. Mike's criticism prodded me into looking for a more portable solution.

It

My solution exploits the fact that cross-AppDomain calls need to preserve stack traces of exceptions propagating across the AppDomain boundary. Cross-AppDomain calls seem to use the serialization infrastructure to get non-trivial data across, so when Exception's SetObjectData constructor sees the CrossAppDomain flag in the supplied SerializationContext, it prepares the exception for subsequent throwing — by setting the crucial _remoteStackTraceString field in essentially the same way as InternalPreserveStackTrace, although SetObjectData forgets to insert a newline after the old stack trace. It remains, then, to call an exception's GetObjectData and SetObjectData, tricking it into believing that it is being serialized across the AppDomain boundary.
The primitive version of my solution relied on BinaryFormatter to do the heavy lifting:

static Exception WithPreservedStackTrace (Exception e)
{
    var context   = new StreamingContext (StreamingContextStates.CrossAppDomain) ;
    var formatter = new BinaryFormatter  (null, context) ;
    formatter.FilterLevel = TypeFilterLevel.Full ;

    using (var stream = new MemoryStream ())
    {
        formatter.Serialize (memory, e) ;
        memory.Position = 0 ; // rewind stream

        return (Exception) formatter.Deserialize (memory) ;
    }
}
This works like a charm, but all the unnecessary extra work done by BinaryFormatter galled me, so I poked around RedBits code some more and evolved the following version, which uses the arcane ObjectManager class:
static void PreserveStackTrace (Exception e)
{
    var context = new StreamingContext  (StreamingContextStates.CrossAppDomain) ;
    var manager = new ObjectManager     (null, context) ;
    var serinfo = new SerializationInfo (e.GetType (), new FormatterConverter ()) ;

    e.GetObjectData  (serinfo, context) ;
    manager.RegisterObject (e, 1, serinfo) ; // prepare for SetObjectData

    manager.DoFixups () ;                    // ObjectManager calls SetObjectData for us

    // voila, e is unmodified save for _remoteStackTraceString
}
This still wastes a lot of cycles compared to InternalPreserveStackTrace, but has the advantage of relying only on public functionality. Purists who really want to avoid calling InternalPreserveStackTrace can use this workaround :3

Update: usage samples which I posted on StackOverflow:
// usage (A): cross-thread invoke, messaging, custom task schedulers etc.
catch (Exception e)
{
    PreserveStackTrace (e) ;

    // store exception to be re-thrown later,
    // possibly in a different thread
    operationResult.Exception = e ;
}

// usage (B): after calling MethodInfo.Invoke() and the like
catch (TargetInvocationException tiex)
{
    PreserveStackTrace (tiex.InnerException) ;

    // unwrap TargetInvocationException, so that typed catch clauses 
    // in library/3rd-party code can work correctly;
    // new stack trace is appended to existing one
    throw tiex.InnerException ;
}

Monday, December 15, 2008

Dynamic method drop

Dynamic methods drove me crazy for the last two days. A completely innocent-looking, verified IL which created delegates from dynamic methods sometimes blew up with all kinds of exceptions: null-reference exceptions in weird places, stack overflows (or hang-ups if not running under Developer Studio) and the enigmatic FatalExecutionEngineError. Other times the code executed without a problem. It was difficult to establish any pattern in these failures. windbg+SoS revealed nothing beyond the fact that the IL was being generated correctly, and excavations of RedBits/Rotor code did not help much either. I went over the whole mess in my mind while listening to a jazz performance, and realized that the flaw was in my delegate-creation IL code, which went like this:

push target object
ldftn dynamic method
newobj Procedure..ctor(object, native int)
store new delegate

This code creates a working delegate, but the delegate's internal _methodBase field is initially null. The bald function pointer does not work as a GC reference, and if there are no other references to the dynamic method, it is liable to be garbage-collected, and the delegate containing the stale function pointer naturally but silently becomes a nest of nasal demons.

Delegate.CreateDelegate overloads don't fill _methodBase either. DynamicMethod.CreateDelegate does fill it explicitly, but it is impossible to get the DynamicMethod object from its token without calling mscorlib's internal methods. I understand the security reasons behind this decision, but it's damned uncomfortable.

The only solution to the problem I have found so far is to call the new delegate's get_Method() function to fill _methodBase and establish a GC-visible reference to the dynamic method. Whew!

Update: reported this issue to Microsoft; they decided to close it as a 'known limitation'. Well, it is known — now :3

Sunday, February 24, 2008

Detroit Public School Repository

Superb photos, somewhat reminiscent of Prypiat schools and kindergartens.