[New-bugs-announce] [issue20629] Python ctypes BigEndianStructure bitfield assignment misbehavior in Linux

Alan Ning report at bugs.python.org
Fri Feb 14 22:43:22 CET 2014


New submission from Alan Ning:

I am seeing a strange issue with bitfields and BigEndianStructure under Ubuntu 12.04 x64, Python 2.7.3.

This bug only occurs if I define my bitfields using c_uint. If I switch to c_ushort, it goes away.

Below is a simple code that highlights the problem. I have two structures - BitField1U and BitField2U. It is a union of a 4 bytes array and a bitfield definition.

Under Linux, by simply setting fields.a = 1 twice, it modifies the underlying byte array twice in a very different way. This behavior does not occur in Windows.

Output: Ubuntu 12.04x64 Python 2.7.3
20000000
20000020 <- problem
20000000
20000000

Output: Window 7 x64 Python 2.7.3
20000000
20000000
20000000
20000000

This bug was originally reported as a question in StackOverflow. 
http://stackoverflow.com/questions/21785874/python-ctypes-bitfield-windows-vs-linux


Source code:

import ctypes
import binascii

class BitField1(ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [
    ('a', ctypes.c_uint, 3),
    ('b', ctypes.c_uint, 1),
    ]

class BitField1U(ctypes.Union):
    _pack_ = 1
    _fields_ = [("fields", BitField1), 
        ("raw_bytes", ctypes.c_ubyte * 4)]

class BitField2(ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [
    ('a', ctypes.c_ushort, 3),
    ('b', ctypes.c_ushort, 1),
    ]

class BitField2U(ctypes.Union):
    _pack_ = 1
    _fields_ = [("fields", BitField2), 
        ("raw_bytes", ctypes.c_ubyte * 4)]

def printBytes(raw_bytes) :
    ba = bytearray(raw_bytes)
    print(binascii.hexlify(ba))
    
def printFields(fields) :
    print(fields.a),
    print(fields.b),
    print

b1 = BitField1U()
b2 = BitField2U()

# Simply set fields.a = 1 twice, and notice how the raw_bytes changes.

b1.fields.a = 1
printBytes(b1.raw_bytes)
b1.fields.a = 1
printBytes(b1.raw_bytes)

b2.fields.a = 1
printBytes(b2.raw_bytes)
b2.fields.a = 1
printBytes(b2.raw_bytes)

----------
components: ctypes
messages: 211241
nosy: Alan.Ning
priority: normal
severity: normal
status: open
title: Python ctypes BigEndianStructure bitfield assignment misbehavior in Linux
versions: Python 2.7

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue20629>
_______________________________________


More information about the New-bugs-announce mailing list