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.