Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1031747
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T13:58:44+00:00 2026-05-16T13:58:44+00:00

I’m trying to call io_submit using python ctypes. The code I’m writing is supposed

  • 0

I’m trying to call io_submit using python ctypes.
The code I’m writing is supposed to work on both 32 and 64-bit Intel/AMD architectures, but here I’ll focus on 64 bits.

I have defined the following:

def PADDED64(type, name1, name2):
    return [(name1, type), (name2, type)]

def PADDEDptr64(type, name1, name2): 
    return [(name1, type)]

def PADDEDul64(name1, name2):
    return [(name1, ctypes.c_ulong)]

class IOVec(ctypes.Structure):
    _fields_ = [("iov_base", ctypes.c_void_p), ("iov_len", ctypes.c_size_t)]

class IOCBDataCommon64(ctypes.Structure):
    _fields_ = PADDEDptr64(ctypes.c_void_p, "buf", "__pad1") + \
        PADDEDul64("nbytes", "__pad2") + \
        [("offset", ctypes.c_longlong), ("__pad3", ctypes.c_longlong), ("flags", ctypes.c_uint), ("resfd", ctypes.c_uint)]

class IOCBDataVector(ctypes.Structure):
    _fields_ = [("vec", ctypes.POINTER(IOVec)), ("nr", ctypes.c_int), ("offset", ctypes.c_longlong)]

class IOCBDataPoll64(ctypes.Structure):
    _fields_ = PADDED64(ctypes.c_int, "events", "__pad1")

class SockAddr(ctypes.Structure):
    _fields_ = [("sa_family", ctypes.c_ushort), ("sa_data", ctypes.c_char * 14)]

class IOCBDataSockAddr(ctypes.Structure):
    _fields_ = [("addr", ctypes.POINTER(SockAddr)), ("len", ctypes.c_int)]

class IOCBDataUnion64(ctypes.Union):
    _fields_ = [("c", IOCBDataCommon64), ("v", IOCBDataVector), ("poll", IOCBDataPoll64), ("saddr", IOCBDataSockAddr)]

class IOCB64(ctypes.Structure):
    _fields_ = PADDEDptr64(ctypes.c_void_p, "data" , "__pad1") + \
        PADDED64(ctypes.c_uint, "key", "__pad2") + \
        [("aio_lio_opcode", ctypes.c_short), ("aio_reqprio", ctypes.c_short), ("aio_fildes", ctypes.c_int), ("u", IOCBDataUnion64)]

class Timespec(ctypes.Structure):
    _fields_ = [("tv_sec", ctypes.c_long), ("tv_nsec", ctypes.c_long)]

class IOEvent64(ctypes.Structure):
    _fields_ = PADDEDptr64(ctypes.c_void_p, "data", "__pad1") + \
        PADDEDptr64(ctypes.POINTER(IOCB64), "obj", "__pad2") + \
        PADDEDul64("res", "__pad3") + \
        PADDEDul64("res2", "__pad4")

I have a wrapper class called AIOCommands:

class AIOCommands:
    def __init__(self, aioCommandList):
        self.__commandList = aioCommandList
        self.__iocbs = (IOCB64 * len(self.__commandList))()
        for i in range(len(self.__commandList)):
            self.__commandList[i].initialize(self.__iocbs[i])
    def size(self):
        return len(self.__iocbs)
    def getIOCBArray(self):
        return self.__iocbs

I have defined the arguments and the return value of io_submit:

class Executor:
    def __init__(self, aioLibraryPath):
        self.__aio = ctypes.CDLL(aioLibraryPath)
        self.__aio.io_submit.argtypes = [self.aio_context_t, ctypes.c_long, ctypes.POINTER(ctypes.POINTER(IOCB64))]
        self.__aio.io_submit.restype = ctypes.c_long

Now, what should Executor.io_submit body look like? I tried:

def io_submit(self, aioContext, aioCommands):
    iocbPtr = ctypes.cast(aioCommands.getIOCBArray(), ctypes.POINTER(self.iocb_t))
    return self.__aio.io_submit(aioContext, aioCommands.size(), ctypes.byref(iocbPtr))

But I get a segmentation fault whenever the length of aioCommandList is greater than 1.
When the list contains just 1 command, the code works as expected.

Could this be a problem with my structure definitions? I’ve tried to imitate the definitions in libaio.h (assuming only little-endian architectures will be supported):

#if defined(__i386__) /* little endian, 32 bits */
#define PADDED(x, y)    x; unsigned y
#define PADDEDptr(x, y) x; unsigned y
#define PADDEDul(x, y)  unsigned long x; unsigned y
#elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__)
#define PADDED(x, y)    x, y
#define PADDEDptr(x, y) x
#define PADDEDul(x, y)  unsigned long x
#elif defined(__powerpc64__) /* big endian, 64 bits */
#define PADDED(x, y)    unsigned y; x
#define PADDEDptr(x,y)  x
#define PADDEDul(x, y)  unsigned long x
#elif defined(__PPC__)  /* big endian, 32 bits */
#define PADDED(x, y)    unsigned y; x
#define PADDEDptr(x, y) unsigned y; x
#define PADDEDul(x, y)  unsigned y; unsigned long x
#elif defined(__s390x__) /* big endian, 64 bits */
#define PADDED(x, y)    unsigned y; x
#define PADDEDptr(x,y)  x
#define PADDEDul(x, y)  unsigned long x
#elif defined(__s390__) /* big endian, 32 bits */
#define PADDED(x, y)    unsigned y; x
#define PADDEDptr(x, y) unsigned y; x
#define PADDEDul(x, y)  unsigned y; unsigned long x
#else
#error  endian?
#endif

struct io_iocb_poll {
    PADDED(int events, __pad1);
};  /* result code is the set of result flags or -'ve errno */

struct io_iocb_sockaddr {
    struct sockaddr *addr;
    int     len;
};  /* result code is the length of the sockaddr, or -'ve errno */

struct io_iocb_common {
    PADDEDptr(void  *buf, __pad1);
    PADDEDul(nbytes, __pad2);
    long long   offset;
    long long   __pad3;
    unsigned    flags;
    unsigned    resfd;
};  /* result code is the amount read or -'ve errno */

struct io_iocb_vector {
    const struct iovec  *vec;
    int         nr;
    long long       offset;
};  /* result code is the amount read or -'ve errno */

struct iocb {
    PADDEDptr(void *data, __pad1);  /* Return in the io completion event */
    PADDED(unsigned key, __pad2);   /* For use in identifying io requests */

    short       aio_lio_opcode; 
    short       aio_reqprio;
    int     aio_fildes;

    union {
        struct io_iocb_common       c;
        struct io_iocb_vector       v;
        struct io_iocb_poll     poll;
        struct io_iocb_sockaddr saddr;
    } u;
};

Any help would be appreciated, I’ve been stuck on this for several hours.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T13:58:44+00:00Added an answer on May 16, 2026 at 1:58 pm

    The way I understand it is that the iocbpp argument to io_submit() is an array of pointers to struct iocb.

    This seems to be reinforced with the Linux-specific example here: http://voinici.ceata.org/~sana/blog/?p=248 and by the EINVAL error documentation here: http://linux.die.net/man/2/io_submit (array subscripting takes precedence over dereferencing)

    What you have provided to io_submit() is a reference to an array of struct iocb. You will surely get a segfault as io_submit dereferences bogus memory addresses as it iterates through the iocbpp array. The first element (index 0) will work fine since there is no memory offset to access it.

    edit
    Another example here: http://www.xmailserver.org/eventfd-aio-test.c

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm using v2.0 of ClassTextile.php, with the following call: $testimonial_text = $textile->TextileRestricted($_POST['testimonial']); ... and
I am writing an app with both english and french support. The app requests
I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
I'm new to using the Perl treebuilder module for HTML parsing and can't figure
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
I am reading a book about Javascript and jQuery and using one of the
I am trying to render a haml file in a javascript response like so:

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.