Memory leak or memory accumulation with freetds-0.82 ctlib's ct_cmd_alloc / ct_cmd_drop?

[email protected]
Newsgroups gmane.comp.db.tds.freetds
Message-ID <1016172266.534641227717619694.JavaMail.root@sz0116a.westchester.pa.mail.comcast.net>

Hi all, 



Is there a known memory leak or memory accumulation issue with ct_cmd_alloc / ct_cmd_drop? 



I'm writing a program to poll a database as regular intervals and it gradually accumulates memory (seen via top). 



Below is source code to attempt and isolate the problem, compiled with the following command: 

   cc -o ctlib_leak ctlib_leak.c /usr/local/lib/libct.a /usr/lib/librt.a 



I am linking with the archive libraries to run against Purify if necessary. 


Quickest way to see memory eaten up (via top) is to direct stdout and stderr to /dev/null (so output doesn't slow down processing). 



Thanks in advance for any input or suggestions.  I can dig deeper, but wanted to know if this is a known issue. 



Regards, Michael 





Here is the source code for ctlib_leak.c: 



#include <ctpublic.h> 
#include <signal.h> 
#include <stdio.h> 



#define DB_SERVER_PORT "crunch3.localdomain 4100" 
#define DB_USER  "root" 
#define DB_PASSWORD "" 



#define RC_ERROR -1 
#define RC_GOOD  0 



#define TRUE  1 
#define FALSE  0 



int   signaled_to_exit; 
CS_CONTEXT  *cntx_ptr; 
CS_CONNECTION  *conn_ptr; 
CS_COMMAND  *cmd_ptr; 



void 
signal_handler(int i_signal) 
{ 
 printf("signaled received, will clean up and exit\n"); 
 signaled_to_exit = TRUE; 
 return; 

} 



main() 
{ 
 int rc; 



 // setup signal handling, so program exits polling loop cleanly 
 // NOTE:  NOT THREAD SAFE, SO IF MAKE MULTI-THREADED REVISIT SIGNALING 
 sigset_t newmask, oldmask; 
 signal(SIGINT, signal_handler); // for Ctrl-C (when run interactively) 
 signal(SIGTERM, signal_handler); 
 sigemptyset(&newmask);  // initialize signal set 
 sigaddset(&newmask, SIGINT); // add SIGINT to signal set 
 sigaddset(&newmask, SIGTERM); // add SIGTERM to signal set 



 // allocate a context 
 rc = cs_ctx_alloc (CS_VERSION_100, &cntx_ptr); 
 if (rc == CS_SUCCEED) { 
  printf("cs_ctx_alloc success\n"); 
 } else { 
  printf("cs_ctx_alloc FAILED\n"); 
  return(RC_ERROR); 
 } 



 // initialize the library 
 rc = ct_init (cntx_ptr,  CS_VERSION_100); 
 if (rc == CS_SUCCEED) { 
  printf("ct_init success\n"); 
 } else { 
  printf("ct_init FAILED\n"); 
  return(RC_ERROR); 
 } 



 // allocate a connection pointer 
 rc = ct_con_alloc(cntx_ptr, &conn_ptr); 
 if (rc == CS_SUCCEED) { 
  printf("ct_con_alloc success\n"); 
 } else { 
  printf("ct_con_alloc FAILED\n"); 
  return(RC_ERROR); 
 } 



 // set the host and port 
 rc = ct_con_props(conn_ptr, CS_SET, CS_SERVERADDR, DB_SERVER_PORT, CS_NULLTERM, NULL); 
 if (rc == CS_SUCCEED) { 
  printf("ct_con_props success\n"); 
 } else { 
  printf("ct_con_props FAILED\n"); 
  return(RC_ERROR); 
 } 



 // set the username property 
 rc = ct_con_props(conn_ptr, CS_SET, CS_USERNAME, DB_USER, CS_NULLTERM, NULL); 
 if (rc == CS_SUCCEED) { 
  printf("ct_con_props success\n"); 
 } else { 
  printf("ct_con_props FAILED\n"); 
  return(RC_ERROR); 
 } 



 // set the password property 
 rc = ct_con_props(conn_ptr, CS_SET, CS_PASSWORD, DB_PASSWORD, CS_NULLTERM, NULL); 
 if (rc == CS_SUCCEED) { 
  printf("ct_con_props success\n"); 
 } else { 
  printf("ct_con_props FAILED\n"); 
  return(RC_ERROR); 
 } 



 // connect to the server 
 rc = ct_connect(conn_ptr, NULL, CS_UNUSED); 
 if (rc == CS_SUCCEED) { 
  printf("ct_connect success\n"); 
 } else { 
  printf("ct_connect FAILED\n"); 
  return(RC_ERROR); 
 } 



 signaled_to_exit = FALSE; 
 while (signaled_to_exit == FALSE) { 


  //************************************************************ 
  // CRITICAL SECTION START -- BLOCK SIGNALS WHILE PROCESSING 
  //************************************************************ 
  // block signals and save current signal mask 
  sigprocmask(SIG_BLOCK, &newmask, &oldmask); 



  rc = func(); 
  if (rc != RC_GOOD) 
   return(rc); 



  // resume the original signal mask 
  sigprocmask(SIG_SETMASK, &oldmask, NULL); 
  //************************************************************ 
  // CRITICAL SECTION END -- UNBLOCK SIGNALS, ALLOW TO EXIT 
  //************************************************************ 
 } 



 // close connection to the database 
 rc = ct_close(conn_ptr, CS_UNUSED); 
 if (rc == CS_SUCCEED) { 
  printf("ct_close success\n"); 
 } else { 
  printf("ct_close FAILED\n"); 
  return(RC_ERROR); 
 } 



 // deallocate the connection 
 rc = ct_con_drop(conn_ptr); 
 if (rc == CS_SUCCEED) { 
  printf("ct_con_drop success\n"); 
 } else { 
  printf("ct_con_drop FAILED\n"); 
  return(RC_ERROR); 
 } 



 // exit client library 
 rc = ct_exit(cntx_ptr, CS_UNUSED); 
 if (rc == CS_SUCCEED) { 
  printf("ct_exit success\n"); 
 } else { 
  printf("ct_exit FAILED\n"); 
  return(RC_ERROR); 
 } 



 // deallocate the context structure 
 rc = cs_ctx_drop(cntx_ptr); 
 if (rc == CS_SUCCEED) { 
  printf("cs_ctx_drop success\n"); 
 } else { 
  printf("cs_ctx_drop FAILED\n"); 
  return(RC_ERROR); 
 } 



 return(RC_GOOD); 
} 



int 
func() 
{ 
 CS_RETCODE  rc; 



 // allocate a command structure 
 rc = ct_cmd_alloc(conn_ptr, &cmd_ptr); 
 if (rc == CS_SUCCEED) { 
  printf("ct_cmd_alloc success\n"); 
 } else { 
  printf("ct_cmd_alloc FAILED\n"); 
  return(RC_ERROR); 
 } 



/**** MEMORY LEAK OR AT LEAST ACCUMULATING ****/ 



 // deallocate the command structure 
 rc = ct_cmd_drop(cmd_ptr); 
 if (rc == CS_SUCCEED) { 
  printf("ct_cmd_drop success\n"); 
 } else { 
  printf("ct_cmd_drop FAILED\n"); 
  return(RC_ERROR); 
 } 



 return(RC_GOOD); 
} 

_______________________________________________
FreeTDS mailing list
[email protected]
http://lists.ibiblio.org/mailman/listinfo/freetds
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.