In sFTP what causes System.AccessViolationException: Attempted to read or write protected memory

0 votes
asked Aug 1, 2012 by Drahcir (150 points)
edited Aug 13, 2012

After my Windows service has been running successfully for a few days I get a corrupt memory error from Rebex sFTP. The error then recurs whenever I try to use Rebex and I have to restart the service.

Is there something I'm doing wrong? I'm using Dispose(), not Disconnect(). And I'm creating a new connection on every operation, rather than trying manage a permanently open connection.

I'd appreciate any suggestions.

Here's the error:

System.AccessViolationException:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.   
at gbMKS.1vL03D.1fZglFZ(String )    
at gbMKS.ULE4T.1fZglFZ(IAsyncResult , String , Int32 )   
at gbMKS.ULE4T.1QP6MBZ(IAsyncResult , Int32 )    
at Rebex.Net.ProxySocket.Connect(String serverName, Int32 serverPort)   
at Rebex.Net.Sftp.Connect(String serverName, Int32 serverPort, SshParameters parameters)  
at Rebex.Net.Sftp.Connect(String serverName, Int32 serverPort)   
at Helper.FTPHelper.GetSFTPAndLogin()   
at Helper.FTPHelper.GetFileNamesInFolder(String path)    
at Helper.FileMoverHelper.DeleteFilesInFolderOlderThan(String folder, Int32 days, ILog logger)

And here's some sample code:

public void DeleteFiles(string folder, ILog logger) 
{
  try
  {
    var files = GetFileNamesInFolder(folder);
    foreach (var file in files)
    {
      var time = GetFileDateTime(file));
        DeleteIfExists(file, folder);
    }
  }
  catch (Exception e)
  {
    logger.Error("Couldn't clear folder : " + folder, e);
    System.Threading.Thread.Sleep(60000);
  }
}

public List<string> GetFileNamesInFolder(string path)
{
  var results = new List<string>();
  using (var sftp = GetSFTPAndLogin())
  {
    sftp.ChangeDirectory(path);

    var items = sftp.GetList();

    foreach (var item in items)
    {
      if (item.IsFile)
        results.Add(item.Name);
    }                
  }
  return results;
}

private Sftp GetSFTPAndLogin()
{

  var sftp = new Sftp();

  sftp.Timeout = 30000;

  if (UseHTTPProxy)            
    sftp.Proxy = new Proxy(ProxyType.HttpConnect, ProxyAuthentication.Ntlm, ProxyHostname, ProxyPort, CredentialCache.DefaultNetworkCredentials);

  sftp.Connect(Hostname, Port);
  sftp.Login(Username, Password);

  return sftp;
}
Applies to: Rebex SFTP

1 Answer

0 votes
answered Aug 1, 2012 by Lukas Pokorny (120,490 points)
edited Aug 13, 2012
 
Best answer

You don't seem to be doing anything wrong. Unfortunately, the problem with this exception is that it doesn't occur immediately during an attempt to access protected memory, but rather somewhat later. In this case, the gbMKS.1vL03D.1fZglFZ method is extremely simple and can't be the real cause of the error:

    public object End (string method)
    {
        if (_endCalled)
            throw new InvalidOperationException (string.Format(EndAlreadyCalled, method));

        _endCalled = true;

        if (_error != null)
            throw _error;

        return _result;
    }

However, you appear to be using NTLM and this is one of the very few pieces of Rebex SFTP code that calls Win32 API methods using P/Invoke functionality, which makes it suspect. Would it be possible to run your application temporarily without a proxy or with a non-NTLM proxy to see whether the issue appears again? If this only happens when using a NTLM proxy, at least we would know where to look.

In the meantime, we will review our NTLM code and try to find any potential issues.

commented Aug 1, 2012 by Drahcir (150 points)
edited Aug 1, 2012

Thanks. Unfortunately I'm inside a large bank accessing a government site through a proxy. NTLM was required to avoid storing passwords in config files (which is I chose Rebex rather than Chilkat or Eldos).

Would it help keeping a singleton connection open, rather than disposing it after every operation?

Otherwise I guess I need to just write another service to restart this service every morning, to avoid the corrupt memory build-up.

commented Aug 1, 2012 by Lukas Pokorny (120,490 points)
edited Aug 1, 2012

We tried rewriting part of the NTLM code, removing any constructs that looked potentially problematic. Please download the current hotfix build of Rebex SFTP from http://www.rebex.net/getfile/32d764c8ac7e454e89d49001100f3eea/RebexSftp-HotfixBuild4597-Trial-Binaries.zip and give it a try. Does it make any difference? (If you aready purchased a license, please ask for a full version of these DLLs at support@rebex.net)

commented Aug 1, 2012 by Lukas Pokorny (120,490 points)
edited Aug 1, 2012

Singleton connection wouldn't help. When a new connection is open, all internal objects are replaced with new ones, which means it's very close to disposing the instance.

commented Aug 10, 2012 by Drahcir (150 points)
edited Aug 10, 2012

Ok, it's been about a week now and the service is still running. I'll keep monitoring it but I think your change fixed it. Thanks for the quick response!

commented Aug 13, 2012 by Lukas Pokorny (120,490 points)
edited Aug 13, 2012

Thanks for letting us know! We will include the changes in the next release.

...