LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-15-2010, 01:40 PM   #16
SeymourButts
LQ Newbie
 
Registered: Jan 2010
Posts: 28

Original Poster
Rep: Reputation: 15

Definition of build_tag()?

Code:
uchar* build_tag  ( register uchar  x, register uchar* p );
 
Old 01-15-2010, 01:46 PM   #17
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by SeymourButts View Post
Definition of build_tag()?

Code:
uchar* build_tag  ( register uchar  x, register uchar* p );
Getting close. That is the declaration of build_tag.

The definition of build_tag starts with another line almost identical to that declaration, but without the ; on the end. That is followed by an {

That line plus everything up to the balancing } is the definition.

It may be in a different source file.
 
Old 01-15-2010, 01:49 PM   #18
SeymourButts
LQ Newbie
 
Registered: Jan 2010
Posts: 28

Original Poster
Rep: Reputation: 15
After the comment about valgrind, I ran the program using gdb and found that p pointer is pointing to an invalid memory address.

Code:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000410a8c in build_tag (x=6 '\006', p=0xffffffffbfffbb0e <Address 0xffffffffbfffbb0e out of bounds>) at ber.c:160
 
Old 01-15-2010, 01:52 PM   #19
SeymourButts
LQ Newbie
 
Registered: Jan 2010
Posts: 28

Original Poster
Rep: Reputation: 15
I think I posted this before a few posts back.
Code:
uchar* build_tag( register uchar x, register uchar* p ){
   *--p = x;
   return p;
}
 
Old 01-15-2010, 01:56 PM   #20
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by SeymourButts View Post
Code:
ucPacket = ucbuild_oid (ber_oid, OIDpollerid_length - 1, ucPacket);
...
ucPacket = build_tag (OBJECT_ID_tag, ucPacket);
Your gdb result makes it most likely that a bad value of ucPacket was passed into build_tag. It is the kind of bad value that most often occurs because code incorrectly assumes sizeof(int)==sizeof(void*) as I guessed earlier.

On x86_64 sizeof(int)==4 and sizeof(void*)==8

Trusting the code in your first post plus this new info, it seems like the definition of ucbuild_oid would be a better place to look than the definition of build_tag

Edit:

Quote:
I think I posted this before a few posts back.
I didn't spot it. (The thread is a bit messy). So I figured out it (definition of build_tag) wasn't actually what I wanted to see right before I confirmed that by finally seeing it.

Last edited by johnsfine; 01-15-2010 at 01:59 PM.
 
Old 01-15-2010, 02:02 PM   #21
SeymourButts
LQ Newbie
 
Registered: Jan 2010
Posts: 28

Original Poster
Rep: Reputation: 15
Sure thing.

Code:
/* -- REQUIRES: l > 0 -- */

uchar* ucbuild_oid  ( register sid* x, register uint l, register uchar* p ){
   register ulong *sidp = x + l, val;
   register uchar *op = p;

   while( l-- ){
      val = *--sidp;
      *--p = val & 0x7f;
      while( val >>= 7 )
         *--p = val | 0x80;
   }
   return  build_len( op - p, p );
}
 
Old 01-15-2010, 02:04 PM   #22
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
From that, it looks like we need the definition of build_len
 
Old 01-15-2010, 02:06 PM   #23
SeymourButts
LQ Newbie
 
Registered: Jan 2010
Posts: 28

Original Poster
Rep: Reputation: 15
Ok.

Code:
uchar* build_len( register uint  x, register uchar* p ){
   if( x > 127 ){
      register uchar len = 0x81;
      *--p = x;
      while( x >>= 8 ){
         *--p = x;
         len++;
      }
      *--p = len;
   } else
      *--p = x;
   return p;
}
 
Old 01-15-2010, 02:10 PM   #24
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Somewhere I went down the wrong track. I'm pretty sure the bug is not there.

Remember your problem line
Code:
ucPacket = build_tag (OBJECT_ID_tag, ucPacket);
Your gdb result indicates ucPacket had a bad value immediately before that line (a 16 character hex value starting with f).

With gdb or with a printout, confirm that value really is bad right before that line, then backtrack and see where it came from.
 
Old 01-16-2010, 09:02 PM   #25
SeymourButts
LQ Newbie
 
Registered: Jan 2010
Posts: 28

Original Poster
Rep: Reputation: 15
The ucbuild_oid() function is definately the problem. When I comment it out, I don't get the segmentation fault for address out of bounds. I commented out build_len() function separately, but address out of bounds still happens.

The ucPacket address goes from [0x7feffcaff] to [0xfffffffffeffcaff] on the return from this function. I used gdb to step through the function, but still haven't pin-pointed the cause.

[Update] Yikes. Adding 1 to sidp increases sidp by 80 on Linux and 40 on Solaris.

Code:
/* Call to ucbuild_oid with the values */
ucPacket = ucbuild_oid(4278168392, 10, "215");


uchar* ucbuild_oid  ( register sid* x, register uint l, register uchar* p ){
   register ulong *sidp = x + l, val;
   register uchar *op = p;

   /* sidp = 4278168472 based on first parm x*/

   while( l-- ){
      val = *--sidp;
      *--p = val & 0x7f;
      while( val >>= 7 )
         *--p = val | 0x80;
   }
   return  build_len( op - p, p );
}

Last edited by SeymourButts; 01-16-2010 at 09:12 PM.
 
Old 01-16-2010, 09:41 PM   #26
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
What is sizeof(ulong) on the solaris box and sizeof(ulong) on the linux box?
 
Old 01-16-2010, 09:42 PM   #27
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
Code:
ucbuild_oid(4278168392, 10, "215");
WTF?! i just relized you are passing a litteral value as a pointer!
 
Old 01-16-2010, 09:43 PM   #28
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
What data type is a sid?

I expect ulong is defined in a way that is 32 bits in your Solaris build but 64 bits in x86_64.

If you get no error for sidp=x+l then sid must be compatible with ulong.

I don't know enough about what you left out nor how all the pieces you quoted fit together to be sure, but the values don't look big enough for 32 bit vs. 64 bit to make a difference in val. If it did make a difference, you would be using more bytes in the target buffer to split val into 7 bit chunks for x86_64 than you did for Solaris.

One possibility from that or other causes is that you are overflowing the buffer (in reverse) and clobbering whatever happens to be stored before it.

You earlier quoted
unsigned char buffer [4096];
Are you sure 4096 is enough for whatever you are storing in that buffer.

Quote:
Originally Posted by SeymourButts View Post
Yikes. Adding 1 to sidp increases sidp by 80 on Linux and 40 on Solaris.
Was that a typo or confusion? Either way a good example of why you shouldn't use the single letter l as the name of a variable.

You said l has the value 10. So you are adding 10 times sizeof(ulong) to the actual value of the pointer. Why would that be surprising?

Quote:
Originally Posted by smeezekitty View Post
Code:
ucbuild_oid(4278168392, 10, "215");
WTF?! i just relized you are passing a litteral value as a pointer!
I assume that was quoted from information displayed by the debugger, not from the source code. So no, it is not a literal passed as a pointer. It is the run time value of a pointer displayed as a literal.

Last edited by johnsfine; 01-16-2010 at 09:51 PM.
 
Old 01-16-2010, 09:45 PM   #29
SeymourButts
LQ Newbie
 
Registered: Jan 2010
Posts: 28

Original Poster
Rep: Reputation: 15
I found the solution. The application was developed on a 32-bit Solaris server. but the Linux server is a 64-bit system.

The 32-bit Solaris OS sets ints, longs and pointers to 32 bits and the 64-bit Linux OS sets ints to 32 bits and longs, pointers to 64 bits.

By setting the "-m32" option on gcc, I was able to compile the application using 32-bit data type sizes.
 
Old 01-16-2010, 09:47 PM   #30
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
Quote:
Originally Posted by johnsfine View Post
What data type is a sid?

I expect ulong is defined in a way that is 32 bits in your Solaris build but 64 bits in x86_64.

If you get no error for sidp=x+l then sid must be compatible with ulong.

I don't know enough about what you left out nor how all the pieces you quoted fit together to be sure, but the values don't look big enough for 32 bit vs. 64 bit to make a difference in val. If it did make a difference, you would be using more bytes in the target buffer to split val into 7 bit chunks for x86_64 than you did for Solaris.

One possibility from that or other causes is that you are overflowing the buffer (in reverse) and clobbering whatever happens to be stored before it.

You earlier quoted
unsigned char buffer [4096];
Are you sure 4096 is enough for whatever you are storing in that buffer.
Look closly:That code is assuming the memory location will always be:
Code:
4278168392
4278168392 is likely not memory that belongs to the program!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
m4 define in a define Four Programming 0 03-04-2007 09:41 PM
c++ question, how to define a member array, and it's size, outside of the class dec.. Winter Knight Programming 2 01-23-2007 07:28 AM
C++ question #define ... Bluesuperman Programming 4 02-01-2005 09:49 AM
Question: How to define an SQL HAVING clause in relational algebra? jdruin Linux - Software 1 11-08-2004 07:50 AM
question on #define h/w Programming 7 12-03-2003 05:14 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:56 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration