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 |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
01-23-2012, 01:40 AM
|
#1
|
|
LQ Newbie
Registered: Apr 2010
Distribution: CentOS
Posts: 7
Rep:
|
64 bit data alignment issue on CentOS 5.7 gcc 4.1.2
While porting an application to 64 bit environment facing data alignment issues. While creating objects using new, less memory is allocated then expected. This is causing memory corruption. valgrind is also reporting invalid reads/writes.
Problem:
If I check the size of the object "sizeof(*this)" within the constructor then the size is showing as 244 bytes. But if I check the size of the object where it is created "sizeof(*ci)" then it is showing as 236 bytes.
Code:
Creating an object of class ConfigInfo as below:
ConfigInfo *ci = new ConfigInfo();
if (ci->init() != CI_SUCCESS)
{
cout << "Unable to initialize ConfigInfo instance." << endl;
}
class ConfigInfo
{
// variables
LVPairList _parameterList;
LVPairList _pdbaIpList;
// size 56 bytes
SQL *_dbConnection;
Mutex _connMutex;
//size (8+104) = 112 bytes
char *_localHostname;
char *_localIpAddr;
char *_remoteIpAddr;
char *_mySide;
char *_dbPref;
char *_dbUnpref;
char *_hostPref;
char *_hostUnpref;
ConnectionType _myConnectionType; //This is enum
// size 68 bytes
//Total = 56 + 112 + 68 = 236 bytes
};
class LVPairList
{
public:
...
protected:
LVPair *_list;
LVPair *_last;
LVPair *_cursor;
int _count;
// size = 28 bytes
};
GCC version is:
$ g++ -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --disable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20080704 (Red Hat 4.1.2-51)
If I create a separate sample program then the allocated memory using new is same as expected, the padding/alignment is done automatically.
I could not figure out why there is a difference in the alignment in the application and in the separate sample program. I am using the same compiler flags and linking options in both the cases.
$ g++ -Wall -g -I. -I../../include -I/usr/include/mysql -c filename.cxx
$ g++ -Wall -L/usr/lib64/mysql -o <EXE> <OBJFILES> -dy -L../../lib -lconf -lmysqlclient_r -lz -lssl -lpthread
Any pointers will be helpful.
Thanks in advance,
-RKD
|
|
|
|
01-23-2012, 02:37 AM
|
#2
|
|
Senior Member
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 1,079
|
Is LVPairList really defined after ConfigInfo?
Anyway, sizeof (LVPairList) should be 32 (alignment), which gives 244 total, with alignment 248
Or perhaps you used a '#pragma pack' or '-fpack-struct' unintentionally
Last edited by NevemTeve; 01-23-2012 at 02:49 AM.
|
|
|
|
01-23-2012, 02:53 AM
|
#3
|
|
LQ Newbie
Registered: Apr 2010
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
LVPairList is defined in another file.
Yes, the sizeof(LVPairList) should be 32 bytes. That is the problem I am facing. While allocating memory, its considering the size as given in my post(i.e., 28 bytes for LVPairList). But while initializing the variables its assuming the size to be 32 bytes, which is causing memory corruption.
|
|
|
|
01-23-2012, 03:17 AM
|
#4
|
|
Senior Member
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 1,079
|
perhaps you used a '#pragma pack' or '-fpack-struct' unintentionally
|
|
|
1 members found this post helpful.
|
01-23-2012, 03:39 AM
|
#5
|
|
LQ Newbie
Registered: Apr 2010
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
I am using "#pragma pack(1)" in some other module to make the structures single byte aligned and at the end changing it back to normal byte alignment.
I did not find ant instance of "-fpack-struct".
Anything else that may be causing the problem?
|
|
|
|
01-23-2012, 03:48 AM
|
#6
|
|
Senior Member
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 1,079
|
> I am using "#pragma pack(1)" in some other module to make the structures single byte aligned and at the end changing it back to normal byte alignment.
How exactly do you that?
|
|
|
|
01-23-2012, 04:08 AM
|
#7
|
|
LQ Newbie
Registered: Apr 2010
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
Using "#pragma pack(8)" to change the alignment to 8 bytes.
|
|
|
|
01-23-2012, 04:19 AM
|
#8
|
|
Senior Member
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,406
|
Quote:
Originally Posted by rajeshkdugar
LVPairList is defined in another file.
Yes, the sizeof(LVPairList) should be 32 bytes. That is the problem I am facing. While allocating memory, its considering the size as given in my post(i.e., 28 bytes for LVPairList). But while initializing the variables its assuming the size to be 32 bytes, which is causing memory corruption.
|
The funny thing about software is that it does not "assume" anything. It performs the actions that it was instructed to do by the programmer. So, depending on how you compiled the code or what is specified in the header file that defines LVPairList (see NevemTeve's previous posts), I find it highly dubious that LVPairList is 28 bytes in size in one area of the code, yet seen as 32 bytes in another, unless of course you are playing "tricks" with the compiler.
Back to your statement that the program (application) is assuming that LVPairList has a size of 32 bytes, how is it making this assumption? Did you hard-code the number 32 as the size, or did you rely on sizeof()?
Without knowing a few details of your application, I took the liberty to throw together the following app based on your comments that were posted previously in your code. ConfigInfo will have a size of 248 bytes, unless you pack LVPairList, which will then make the size 240. If you pack ConfigInfo, and not LVPairList, the size will be 244 bytes. If you pack both structures, then ConfigInfo will have a size of 236 bytes.
Code:
// typedefs used to fill in the "unknown"
//
typedef char Mutex[104]; // based on OP's comment
typedef char SQL;
typedef char LVPair;
enum ConnectionType {};
// Under 64-bit, all pointers, regardless of type, have a size of 8 bytes.
// LVPairList will have a size of 8+8+8+4 = 28 bytes, but when rounded
// to the next word boundary, it will have a size of 32 bytes. If the
// structure is packed, the size will remain at 28 bytes.
//
//#pragma pack(1)
class LVPairList
{
private:
LVPair *_list;
LVPair *_last;
LVPair *_cursor;
int _count;
};
//#pragma pack(0)
// ConfigInfo will have a size of 32+32+8+104+(8*8)+4 = 248 bytes, unless
// LVPairList is packed, in which case it will be 240 bytes. If LVPairList
// is not packed, yet ConfigInfo is, then the size will be 244 bytes. If both
// structures are packed, ConfigInfo will have a size of 236 bytes.
//
//#pragma pack(1)
class ConfigInfo
{
private:
LVPairList _parameterList;
LVPairList _pdbaIpList;
SQL *_dbConnection;
Mutex _connMutex;
char *_localHostname;
char *_localIpAddr;
char *_remoteIpAddr;
char *_mySide;
char *_dbPref;
char *_dbUnpref;
char *_hostPref;
char *_hostUnpref;
ConnectionType _myConnectionType;
};
//#pragma pack(0)
#include <iostream>
int main()
{
std::cout << "LVPairList : " << sizeof(LVPairList) << '\n'
<< "SQL pointer : " << sizeof(SQL*) << '\n'
<< "Mutex : " << sizeof(Mutex) << '\n'
<< "ConnectionType: " << sizeof(ConnectionType) << '\n'
<< "ConfigInfo : " << sizeof(ConfigInfo)
<< std::endl;
}
Last edited by dwhitney67; 01-23-2012 at 04:21 AM.
|
|
|
|
01-23-2012, 07:53 AM
|
#9
|
|
Senior Member
Registered: Dec 2007
Distribution: Mepis, Centos
Posts: 4,728
|
Quote:
Originally Posted by rajeshkdugar
I am using "#pragma pack(1)" in some other module to make the structures single byte aligned and at the end changing it back to normal byte alignment.
|
If those are the only occurrences of #pragma pack in your project, then it is likely that those are somehow causing the problem.
Without seeing everything (code and build rules) it would be very hard to diagnose the exact sequence as understood by the compiler. But everything you have said indicates the header of the problem class (or a member of it) is read by the compiler in different parts of your project with different settings for pack
|
|
|
|
01-24-2012, 12:01 AM
|
#10
|
|
LQ Newbie
Registered: Apr 2010
Distribution: CentOS
Posts: 7
Original Poster
Rep:
|
Thanks Guys for your valuable response. One of the #pragma pack statement was set to "#pragma pack(4)" at the end of a structure to change the alignment back to normal. On the 32 bit environment it was working fine. but causing problem on 64 bit environment.
Changing the end pragma statement to “#pragma pack(8)” fixed the problem.
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 04:05 PM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|