How to change method at runtime.
Hi,
Supose we have a method named method1. If we run our app in debug mode, we can stop at a brake point and than chagne some code and continue to run the app. Is there a way to do it using code? When I searched I only found useful Reflection.Emit namespace yet it can only build dynamic things, it can not change class structure, or method body. The scenerio can look like this. App is running. App is unloading dll. App is changing dll (it can only know something from Reflection). App is changing dll. App is loding dll. Of course it would be great if unloading/loding steps could be thrown out form this "flow". If someone knows how to deal with this problem please help me:)
[702 byte] By [
Neo_ms] at [2008-2-25]
Hi,
This polimorfizm scenerio is imposible to apply; What is the reason of what I'm doing:
Supose someone had written a dll. And what you need to do is to add some extra functionality to methods, yet without its touching .cs code. Supose a user has an interface and what to ensure that some conditions are passed before and after method execution. This is something like aspect programing, yet method are already there in dll and what you need is to wrap them using you dynamilcy generated code. When you use VS, you can Edit & Continue while debbuging. I would like to know how visual do it, and do the same using my code. envDTE namespace provide a lot of usefull classes yet I coudnt find what I need...
When you change code in a debug session with the Visual Studio, you're using the "Edit and Continue" (EnC) functionality as implemented by the CLR Debugging Services API (ICorDebug). This is really just designed for debuggers, and not for applications running in production scenarios applying it on themselves. (For the same reasoning that we discourage using EnC as an AOP Weaver). I gave a presentation at a MSR workshop about Debugging technologies and AOP which may be useful. Link to slides is here.
Possible solutions usign .NET 2.0 include:
1. At runtime, Use Ref.Emit to emit a new class. This does not sound exactly like what you want, but it's a related scenario.
2. At runtime, Use the CLR Profiling API for either IL rewriting (valid only when the module is first loaded) or Function Enter / Leave hooks.
3. At build time, you can rewrite the assembly such as via ILdasm/ILasm round-tripping. See example here. I believe there are fancier class libraries than ILasm/ILDasm floating around for such IL manipulation. This would basically be a post-build step.
It sounds like #3 would work for your scenarios.
Yes, I also thought about lidasm/liasm trip, yet I was very courious how does Visual do EnC for you. The debugger must deal with this problem somehow. What is comming to my mind is that the debuger saves the stack/heap somehow, rebuilds the code (this could be complicated because of loosing integration with "pointers" in saved stack/heap and starts app form the point where it made chages to the code. Do you perhaps know how the debugger deal with EnC?
Can you tell something more about Profiling API and IL rewrithing and Funtion Enter/Leave hooks. I'm familiar with CRL Profiler yet when I scan the code, it looks as if it goes inside CLR or MSIL.
Maybe it is possible to get to JIT and somehow replace input stream?
Thanks very much for help Mike :)
The MDbg sample has a demo on how EnC works under the covers (see mdbg\demo\EditAndContinue in the latest sample). I also have a blog category on EnC that may be useful here.
A quick start on the profiler API is here. An article on rewriting is here.