Search code examples
.netvb.netmemoryaccess-violationprotected

VB.Net in Visual Studio 2015 - "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."


everyone. I hope all are well during this pandemic.

I have a maintenance program in which I have been using the following feature successfully for years until we recently changed from Windows 7 to Windows 10.

Among other things, my program displays PDF documents that were scanned into Xerox Docushare. The documents are associated with a reference Id from a bar code. There could be one or dozens of scan instances for a single coversheet (barcode).

I have a user defined control (ucDocushare_DocumentSetByRefID.vb), which has a ListView (lvwDocuments) and a TabControl (tcDocumentScanInstances). The functionality is that the ListView displays the coversheets that represent the scan sets. When a user clicks an item in the ListView, the TabControl is displayed with a tab for each individual scan instance related to the selected coversheet.

Every now and then, for no apparent reason, when I click a coversheet item in the ListView, the program directly terminates. When debugging in Visual Studio 2015, following message is displayed. It is not related to the size of the document or to the number of scan instances. I have brought up very large documents with many pages successfully. I also have had many scan instances successfully appear.

System.AccessViolationException was unhandled Message: An unhandled exception of type 'System.AccessViolationException' occurred in System.Windows.Forms.dll

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Also, a Break Mode tab appears with the following:

The application is in break mode

Your app has entered a break state, but there is no code to show because all threads were executing external code (typically system or framework code).

The error occurs immediately when stepping from the End Sub line of this:

Private Sub tcDocumentScanInstances_DrawItem(sender As Object, e As DrawItemEventArgs) _
    Handles tcDocumentScanInstances.DrawItem

This DrawItem sub does a little font managing for the tab labels but primarily determines which icon is displayed on those labels.

This is the full code for that sub:

'Color code document tab labels and display appropriate icons.
 Private Sub tcDocumentScanInstances_DrawItem(sender As Object, e As DrawItemEventArgs) _
    Handles tcDocumentScanInstances.DrawItem

Try

    Dim intTabIndex As Integer = 0

    '  Identify which TabPage is currently selected
    Dim SelectedTab As TabPage = tcDocumentScanInstances.TabPages(e.Index)

    '  Get the area of the header of this TabPage.  This is the actual label for the tab page.
    Dim HeaderRect As Rectangle = tcDocumentScanInstances.GetTabRect(e.Index)

    '  Create a Brush to paint the Text
    Dim sbBlackBrush As New SolidBrush(Color.Black)
    Dim sbRedBrush As New SolidBrush(Color.Red)

    '  Set the Alignment of the Text
    Dim sf As New StringFormat()
    sf.Alignment = StringAlignment.Center
    sf.LineAlignment = StringAlignment.Center

    '  Paint the Text using the appropriate Bold setting 
    Dim intIconPositionX As Integer = HeaderRect.Left + 4
    Dim intIconPositionY As Integer = HeaderRect.Top + 7

    Dim dicImages As New Dictionary(Of String, Image)()
    dicImages("Tab" & e.Index) = Nothing  ' Set the value of the "variable"

    tcDocumentScanInstances.Padding = New System.Drawing.Point(15, 15)
    'tcDocumentScanInstances.TabPages(0).Width = 500

    If Convert.ToBoolean(e.State And DrawItemState.Selected) Then

        Dim BoldFont As New Font(tcDocumentScanInstances.Font.Name, tcDocumentScanInstances.Font.Size, FontStyle.Bold)

        e.Graphics.FillRectangle(New SolidBrush(SystemColors.ButtonFace), e.Bounds)

        If tcDocumentScanInstances.TabPages(e.Index).Tag Is Nothing Then
            tcDocumentScanInstances.TabPages(e.Index).Tag = ""
        End If

        Select Case tcDocumentScanInstances.TabPages(e.Index).Tag.ToString
            Case "Delete", "Delete Client Letter", "Excessive Documentation"
                dicImages("Tab" & e.Index) = ilTabIconsForDocumentScanInstances.Images(IconsForDocumentScanInstances.DeleteDocument)
                e.Graphics.DrawString(SelectedTab.Text, BoldFont, sbRedBrush, HeaderRect, sf)
                sbRedBrush.Dispose()
            Case "No Documentation"
                dicImages("Tab" & e.Index) = ilTabIconsForDocumentScanInstances.Images(IconsForDocumentScanInstances.NoDocumentExists)
                e.Graphics.DrawString(SelectedTab.Text, BoldFont, sbBlackBrush, HeaderRect, sf)
                sbBlackBrush.Dispose()
            Case Else
                dicImages("Tab" & e.Index) = ilTabIconsForDocumentScanInstances.Images(IconsForDocumentScanInstances.DocumentExists)
                e.Graphics.DrawString(SelectedTab.Text, BoldFont, sbBlackBrush, HeaderRect, sf)
                sbBlackBrush.Dispose()
        End Select

        e.Graphics.DrawImage(dicImages("Tab" & e.Index), intIconPositionX, intIconPositionY)

    Else

        e.Graphics.FillRectangle(New SolidBrush(Color.FromArgb(128, 167, 240)), e.Bounds)
        If tcDocumentScanInstances.TabPages(e.Index).Tag Is Nothing Then
            tcDocumentScanInstances.TabPages(e.Index).Tag = ""
        End If

        Select Case tcDocumentScanInstances.TabPages(e.Index).Tag.ToString
            Case "Delete", "Delete Client Letter", "Excessive Documentation"
                dicImages("Tab" & e.Index) = ilTabIconsForDocumentScanInstances.Images(IconsForDocumentScanInstances.DeleteDocument)
                e.Graphics.DrawString(SelectedTab.Text, e.Font, sbRedBrush, HeaderRect, sf)
                sbRedBrush.Dispose()
            Case "No Documentation", "Missing Documentation"
                dicImages("Tab" & e.Index) = ilTabIconsForDocumentScanInstances.Images(IconsForDocumentScanInstances.NoDocumentExists)
                e.Graphics.DrawString(SelectedTab.Text, e.Font, sbBlackBrush, HeaderRect, sf)
                sbBlackBrush.Dispose()
            Case Else
                dicImages("Tab" & e.Index) = ilTabIconsForDocumentScanInstances.Images(IconsForDocumentScanInstances.DocumentExists)
                e.Graphics.DrawString(SelectedTab.Text, e.Font, sbBlackBrush, HeaderRect, sf)
                sbBlackBrush.Dispose()
        End Select

        e.Graphics.DrawImage(dicImages("Tab" & e.Index), intIconPositionX, intIconPositionY)

    End If

    If tcDocumentScanInstances.SelectedTab.Tag Is Nothing Then
        tcDocumentScanInstances.SelectedTab.Tag = ""
    End If

    If frmCaseMaintenance.tcDocumentationByRefID.TabPages( _
        frmCaseMaintenance.tcDocumentationByRefID.SelectedIndex).Tag.ToString.Length >= "Delete".Length Then

        If frmCaseMaintenance.tcDocumentationByRefID.TabPages( _
            frmCaseMaintenance.tcDocumentationByRefID.SelectedIndex).Tag.ToString.Substring(0, "Delete".Length) <> "Delete" Then
            'The coversheet and all associated documents, together, are not marked for deletion.

            Select Case tcDocumentScanInstances.SelectedTab.Tag.ToString.Trim
                Case "Delete", "Delete Client Letter"
                    btnMarkCurrentDocumentForDeletion.Enabled = False
                    btnUnmarkCurrentDocumentForDeletion.Enabled = True
                Case "No Documentation", "Missing Documentation"
                    'A tab displaying a message that there is no documentation can not be deleted.
                    btnMarkCurrentDocumentForDeletion.Enabled = False
                    btnUnmarkCurrentDocumentForDeletion.Enabled = False
                Case Else
                    btnMarkCurrentDocumentForDeletion.Enabled = True
                    btnUnmarkCurrentDocumentForDeletion.Enabled = False
            End Select

        Else 'the coversheet and all associated documents, together, are marked for deletion.

            btnMarkCurrentDocumentForDeletion.Enabled = False
            btnUnmarkCurrentDocumentForDeletion.Enabled = False

        End If

    Else 'the coversheet and all associated documents, together, are marked for deletion.

            Select Case tcDocumentScanInstances.SelectedTab.Tag.ToString.Trim
                Case "Delete", "Delete Client Letter"
                    btnMarkCurrentDocumentForDeletion.Enabled = False
                    btnUnmarkCurrentDocumentForDeletion.Enabled = True
                Case "No Documentation", "Missing Documentation"
                    'A tab displaying a message that there is no documentation can not be deleted.
                    btnMarkCurrentDocumentForDeletion.Enabled = False
                    btnUnmarkCurrentDocumentForDeletion.Enabled = False
                Case Else
                    btnMarkCurrentDocumentForDeletion.Enabled = True
                    btnUnmarkCurrentDocumentForDeletion.Enabled = False
            End Select

    End If

Catch ex As Exception

    If Err.Description = "A generic error occurred in GDI+." Then
        'This error probably was tripped by this line:  e.Graphics.FillRectangle(New SolidBrush(SystemColors.ButtonFace), e.Bounds)
        'tabDocumentScanInstance_DrawItem() will execute again without that line causing a problem, so we do nothing here.
    Else
            MessageBox.Show( _
                 "Class Name:  " & Me.Name & vbCrLf & _
                 "Sub Name:  tcDocumentScanInstances_DrawItem()" & vbCrLf & _
                 "Error Number:  " & Err.Number & vbCrLf & _
                 "Message:  " & Err.Description, _
                 gstrExecutableName & " - Error", _
                 MessageBoxButtons.OK, MessageBoxIcon.Error)
    End If

End Try

End Sub

PRODUCTS IN USE

Microsoft Visual Studio Professional 2015 Version 14.0.25431.01 Update 3

Microsoft .NET Framework Version 4.8.03752

ATTEMPTED SOLUTIONS

  • rebooted computer

  • deleted executable and generated a new one

  • executed “netsh winsock reset” in the Command Prompt and rebooted; also executed “netsh winsock reset catalog” in the Command Prompt and rebooted

  • changed the "Platform target" from "Any CPU" to "x86".

    1. [Project Name] Properties ->”Compile” tab -> “Compile Options” -> “Target CPU”
    2. Rebuild/Build project. (I changed it back to “Any CPU” when “x86” failed to correct the problem.)
  • It was suggested that the following be unchecked in Visual Studio. It already was.

       Tools menu ->Options -> Debugging -> General -> Uncheck this option "Suppress JIT optimization on module load"
    
  • replaced System.Windows.Forms.dll located here with another copy of the file (same date/time and file size): C:\Windows\Microsoft.NET\Framework\v2.0.50727

I appreciate input.


Solution

  • I succeeded with a brute force workaround. I discovered that the problem happened if I selected the troublesome item from the ListView without first having selected any other items from the ListView which didn't cause the problem. So, the solution was somehow to select an item which didn't cause the problem before selecting one that did. How would I know which one I could select that wouldn't cause the problem? Also, if there were only one item in the list, what could I do then?

    The solution was to create a dummy document and always load it first.

    As before, the user selects a category that populates the ListView (lvwDocuments), which displays the coversheets that represent the scan sets. Now, however, before those coversheets are loaded into the list, an item is loaded that represents the dummy coversheet. (The first item in the list is the dummy coversheet and the rest are valid items for the category selected.) Based on that dummy item as the first item in the list, I load the dummy document onto a tab in the tabControl (tcDocumentScanInstances). I delete the dummy coversheet item from the ListView (lvwDocuments) and hide the dummy document on the tab with a panel that displays a message telling the user that scan instances will appear in tabs when a coversheet item is selected. (Surprisingly, it actually looks better than the interface I had before and the message does not seem unnecessary or out of place!) The user never sees dummy item in the list as it is loaded and deleted so quickly.

    There you have it. From what I found when searching for a solution, there seem to be so many different situations in which this error occurs. I wish I knew a better way to prevent this, a way that could be applied to other situations, as well. This solution works for me in this instance. I hope it helps someone somehow.