io-net crash with function call

Hi, We’re running QNX RTOS 6.1a. We’re developing an ipfilter.
It seems to crash io-net when when we receive any ip packets, but only when we call our display function in the ipf_init() function that is called by io-net. The display function basically just outputs our array of rules to an output file. It seems to output the data fine.
Below is some of our code:


//this is the structure for each rule
typedef struct rule_data{
unsigned char ip_1[4];
unsigned char netmask_1;
unsigned char type;
unsigned char port[2];
unsigned char ip_2[4];
unsigned char netmask_2;
unsigned char rulemask;
unsigned char rule_no[2];
char dev[20];
}BINDATA;

BINDATA *dst_info, *src_info;

int ipf_init(void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char *options)
{
ipf_dll_hdl = dll_hdl;
ipf_ion = ion;

of=fopen("/tr/output.dat",“aw”); //open debug file


store_bin();
display(dst_info,8); <<<<----- when this function call is included the filter crashes when receiving IP packets

if(!ipf_register_filter()) //register filter with io-net
return(-1); //couldn’t register

//register what type of sub
ipf_ion->reg_byte_pat(ipf_reg_hdl, 0, 0, NULL, _BYTE_PAT_ALL);


return (0); // success
}

THESE ARE THE ONLY TWO FUNCTIONS CALLING THE POINTERS
TO THE BINDATA STRUCTURE
//stores binfile info into arrays of BINDATA allocates arrays to number of rules in file
int store_bin(void)
{
FILE *bp; //bin file pointer
int src_fd,dst_fd,i;
long size_of_file;

bp=fopen(SRC_BINFILE,“r”);
fseek(bp,0L,SEEK_END); //considering that the src and dest bin files
size_of_file = ftell(bp); //are the same size I only need to open the one
fclose(bp); //file
no_rules=size_of_file/sizeof(struct rule_data);

dst_info=(BINDATA*)malloc(no_rules); //allocate memory for #of rules in file
src_info=(BINDATA*)malloc(no_rules);; //allocate memory for #of rules in file

src_fd = open(SRC_BINFILE, O_RDONLY );
dst_fd = open(DST_BINFILE, O_RDONLY);

//read rules into BINDATA arrays
for(i=0;i<=no_rules;i++)
{
read(src_fd,&src_info_,sizeof(struct rule_data)); //read from source binary file
read(dst_fd,&dst_info,sizeof(struct rule_data)); //read from dest. bin file
}

close(src_fd);
close(dst_fd);
return(1);
}


THE DISPLAY FUNCTION
//output contents of rule array to file
void display(BINDATA *rule_info,int no_rules)
{
int i,j;

for(i=0;i<no_rules;i++)
{
fprintf(of,"–\n");
for(j=0;j<4;j++)
fprintf(of,"%d",rule_info.ip_1[j]);
fprintf(of,"%d",rule_info.netmask_1);
fprintf(of,"%d",rule_info.type);
fprintf(of,"%d",rule_info.port[0]);
fprintf(of,"%d",rule_info.port[1]);
for(j=0;j<4;j++)
fprintf(of,"%d",rule_info.ip_2[j]);
fprintf(of,"%d",rule_info.netmask_1);
fprintf(of,"%d",rule_info.rulemask);
fprintf(of,"%d",rule_info[i].rule_no[0]);
fprintf(of,"%d",rule_info[i].rule_no[1]);
fprintf(of,"%s",rule_info[i].dev);
}
fflush(of);
}

If I don’t include the display function io-net stays up and running no problem with
packets flowing through the filter. If someone could help it would be greatly appreciated.
Thanks.

QNX SLC Project Group_

From the previous Message:
We’ve narrowed our problem down to the malloc. Is the io-net crashing because we can’t dynamically create arrays in this method. For the time
being I’m using a set sized array.
ex.

BINDATA dst_info[MAX_RULES];

Is there a way to possibly dynamically create the array?

Thanks

QNX SLC Project Group

You can definitely call malloc() from within io-net.

-seanb

QNX SLC Project Group <qnx_project@canada.com> wrote:
: From the previous Message:
: We’ve narrowed our problem down to the malloc. Is the io-net crashing because we can’t dynamically create arrays in this method. For the time
: being I’m using a set sized array.
: ex.

: BINDATA dst_info[MAX_RULES];

: Is there a way to possibly dynamically create the array?

: Thanks

: QNX SLC Project Group

I noticed you are casting the return value of malloc() - this is not needed
(malloc returns a void*, which is implicitly cast), nor a good idea, since
it masks potential problems (not including the proper headers and other
issues). I also notice you’re not checking the return value of malloc() to
see if it successful or not - this might be another source of problems (ie
trying to use memory you think is allocated).

If you can use a predefined array, then you can use a malloc()'d hunk of
memory. You mentioned that you narrowed it down to the malloc() - are you
SIGSEGV’ing in the malloc or when you try to access the memory (recall you
assume it always works - really bad idea) allocated.


Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>


QNX SLC Project Group <qnx_slcproject@canada.com> wrote in
news:Voyager.020331160658.1847330A@localhost.localdomain:

Hi, We’re running QNX RTOS 6.1a. We’re developing an ipfilter.
It seems to crash io-net when when we receive any ip packets, but only
when we call our display function in the ipf_init() function that is
called by io-net. The display function basically just outputs our array
of rules to an output file. It seems to output the data fine. Below is
some of our code:


//this is the structure for each rule
typedef struct rule_data{
unsigned char ip_1[4];
unsigned char netmask_1;
unsigned char type;
unsigned char port[2];
unsigned char ip_2[4];
unsigned char netmask_2;
unsigned char rulemask;
unsigned char rule_no[2];
char dev[20];
}BINDATA;

BINDATA *dst_info, *src_info;

int ipf_init(void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char
*options) {
ipf_dll_hdl = dll_hdl;
ipf_ion = ion;

of=fopen("/tr/output.dat",“aw”); //open debug file


store_bin();
display(dst_info,8); <<<<----- when this function call
is
included the filter

crashes when receiving IP

packets

if(!ipf_register_filter()) //register filter with
io-net
return(-1); //couldn’t register

//register what type of sub
ipf_ion->reg_byte_pat(ipf_reg_hdl, 0, 0, NULL, _BYTE_PAT_ALL);


return (0); // success
}

THESE ARE THE ONLY TWO FUNCTIONS CALLING THE POINTERS
TO THE BINDATA STRUCTURE
//stores binfile info into arrays of BINDATA allocates arrays to number
of rules in file int store_bin(void)
{
FILE *bp;
//bin file pointer int src_fd,dst_fd,i;
long size_of_file;

bp=fopen(SRC_BINFILE,“r”);
fseek(bp,0L,SEEK_END);
//considering that the src and dest bin files size_of_file =
ftell(bp); //are the same
size I only need to open the one fclose(bp);
//file
no_rules=size_of_file/sizeof(struct rule_data);

dst_info=(BINDATA*)malloc(no_rules); //allocate
memory
for #of rules in file
src_info=(BINDATA*)malloc(no_rules);;
//allocate memory for
#of
rules in file

src_fd = open(SRC_BINFILE, O_RDONLY );
dst_fd = open(DST_BINFILE, O_RDONLY);

//read rules into BINDATA arrays
for(i=0;i<=no_rules;i++)
{
read(src_fd,&src_info> ,sizeof(struct rule_data));
//read from source binary file
read(dst_fd,&dst_info> ,sizeof(struct rule_data));
//read from dest. bin file
}

close(src_fd);
close(dst_fd);
return(1);
}


THE DISPLAY FUNCTION
//output contents of rule array to file
void display(BINDATA *rule_info,int no_rules)
{
int i,j;

for(i=0;i<no_rules;i++)
{
fprintf(of,"–\n");
for(j=0;j<4;j++)
fprintf(of,"%d",rule_info> .ip_1[j]);
fprintf(of,"%d",rule_info> .netmask_1);
fprintf(of,"%d",rule_info> .type);
fprintf(of,"%d",rule_info> .port[0]);
fprintf(of,"%d",rule_info> .port[1]);
for(j=0;j<4;j++)
fprintf(of,"%d",rule_info> .ip_2[j]);
fprintf(of,"%d",rule_info> .netmask_1);
fprintf(of,"%d",rule_info> .rulemask);
fprintf(of,"%d",rule_info[i].rule_no[0]);
fprintf(of,"%d",rule_info[i].rule_no[1]);
fprintf(of,"%s",rule_info[i].dev);
}
fflush(of);
}

If I don’t include the display function io-net stays up and running no
problem with packets flowing through the filter. If someone could help
it would be greatly appreciated. Thanks.

QNX SLC Project Group

By the way you did not mention whether the malloc itself is crashing or your
program is crashing after the malloc.Anyway Make sure your “no_rules”
variable is not negativeI think the size_t is an unsigned int and if you
pass a negative number then malloc tries to allocate a huge memory.In case
the value is zero you will get a non null value but it will be a dangling
pointer.

Hope that helps.
Sreekanth

“Adam Mallory” <amallory@qnx.com> wrote in message
news:Xns91E48A874D334amalloryqnxcom@209.226.137.4

I noticed you are casting the return value of malloc() - this is not
needed
(malloc returns a void*, which is implicitly cast), nor a good idea, since
it masks potential problems (not including the proper headers and other
issues). I also notice you’re not checking the return value of malloc()
to
see if it successful or not - this might be another source of problems (ie
trying to use memory you think is allocated).

If you can use a predefined array, then you can use a malloc()'d hunk of
memory. You mentioned that you narrowed it down to the malloc() - are you
SIGSEGV’ing in the malloc or when you try to access the memory (recall you
assume it always works - really bad idea) allocated.


Cheers,
Adam

QNX Software Systems Ltd.
[ > amallory@qnx.com > ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <> pschon@baste.magibox.net


QNX SLC Project Group <> qnx_slcproject@canada.com> > wrote in
news:> Voyager.020331160658.1847330A@localhost.localdomain> :

Hi, We’re running QNX RTOS 6.1a. We’re developing an ipfilter.
It seems to crash io-net when when we receive any ip packets, but only
when we call our display function in the ipf_init() function that is
called by io-net. The display function basically just outputs our array
of rules to an output file. It seems to output the data fine. Below is
some of our code:


//this is the structure for each rule
typedef struct rule_data{
unsigned char ip_1[4];
unsigned char netmask_1;
unsigned char type;
unsigned char port[2];
unsigned char ip_2[4];
unsigned char netmask_2;
unsigned char rulemask;
unsigned char rule_no[2];
char dev[20];
}BINDATA;

BINDATA *dst_info, *src_info;

int ipf_init(void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char
*options) {
ipf_dll_hdl = dll_hdl;
ipf_ion = ion;

of=fopen("/tr/output.dat",“aw”); //open debug file


store_bin();
display(dst_info,8); <<<<----- when this function call
is
included the filter

crashes when receiving IP

packets

if(!ipf_register_filter()) //register filter with
io-net
return(-1); //couldn’t register

//register what type of sub
ipf_ion->reg_byte_pat(ipf_reg_hdl, 0, 0, NULL, _BYTE_PAT_ALL);


return (0); // success
}

THESE ARE THE ONLY TWO FUNCTIONS CALLING THE POINTERS
TO THE BINDATA STRUCTURE
//stores binfile info into arrays of BINDATA allocates arrays to number
of rules in file int store_bin(void)
{
FILE *bp;
//bin file pointer int src_fd,dst_fd,i;
long size_of_file;

bp=fopen(SRC_BINFILE,“r”);
fseek(bp,0L,SEEK_END);
//considering that the src and dest bin files size_of_file =
ftell(bp); //are the same
size I only need to open the one fclose(bp);
//file
no_rules=size_of_file/sizeof(struct rule_data);

dst_info=(BINDATA*)malloc(no_rules); //allocate
memory
for #of rules in file
src_info=(BINDATA*)malloc(no_rules);;
//allocate memory for
#of
rules in file

src_fd = open(SRC_BINFILE, O_RDONLY );
dst_fd = open(DST_BINFILE, O_RDONLY);

//read rules into BINDATA arrays
for(i=0;i<=no_rules;i++)
{
read(src_fd,&src_info> ,sizeof(struct rule_data));
//read from source binary file
read(dst_fd,&dst_info> ,sizeof(struct rule_data));
//read from dest. bin file
}

close(src_fd);
close(dst_fd);
return(1);
}


THE DISPLAY FUNCTION
//output contents of rule array to file
void display(BINDATA *rule_info,int no_rules)
{
int i,j;

for(i=0;i<no_rules;i++)
{
fprintf(of,"–\n");
for(j=0;j<4;j++)
fprintf(of,"%d",rule_info> .ip_1[j]);
fprintf(of,"%d",rule_info> .netmask_1);
fprintf(of,"%d",rule_info> .type);
fprintf(of,"%d",rule_info> .port[0]);
fprintf(of,"%d",rule_info> .port[1]);
for(j=0;j<4;j++)
fprintf(of,"%d",rule_info> .ip_2[j]);
fprintf(of,"%d",rule_info> .netmask_1);
fprintf(of,"%d",rule_info> .rulemask);
fprintf(of,"%d",rule_info[i].rule_no[0]);
fprintf(of,"%d",rule_info[i].rule_no[1]);
fprintf(of,"%s",rule_info[i].dev);
}
fflush(of);
}

If I don’t include the display function io-net stays up and running no
problem with packets flowing through the filter. If someone could help
it would be greatly appreciated. Thanks.

QNX SLC Project Group


\

First, you should check the return of ANY function that could possibly fail,
especially malloc() which could quite possibly fail even through no fault of
the programmer. If you worked for em and didn’t check return codes you get
a demerit for that. (OK, I made that part up.)

But Adam, didn’t we go through this argument about a month ago about casting
the return of malloc(). I’d give a demerit for not casting it. What are
these potential problems you think lurk in the shadows?

We code in C++. With C++ the type casting is necessary.

“Adam Mallory” <amallory@qnx.com> wrote in message
news:Xns91E48A874D334amalloryqnxcom@209.226.137.4

I noticed you are casting the return value of malloc() - this is not
needed
(malloc returns a void*, which is implicitly cast), nor a good idea, since
it masks potential problems (not including the proper headers and other
issues). I also notice you’re not checking the return value of malloc()
to
see if it successful or not - this might be another source of problems (ie
trying to use memory you think is allocated).

If you can use a predefined array, then you can use a malloc()'d hunk of
memory. You mentioned that you narrowed it down to the malloc() - are you
SIGSEGV’ing in the malloc or when you try to access the memory (recall you
assume it always works - really bad idea) allocated.


Cheers,
Adam

QNX Software Systems Ltd.
[ > amallory@qnx.com > ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <> pschon@baste.magibox.net


QNX SLC Project Group <> qnx_slcproject@canada.com> > wrote in
news:> Voyager.020331160658.1847330A@localhost.localdomain> :

Hi, We’re running QNX RTOS 6.1a. We’re developing an ipfilter.
It seems to crash io-net when when we receive any ip packets, but only
when we call our display function in the ipf_init() function that is
called by io-net. The display function basically just outputs our array
of rules to an output file. It seems to output the data fine. Below is
some of our code:


//this is the structure for each rule
typedef struct rule_data{
unsigned char ip_1[4];
unsigned char netmask_1;
unsigned char type;
unsigned char port[2];
unsigned char ip_2[4];
unsigned char netmask_2;
unsigned char rulemask;
unsigned char rule_no[2];
char dev[20];
}BINDATA;

BINDATA *dst_info, *src_info;

int ipf_init(void *dll_hdl, dispatch_t *dpp, io_net_self_t *ion, char
*options) {
ipf_dll_hdl = dll_hdl;
ipf_ion = ion;

of=fopen("/tr/output.dat",“aw”); //open debug file


store_bin();
display(dst_info,8); <<<<----- when this function call
is
included the filter

crashes when receiving IP

packets

if(!ipf_register_filter()) //register filter with
io-net
return(-1); //couldn’t register

//register what type of sub
ipf_ion->reg_byte_pat(ipf_reg_hdl, 0, 0, NULL, _BYTE_PAT_ALL);


return (0); // success
}

THESE ARE THE ONLY TWO FUNCTIONS CALLING THE POINTERS
TO THE BINDATA STRUCTURE
//stores binfile info into arrays of BINDATA allocates arrays to number
of rules in file int store_bin(void)
{
FILE *bp;
//bin file pointer int src_fd,dst_fd,i;
long size_of_file;

bp=fopen(SRC_BINFILE,“r”);
fseek(bp,0L,SEEK_END);
//considering that the src and dest bin files size_of_file =
ftell(bp); //are the same
size I only need to open the one fclose(bp);
//file
no_rules=size_of_file/sizeof(struct rule_data);

dst_info=(BINDATA*)malloc(no_rules); //allocate
memory
for #of rules in file
src_info=(BINDATA*)malloc(no_rules);;
//allocate memory for
#of
rules in file

src_fd = open(SRC_BINFILE, O_RDONLY );
dst_fd = open(DST_BINFILE, O_RDONLY);

//read rules into BINDATA arrays
for(i=0;i<=no_rules;i++)
{
read(src_fd,&src_info> ,sizeof(struct rule_data));
//read from source binary file
read(dst_fd,&dst_info> ,sizeof(struct rule_data));
//read from dest. bin file
}

close(src_fd);
close(dst_fd);
return(1);
}


THE DISPLAY FUNCTION
//output contents of rule array to file
void display(BINDATA *rule_info,int no_rules)
{
int i,j;

for(i=0;i<no_rules;i++)
{
fprintf(of,"–\n");
for(j=0;j<4;j++)
fprintf(of,"%d",rule_info> .ip_1[j]);
fprintf(of,"%d",rule_info> .netmask_1);
fprintf(of,"%d",rule_info> .type);
fprintf(of,"%d",rule_info> .port[0]);
fprintf(of,"%d",rule_info> .port[1]);
for(j=0;j<4;j++)
fprintf(of,"%d",rule_info> .ip_2[j]);
fprintf(of,"%d",rule_info> .netmask_1);
fprintf(of,"%d",rule_info> .rulemask);
fprintf(of,"%d",rule_info[i].rule_no[0]);
fprintf(of,"%d",rule_info[i].rule_no[1]);
fprintf(of,"%s",rule_info[i].dev);
}
fflush(of);
}

If I don’t include the display function io-net stays up and running no
problem with packets flowing through the filter. If someone could help
it would be greatly appreciated. Thanks.

QNX SLC Project Group


\

“Bill Caroselli (Q-TPS)” <QTPS@EarthLink.net> wrote in
news:a8fgnk$lc2$1@inn.qnx.com:

First, you should check the return of ANY function that could possibly
fail, especially malloc() which could quite possibly fail even through
no fault of the programmer. If you worked for em and didn’t check
return codes you get a demerit for that. (OK, I made that part up.)

Yep, failure to check return values is a no-no.

But Adam, didn’t we go through this argument about a month ago about
casting the return of malloc(). I’d give a demerit for not casting it.
What are these potential problems you think lurk in the shadows?

1 . The cast isn’t required by ANSI C
2 . The cast will mask the failure to include the proper header, which
leads to undefined behaviour.
3. Without the header, the default return type is int - you may have sign
propagation issues, when casting to certain types (also the sizes of these
types might not be interchangeable).
4. You could cast to a wrong type by accident.
5. if you change the type being malloc’d, you have to change all the casts
as well.

We code in C++. With C++ the type casting is necessary.

Great, then in C++ you should cast. They, on the other hand, are not using
C++.

Feel free to disagree with me, but I am not in the minority (read
comp.lang.c). They even added it as an errata for the good ol’ K&R book.
See http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html, item 142.

Slowly, I’ll convert everyone :slight_smile:


Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>

OK. I checked your reference. I get it. But . . .

Clearly, 1) not including the correct header for ANY function is the bigger
sin. 2) This is just yet another example of why C++ is better than C. C++
won’t let you get away with either of these programming oversights.

Hey, you want to kick around casting NULL next?

“Adam Mallory” <amallory@qnx.com> wrote in message
news:Xns91E68469D94FEamalloryqnxcom@209.226.137.4

“Bill Caroselli (Q-TPS)” <> QTPS@EarthLink.net> > wrote in
news:a8fgnk$lc2$> 1@inn.qnx.com> :

First, you should check the return of ANY function that could possibly
fail, especially malloc() which could quite possibly fail even through
no fault of the programmer. If you worked for em and didn’t check
return codes you get a demerit for that. (OK, I made that part up.)

Yep, failure to check return values is a no-no.

But Adam, didn’t we go through this argument about a month ago about
casting the return of malloc(). I’d give a demerit for not casting it.
What are these potential problems you think lurk in the shadows?

1 . The cast isn’t required by ANSI C
2 . The cast will mask the failure to include the proper header, which
leads to undefined behaviour.
3. Without the header, the default return type is int - you may have sign
propagation issues, when casting to certain types (also the sizes of these
types might not be interchangeable).
4. You could cast to a wrong type by accident.
5. if you change the type being malloc’d, you have to change all the
casts
as well.

We code in C++. With C++ the type casting is necessary.

Great, then in C++ you should cast. They, on the other hand, are not
using
C++.

Feel free to disagree with me, but I am not in the minority (read
comp.lang.c). They even added it as an errata for the good ol’ K&R book.
See > http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html> , item 142.

Slowly, I’ll convert everyone > :slight_smile:


Cheers,
Adam

QNX Software Systems Ltd.
[ > amallory@qnx.com > ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <> pschon@baste.magibox.net

“Bill Caroselli (Q-TPS)” <QTPS@EarthLink.net> wrote in
news:a8i50v$j5c$1@inn.qnx.com:

OK. I checked your reference. I get it. But . . .

Clearly, 1) not including the correct header for ANY function is the
bigger sin.

Sure it’s a sin, the point is the cast will potentially mask that. Casting
essentially (not always) tells the compiler to “shut up and do what I say”,
regardless of what you may “think” is happening. Why limit C’s already
limited type checking unnecessarily?

Anyways, I think we all understand now… and I’m flogging a dead horse :slight_smile:

  1. This is just yet another example of why C++ is better
    than C. C++ won’t let you get away with either of these programming
    oversights.

Well, I believe in the “right tool for the right job”. C++ is good at lots
of things, C is also good at lots of things. LISP is good for many
things…

I can thing of lots of things C++ does which violate the OOP concept. So
while I don’t agree that C++ “is better than C”, it does support some nice
features, and has some not so nice features.

Hey, you want to kick around casting NULL next?

I’m not touch that with a ten foot pole. I think everyone knows how I feel
about casting things :slight_smile:

\

Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>