Re: Problem with alignment under Linux [SEC=UNCLASSIFIED]
"Andrew MacIntyre" <[email protected]> Thu, 9 Feb 2012 08:28:41 +0000
| Newsgroups | gmane.comp.python.ctypes |
|---|---|
| Message-ID | <A1E4E9D08D14924498E135FB4441EE8D18FEB761@act01exmbx01vp.internal.govt> |
In the 32bit linux environment, which I would have expected to include a 32bit binary on a 64bit kernel, the standard packing is 4 bytes. As far as I can tell the only basic datatype in this ABI that demands 8 byte alignment is long long - which doesn't appear directly in what you're working with... So there has to be something in the C headers you're working from that triggers 8 byte packing. I went back through the old thread, but didn't see any reference to any actual structure/union declarations as they appear in the C headers, so it would be useful to know how this is being triggered. BTW, it seems to me that there's a bug in the fill_union() function as I think the union as shown should be 8 bytes rather than the 16 bytes reported - I think the calculation of the delta should be something like delta = size % 8 if delta: delta = 8 - delta to produce the correct size. -------------------------> "These thoughts are mine alone!" <--------- Andrew MacIntyre Operations Branch tel: +61 2 6219 5356 Communications Infrastructure Division fax: +61 2 6253 3277 Australian Communications & Media Authority email: [email protected] http://www.acma.gov.au/ > -----Original Message----- > From: Axel Seibert [mailto:[email protected]] > Sent: Thursday, 9 February 2012 12:43 AM > To: [email protected] > Subject: [ctypes-users] Problem with alignment under Linux > > Dear list! > > Please excuse the long posting. > > Nearly two years ago we had a discussion here on the list about an issue that > I have under Linux > (http://sourceforge.net/mailarchive/forum.php?thread_name=C3A6EB6D- > E1DD-4D91-A579-9A88F5040ED5%40globonaut.org&forum_name=ctypes- > users). > Unfortunately, we never resolved the issue, and I would like to take up the > discussion once more. > > Problem: > I'm wrapping a C library from an enterprise software environment > (ARSystem > from BMC) with ctypes in python (I don't have access to the source code or > any > details about the compiler used). This is working fine under Windows and > SPARC > Solaris. Under Linux it's not working with the standard ctypes setup. "Does > not work" means that I cannot use any of the library calls to talk to the > server, as it does not receive the parameters correctly. > > Assumption > It seems that the memory alignment for this library under Linux does not > match > ctypes' expectations. > > Workaround 1 > By using _pack_ = 8, for some of the structures and unions, I can get this to > work reliably. > The problem is that ctypes' implementation limits the maximum size of the > _pack_ value. In other words, my workaround only works with a patched > version > of ctypes (for a patch against python 2.7.2, please see below). > > Workaround 2 > During the discussion here on the mailinglist, Thomas developed two python > workarounds, one for structures > (http://sourceforge.net/mailarchive/message.php?msg_id=24837697), and > one for > unions > (http://sourceforge.net/mailarchive/message.php?msg_id=25006328), to > cope with my problem. > However, with those workarounds, it still does not work. > > I have now researched this a bit more, and have come up with the following > test case: > > ----------------------------------------- > #!env python > > from ctypes import * > import sys > > def fill_structure(a, fields, override = False): > """Patch the 'fields' sequence for a ctypes Structure by inserting > dummy fields named '' so that the alignment of the original fields > is a multiple of the 'a' value. > """ > if sys.platform.startswith('linux') or override: > result = [] > size = 0 > for n, t in fields: > size += sizeof(t) > missing = (a - sizeof(t)) % a > result.append((n, t)) > if missing: > result.append(("", c_char * missing)) > return result > else: > return fields > > def fill_union(value, fields, override = False): > if sys.platform.startswith('linux') or override: > size = 0 > for name, typ in fields: > size = max(size, sizeof(typ)) > delta = 8 - size % 8 > return fields + [("", c_char * (size + delta))] > else: > return fields > > > size_t = c_uint > ARLong32 = c_long > ARTimestamp = ARLong32 > ARTime = ARLong32 > ARULong32 = c_ulong > > class N13ARValueStruct3DOLLAR_1E(Union): > _fields_ = fill_union(8, [ > # ar.h 756 > ('noval_', size_t), > ('keyNum', c_uint), > ('intVal', ARLong32), > ('realVal', c_double), > ('charVal', c_char_p), > ('diaryVal', c_char_p) > ], override=True) > > class ARValueStruct(Structure): > _fields_ = fill_structure(8, [ > # ar.h 753 > ('dataType', c_uint), > ('u', N13ARValueStruct3DOLLAR_1E), > ], override=True) > > > print "This is on plattform: %s" % sys.platform > print "This is the alignment:" > print "%14s: %7s %5s %9s" % ('Name', 'Offset', 'Size', 'Alignment') > for name, typ in ARValueStruct._fields_: > if name: > print "%14s: %7d %5d %9d" % (name, getattr(ARValueStruct, > name).offset, sizeof(typ), alignment(typ)) > > for name, typ in N13ARValueStruct3DOLLAR_1E._fields_: > if name: > print "%14s: %7d %5d %9d" % (name, > getattr(N13ARValueStruct3DOLLAR_1E, > name).offset, sizeof(typ), alignment(typ)) > > ----------------------------- > > If you run this under Linux, it will print out the following result: > This is on plattform: linux3 > This is the alignment: > Name: Offset Size Alignment > dataType: 0 4 4 > u: 8 16 4 > noval_: 0 4 4 > keyNum: 0 4 4 > intVal: 0 4 4 > realVal: 0 8 4 > charVal: 0 4 4 > diaryVal: 0 4 4 > > > When I take the Structure and Union definition, add a _pack_ = 8 and use my > patched version of ctypes, I receive the following (please note the different > output for the field 'u'): > This is on plattform: linux3 > This is the alignment: > Name: Offset Size Alignment > dataType: 0 4 4 > u: 8 16 8 > noval_: 0 4 4 > keyNum: 0 4 4 > intVal: 0 4 4 > realVal: 0 8 4 > charVal: 0 4 4 > diaryVal: 0 4 4 > > I'm asking the experts on this list to try to understand my problem. If you > are missing any details or additional information, please do not hesitate to > contact me. I'm also willing to run any kinds of tests and stuff. I would very > much appreciate any python based solution. The current situation, that users > of the library need to patch Python cannot be the solution. > > Thanx for your time & help! > Axel > > > Patch for python 2.7.2 > *** Modules/_ctypes/cfield.c.orig 2012-02-05 12:56:21.902652940 +0100 > --- Modules/_ctypes/cfield.c 2012-02-05 12:56:41.770652136 +0100 > *************** > *** 150,156 **** > /* fall through */ > case NO_BITFIELD: > if (pack) > ! align = min(pack, dict->align); > else > align = dict->align; > if (align && *poffset % align) { > --- 150,156 ---- > /* fall through */ > case NO_BITFIELD: > if (pack) > ! align = pack; /*min(pack, dict->align);*/ > else > align = dict->align; > if (align && *poffset % align) { > > > ------------------------------------------------------------------------------ > Keep Your Developer Skills Current with LearnDevNow! > The most comprehensive online learning library for Microsoft developers > is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, > Metro Style Apps, more. Free future releases when you subscribe now! > http://p.sf.net/sfu/learndevnow-d2d > _______________________________________________ > ctypes-users mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/ctypes-users NOTICE: This email message is for the sole use of the intended recipient(s) and may contain confidential and privileged information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message. ------------------------------------------------------------------------------ Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service. http://www.accelacomm.com/jaw/sfnl/114/51521223/