qnx6 devb-eide memory leak problem...

i tried qnx6 filesystem performance test…

the program is:

//
// app.cc
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <malloc.h>
#include <dirent.h>
#include <time.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

enum operation_t {
OP_Prompt,
OP_FileWrite,
OP_FileRead,
OP_FileReadWrite,
OP_TCP_ReadWrite,
OP_UDP_ReadWrite,
OP_Exit,
};

#define SIZE_5K 10245
#define SIZE_10K 1024
10
#define SIZE_30K 1024*30

#define TCP_PORT 3480
#define UDP_PORT 3481

struct test_info_t {
int op;
int size;
char filename[64];
};

#define DEF_SIZE SIZE_30K
#define DEF_COUNT 10
#define DEF_OPERATION OP_Prompt
#define DEF_TARGET “127.1”

int g_size = DEF_SIZE;
int g_count = DEF_COUNT;
int g_operation = DEF_OPERATION;
char g_target[64] = DEF_TARGET;
char* g_src_file = NULL;
char* g_dst_file = NULL;
int g_prompt = 0;
int g_remove = 0;
int g_loop = 0;
char* buffer = NULL;
FILE* log_fd = NULL;
time_t tm;

int op_file_write()
{
int fd_src = open(g_src_file, O_RDONLY);
if (fd_src < 0) { perror(“src open”); return 1; }
int size = read(fd_src, buffer, g_size);
close(fd_src);
if (size == -1) { perror(“src read”); return 1; }

long msec;
timespec start, stop;
clock_gettime(CLOCK_REALTIME, &start);

for (int i = 1; i <= g_count; i++) {
char str[256];
sprintf(str, “data/test_%05d.dat”, i);
int fd_dst = open(str, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
if (fd_dst < 0) { perror(“dst open”); return 1; }
size = write(fd_dst, buffer, g_size);
close(fd_dst);
if (size == -1) { perror(“dst write”); return 1; }

if (i % 10) continue;

clock_gettime(CLOCK_REALTIME, &stop);
msec = (stop.tv_sec-start.tv_sec)*1000 +
(stop.tv_nsec-start.tv_nsec)/1000000;
printf("%8d average:%ldms, total:%ldms \r", i, msec/i, msec);
fflush(stdout);
}

printf("\n");
return 0;
}

int op_file_read()
{
long msec;
timespec start, stop;
clock_gettime(CLOCK_REALTIME, &start);

for (int i = 1; i <= g_count; i++) {
char str[256];
sprintf(str, “data/test_%05d.dat”, i);
int fd_src = open(str, O_RDONLY);
if (fd_src < 0) { perror(“src open”); return 1; }
int size = read(fd_src, buffer, g_size);
close(fd_src);
if (size == -1) { perror(“src read”); return 1; }

if (i % 10) continue;

clock_gettime(CLOCK_REALTIME, &stop);
msec = (stop.tv_sec-start.tv_sec)*1000 +
(stop.tv_nsec-start.tv_nsec)/1000000;
printf("%8d average:%ldms, total:%ldms \r", i, msec/i, msec);
fflush(stdout);
}

printf("\n");
return 0;
}

int op_file_readwrite()
{
long msec;
timespec start, stop;
clock_gettime(CLOCK_REALTIME, &start);

for (int i = 1; i <= g_count; i++) {
char str[256];
sprintf(str, “data/test_%05d.dat”, i);
int fd_src = open(str, O_RDONLY);
if (fd_src < 0) { perror(“src open”); return 1; }
int size = read(fd_src, buffer, g_size);
close(fd_src);
if (size == -1) { perror(“src read”); return 1; }

sprintf(str, “dest/test_%05d.dat”, i);
int fd_dst = open(str, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
if (fd_dst < 0) { perror(“dst open”); return 1; }
size = write(fd_dst, buffer, g_size);
close(fd_dst);
if (size == -1) { perror(“dst write”); return 1; }

if (i % 10) continue;

clock_gettime(CLOCK_REALTIME, &stop);
msec = (stop.tv_sec-start.tv_sec)*1000 +
(stop.tv_nsec-start.tv_nsec)/1000000;
printf("%8d average:%ldms, total:%ldms \r", i, msec/i, msec);
fflush(stdout);
}

printf("\n");
return 0;
}

int remove_data(char* dir)
{
printf(“remove files in %s\n”, dir);

DIR* d = opendir(dir);
if (d == NULL) {
perror(“opendir”);
return 1;
}

long msec;
timespec start, stop;
clock_gettime(CLOCK_REALTIME, &start);

dirent* de = NULL;
de = readdir(d); // .
de = readdir(d); // …
for (int i = 1; (de = readdir(d)) != NULL; i++) {
char str[256];
sprintf(str, “%s/%s”, dir, de->d_name);
if (remove(str)) perror(“remove”);

if (i % 10) continue;

clock_gettime(CLOCK_REALTIME, &stop);
msec = (stop.tv_sec-start.tv_sec)*1000 +
(stop.tv_nsec-start.tv_nsec)/1000000;
printf("%8d average:%ldms, total:%ldms \r", i, msec/i, msec);
fflush(stdout);
}

printf("\n");
closedir(d);
return 0;
}

int generate_test_data(char* data_file, int size)
{
struct stat buf;
if ((stat(data_file, &buf) == 0) && (buf.st_size == size)) return 0;

int fd = open(data_file, O_WRONLY|O_CREAT|O_TRUNC,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);

if (fd == -1) {
perror(“generate_test_data open”);
return 1;
}

for (int i = 0; i < size/80; i++) {
char str[100];
sprintf(str,

“%08d:0123456789012345678901234567890123456789012345678901234567890123456789
\n”, i*80);
write(fd, str, 80);
}
close(fd);

printf(“file generate: %s, size: %d\n”, data_file, size);

return 0;
}

int parse(int argc, char* argv[])
{
int opt;
while ((opt = getopt(argc, argv, “c:o:t:s:nprl”)) != -1) {
switch (opt) {
case ‘c’: g_count = atoi(optarg); break;
case ‘o’: g_operation = atoi(optarg); break;
case ‘t’: strcpy(g_target, optarg); break;
case ‘s’:
{
int size = atoi(optarg);
size = (size < 1) ? 1 : ((size > 1024) ? 1024 : size);
g_size = size*1024;
}
break;
case ‘p’: g_prompt = 1; break;
case ‘r’: g_remove = 1; break;
case ‘l’: g_loop = 1; break;
default: break;
}
}

return 0;
}

void free_buffer()
{
if (log_fd) {
fclose(log_fd);
log_fd = NULL;
}
if (buffer) {
free(buffer);
buffer = NULL;
}
}

void sig_handler(int signo)
{
pthread_t tid = pthread_self();
printf(“signal… pthread_self() is %d\n”, tid);

free_buffer();
// exit(1);
printf(“main thread exit…\n”);
pthread_exit(NULL);
}

int main(int argc, char* argv[])
{
parse(argc, argv);
printf(“count:%d, size:%d \n”, g_count, g_size);

buffer = (char*)malloc(g_size);
if (buffer == NULL) {
printf(“malloc error\n”);
return EXIT_FAILURE;
}

atexit(free_buffer);

log_fd = fopen(“perftest.log”, “w”);
if (log_fd == NULL) { perror(“log open”); return 1; }
fprintf(log_fd, “perftest.log\n”);

fprintf(log_fd, “count:%d, size:%d \n”, g_count, g_size);

#if 1
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
struct sigaction act;
act.sa_flags = 0;
act.sa_mask = set;
act.sa_handler = &sig_handler;
sigaction(SIGINT, &act, NULL);
#endif

if ((mkdir(“data”, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0) && (errno
!= EEXIST)) {
perror(“mkdir data”);
return EXIT_FAILURE;
}

if ((mkdir(“dest”, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0) && (errno
!= EEXIST)) {
perror(“mkdir dest”);
return EXIT_FAILURE;
}

g_src_file = “test_src.dat”;
if (generate_test_data(g_src_file, g_size) != 0) return EXIT_FAILURE;

if (g_remove && (remove_data(“data”) != 0)) return EXIT_FAILURE;
if (g_remove && (remove_data(“dest”) != 0)) return EXIT_FAILURE;

tm = time(NULL);
fprintf(log_fd, “start at %s\n”, ctime(&tm));

int i = 1;
do {
printf("********************************\n");
sleep(1);

printf(“write test…\n”);
if (op_file_write() != 0) {
fprintf(log_fd, “error: op_file_write() %s\n”, strerror(errno));
return EXIT_FAILURE;
}
sync();

printf(“read test…\n”);
if (op_file_read() != 0) {
fprintf(log_fd, “error: op_file_read() %s\n”, strerror(errno));
return EXIT_FAILURE;
}
sync();

printf(“read write test…\n”);
if (op_file_readwrite() != 0) {
fprintf(log_fd, “error: op_file_readwrite() %s\n”, strerror(errno));
return EXIT_FAILURE;
}
sync();

if (g_remove) {
if (remove_data(“data”) || remove_data(“dest”)) {
fprintf(log_fd, “error: remove_data() %s\n”, strerror(errno));
return EXIT_FAILURE;
}
}
sync();

tm = time(NULL);
fprintf(log_fd, “%05d done at %s\n”, i++, ctime(&tm));
sync();
} while (g_loop);

return EXIT_SUCCESS;
}

//
// end app.cc
//

i run it with -l option…
then one day after, the program terminate with an error message…
what’s wrong??

“dolsemix” <dolsemix@rtsolutions.co.kr> wrote in message
news:9uf9pt$ihi$1@inn.qnx.com

i run it with -l option…
then one day after, the program terminate with an error message…

What error message? And what program terminted, your’s or devb-eide?

what’s wrong??
\

What error message? And what program terminted, your’s or devb-eide?

Hi Mario.

It is “not enough memory”…
The error occurs always in “open()”,
and my “app” program terminated.

I confirmed as follows…
#pidin mem
→ devb-eide occupy the whole memory…
What is “/dev/zero”?

Thanks.

“dolsemix” <dolsemix@rtsolutions.co.kr> wrote in message
news:9uh7sh$1a5$1@inn.qnx.com

What error message? And what program terminted, your’s or devb-eide?

Hi Mario.

It is “not enough memory”…
The error occurs always in “open()”,
and my “app” program terminated.

I confirmed as follows…
#pidin mem

→ devb-eide occupy the whole memory…

That sounds like a bug in devb-eide. Let’s hope someone from QSSL jumps
in…

What is “/dev/zero”?

It’s a null device, everything that is written into
the device misteriously disappears :wink:

Thanks.

Mario Charest <mcharest@clipzinformatic.com> wrote:

“dolsemix” <> dolsemix@rtsolutions.co.kr> > wrote in message
news:9uh7sh$1a5$> 1@inn.qnx.com> …
What error message? And what program terminted, your’s or devb-eide?

Hi Mario.

It is “not enough memory”…
The error occurs always in “open()”,
and my “app” program terminated.

I confirmed as follows…
#pidin mem

→ devb-eide occupy the whole memory…

That sounds like a bug in devb-eide. Let’s hope someone from QSSL jumps
in…

What is “/dev/zero”?


It’s a null device, everything that is written into
the device misteriously disappears > :wink:

And, even better, you can read a continuous stream of 0x00’s from it…
(It has internal uses as well).

-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Consulting and Training at www.parse.com
Email my initials at parse dot com.

“Mario Charest” <mcharest@clipzinformatic.com> wrote in message
news:9uio7b$1us$1@inn.qnx.com

What is “/dev/zero”?


It’s a null device, everything that is written into
the device misteriously disappears > :wink:


Is there any difference between this and /dev/null?


Bill Caroselli – 1(530) 510-7292
Q-TPS Consulting
QTPS@EarthLink.net

Bill Caroselli <qtps@earthlink.net> wrote:

“Mario Charest” <> mcharest@clipzinformatic.com> > wrote in message
news:9uio7b$1us$> 1@inn.qnx.com> …
What is “/dev/zero”?


It’s a null device, everything that is written into
the device misteriously disappears > :wink:


Is there any difference between this and /dev/null?

/dev/null immediately returns EOF on a read, whereas /dev/zero returns
an infinite stream of zeros… /dev/ying and /dev/yang :wink:


Bill Caroselli – 1(530) 510-7292
Q-TPS Consulting
QTPS@EarthLink.net



Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Consulting and Training at www.parse.com
Email my initials at parse dot com.

dolsemix <dolsemix@rtsolutions.co.kr> wrote:
: It is “not enough memory”…
: The error occurs always in “open()”,
: and my “app” program terminated.
: I confirmed as follows…
: #pidin mem
: → devb-eide occupy the whole memory…

This looks like an old bug with the smalloc/sfree routines in the libc
leaking heap memory across threads (internal PR/7299). From July
devb-* no longer use those calls, and from September the libc is fixed.
So, a more recent release (6.1 or 6.1.1) should fix this situation.

_smalloc is still used in the devc-ser800 ppc drivers – can/should those
calls be changed to use malloc() instead, or is there something special
about _smalloc (other than the leak)?

“John Garvey” <jgarvey@qnx.com> wrote in message
news:9uk4qe$qvf$1@nntp.qnx.com

dolsemix <> dolsemix@rtsolutions.co.kr> > wrote:
: It is “not enough memory”…
: The error occurs always in “open()”,
: and my “app” program terminated.
: I confirmed as follows…
: #pidin mem
: → devb-eide occupy the whole memory…

This looks like an old bug with the smalloc/sfree routines in the libc
leaking heap memory across threads (internal PR/7299). From July
devb-* no longer use those calls, and from September the libc is fixed.
So, a more recent release (6.1 or 6.1.1) should fix this situation.

Issam Haddad <ihaddad@asurent.com> wrote:
: _smalloc is still used in the devc-ser800 ppc drivers – can/should those
: calls be changed to use malloc() instead, or is there something special
: about _smalloc (other than the leak)?

smalloc is now fixed; and the bug only showed up on thread destruction,
I think devc-*/io-char lib are all single-threaded, so is a non-issue.

John,

do you have any ideas why devb-eide might consume as much as 73Mb or RAM?
Total memory size is 256Mb and 73Mb seems like quite a big chunk of it. I
never seen it eating more than that, but it always gets to that point under
heavy usage. Number of threads at that time tends to be large too, like
20-ies. That is on 6.1.

  • igor

“John Garvey” <jgarvey@qnx.com> wrote in message
news:9uop2r$5rs$1@nntp.qnx.com

Issam Haddad <> ihaddad@asurent.com> > wrote:
: _smalloc is still used in the devc-ser800 ppc drivers – can/should
those
: calls be changed to use malloc() instead, or is there something special
: about _smalloc (other than the leak)?

smalloc is now fixed; and the bug only showed up on thread destruction,
I think devc-*/io-char lib are all single-threaded, so is a non-issue.

Ok, I found the thread about the “memory leak” in devb-eide. Is this a
“leak” or does it just need a lot of memory? If it just needs a lot of
memory, I can add more memory, but I would prefer the devb-eide just not use
that much memory. :slight_smile:

So has anyone come to a definite conclusion on this? Is it a leak that has
been fixed in 6.1?

TIA,

Jim

“Igor Kovalenko” <kovalenko@home.com> wrote in message
news:9uq2ev$8ec$1@inn.qnx.com

John,

do you have any ideas why devb-eide might consume as much as 73Mb or RAM?
Total memory size is 256Mb and 73Mb seems like quite a big chunk of it. I
never seen it eating more than that, but it always gets to that point
under
heavy usage. Number of threads at that time tends to be large too, like
20-ies. That is on 6.1.

  • igor

“John Garvey” <> jgarvey@qnx.com> > wrote in message
news:9uop2r$5rs$> 1@nntp.qnx.com> …
Issam Haddad <> ihaddad@asurent.com> > wrote:
: _smalloc is still used in the devc-ser800 ppc drivers – can/should
those
: calls be changed to use malloc() instead, or is there something
special
: about _smalloc (other than the leak)?

smalloc is now fixed; and the bug only showed up on thread destruction,
I think devc-*/io-char lib are all single-threaded, so is a non-issue.

Jim Lambert <jlambert@futurex.com> wrote:

Ok, I found the thread about the “memory leak” in devb-eide. Is this a
“leak” or does it just need a lot of memory? If it just needs a lot of
memory, I can add more memory, but I would prefer the devb-eide just not
use that much memory. > :slight_smile:

It will leak indefinitely (well, bounded by RAM :slight_smile:. It is not devb itself
leaking but the libc routine _smalloc(), so this will also affect any multi-
threaded resource manager using this allocation call (although I think we
decided it was only devb which fit both categories :frowning:.

So has anyone come to a definite conclusion on this? Is it a leak that has
been fixed in 6.1?

As per that thread, devb no longer uses this call, and _smalloc() itself
has been fixed. Not sure what the release status is (I did double-commit
the devb mods, which suggests it did make 6.1, but I don’t think the libc
was fixed until 6.1.1). Otherwise, you can work around this meanwhile by
pinning the number of threads to a fixed amount, via “blk thread=8:8:8”,
for instance.

Does anyone know if this bug also exists in the devb-ram driver?

“John Garvey” <jgarvey@qnx.com> wrote in message
news:9v9cav$2jm$1@nntp.qnx.com

Jim Lambert <> jlambert@futurex.com> > wrote:
Ok, I found the thread about the “memory leak” in devb-eide. Is this a
“leak” or does it just need a lot of memory? If it just needs a lot of
memory, I can add more memory, but I would prefer the devb-eide just not
use that much memory. > :slight_smile:

It will leak indefinitely (well, bounded by RAM > :slight_smile:> . It is not devb
itself
leaking but the libc routine _smalloc(), so this will also affect any
multi-
threaded resource manager using this allocation call (although I think we
decided it was only devb which fit both categories > :frowning:> .

So has anyone come to a definite conclusion on this? Is it a leak that
has
been fixed in 6.1?

As per that thread, devb no longer uses this call, and _smalloc() itself
has been fixed. Not sure what the release status is (I did double-commit
the devb mods, which suggests it did make 6.1, but I don’t think the libc
was fixed until 6.1.1). Otherwise, you can work around this meanwhile by
pinning the number of threads to a fixed amount, via “blk thread=8:8:8”,
for instance.