Archived Forum Post

Index of archived forum posts

Question:

.Net 4.5 AccessViolationException at Imap.SetMailFlag

Aug 10 '13 at 05:17

Error getting email from bundle: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at ClsImap.SetMailFlag(ClsImap , ClsEmail , XString , Int32 , ProgressEvent ) at Chilkat.Imap.SetMailFlag(Email email, String flagName, Int32 value)

Calling with SetMailFlag(email, "Deleted", 1) Runtime Version v4.0.30319 Version 9.4.1.0 Net 4.5 x64


Answer

Thanks! I'll have a look right now.


Answer

I'm not able to reproduce the error. I'm posting the C# code I used for testing below. I'm confused about what .NET Framework you are using -- is it 4.0 or 4.5?

Your post indicate 4.0 by this: "Runtime Version v4.0.3031", but you seem to be using the Chilkat assembly for the 4.5 Framework?

private void setMailFlagToolStripMenuItem_Click(object sender, EventArgs e)
{
    Chilkat.Imap imap = new Chilkat.Imap();

bool success = imapConnectAndLogin("fausey@chilkatsoft.com", imap);
    if (!success) return;

success = imap.SelectMailbox("Inbox");
    if (!success)
    {
        textBox2.Text = imap.LastErrorText;
        return;
    }

// Download the 1st email and set the delete flag.
    Chilkat.Email email = imap.FetchSingle(1, false);
    if (email == null)
    {
        textBox2.Text = imap.LastErrorText;
        return;
    }

success = imap.SetMailFlag(email, "Deleted", 1);
    if (!success)
    {
        textBox2.Text = imap.LastErrorText;
        return;
    }

if (success)
    {
        textBox2.Text = "Success.";
    }
    return;
}


Answer

good question. the version of system.dll, for example, is 4.0.30319.18044 the version of mscoreei.dll is 4.0.30319.17929 I think those mean .net 4.5. Sorry I wasn't more specific, I'm just learning that the 4.0.3031 part did not change between 4 and 4.5

Anyway, the exception is sporadic. I just catch, sleep and try from scratch with a new mail instance. It started with 9.4.1.0.
9.3.2.0 4.5 did not exhibit this.
9.3.1.0 4.0 (i think) use to give me the same sporadic exception but in Imap.FetchBundle (which a saw in a related question that you fixed.)

my code goes something like:

while (true)
{
    try
    {
        if (_mail == null)
        {
            _mail = new Imap();
            _mail.UnlockComponent("");
            _mail.KeepSessionLog = false;
            _mail.Ssl = true;
            _mail.Port = 993;
            _mail.Connect("blah");
            _mail.Login("me+blah.com", "passwork")
            _mail.SelectMailbox("INBOX")

            _bounce = new Bounce();
            _bounce.UnlockComponent("xxxxx");
        }

        // Get the message IDs of all the emails in the mailbox
        var messageSet = _mail.Search("ALL", true);
        var bundle = _mail.FetchBundle(messageSet);

        for (var i = 0; i < bundle.MessageCount; i++)
        {
            var email = bundle.GetEmail(i);

            if (_bounce.ExamineEmail(email) && _bounce.BounceType > 0)
            {
                //....
            }
            else
            {
                //look at email
            }
            _mail.SetMailFlag(email, "Deleted", 1);
        }

        //todo: why doing this way?
        //It is ok to call Expunge when nothing was deleted.
        _mail.Expunge();
    }
    catch (AccessViolationException)
    {
        if (_mail != null)
        {
            _mail.Disconnect();
            _mail = null;
        }
    }
    catch (Exception)
    {
        if (_mail != null)
        {
            _mail.Disconnect();
            _mail = null;
        }
    }
    Thread.Sleep(3000);
}

Answer

The DebugLogFilePath property, which is now common to all Chilkat classes, is designed to help with these difficult situations. If you set it to the path of a log file that is to be created, then every Chilkat method call on the object will log to the file each line that goes into the LastErrorText. Each line is logged by opening the log file, writing the line, and closing the file so as to avoid file I/O buffering issues.

Do this: On the line before the call to SetMailFlag, set the DebugLogFilePath property to the path of a log file you want created (for example: C:/temp/chilkatLog.txt) Also, add a line of code to delete the log file. This way, each time SetMailFlag is called, no log file exists, it is created, and if the crash occurs, you'll be left with a log of what happened up until the crash. Make sure to turn on verbose logging by setting the VerboseLogging property = true. This will provide more detailed information in the log file. After the call to SetMailFlag, set the DebugLogFilePath to the empty string so that nothing more is logged -- you only need it for the call to SetMailFlag. Then run to get the next crash and send me the log file (or post it here).

In pseudo-code, the changes would look like this:

_mail.DebugLogFilePath = "c:/temp/chilkatLog.txt"
_mail.VerboseLogging = true;
If the file c:/temp/chilkatLog.txt exist, then delete it.
_mail.SetMailFlag(email, "Deleted", 1);
_mail.DebugLogFilePath = "";
_mail.VerboseLogging = false;


Answer

The trap has been set!


Answer

Caught one! The trap:

Dim chilkatLog = "C:\chilkatLog.txt";
try
{
    _mail.DebugLogFilePath = chilkatLog;
    _mail.VerboseLogging = true;
    _mail.SetMailFlag(email, "Deleted", 1)
}
catch (AccessViolationException e)
{
    if (File.Exists(chilkatLog))
    {
        File.Copy(chilkatLog, 
            chilkatLog.Replace(".txt", Guid.NewGuid() + ".txt"), true);
    }
}
finally
{
    _mail.DebugLogFilePath = "";
    _mail.VerboseLogging = false;
    if (File.Exists(chilkatLog))
    {
        File.Delete(chilkatLog);
    }
}

The Log:

SetMailFlag:
    DllDate: Jul  9 2013
    ChilkatVersion: 9.4.1.26
    UnlockPrefix: KEN**********LQ
    Username: YOUCOULD:Ken
    Architecture: Little Endian; 64-bit
    Language: .NET 4.5 / x64
    VerboseLogging: 1
    Flag: Deleted
    Value: 1
    bUid: 1
    UidOrSeqNum: 48226
    ImapCmdSent: aitq UID STORE 48226 +FLAGS.SILENT (\Deleted)
    getCompleteResponse:
        rcvUntilMatchStringQP:

        dbReceived0: 
        tlsRecvAppData:
            readIncomingTls_appData:
                readTlsRecord:
                    TLS 1.0, Application, sz=48
                    paddingLen: 1
                    macLen: 20
                    decryptedMsg: [aitq OK Store completed.

]
                    (leaveContext)
                processTlsRecord:
                    processApplicationData:
                        (leaveContext)
                    (leaveContext)
                (leaveContext)
            rcvAppData: success, nReceived = 26
            (leaveContext)
        startIdx: 0
        dbReceived: aitq OK Store completed.

        Found match string.
        ImapCmdResp: aitq OK Store completed.
        (leaveContext)

The Exception:

System.AccessViolationException: Attempted to read or write protected memory. 
This is often an indication that other memory is corrupt.
       at ClsImap.SetMailFlag(ClsImap* , ClsEmail* , XString* , Int32 , ProgressEvent* )
       at Chilkat.Imap.SetMailFlag(Email email, String flagName, Int32 value)
       at SCS.Import.EmailPoller.Start() in c:\SCS\Code\Import\EmailPoller.cs:line 88

Answer

Thanks. Please do exactly the same with this new build:

http://www.chilkatsoft.com/preRelease/ChilkatDotNet45-9.4.1-x64.zip

If you get the exception again, post the log file. There is additional information that should help isolate the source of the problem.


Answer

Here is what the new dll logs before the AccessViolationException:

SetMailFlag:
    DllDate: Aug  5 2013
    ChilkatVersion: 9.4.1.34
    UnlockPrefix: KEN**********LQ
    Username: YOUCOULD:Ken
    Architecture: Little Endian; 64-bit
    Language: .NET 4.5 / x64
    VerboseLogging: 1
    setFlag:
        Flag: Deleted
        Value: 1
        bUid: 1
        UidOrSeqNum: 48657
        ImapCmdSent: afjk UID STORE 48657 +FLAGS.SILENT (\Deleted)
        getCompleteResponse:
            rcvUntilMatchStringQP:

            dbReceived0: 
            tlsRecvAppData:
                readIncomingTls_appData:
                    readTlsRecord:
                        TLS 1.0, Application, sz=48
                        paddingLen: 1
                        macLen: 20
                        decryptedMsg: [afjk OK Store completed.

]
                        (leaveContext)
                    processTlsRecord:
                        processApplicationData:
                            (leaveContext)
                        (leaveContext)
                    (leaveContext)
                rcvAppData: success, nReceived = 26
                (leaveContext)
            startIdx: 0
            dbReceived: afjk OK Store completed.

            Found match string.
            ImapCmdResp: afjk OK Store completed.
            (leaveContext)
        (leaveContext)
    addingMimeHeader: ckx-imap-deleted
    Checking for the ckx-imap-flags header..

and the exception:

 System.AccessViolationException: Attempted to read or write protected memory. 
    This is often an indication that other memory is corrupt.
     at ClsImap.SetMailFlag(ClsImap* , ClsEmail* , XString* , Int32 , ProgressEvent* )
     at Chilkat.Imap.SetMailFlag(Email email, String flagName, Int32 value)
     at SCS.Import.EmailPoller.Start() in c:\SCS\Code\Import\EmailPoller.cs:line 92

Answer

Thanks! I think this new build will likely fix the problem:

http://www.chilkatsoft.com/preRelease/ChilkatDotNet45-9.4.1-x64.zip


Answer

You have fixed it. Thank you. -Ken