Hi,
I have recently been having some problems with my NetOS 7.5 on CC9P crashing. The nature of the crashes led me to believe that I had a memory leak. After much wailing and gnashing of teeth, I believe that I have tracked this down.
The system that I am working on periodically needs to send data via HTTP POST. These posts may be kicked of at various times and a different places in the application. The main application must also remain responsive whilst the POST is taking place.
To achieve this I decided to generate a routine that dynamically allocates a new thread, lets this new thread do the actual post, and then deletes the thread once it is complete. Within the new thread I have a number of printf statements to show the various states involved in looking up DNS, getting a connection to the host, sending the data, and waiting for the response.
It would appear that each time I created, ran and then deleted the threads, I was loosing 1032 bytes from the heap (checked with NABspGetHeapSnapshot()).
I then simplified things, by starting a new application. This defines a thread function that simply sleeps for a couple of seconds. The main application runs a very simple loop to create a thread, wait for it to complete, and then delete it.
If the thread includes a printf statement there is a 1032 byte loss of the heap. The following code shows the test I am using
Has anyone else seen this problem or have any ideas what exactly is going on?
#include
#include
#include
#include
#include "appconf_api.h"
#include "appconf.h"
/*****************************************************************************
Defined Constants
*****************************************************************************/
#define THREAD_STACK_SZ (4096)
static int GLB_PrevTotAlloc = 0;
void GetHeapInfo(void)
{
int status;
int alloc_change;
NABspMallocStats stats;
const char *MEM_FMT = "MEM:[%08ld] %s: %d
";
const char *ERR_FMT = "ERR:[%08ld] %s() failed with status %d
";
status = NABspGetHeapSnapshot(&stats);
if (status) {
printf(ERR_FMT, tx_time_get(), "NABspMallocStats", status);
return;
}
// printf(MEM_FMT, tx_time_get(), "Total RAM", stats.system);
// printf(MEM_FMT, tx_time_get(), "Alloc RAM", stats.arena);
// printf(MEM_FMT, tx_time_get(), "Chunks F", stats.ordblks);
// printf(MEM_FMT, tx_time_get(), "Region Sp", stats.hblks);
// printf(MEM_FMT, tx_time_get(), "Regions", stats.hblkhd);
printf(MEM_FMT, tx_time_get(), "Usr Alloc", stats.uordblks);
// printf(MEM_FMT, tx_time_get(), "UnAlloc Tot", stats.fordblks);
// printf(MEM_FMT, tx_time_get(), "UnAlloc End", stats.fordblks);
alloc_change = stats.uordblks - GLB_PrevTotAlloc;
GLB_PrevTotAlloc = stats.uordblks;
printf(MEM_FMT, tx_time_get(), "Alloc Chng", alloc_change);
}
static UINT GetThreadState(TX_THREAD *the_thread)
{
CHAR *name;
UINT state;
ULONG run_count;
UINT priority;
UINT preemption_threshold;
ULONG time_slice;
TX_THREAD *next_thread;
TX_THREAD *suspended_thread;
UINT status;
/* Retrieve information about the thread */
status = tx_thread_info_get(the_thread,
&name,
&state,
&run_count,
&priority,
&preemption_threshold,
&time_slice,
&next_thread,
&suspended_thread);
if (status != TX_SUCCESS) {
printf("ERR:[%08ld] tx_thread_info_get() status:%d
", tx_time_get(), status);
return(0xFFFFFFFF);
}
return (state);
}
static void ThreadFunction(ULONG initial_input)
{
// printf("INF:[%08ld] ThreadFunction Started
", tx_time_get());
tx_thread_sleep(200);
// printf("INF:[%08ld] ThreadFunction Ended
", tx_time_get());
}
void MainApp(void)
{
unsigned char ThreadStack[THREAD_STACK_SZ];
TX_THREAD ThreadCtrlBlk = {0};
UINT status;
UINT thread_state;
printf("________After Initialisation___________
");
GetHeapInfo();
while (1) {
printf("_______________START___________________
");
GetHeapInfo();
/* Create the thread */
status = tx_thread_create(&ThreadCtrlBlk, /* control block for thread*/
"A Thread", /* thread name*/
ThreadFunction, /* entry function*/
(ULONG)NULL, /* parameter*/
ThreadStack, /* start of stack*/
THREAD_STACK_SZ, /* size of stack*/
APP_DEFAULT_API_PRIORITY, /* priority*/
APP_DEFAULT_API_PRIORITY, /* preemption threshold */
1, /* time slice threshold*/
TX_AUTO_START); /* start immediately*/
if (status != TX_SUCCESS) {
printf("ERR:[%08ld] tx_thread_create() status:%d
", tx_time_get(), status);
break;
}
/* Wait for thread to complete */
while ((thread_state = GetThreadState(&ThreadCtrlBlk)) != TX_COMPLETED) {
printf("INF:[%08ld] tx_thread_create() state:%d
", tx_time_get(), thread_state);
tx_thread_sleep(10);
}
/* Delete the thread */
status = tx_thread_delete(&ThreadCtrlBlk);
if (status != TX_SUCCESS) {
printf("ERR:[%08ld] tx_thread_delete() status:%d
", tx_time_get(), status);
break;
}
tx_thread_sleep(100);
printf("________________END____________________
");
}
printf("________________On Exit________________
");
GetHeapInfo();
}