Extension of Xorg server 32/64 Bits problem

Alan Coopersmith alan.coopersmith at oracle.com
Tue Jun 5 09:46:48 PDT 2012


On 06/ 5/12 07:46 AM, Leo Chapiro wrote:
>> Hard to say much more than you have a bug in your code and need to debug it.
>> You don't even include the error code, which is one of the most important bits
>> of information for such debugging.
> 
> I have forgot to add the error message :(
> 
>>> X Error of failed request:  BadLength (poly request too large or internal
>>> Xlib length error)
> 
> Basically I have a protocol with following request / reply:
> 
> typedef struct 
> {
>     CARD8       reqType;/* major opcode of request, allocated by server on
> extension initialization */
>     CARD8       data;/* undefined, usually used as 'minor opcode' */
>     CARD16      length B16;
>     CARD16      majorVersion B16;
>     CARD16      minorVersion B16;
> } xSerialQueryVersionReq;
> #define sz_xSerialQueryVersionReq 8
>
> typedef struct
> {
>     CARD8   type;
>     CARD8   pad0;
>     CARD16  sequenceNumber B16;
>     CARD32  length B32;
>     CARD16  majorVersion B16;
>     CARD16  minorVersion B16;
>     CARD32  pad1 B32;
>     CARD32  pad2 B32;
>     CARD32  pad3 B32;
>     CARD32  pad4 B32;
>     CARD32  pad5 B32;
>  } xSerialQueryVersionReply;
> #define sz_xSerialQueryVersionReply  32
> 
> Now I try to use it over client_lib:
> 
> Status XMntQueryVersion(
> #if NeedFunctionPrototypes
>     Display*dpy,
>     int*nMajor,
>     int*nMinor,
>     int*nTeeny
> #endif
> )
> {
> xSerialQueryVersionReq* req;
> xSerialQueryVersionReply rep;
> 
> XExtCodes *pOpcode = XInitExtension(dpy, SERIAL_NAME);
> 
> LockDisplay(dpy);
> GetReq(SerialQueryVersion, req);
> req->reqType = pOpcode->major_opcode;
> req->data = X_SerialQueryVersion;
> req->majorVersion = SERIAL_MAJOR_VERSION;
> req->minorVersion = SERIAL_MINOR_VERSION;
> 
> if (!_XReply(dpy,(xReply *)&rep, 0, True))
> {
> UnlockDisplay(dpy);
> SyncHandle();
> return XMntFailure;
> }
> 
> *nMajor = rep.majorVersion;
> *nMinor = rep.minorVersion;
> *nTeeny = XMNT_TEENY_VERSION;
> 
> UnlockDisplay(dpy);
> SyncHandle();
> 
> return XMntSuccess;
> }
> 
> And on the server side after init and dispatch I do following:
> 
> static int
> ProcSerialQueryVersion(ClientPtr client)
> {
> REQUEST_SIZE_MATCH(xSerialQueryVersionReq);
> 
> xSerialQueryVersionReply rep;
> int n;
> 
>     rep.type        = X_Reply;
>     rep.sequenceNumber = client->sequence;
>     rep.length         = 0;
>     rep.majorVersion  = SERIAL_MAJOR_VERSION;
>     rep.minorVersion  = SERIAL_MINOR_VERSION;
> 
>     if(client->swapped)
> {
> swaps(&rep.sequenceNumber, n);
> swaps(&rep.majorVersion, n);
> swaps(&rep.minorVersion, n);
> }
> 
>     (void)WriteToClient(client, sizeof(xSerialQueryVersionReply), (char *)&rep);
> 
>     return Success;
> }
> 
> The issue is that REQUEST_SIZE_MATCH sucks: client->req_len is always 0 !

And yet it works correctly for hundreds of existing requests in the core
protocol and mainstream extensions - experience suggests there's a subtle
bug in your code, not in the macro everyone else successfully uses.  If req_len
wasn't getting correctly filled in, then the core server IO & dispatch code
wouldn't know it had a complete request ready to provide to your extension.

Unfortunately, I don't see anything jumping out at me from the above as
obviously incorrect.   I'd double-check to make sure you're using the same
headers in your 32-bit & 64-bit builds and didn't forget to update one or
the other at some point.

-- 
	-Alan Coopersmith-              alan.coopersmith at oracle.com
	 Oracle Solaris Engineering - http://blogs.oracle.com/alanc


More information about the xorg-devel mailing list