Support for break in glBegin/End (patch)

Anonymous
2008-01-02
2013-06-13
  • Anonymous

    Anonymous - 2008-01-02

    The following patch against 0.0.20071206 will add graceful handling for halts in-between glBegin and glEnd to gldb.

    It does this by introducing a new protocol message: RESP_BUSY, to indicate the debuggee can't be interrupted right now, and that the debugger should retry immediately or after a short time.

    Patch:
    diff -ur bugle-0.0.20071206/common/protocol.h bugle-0.0.20071206-new/common/protocol.h
    --- bugle-0.0.20071206/common/protocol.h    2007-11-28 16:23:54.000000000 +0100
    +++ bugle-0.0.20071206-new/common/protocol.h    2008-01-02 12:17:21.000000000 +0100
    @@ -24,6 +24,7 @@
    #define RESP_DATA                      0xabcd000aUL
    #define RESP_STATE_NODE_BEGIN_RAW      0xabcd000bUL
    #define RESP_STATE_NODE_END_RAW        0xabcd000cUL
    +#define RESP_BUSY                      0xabcd000dUL

    #define REQ_RUN                        0xdcba0000UL
    #define REQ_CONT                       0xdcba0001UL
    diff -ur bugle-0.0.20071206/doc/protocol.txt bugle-0.0.20071206-new/doc/protocol.txt
    --- bugle-0.0.20071206/doc/protocol.txt    2007-11-28 16:29:25.000000000 +0100
    +++ bugle-0.0.20071206-new/doc/protocol.txt    2008-01-02 12:59:13.000000000 +0100
    @@ -121,6 +121,12 @@
                    width, height
                  REQ_DATA_SHADER:
                    none
    +RESP_BUSY:   This response is a reaction to REQ_ASYNC, and indicates that
    +             the program cannot currently be stopped.
    +             The normal reason for this is that the program is still
    +             between glBegin and glEnd calls.
    +             The recommended response is to immediately retry the
    +             REQ_ASYNC.

    Each request has a certain set of legal responses, as described below.
    Note that requests that start the program running (the first three) will
    @@ -131,7 +137,7 @@
    REQ_STEP:  none
    REQ_BREAK: RESP_ANS, RESP_ERROR
    REQ_BREAK_ERROR: RESP_ANS
    -REQ_ASYNC: none
    +REQ_ASYNC: RESP_BUSY
    REQ_STATE_TREE: RESP_STATE_BEGIN, RESP_STATE_END (multiple)
    REQ_STATE_TREE_RAW: RESP_STATE_BEGIN_RAW, RESP_STATE_END_RAW (multiple)
    REQ_QUIT:  none
    diff -ur bugle-0.0.20071206/filters/debugger.c bugle-0.0.20071206-new/filters/debugger.c
    --- bugle-0.0.20071206/filters/debugger.c    2007-11-28 17:07:48.000000000 +0100
    +++ bugle-0.0.20071206-new/filters/debugger.c    2008-01-02 12:44:22.000000000 +0100
    @@ -881,6 +881,11 @@
             if (!stopped)
             {
                 resp_str = budgie_string_io(dump_any_call_string_io, call);
    +            if (bugle_in_begin_end()) {
    +              gldb_protocol_send_code(out_pipe, RESP_BUSY);
    +              gldb_protocol_send_code(out_pipe, start_id);
    +              break;
    +            }
                 stopped = true;
                 gldb_protocol_send_code(out_pipe, RESP_STOP);
                 gldb_protocol_send_code(out_pipe, start_id);
    diff -ur bugle-0.0.20071206/gldb/gldb.c bugle-0.0.20071206-new/gldb/gldb.c
    --- bugle-0.0.20071206/gldb/gldb.c    2007-12-01 12:41:42.000000000 +0100
    +++ bugle-0.0.20071206-new/gldb/gldb.c    2008-01-02 13:08:26.000000000 +0100
    @@ -281,6 +281,10 @@
             free(screenshot_file);
             screenshot_file = NULL;
             break;
    +    case RESP_BUSY:
    +        /* fputs("GL app busy. Retrying. \n", stderr); */
    +        gldb_send_async(0);
    +        return 0;
         }
         gldb_free_response(r);

    diff -ur bugle-0.0.20071206/gldb/gldb-common.c bugle-0.0.20071206-new/gldb/gldb-common.c
    --- bugle-0.0.20071206/gldb/gldb-common.c    2007-12-01 12:43:16.000000000 +0100
    +++ bugle-0.0.20071206-new/gldb/gldb-common.c    2008-01-02 13:10:04.000000000 +0100
    @@ -206,6 +206,10 @@
                 state_root = ((gldb_response_state_tree *) r)->root;
                 free(r);
             }
    +        else if (r->code == RESP_ERROR)
    +        {
    +          fprintf(stderr, "RESP_ERROR happened: %s\n", ((gldb_response_error *) r)->error);
    +        }
             state_dirty = false;
             /* FIXME: report any error to the GUI */
         }
    @@ -440,6 +444,16 @@
         }
    }

    +static gldb_response *gldb_get_response_busy(uint32_t code, uint32_t id)
    +{
    +  gldb_response *r;

    +  r = bugle_malloc(sizeof(gldb_response));
    +  r->code = code;
    +  r->id = id;
    +  return r;
    +}
    +
    gldb_response *gldb_get_response(void)
    {
         uint32_t code, id;
    @@ -460,6 +474,7 @@
         case RESP_SCREENSHOT: return gldb_get_response_screenshot(code, id);
         case RESP_STATE_NODE_BEGIN_RAW: return gldb_get_response_state_tree(code, id);
         case RESP_DATA: return gldb_get_response_data(code, id);
    +    case RESP_BUSY: return gldb_get_response_busy(code, id);
         default:
             fprintf(stderr, "Unexpected response %#08x\n", code);
             return NULL;
    @@ -697,6 +712,7 @@
         assert(status != GLDB_STATUS_DEAD && status != GLDB_STATUS_STOPPED);
         gldb_protocol_send_code(lib_out, REQ_ASYNC);
         gldb_protocol_send_code(lib_out, id);
    +    last_async_id=id;
    }

    void gldb_send_state_tree(uint32_t id)
    diff -ur bugle-0.0.20071206/gldb/gldb-gui.c bugle-0.0.20071206-new/gldb/gldb-gui.c
    --- bugle-0.0.20071206/gldb/gldb-gui.c    2007-12-01 12:38:00.000000000 +0100
    +++ bugle-0.0.20071206-new/gldb/gldb-gui.c    2008-01-02 12:54:17.000000000 +0100
    @@ -417,6 +417,9 @@
             stopped(context, msg);
             free(msg);
             break;
    +    case RESP_BUSY:
    +        gldb_send_async(0);
    +        break;
         case RESP_BREAK:
             bugle_asprintf(&msg, _("Break on %s"), ((gldb_response_break *) r)->call);
             stopped(context, msg);

     
    • Anonymous

      Anonymous - 2008-01-02

      Agh. Ignore the last_async_id bit, please, it's a relic from an abandoned approach.

      Sorry. :)

       
    • Bruce Merry

      Bruce Merry - 2008-01-02

      Thanks for the contribution! In the end I decided not to apply the patch, but rather put extra logic into the debugger so that it would simply defer any response until outside of begin/end. This avoids extending the protocol unnecessarily, as well as protocol overhead inside begin/end. It's checked into subversion.

      If you're interested in working on bugle (and I'd like to get more developers involved, since I'll be starting a full-time job next month), I've currently got the "defer until out of begin-end" behaviour controlled by a boolean in the debugger filter-set (stop_in_begin_end), but it would be nice to have this controlled by a check box on, say, the options menu, with a protocol extension to set or clear this bit (perhaps replacing the existing "breakpoint", "break on error", and activate/deactivate protocols with a generic protocol for toggling bits, with a subtype field and optional name field).

       
    • Anonymous

      Anonymous - 2008-01-03

      I primarily fixed the glBegin/End behavior out of necessity, since this problem made gldb unusable with my glBegin/End-heavy application. Also have my head full with studying and all.

      But thanks for the offer! :)

      Apart from that, your solution is probably better. I haven't really read much of the code yet; just enough to understand how to fix the issue at hand. Looks very clean, by the way.

      Good to know this is fixed. Thanks.

       

Log in to post a comment.