freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
[freetds] Memory leak or memory accumulation with freetds-0.82 ctlib's ct_cmd_alloc / ct_cmd_drop?
- From: mtbrown88 AT comcast.net
- To: freetds AT lists.ibiblio.org
- Subject: [freetds] Memory leak or memory accumulation with freetds-0.82 ctlib's ct_cmd_alloc / ct_cmd_drop?
- Date: Wed, 26 Nov 2008 16:40:19 +0000 (UTC)
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] Memory leak or memory accumulation with freetds-0.82 ctlib's ct_cmd_alloc / ct_cmd_drop?,
mtbrown88, 11/26/2008
-
Re: [freetds] Memory leak or memory accumulation with freetds-0.82 ctlib's ct_cmd_alloc / ct_cmd_drop?,
Frediano Ziglio, 11/27/2008
-
Re: [freetds] Memory leak or memory accumulation with freetds-0.82 ctlib's ct_cmd_alloc / ct_cmd_drop?,
mtbrown88, 11/27/2008
- Re: [freetds] Memory leak or memory accumulation with freetds-0.82 ctlib's ct_cmd_alloc / ct_cmd_drop?, Frediano Ziglio, 11/29/2008
-
Re: [freetds] Memory leak or memory accumulation with freetds-0.82 ctlib's ct_cmd_alloc / ct_cmd_drop?,
mtbrown88, 11/27/2008
-
Re: [freetds] Memory leak or memory accumulation with freetds-0.82 ctlib's ct_cmd_alloc / ct_cmd_drop?,
Frediano Ziglio, 11/27/2008
Archive powered by MHonArc 2.6.24.