From mpvenkatesh at lycos.com  Mon May  5 02:07:30 2003
From: mpvenkatesh at lycos.com (mpvenkatesh@lycos.com)
Date: Mon May  5 01:07:43 2003
Subject: [Rd] R-1.7.0: Rproxy.dll loadlibrary/freelibrary error (PR#2914)
Message-ID: <200305042307.h44N7U2b006301@pubhealth.ku.dk>

Full_Name: Venkatesh Mysore
Version: R-1.7.0
OS: WindowsXP
Submission from: (NULL) (216.165.110.10)


While accessing Rproxy.dll repeatedly (using the code from the (D)COM example in
the R website) causes a failure in the 24th iteration. R-1.6.2 does NOT give
this error. This seems to be a memory management error, that might be linked to
the huge leakage difference between R-1.7.0 and R-1.6.2 (leakage observed using
Windows Task Manager).

Here is a C program that can be used to reproduce the error:
(the files SC-Proxy.h, Defn.h, Rinternals.h etc.. are to be included in the path
- see StatConnector.cpp in the (D)COM server example)


#include "windows.h"
#include "stdio.h"
#include "SC_Proxy.h"
#define RDLL "Rproxy.dll"
struct _SC_Proxy_Object* m_ProxyObject;
HMODULE m_ProxyModule;


#define SERVER_MAJOR_VERSION  "1"
#define SERVER_MINOR_VERSION "2"

#define	SCN_IERR_INTERFACENOTFOUND      0x81000000
#define	SCN_IERR_LIBRARYNOTFOUND        0x81000001
#define	SCN_IERR_INVALIDLIBRARY         0x81000002
#define	SCN_IERR_INITIALIZATIONFAILED   0x81000003
#define	SCN_IERR_INVALIDCONNECTORNAME   0x81000004
#define SCN_ERR_INITIALIZED             0x81000005
#define SCN_ERR_NOTINITIALIZED          0x81000006

#define TRACEBUFSIZE 1024
// 00-02-18 | baier | support arguments for connector initialization
// 01-04-04 | baier | enhancements by BDR: set RHOME from registry
// 03-04-07 | baier | check registry key on failure even if R_HOME is set,
//                    check PATH if everything else fails. trace failures!
int loadDll()
{
	  static char lTraceBuffer[TRACEBUFSIZE];
     // get entry-point
	if (getenv ("R_HOME"))
	  { // BDR
		  OutputDebugString("from env:");
		  char DLLlocation[MAX_PATH];
		  strcpy(DLLlocation, getenv("R_HOME"));
		  strcat(DLLlocation, "\\bin\\");
		  strcat(DLLlocation, RDLL);
		  OutputDebugString(DLLlocation);
		  m_ProxyModule = LoadLibraryEx (DLLlocation, NULL, 
					 LOAD_WITH_ALTERED_SEARCH_PATH);
		  // trace failure!
		  if (m_ProxyModule == 0) {
			  sprintf(lTraceBuffer,"R_HOME set to \"%s\", failed to load \"%s\"\n",
				  getenv("R_HOME"),DLLlocation);
			  OutputDebugString(lTraceBuffer);
		  }
	  }

      if (m_ProxyModule == 0)
	  {
	  // look in the registry
	  OutputDebugString("from reg:");
	  char DLLlocation[MAX_PATH];
	  LONG rc;
	  HKEY hkey;
	  DWORD keytype = REG_SZ;
	  DWORD cbData = sizeof (DLLlocation);
	  rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\R-core\\R", 0, 
			     KEY_READ, &hkey);
	  if (rc == ERROR_SUCCESS)
	    {
	      rc = RegQueryValueEx (hkey, "InstallPath", 0, &keytype, 
				    (LPBYTE)DLLlocation, &cbData);
	      RegCloseKey (hkey);
	    }

	  if (rc == ERROR_SUCCESS)
	    {
	      // set R_HOME
	      char *buf;
	      buf =
		(char *) malloc ((strlen (DLLlocation) + 8) * sizeof (char));
	      strcpy (buf, "R_HOME=");
	      strcat (buf, DLLlocation);
	      putenv (buf);
	      //SetEnvironmentVariable ("R_HOME",DLLlocation);
	      strcat (DLLlocation, "\\bin\\");
		  strcat (DLLlocation, RDLL);
		  OutputDebugString(DLLlocation);
	      m_ProxyModule = LoadLibraryEx (DLLlocation, NULL, 
					     LOAD_WITH_ALTERED_SEARCH_PATH);
	      if (m_ProxyModule == 0) {
		sprintf(lTraceBuffer,"Registry information said to load \"%s\", failed!\n",
		        DLLlocation);
		OutputDebugString(lTraceBuffer);
	      }
	    }
	  } //module==0

	//m_ProxyModule = LoadLibraryEx ("C:\\R\\rw1070\\bin\\Rproxy.dll", NULL, 
	//				 LOAD_WITH_ALTERED_SEARCH_PATH);

	

      SC_PROXY_GET_OBJECT lFunc;
      
      lFunc = (SC_PROXY_GET_OBJECT) GetProcAddress (m_ProxyModule,
    						   SC_PROXY_GET_OBJECT_FUN);
	  
      
      if (lFunc == 0)
    	{
          return -1;
    	}
      
      // get proxy object
      ULONG lRc = lFunc (&m_ProxyObject,SC_PROXY_INTERFACE_VERSION);
      
	  
      if ((lRc != SC_PROXY_OK) || (m_ProxyObject == 0))
    	{
    	  FreeLibrary (m_ProxyModule);
    	  m_ProxyModule = 0;
    	  
          return -2;
    	}
      
      char* lParams = 0;

	lParams = strdup ("");
	OutputDebugString("vtbl->init getting called:");         
      // init R
      lRc = m_ProxyObject->vtbl->init (m_ProxyObject,lParams);
	OutputDebugString("done init.");      
      free (lParams);

      if (lRc != SC_PROXY_OK)
    	{
    	  m_ProxyObject->vtbl->release (m_ProxyObject);
    	  m_ProxyObject = 0;
    	  FreeLibrary (m_ProxyModule);
    	  m_ProxyModule = 0;
    	  
    	  return -3;
    	}
    return 1;
}

int unloadDll()
{

      m_ProxyObject->vtbl->release (m_ProxyObject);
	  m_ProxyObject = 0;

	  DWORD err;
      int b = FreeLibrary (m_ProxyModule);
	  if (b==0) {
		  err = GetLastError();
		char ss[100];
		sprintf(ss,"\n\nErr = %d\n\n", err);
		OutputDebugString(ss);
		return -1;
	  } else OutputDebugString("no error unloading Rproxy dll.\n\n");

	  m_ProxyModule = 0;
    
  return 1;
}


int main() {
	char ss[100];
	int i,x,a;
	for (i=1; i<=100; i++) {
		sprintf(ss,"Iteration: %d", i);
		OutputDebugString(ss);
	x=loadDll();
	if (x<=0) OutputDebugString("LoadLibraryEx ERROR.");
	else OutputDebugString("LoadLibraryEx succeeded.");
	a = unloadDll();
	if (a<=0) OutputDebugString("FreeLibrary ERROR.");
	else OutputDebugString("FreeLibrary succeeded.");
	}
}

-----------------------------------------

-Venkatesh Mysore
Bioinformatics Group,
New York University


[Rd] R-1.7.0: Rproxy.dll loadlibrary/freelibrary error (PR#2914)
mpvenkatesh@lycos.com