From b287c1b1670bec76dec2856a52354be9087fca7c Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Tue, 29 Sep 2009 10:28:17 -0700 Subject: Add support for setting breakpoints on extension requests Signed-off-by: Alan Coopersmith --- scope.c | 39 +++++++++++++++++++++++++++++++++++---- server.c | 7 ++++++- xscope.man | 9 ++++++++- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/scope.c b/scope.c index c93e414..c32351c 100644 --- a/scope.c +++ b/scope.c @@ -55,6 +55,7 @@ #include "scope.h" #include "nas.h" +#include "extensions.h" #include #include @@ -118,6 +119,7 @@ typedef struct _BreakPoint { struct _BreakPoint *next; int number; unsigned char request; + int minorop; Boolean enabled; } BP; @@ -385,12 +387,22 @@ TestBreakPoints ( { if (bp->request == buf[0]) { - break; + if (bp->request < EXTENSION_MIN_REQ) /* Core protocol, not extension */ + break; + else if ((bp->minorop == -1) || (bp->minorop == buf[1])) + /* extension, either matching minor opcode or all minor opcodes */ + break; } } if (bp) { - printf ("Breakpoint on request %d\n", bp->request); + if (bp->request < EXTENSION_MIN_REQ) + printf ("Breakpoint on request %d\n", bp->request); + else if (bp->minorop == -1) + printf ("Breakpoint on extension %d\n", bp->request); + else + printf ("Breakpoint on extension %d, minor request %d\n", + bp->request, bp->minorop); ReadCommands (); } } @@ -437,7 +449,8 @@ CMDBreak ( char **argv) { BP *bp, **prev; - int request; + int request, minorop; + char *minorname; if (argc == 1) { @@ -447,6 +460,8 @@ CMDBreak ( bp->enabled ? "enabled" : "disabled", bp->request); PrintENUMERATED(&bp->request, 1, TD[REQUEST].ValueList); + if (bp->minorop != -1) + printf (":%d", bp->minorop); printf ("\n"); } } @@ -454,12 +469,28 @@ CMDBreak ( { for (prev = &breakPoints; *prev; prev = &(*prev)->next); while (*++argv) { + if (minorname = strchr(*argv, ':')) { + int r; + *minorname = '\0'; + if (!CMDStringToInt (minorname + 1, &minorop) || + (minorop < 0) || (minorop > 255)) { + *minorname = ':'; /* restore string for error message */ + return CMDSyntax; + } + } else { + minorop = -1; + } request = GetXRequestFromName (*argv); if (request < 0 && !CMDStringToInt (*argv, &request)) return CMDSyntax; + if ((request < EXTENSION_MIN_REQ) && (minorname != NULL)) { + *minorname = ':'; /* restore string for error message */ + return CMDSyntax; + } bp = (BP *) malloc (sizeof (BP)); - bp->request = request; bp->number = ++breakPointNumber; + bp->request = request; + bp->minorop = minorop; bp->enabled = true; bp->next = NULL; *prev = bp; diff --git a/server.c b/server.c index 610a0b3..fa664b8 100644 --- a/server.c +++ b/server.c @@ -777,5 +777,10 @@ long GetXRequestFromName ( const char *name) { - return GetEValue (REQUEST, name); + long req = GetEValue (REQUEST, name); + + if (req < 0) + req = GetEValue (EXTENSION, name); + + return req; } diff --git a/xscope.man b/xscope.man index b52746f..892fffe 100644 --- a/xscope.man +++ b/xscope.man @@ -107,7 +107,14 @@ List currently defined breakpoints. Create a breakpoint for the specified protocol requests. The breakpoint will be enabled by default. When the breakpoint is enabled, \fBxscope\fP will stop for interactive commands after processing a request of the -specified type. +specified type. Requests and extensions may be specified by name or number. +If an extension is followed by a ":" and a number, it will only +break for the specified minor opcode for that extension. Note that since +extension opcodes are not known until the extension is first seen, breakpoints +cannot currently be set on extensions until after a QueryExtension request +and reply are processed for that extension, so users may need to initially +set a breakpoint on QueryExtension, and after processing that set the +breakpoint for the target extension. .TP 10 .B cont, c Resume processing of data passing between server and clients. -- cgit v1.2.1