Thursday Night

Paul Betts’s personal website / blog / what-have-you

Archive for the ‘Mono / .NET’ Category

Debugging .NET exceptions *without* VS installed using WinDbg

one comment

If your .NET app is crashing on a machine that doesn’t have Visual Studio, here’s the easy way to get the managed exception – people have written way better articles on SOS and WinDbg, but here’s a 10sec overview; even if you have no idea how WinDbg works, often just having the managed exception will give you enough good info, and WinDbg is way easier to install and lightweight than VS.

Install the Debugging Tool for Windows, then spin up WinDbg (or cdb, the command-line version if you’re even more metal). Either attach to a running instance of your program, or start a new one. Run these commands to get started once you get the prompt (if you don’t get the prompt, and you’ve attached, you need to break-in by hitting Ctrl-C):

.sympath srv*http://msdl.microsoft.com/download/symbols
.sympath+ C:\path\to\your\binary\directory
.reload -f
g

Ok, your app is running – one thing that will totally fool you if you’re used to using VS is, if you start the program with WinDbg, your program will break-in immediately once you start it, before any code in your app has run (even the .NET startup code). Now, crash your app; you should’ve been kicked back into the debugger now and back at the prompt, with something like:

CLR exception type: System.Collections.Generic.KeyNotFoundException
    "The given key was not present in the dictionary."
eax=001fe078 ebx=e0434f4d ecx=00000001 edx=00000000 esi=001fe100 edi=005461d8
eip=76c5f35f esp=001fe078 ebp=001fe0c8 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
KERNEL32!RaiseException+0×58:
76c5f35f c9              leave
0:000>

Now, here’s where we get to the real work – to debug .NET framework apps, we need the SOS extension, so we’ll pull that in, then use one of the functions that SOS defines (to see them all, run !help):

0:000> .loadby sos mscorwks
0:000> !printexception

*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll –
PDB symbol for mscorwks.dll not loaded
Exception object: 22e0580c
Exception type: System.Collections.Generic.KeyNotFoundException
Message: The given key was not present in the dictionary.
InnerException: [none]

StackTrace (generated):
    SP       IP       Function
    001FE1F4 6BFB480D mscorlib_ni!System.ThrowHelper.ThrowKeyNotFoundException()+0×1d
    001FE1FC 06DF1E20 mscorlib_ni!System.Collections.Generic.Dictionary`2[[LogDebugger.EventGroupingKeys, LogDebugger.Engine],[System.__Canon, mscorlib]].get_Item(LogDebugger.EventGroupingKeys)+0×38
    001FE208 06494B36 LogDebuggerUI!LogDebugger.Ui.FilterEnvironment.[buildhighlightbrushmap]b__e(LogDebugger.LDEvent)+0xe

   [ [ rest of stack trace… ] ]

There’s way more you can do with WinDbg and SOS (it’s the way we debug Windows programs at Microsoft), but this should get anyone who wants a quick way to see an exception the way to do it. Using Mono, you can actually get the exception trace even easier (but you can’t do any debugging), as any app you run via the command line (i.e. via mono ./path/to/app.exe) will print the same information to STDERR.

Written by Paul Betts

May 24th, 2008 at 1:45 pm

Posted in Mono / .NET

No news as of late – but Inkscape now has XAML

one comment

Sorry this blog has been dead lately, I posted a rather depressing article but Wordpress ate it, perhaps it was fate (or its stop being so whiny alarm kicked in). The 2-second summary is, I don’t have many people around but it’s my own damn fault. Ok, now that we’ve got that out of the way, I’ve been working on learning RSpec/TDD in Ruby at home, and at work I’m doing cool WPF stuff (but no TDD, because I hate VS’s test framework support).

Here’s a small news item that got me interested though, via Jon Galloway. The latest versions of Inkscape now export XAML directly, which is great for me because I don’t have an Illustrator license at work (apparently it’s a “competitive product”), and I really don’t jive with Expression Design; then again, I don’t jive with Illustrator either for that matter, but I’d consider forcing myself to learn it because it’s the industry standard. Now, I can easily convert SVGs or bitmaps via VectorMagic into XAML that I can put into my project.

Written by Paul Betts

January 14th, 2008 at 12:29 pm

Posted in Microsoft, Mono / .NET

Seriously cool – NStatic solves linear equations

Equation Solving with static code analysis

NStatic sees the assertions, then determines the only way that this function can execute is via setting the three parameters to the solution of the linear equation. That’s a pretty awesome demo.

Written by Paul Betts

June 18th, 2007 at 9:58 am

Posted in Microsoft, Mono / .NET

Silverlight + Ruby for .NET? Awesome.

2 comments

As part of the big hullabaloo around Mix ‘07, Microsoft announced their new Silverlight product, which is basically a less cracked-out Flash, which lets you use .NET languages (including IronPython) to create Flash-like animations and games. Finally, people can design awesome UIs and use a programming language that isn’t evil.

But more importantly, MS created a compiler for Ruby that compiles to MSIL called IronRuby. This means I can use Ruby at work and actually have other people use it. It also means that I might even learn this Silverlight thing if I can create awesome UIs in Ruby, and have it be cross-platform (even though “cross-platform” apparently doesn’t include Linux, don’t worry; Miguel’s gonna have that shit covered post-haste).

Written by Paul Betts

May 2nd, 2007 at 10:05 am

Posted in Microsoft, Mono / .NET, Ruby

I’m officially a GNOME developer…kind of

…or at least I have Subversion access for my language work in Beagle. I’ve been working on this for awhile now and the patches got so big that it was much easier to move it to a branch than try to maintain them all. You can check out my code at:

svn co http://svn.gnome.org/svn/beagle/branches/beagle-textcat-branch

What does this freaking do, you may ask? Well, the fundamental idea is that you can do a much better job at searching if you can split words up into the main piece, called the “stem”. For example “singing” => “sing”. As you can imagine, this is very language specific and tricky, so you need a way to figure out what language a piece of text is in before you can attempt to stem it. Fortunately, you can use a trick and do some statistical analysis (here’s the paper on it) to usually figure out the language, if you’ve got enough text.

As for the actual algorithm to stem the text, enter Snowball, a string processing language that’s built for writing stemmer programs. I ported the compiler generator to C# (wasn’t too hard, it had a generator for Java) so now the code is generated on-the-fly for a whole bunch of different languages from the Snowball source.

Now there’s only a few things left to do:

  • Load the stemmer classes at runtime using Reflection
  • Decide which one to use based on the language, and the biggest one…
  • Make sure that it doesn’t drive performance through the floor

Unfortunately, doing all this language analysis isn’t cheap, both in terms of memory and processor utilization. One of the things I have to do is go through the code with a fine-toothed comb trying to make it run really fast so Beagle doesn’t get bogged down

Written by Paul Betts

February 1st, 2007 at 12:02 am

Posted in Linux, Mono / .NET

Mono now ships with IronPython + extras and IKVM

I didn’t know they did this, but Mono, the Free .Net implementation now ships with IronPython Community Edition as well as FePy, a library to make .Net and Python get along a bit better. It also now ships by default with IKVM, which is a library that allows you to use Java and .Net together seamlessy (call Java objects from .Net and vice-versa).

So to review, using .Net and Mono, you can now write programs that interoperate seamlessly together in:

  • C#
  • C/C++ (.Net only)
  • Java
  • ECMAScript (aka Javascript)
  • Visual Basic
  • Python
  • Boo
  • MSIL

That’s pretty awesome; hopefully soon this will catch on and we’ll end the “Man, I want to use this library but it’s written in…” problem once and for all.

Written by Paul Betts

January 25th, 2007 at 6:13 pm

Why Ruby is so much shorter

Chuck:
What features or aspects of Ruby enable it to be half the number of lines as Boo?

Well, there are several aspects of Ruby that allow it to be smaller. Firstly, I’m a better functional coder than I was when I wrote the Boo version, so some of it is certainly because of that. However, several aspects of Ruby make the code much more elegant than it was; I’ll highlight a few in this blog entry.

Using yield effectively

If you judiciously use yield to retrieve extra information from the caller, you can make your code read much better. For example, here’s an excerpt from the main() of my program

# Process the library
library.load file_list do |progress|
    puts _("%s%% complete") % (progress * 100.0)
end

library.find_soundtracks do |curname|
    print _("’%s’ may be a soundtrack or compilation. Is it? (Y/n) ") % curname
    (STDIN.gets =~ /^[Nn]/ ? false : true)
end

list = library.create_action_list(results[:target],
                  results[:musicformat],
                  results[:sndtrkformat]) do |tag, invalid|
    puts _("The tag ‘%s’ has invalid characters; ‘%s’ are not allowed") % [tag, invalid]
    puts _("Please enter a replacement:")
    STDIN.gets
end

# …. snip -> in find_soundtracks …

# Call out the handler
@is_soundtrack[curname] = true if yield(curname)

See how clean the main function reads? This kind of thing is really easy and clean in Ruby; in Boo I can do the same thing using delegates but there’s more syntactic nonsense (and even more in C#).

Regular Expressions are built into everything

Regular expression support exists in Boo and it’s better than C#, but Ruby really emphasizes using them in the standard library, whereas in .NET it feels kind of like an add-on. For example, here’s a (inefficient) method to pull all the XML’ish tags from a string (like <artist>/<album> => [”artist”, “album”…)

First_Tag = /(< \S*?>)+[^< ]*/
def get_tags(xml_string)
    # Find the tags used in the string
    s = xml_string.downcase
    tags_used = []
    while First_Tag.match s do
        tags_used << $1
        s.sub! First_Tag, ”
    end
        tags_used

I’m sure as soon as I post this, someone will chime up with a “That’s a horrible way to do that!”, but my point is, Regular Expressions being built-in to a lot of methods as well as all of the match parts (\1, \2, \3…) being set to global variables like Perl makes life much easier

Dynamic class loading ain’t no thang

In Ruby, it’s even easier than C# or Boo to load new classes, because the “using” statement (”require”) isn’t some special declaration, it’s a statement just like any other. This sample loads all the classes that can dig information out of music files:


def load_taggers(*paths)
    # Load the defaults, then the ones specified in the param
    paths.each do |x|
        Pathname.new(x).each_entry { |y| require File.join(x,y) if y.extname == '.rb' }
    end

    # Now reflect through the objects and find ones that match
    @taggers = []
    tagger_classes = ObjectSpace.each_object(Class) do |x|
        pm = x.public_instance_methods(true)
        next unless pm.include? 'get_tags?' and pm.include? 'song_info'
        @taggers < < x.instance
    end
    @taggers = nil unless @taggers.size > 0
end

Basically in this sample, we load all files in a list of directories, then we dig through all the classes looking for ones that implement the get_tags? and song_info methods. If so, we add the singleton instance to an array (All tag-retrieving classes are Singletons).

Right now, I only have a dummy implementation and one that uses TagLib, but I intend to add a few more to pick up WMA/M4A's, and so all I have to do to implement that is add two more files in those directories.

Written by Paul Betts

January 17th, 2007 at 1:09 pm

Posted in Mono / .NET, Ruby

Imagine Cup 2007 disappoints Nemerele’rs

Matt Nedrich from NTSig sent out a message recently about Imagine Cup 2007, and I was interested to check out their software design competition. However, I was more interested to find out you can compete using alternate languages, as long as you make a valid .NET 2.0 assembly. I took this as a chance to write some code in Nemerle, a functional .NET language that has some cool tricks (and as one knows, one must always use cool tricks in programming competitions). However, even after downloading KChmViewer to read their specs and resubmitting several times, I can’t get their site to accept a .DLL written in Nemerle. Here’s my code (since it’s the tutorial, I don’t think it’s cheating to share):

namespace L100Math {

public class MathHelper
{
  public static Add(a:int, b:int) : int {a+b;}
  public static Subtract(a:int, b:int) : int {a-b;}
  public static Multiply(a:int, b:int) : int {a*b;}
  public static Divide(a:int, b:int) : int {a/b;}
}

}

and here’s the monodis output:

.assembly extern mscorlib
{
  .ver 2:0:0:0
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
}
.assembly ‘L100Math’
{
  .custom instance void class [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32)(01 00 08 00 00 00 00 00 ) // ……..

  .hash algorithm 0×00008004
  .ver  0:0:0:0
}
.module L100Math // GUID = {DA51AA57-2311-42ED-B694-827673D18D36}

.namespace L100Math
{
  .class public auto ansi MathHelper
    extends [mscorlib]System.Object
  {

    // method line 1
    .method public hidebysig  specialname  rtspecialname
           instance default void .ctor ()  cil managed
    {
        // Method begins at RVA 0×20ec
    // Code size 7 (0×7)
    .maxstack 8
    IL_0000:  ldarg.0
    IL_0001:  call instance void object::.ctor()
    IL_0006:  ret
    } // end of method MathHelper::.ctor

    // method line 2
    .method public static  hidebysig
           default int32 Add (int32 a, int32 b)  cil managed
    {
        // Method begins at RVA 0×20f4
    // Code size 4 (0×4)
    .maxstack 8
    IL_0000:  ldarg.0
    IL_0001:  ldarg.1
    IL_0002:  add.ovf
    IL_0003:  ret
    } // end of method MathHelper::Add

    // method line 3
    .method public static  hidebysig
           default int32 Subtract (int32 a, int32 b)  cil managed
    {
        // Method begins at RVA 0×20fc
    // Code size 4 (0×4)
    .maxstack 8
    IL_0000:  ldarg.0
    IL_0001:  ldarg.1
    IL_0002:  sub.ovf
    IL_0003:  ret
    } // end of method MathHelper::Subtract

    // method line 4
    .method public static  hidebysig
           default int32 Multiply (int32 a, int32 b)  cil managed
    {
        // Method begins at RVA 0×2104
    // Code size 4 (0×4)
    .maxstack 8
    IL_0000:  ldarg.0
    IL_0001:  ldarg.1
    IL_0002:  mul.ovf
    IL_0003:  ret
    } // end of method MathHelper::Multiply

    // method line 5
    .method public static  hidebysig
           default int32 Divide (int32 a, int32 b)  cil managed
    {
        // Method begins at RVA 0×210c
    // Code size 4 (0×4)
    .maxstack 8
    IL_0000:  ldarg.0
    IL_0001:  ldarg.1
    IL_0002:  div
    IL_0003:  ret
    } // end of method MathHelper::Divide

  } // end of class L100Math.MathHelper
}

Am I doing something wrong? That looks pretty correct, I used “ncc -tdll -o L100Math.dll L100Math.n” as my compile command. Thoughts? Comments? Ideas?

Written by Paul Betts

November 27th, 2006 at 10:17 pm

Posted in Microsoft, Mono / .NET

Tomboy Update: School ruins my fun

After reading through my referrer logs, imagine my suprise when I find that I’m in the MediaWiki page for Tomboy! Unfortunately, my development on this has stalled for several reasons. First, school has been really busy and I haven’t had any free time to work on much of anything. The second reason is that the author of Tomboy has talked about doing a lot of rewrites (moving to gtk-sharp 2, etc.), so I’d like to wait until things settle down before trying to write some more code, as well as get the author’s input (I filed a bug report today).

Written by Paul Betts

March 9th, 2006 at 4:13 pm

Posted in Linux, Mono / .NET

Gnome Dev forums

A lot of people have already blogged about it, but just to put some extra noise behind it, GnomeDev.com has recently been created, it’s a programming forum related to GNOME development, including Python and Mono. Even though the traditional solution for this sort of thing has been the mailing list, I personally find forums to be somewhat more intuitive to search through old posts and find information. It also allows for people to answer simple questions without worrying about cluttering the mailing list, and without having to create a whole bunch of separate lists.

Written by Paul Betts

February 27th, 2006 at 12:01 am

Posted in Linux, Mono / .NET