|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
  |
|
MQSD structure padding on 64 bit applications |
View previous topic :: View next topic |
Author |
Message
|
tczielke |
Posted: Fri Jan 23, 2015 6:52 pm Post subject: MQSD structure padding on 64 bit applications |
|
|
Guardian
Joined: 08 Jul 2010 Posts: 941 Location: Illinois, USA
|
I spun my wheels on this today, so I wanted to document this, in case it could help out anybody else that encounters this in the future. This information would probably be helpful for anyone who looks at MQI data structures in traces or the Application Activity Trace.
It looks like the MQSD (Subscription descriptor) is not properly aligned from a 64 bit stand point, and has some structure padding occurring in it.
Here is what the MQSD looks like from a C structure stand point:
Code: |
struct tagMQSD {
MQCHAR4 StrucId; /* Structure identifier */
MQLONG Version; /* Structure version number */
MQLONG Options; /* Options associated with */
/* subscribing */
MQCHAR48 ObjectName; /* Object name */
MQCHAR12 AlternateUserId; /* Alternate user identifier */
MQBYTE40 AlternateSecurityId; /* Alternate security identifier */
MQLONG SubExpiry; /* Expiry of Subscription */
MQCHARV ObjectString; /* Object long name */
MQCHARV SubName; /* Subscription name */
MQCHARV SubUserData; /* Subscription user data */
MQBYTE24 SubCorrelId; /* Correlation Id related to this */
/* subscription */
MQLONG PubPriority; /* Priority set in publications */
MQBYTE32 PubAccountingToken; /* Accounting Token set in */
/* publications */
MQCHAR32 PubApplIdentityData; /* Appl Identity Data set in */
/* publications */
MQCHARV SelectionString; /* Message selector structure */
MQLONG SubLevel; /* Subscription level */
MQCHARV ResObjectString; /* Resolved long object name */
};
|
Here is an Activity Trace print out of a MQSD from a 64 bit application (the amqssub sample program).
Code: |
MQSD Structure:
00000000: 5344 2020 0000 0001 0020 2022 2020 2020 'SD ..... " '
00000010: 2020 2020 2020 2020 2020 2020 2020 2020 ' '
00000020: 2020 2020 2020 2020 2020 2020 2020 2020 ' '
00000030: 2020 2020 2020 2020 2020 2020 2020 2020 ' '
00000040: 2020 2020 2020 2020 0000 0000 0000 0000 ' ........'
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 '................'
00000060: 0000 0000 0000 0000 0000 0000 0000 0000 '................'
00000070: FFFF FFFF 0000 0000 0007 FFFE F343 4380 '.............CC.'
00000080: 0000 0000 0000 0000 0000 0006 0000 0333 '...............3'
00000090: 0000 0000 0000 0000 0000 0000 0000 0001 '................'
000000A0: 0000 0000 0000 0333 0000 0000 0000 0000 '.......3........'
000000B0: 0000 0000 0000 0000 0000 0000 0000 0333 '...............3'
000000C0: 414D 5120 4C4C 4C4C 4C4C 4C4C 2E4D 5154 'AMQ LLLLLLLL.MQT'
000000D0: 54BF C641 2000 2405 FFFF FFFD 0332 3434 'T..A .$......244'
000000E0: 0000 0000 0000 0000 0000 0000 0000 0000 '................'
000000F0: 0000 0000 0000 0000 0000 0006 0000 0000 '................'
00000100: 0000 0000 0000 0000 0000 0000 0000 0000 '................'
00000110: 0000 0000 0000 0000 0000 0000 54C2 BA56 '............T..V'
00000120: 0000 0000 0000 0000 0000 0000 0000 0000 '................'
00000130: 0000 0000 0000 0333 0000 0001 FEBE DBD0 '.......3........'
00000140: 0000 0000 0000 0000 0000 0000 0000 0000 '................'
00000150: 0000 0006 0000 04B8
|
At offset x’70’ in the MQSD structure, is the SubExpiry field which is a MQLONG (4 byte signed binary integer). It contains x’FFFFFFFF’ = -1 or MQEI_UNLIMITED.
The next field should be the ObjectString, which is an MQCHARV (listed below):
Code: |
struct tagMQCHARV {
MQPTR VSPtr; /* Address of variable length string */
MQLONG VSOffset; /* Offset of variable length string */
MQLONG VSBufSize; /* Size of buffer */
MQLONG VSLength; /* Length of variable length string */
MQLONG VSCCSID; /* CCSID of variable length string */
};
|
The first field in the MQCHARV is an MQPTR, which is an 8 byte binary integer for a 64 bit application. It should start at offset x’74’. However, it is starting at offset x’78’ and there are 4 “mystery” bytes at offset x’74’.
I believe this is due to structure padding that the compiler is inserting. Since this is a 64 bit application, an 8 byte integer field like the VSPtr needs to start at an address that is 8 byte aligned. The compiler would start the MQSD at an 8 byte aligned address. Therefore offsets in the MQSD structure like x’08’, x’10’, x’18’, x’20’, x’28’, etc. would be 8 byte aligned offsets. Since the next address for the VSPtr (which would be at offset x’74’) does not fall at an 8 byte aligned offset, the compiler inserts 4 bytes of structure padding so that the VSPtr can be at an 8 byte aligned address at offset x’78’. At least, this is how I understand this to work.
The same things happens at offset x’11C’, to 8 byte align the VSPtr of the SelectionString field at offset x’120’. Also at offset x’13C’, to 8 byte align the VSPtr of the ResObjectString field at offset x’140’. This results in 12 extra bytes being added to the MQSD for structure padding.
This isn’t a big deal, but it can be very confusing if you are trying to read a raw MQSD structure in a trace, so I wanted to pass it on. Also, if you are trying to programmatically step through an MQSD in a 64 bit application with using offset logic, watch out! |
|
Back to top |
|
 |
mqjeff |
Posted: Mon Jan 26, 2015 5:21 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
It's possible, if not even somewhat likely, that the MQCHARV is a Unicode string, that is in one of the Unicode representations that starts with a length identifier. |
|
Back to top |
|
 |
tczielke |
Posted: Mon Jan 26, 2015 5:59 am Post subject: |
|
|
Guardian
Joined: 08 Jul 2010 Posts: 941 Location: Illinois, USA
|
I didn't quite follow that. Are you suggesting that those 4 byte "gaps" at offset x'74', x'11C' and x'13C' are length identifiers for the MQCHARV? If so, note that the SubName and SubUser data MQCHARV fields do not have these extra 4 bytes before their fields. The SubName and SubUserData start at offsets x'90' and x'A8'. These 2 MQCHARV fields start at 8 byte offsets in the MQSD structure, so their 8-byte VS-Ptr field would start on a virtual address that is divisible by 8 (i.e. 8-byte aligned).
It is also interesting to note that the MQIMPO data structure has this "Reserved1" field in its structure, before the MQCHARV ReturnedName. It is somewhat rare for a Reserved field to be put in a MQI data structure, especially for a version 1 part of the structure. More than likely, that was probably done to align the MQPtr in the ReturnedName to fall on a 8-byte aligned virtual address and to avoid compiler inserted structure padding, I am thinking.
Code: |
typedef struct tagMQIMPO MQIMPO;
struct tagMQIMPO {
MQCHAR4 StrucId; /* Structure identifier */
MQLONG Version; /* Structure version number */
MQLONG Options; /* Options that control the action of
MQINQMP */
MQLONG RequestedEncoding; /* Requested encoding of Value */
MQLONG RequestedCCSID; /* Requested character set identifier
of Value */
MQLONG ReturnedEncoding; /* Returned encoding of Value */
MQLONG ReturnedCCSID; /* Returned character set identifier
of Value */
MQCHAR Reserved1 /* Reserved field */
MQCHARV ReturnedName; /* Returned property name */
MQCHAR8 TypeString; /* Property data type as a string */
}; |
|
|
Back to top |
|
 |
mqjeff |
Posted: Mon Jan 26, 2015 6:17 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
Well, I guess I meant a Byte Order Mark rather than a length.
But ti's just speculation. |
|
Back to top |
|
 |
|
|
  |
|
Page 1 of 1 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|