views:

456

answers:

6

Given an assembly with an entry point like:

int FooClass::doFoo(int x, double y)
{
   int ret;
   // Do some foo
   return ret;
}

Is it possible to use yet another assembly to simulate something like:

int FooClass::doFoo(int x, double y)
{
   int ret;
   TRACE_PARAM_INT(x)
   TRACE_PARAM_DOUBLE(y)
   // Do some foo
   TRACE_RETURN_INT(ret)
   return ret;
}

And only enable this code injection when DEBUG is present. If there is such way, how do you load the "debugging" assembly?

EDIT 1: #ifdef is not an option. Say, I don't want to modify the code base.

EDIT 2: My main question is "How to INJECT code to an already compiled assembly". I do have the base code but I'd rather not add the K of lines for tracing in that main code but have another assembly that do such. I do know how to use VS to debug, what I want to is add tracing mechanism of variables (among other things).

+10  A: 

You could try an AOP post-compiler like PostSharp. It works with all .net languages, but I have not tried it with C++.

Jared314
agreed, i've used postsharp with the enterprise library logging block, to log parameters passed to a method, it works well (c#)
Neil
A: 

Depends on whether you have the source code for the assembly and whether you're able to recompile it to allow debugging.

Assuming that you have the source code, and you can compile it with debugging enabled, then you should be able to use your developer tool (Visual Studio, I'm guessing) to single step through the code and see the values of X, Y and ret, as you go.

This would not requie modification of the code - just the ability to compile a debug version.

belugabob
+3  A: 

For injecting code into an existing assembly, I would use the Cecil library, which lets you work with IL. This would let you rewrite the assembly if that's what you're after. I have to warn you: it's no small feat.

Oh, there's also an add-in for Reflector, called Reflexil, which lets you edit assemblies.

By the way, AOP-based tracing doesn't add code directly to your assembly. You can keep all the AOP stuff in a separate assembly (in fact, it's a very good idea), and then apply it with attributes. PostSharp will hard-wire code for you, but other AOP frameworks such as Spring or PIAB make things more flexible as they use dynamic proxies, so you can effectively 'turn off' your aspects when they are not needed.

Dmitri Nesteruk
+2  A: 

The Enterprise Library Policy Injection Application Block allows you to execute code between method calls. It wont do the complex things you've asked for in your question which involve injecting code inside methods, but it may be sufficient for your needs and it's freely availably.

Programming Hero
this might actually suffice my needs. I don't really need to inject code to the method's body, but keep track of method calls and return statements.
Anzurio
A: 

Have you looked at CThru (http://cthru.codeplex.com/Wiki/View.aspx?title=Using%20the%20CThru%20Engine)?

It allows you trace method calls, constructor calls, etc so you could trace everything from the outside. It is part of a mocking library but it is so much more useful.

L2Type
A: 

If the doFoo function is not virtual, or if the class is not accessed through an interface, you cannot do it.

The reason is that when you are compiling the class that uses the doFoo is compiled to call the exact function on that exact class. So the target class for receiving the call is evaluated at compile time. If the function is virtual however, or you access the class through an interface, the target class for receiving the call is evaluated at runtime.

So in order to use any AOP (aspect oriented programming) or DI (direct injection) frameworks for accomplishing what you want, the target class needs to fulfill either of these conditions. Normally accessing the class through an interface would be the preferred way.

There are many different AOP and DI frameworks out there, but the post was not about which one to use, so I'll keep myself from doing that, but if you don't need such one, you can use DynamicProxy to create a decorator to add logging functionality, both to an interface, and to a class with virtual functions. The latter creates a new class that is a subclass of the one that you already have

Pete