Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to automatically break into debugger when my class library functions are getting called?

I have a managed class library (say mylib.dll) and a 3rd party managed app (say app.exe) which is using mylib.dll. I have the code of mylib.dll but not of the app.exe. So currently what i do is i build mylib.dll, copy it to app.exe's directory, start app.exe and attach to the process. That way if i put breakpoints in code mylib.dll , i see them being hit. But is there anyway to automatically break in code of mylib.dll whenever any external application calls one of its exposed methods ? ie. Only for entrypoints of the dll.

thanks, Mishal

like image 692
mishal153 Avatar asked Apr 12 '10 12:04

mishal153


2 Answers

Under Project -> Properties -> Debug -> Start Action you should specify the option Start external program and enter the path to your app.exe. This should launch app.exe with the debugger attached.

See also How to: Change the Start Action for Application Debugging

Update: Breakpoints in Visual Studio are either bound to a certain location (i.e. a specific line of code in a source file) or to a function name. Therefore you basically have two options to break any time a function in your assembly gets called: Either put breakpoints on all function declarations or on all function names (Debug -> New Breakpoint -> Break on Function Name). Unfortunately, the latter option requires the full function name and does not allow wildcards.

Another alternative you might consider is to place Debug.Assert(false) at the start of all your library functions.

Yet another option would be to use a Visual Studio macro. The macro below iterates over your code DOM and adds a breakpoint to all public methods and properties:

Option Strict Off
Option Explicit Off
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports System.Windows.Forms

Public Module Breakpoints

    Sub AddBreakpointsToAllFunctionsAndProperties()
        Try
            If DTE.ActiveSolutionProjects.Length <> 1 Then
                MsgBox("Select one project within the Solution Explorer, then re-run this macro.")
                Exit Sub
            End If

            AddBreakpointsToProject(DTE.ActiveSolutionProjects(0))
        Catch ex As System.Exception
            MessageBox.Show(ex.ToString)
        End Try
    End Sub

    Private Sub AddBreakpointsToProject(ByVal proj As Project)
        For i As Integer = 1 To proj.ProjectItems.Count
            If Not proj.ProjectItems.Item(i).FileCodeModel Is Nothing Then
                AddBreakpointsToProjectItems(proj.ProjectItems.Item(i).FileCodeModel.CodeElements)
            End If
        Next
    End Sub


    Private Sub AddBreakpointsToProjectItems(ByVal colCodeElements As CodeElements)
        Dim objCodeElement As EnvDTE.CodeElement

        If Not (colCodeElements Is Nothing) Then
            For Each objCodeElement In colCodeElements
                AddBreakpointsToProjectItem(objCodeElement)
            Next
        End If
    End Sub

    Private Sub AddBreakpointsToProjectItem(ByVal objCodeElement As CodeElement)

        Dim objCodeNamespace As EnvDTE.CodeNamespace
        Dim objCodeType As EnvDTE.CodeType
        Dim objCodeFunction As EnvDTE.CodeFunction
        Dim objCodeProperty As EnvDTE.CodeProperty

        Try
            'MessageBox.Show(objCodeElement.FullName & " (Kind: " & objCodeElement.Kind.ToString & ")")

            If objCodeElement.Kind = vsCMElement.vsCMElementFunction Then
                objCodeFunction = DirectCast(objCodeElement, EnvDTE.CodeFunction)
                If objCodeFunction.Access = vsCMAccess.vsCMAccessPublic Then
                    DTE.Debugger.Breakpoints.Add(objCodeElement.FullName)
                End If
            ElseIf objCodeElement.Kind = vsCMElement.vsCMElementProperty Then
                objCodeProperty = DirectCast(objCodeElement, EnvDTE.CodeProperty)
                DTE.Debugger.Breakpoints.Add(objCodeElement.FullName)
            End If
        Catch ex As System.Exception
            ' Ignore
        End Try

        If TypeOf objCodeElement Is EnvDTE.CodeNamespace Then
            objCodeNamespace = CType(objCodeElement, EnvDTE.CodeNamespace)
            AddBreakpointsToProjectItems(objCodeNamespace.Members)
        ElseIf TypeOf objCodeElement Is EnvDTE.CodeType Then
            objCodeType = CType(objCodeElement, EnvDTE.CodeType)
            AddBreakpointsToProjectItems(objCodeType.Members)
        ElseIf TypeOf objCodeElement Is EnvDTE.CodeFunction Then
            objCodeFunction = DirectCast(objCodeElement, EnvDTE.CodeFunction)
            AddBreakpointsToProjectItems(CType(objCodeElement, CodeFunction).Parameters)
        End If
    End Sub

End Module
like image 162
Dirk Vollmar Avatar answered Nov 15 '22 11:11

Dirk Vollmar


I haven't tried it in a class library but this might work.

System.Diagnostics.Debugger.Break();
like image 21
Hans Olsson Avatar answered Nov 15 '22 09:11

Hans Olsson