2009-08-14 8 views
2

eine Baugruppe mit einem Eintrittspunkt wie Gegeben:[net] Wie Debugging-Code in eine Assembly injizieren?

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

Ist es möglich, noch eine andere Anordnung zu verwenden, so etwas wie zu simulieren:

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; 
} 

Und nur diese Code-Injektion aktivieren, wenn DEBUG vorhanden ist . Wenn das so ist, wie lädt man die "Debugging" -Montage?

EDIT 1: #ifdef ist keine Option. Sagen wir, ich möchte die Codebasis nicht ändern.

EDIT 2: Meine Hauptfrage ist "Wie INJECT-Code zu einer bereits kompilierten Assembly INJECT". Ich habe den Basiscode, aber ich würde lieber nicht das K von Zeilen für die Verfolgung in diesem Hauptcode hinzufügen, sondern eine andere Assembly, die das tut. Ich weiß, wie man VS benutzt, um zu debuggen, was ich hinzufügen will, ist das Verfolgen des Mechanismus von Variablen (unter anderem).

+0

Sie sagen, Sie können die ursprüngliche Baugruppe aus irgendeinem Grund nicht berühren? – Jared314

Antwort

10

Sie könnten versuchen, einen AOP Post-Compiler wie PostSharp. Es funktioniert mit allen .net-Sprachen, aber ich habe es nicht mit C++ versucht.

+0

vereinbart, ich habe mit der Enterprise Library Logging-Block verwendet Postsharp, Parameter an eine Methode übergeben, um sich einzuloggen, es funktioniert gut (C#) – Neil

-2

Hängt davon ab, ob Sie den Quellcode für die Assembly haben und ob Sie ihn neu kompilieren können, um das Debuggen zu ermöglichen.

Angenommen, Sie haben den Quellcode, und Sie können es mit aktiviertem Debuggen kompilieren, dann sollten Sie in der Lage sein, Ihr Entwicklertool zu verwenden (Visual Studio, ich rate), um den Code durchzugehen und die Werte zu sehen von X, Y und ret, wie du gehst.

Dies würde keine Änderung des Codes erfordern - nur die Möglichkeit, eine Debug-Version zu kompilieren.

3

Zum Eingeben von Code in eine vorhandene Baugruppe würde ich die Cecil-Bibliothek verwenden, mit der Sie mit IL arbeiten können. Dadurch können Sie die Assembly neu schreiben, wenn Sie danach suchen. Ich muss dich warnen: Es ist keine kleine Leistung.

Oh, es gibt auch ein Add-In für Reflector namens Reflexil, mit dem Sie Baugruppen bearbeiten können.

Übrigens, AOP-basierte Ablaufverfolgung fügt Code nicht direkt zu Ihrer Baugruppe hinzu. Sie können alle AOP-Dateien in einer separaten Assembly aufbewahren (in der Tat ist dies eine sehr gute Idee) und dann mit Attributen versehen. PostSharp wird Code für Sie hart verdrahten, aber andere AOP-Frameworks wie Spring oder PIAB machen die Dinge flexibler, da sie dynamische Proxies verwenden, so dass Sie Ihre Aspekte effektiv "ausschalten" können, wenn sie nicht benötigt werden.

2

The Enterprise Library Policy Injection Application Block können Sie Code zwischen Methodenaufrufen ausführen. Es macht nicht die komplexen Dinge, die Sie in Ihrer Frage gefragt haben, die Code in Methoden einfügen, aber es kann für Ihre Bedürfnisse ausreichend sein und es ist frei verfügbar.

+0

diese könnte in der Tat meine Bedürfnisse ausreichen. Ich muss Code nicht unbedingt in den Body der Methode einfügen, sondern Methodenaufrufe verfolgen und Anweisungen zurückgeben. – Anzurio

0

Wenn die DoFoo-Funktion nicht virtuell ist oder wenn auf die Klasse nicht über eine Schnittstelle zugegriffen wird, können Sie dies nicht tun.

Der Grund ist, dass beim Kompilieren der Klasse, die das DoFoo verwendet kompiliert wird, um die genaue Funktion für diese genaue Klasse aufzurufen. Daher wird die Zielklasse für den Empfang des Aufrufs zur Kompilierungszeit ausgewertet. Wenn die Funktion jedoch virtuell ist oder Sie über eine Schnittstelle auf die Klasse zugreifen, wird die Zielklasse für den Empfang des Aufrufs zur Laufzeit ausgewertet.

Um also alle AOP (aspektorientierte Programmierung) oder DI (direkte Injektion) Frameworks zu verwenden, um das zu erreichen, was Sie wollen, muss die Zielklasse eine dieser Bedingungen erfüllen. Normalerweise wäre der Zugriff auf die Klasse über eine Schnittstelle der bevorzugte Weg.

Es gibt viele verschiedene AOP- und DI-Frameworks da draußen, aber die Post war nicht darüber, welche zu verwenden, also werde ich mich davon abhalten, aber wenn Sie solche nicht brauchen, können Sie DynamicProxy verwenden Erstellen eines Dekorators zum Hinzufügen von Protokollierungsfunktionen, sowohl zu einer Schnittstelle als auch zu einer Klasse mit virtuellen Funktionen. Letzteres erstellt eine neue Klasse, die eine Unterklasse von der ist, die Sie bereits haben

Verwandte Themen