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