From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22775 invoked by alias); 12 Oct 2010 20:25:13 -0000 Received: (qmail 22731 invoked by uid 22791); 12 Oct 2010 20:25:10 -0000 X-SWARE-Spam-Status: No, hits=-5.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_WB,TW_YB,T_FILL_THIS_FORM_SHORT,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 12 Oct 2010 20:25:01 +0000 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o9CKOsJb020794 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 12 Oct 2010 16:24:54 -0400 Received: from localhost.localdomain.redhat.com (ovpn-113-38.phx2.redhat.com [10.3.113.38]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o9CKOorU001600; Tue, 12 Oct 2010 16:24:51 -0400 From: Phil Muldoon To: Tom Tromey Cc: Pedro Alves , gdb-patches@sourceware.org, dan@codesourcery.com Subject: Re: [patch] Add visible flag to breakpoints. References: <201009301741.32379.pedro@codesourcery.com> <201010081435.15174.pedro@codesourcery.com> Reply-to: pmuldoon@redhat.com X-URL: http://www.redhat.com Date: Tue, 12 Oct 2010 20:25:00 -0000 In-Reply-To: (Tom Tromey's message of "Fri, 08 Oct 2010 12:44:24 -0600") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-10/txt/msg00204.txt.bz2 Tom Tromey writes: >>>>>> "Phil" == Phil Muldoon writes: > Why don't we just put a reference to the PyObject into struct > breakpoint? This solves the problem completely, or at least pushes it > up to whatever algorithms are used in breakpoint.c. This can easily be > done in a way that does not break the Python-less case (see varobj.c for > an example). In this patch iteration I removed any form of storage/tracking of breakpoints. Instead, as above, I placed a reference in the breakpoint struct. There are two disadvantages that stem from this: * I had to extern breakpoint_chain * I had to move the ALL_BREAKPOINTS macro to breakpoint.h I'm not sure how to get around those, or, if indeed they are perceived as disadvantages. Anyway, please take a look and let me know what you think. I will rewrite the ChangeLogs on patch approval. Tested with no regressions on x86-64. Cheers, Phil -- diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index b4502e7..47d5bf2 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -345,12 +345,6 @@ static int executing_breakpoint_commands; /* Are overlay event breakpoints enabled? */ static int overlay_events_enabled; -/* Walk the following statement or block through all breakpoints. - ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current - breakpoint. */ - -#define ALL_BREAKPOINTS(B) for (B = breakpoint_chain; B; B = B->next) - #define ALL_BREAKPOINTS_SAFE(B,TMP) \ for (B = breakpoint_chain; \ B ? (TMP=B->next, 1): 0; \ @@ -4939,7 +4933,8 @@ breakpoint_1 (int bnum, int allflag, int (*filter) (const struct breakpoint *)) if (filter && !filter (b)) continue; - if (allflag || user_settable_breakpoint (b)) + if (allflag || (user_settable_breakpoint (b) + && b->number > 0)) { int addr_bit, type_len; @@ -5007,7 +5002,8 @@ breakpoint_1 (int bnum, int allflag, int (*filter) (const struct breakpoint *)) /* We only print out user settable breakpoints unless the allflag is set. */ - if (allflag || user_settable_breakpoint (b)) + if (allflag || (user_settable_breakpoint (b) + && b->number > 0)) print_one_breakpoint (b, &last_loc, print_address_bits, allflag); } } @@ -5456,6 +5452,7 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch, b->syscalls_to_be_caught = NULL; b->ops = NULL; b->condition_not_parsed = 0; + b->py_bp_object = NULL; /* Add this breakpoint to the end of the chain so that a list of breakpoints will come out in order @@ -6914,7 +6911,8 @@ create_breakpoint_sal (struct gdbarch *gdbarch, char *cond_string, enum bptype type, enum bpdisp disposition, int thread, int task, int ignore_count, - struct breakpoint_ops *ops, int from_tty, int enabled) + struct breakpoint_ops *ops, int from_tty, + int enabled, int internal) { struct breakpoint *b = NULL; int i; @@ -6951,8 +6949,13 @@ create_breakpoint_sal (struct gdbarch *gdbarch, if (i == 0) { b = set_raw_breakpoint (gdbarch, sal, type); - set_breakpoint_count (breakpoint_count + 1); - b->number = breakpoint_count; + if (internal) + b->number = internal_breakpoint_number--; + else + { + set_breakpoint_count (breakpoint_count + 1); + b->number = breakpoint_count; + } b->thread = thread; b->task = task; @@ -7034,7 +7037,12 @@ Couldn't determine the static tracepoint marker to probe")); = xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address)); b->ops = ops; - mention (b); + if (internal) + /* Do not mention breakpoints with a negative number, but do + notify observers. */ + observer_notify_breakpoint_created (b->number); + else + mention (b); } /* Remove element at INDEX_TO_REMOVE from SAL, shifting other @@ -7190,7 +7198,7 @@ create_breakpoints_sal (struct gdbarch *gdbarch, enum bptype type, enum bpdisp disposition, int thread, int task, int ignore_count, struct breakpoint_ops *ops, int from_tty, - int enabled) + int enabled, int internal) { int i; @@ -7201,7 +7209,8 @@ create_breakpoints_sal (struct gdbarch *gdbarch, create_breakpoint_sal (gdbarch, expanded, addr_string[i], cond_string, type, disposition, - thread, task, ignore_count, ops, from_tty, enabled); + thread, task, ignore_count, ops, + from_tty, enabled, internal); } } @@ -7464,25 +7473,24 @@ decode_static_tracepoint_spec (char **arg_p) return sals; } -/* Set a breakpoint. This function is shared between CLI and MI - functions for setting a breakpoint. This function has two major - modes of operations, selected by the PARSE_CONDITION_AND_THREAD - parameter. If non-zero, the function will parse arg, extracting - breakpoint location, address and thread. Otherwise, ARG is just the - location of breakpoint, with condition and thread specified by the - COND_STRING and THREAD parameters. Returns true if any breakpoint - was created; false otherwise. */ +/* Set a breakpoint. This function has two major modes of operations, + selected by the PARSE_CONDITION_AND_THREAD parameter. If non-zero, + the function will parse arg, extracting breakpoint location, + address and thread. Otherwise, ARG is just the location of + breakpoint, with condition and thread specified by the COND_STRING + and THREAD parameters. If INTERNAL is non-zero, the breakpoint + number will be allocated from the internal breakpoint count. + Returns true if any breakpoint was created; false otherwise. */ int -create_breakpoint (struct gdbarch *gdbarch, +create_new_breakpoint (struct gdbarch *gdbarch, char *arg, char *cond_string, int thread, int parse_condition_and_thread, int tempflag, enum bptype type_wanted, int ignore_count, enum auto_boolean pending_break_support, struct breakpoint_ops *ops, - int from_tty, - int enabled) + int from_tty, int enabled, int internal) { struct gdb_exception e; struct symtabs_and_lines sals; @@ -7658,12 +7666,15 @@ create_breakpoint (struct gdbarch *gdbarch, cond_string, type_wanted, tempflag ? disp_del : disp_donttouch, thread, task, ignore_count, ops, - from_tty, enabled); + from_tty, enabled, internal); do_cleanups (old_chain); /* Get the tracepoint we just created. */ - tp = get_breakpoint (breakpoint_count); + if (internal) + tp = get_breakpoint (internal_breakpoint_number); + else + tp = get_breakpoint (breakpoint_count); gdb_assert (tp != NULL); /* Given that its possible to have multiple markers with @@ -7679,7 +7690,7 @@ create_breakpoint (struct gdbarch *gdbarch, create_breakpoints_sal (gdbarch, sals, addr_string, cond_string, type_wanted, tempflag ? disp_del : disp_donttouch, thread, task, ignore_count, ops, from_tty, - enabled); + enabled, internal); } else { @@ -7688,8 +7699,13 @@ create_breakpoint (struct gdbarch *gdbarch, make_cleanup (xfree, copy_arg); b = set_raw_breakpoint_without_location (gdbarch, type_wanted); - set_breakpoint_count (breakpoint_count + 1); - b->number = breakpoint_count; + if (internal) + b->number = internal_breakpoint_number--; + else + { + set_breakpoint_count (breakpoint_count + 1); + b->number = breakpoint_count; + } b->thread = -1; b->addr_string = addr_string[0]; b->cond_string = NULL; @@ -7699,13 +7715,19 @@ create_breakpoint (struct gdbarch *gdbarch, b->ops = ops; b->enable_state = enabled ? bp_enabled : bp_disabled; b->pspace = current_program_space; + b->py_bp_object = NULL; if (enabled && b->pspace->executing_startup && (b->type == bp_breakpoint || b->type == bp_hardware_breakpoint)) b->enable_state = bp_startup_disabled; - mention (b); + if (internal) + /* Do not mention breakpoints with a negative number, but do + notify observers. */ + observer_notify_breakpoint_created (b->number); + else + mention (b); } if (sals.nelts > 1) @@ -7727,6 +7749,31 @@ create_breakpoint (struct gdbarch *gdbarch, return 1; } + +/* Set a breakpoint. This function is shared between CLI and MI + functions for setting a breakpoint. It wraps create_new_breakpoint + and never asks for an internal breakpoint number to be allocated + against the breakpoint. Returns true if any breakpoint was + created; false otherwise. */ + +int +create_breakpoint (struct gdbarch *gdbarch, + char *arg, char *cond_string, int thread, + int parse_condition_and_thread, + int tempflag, enum bptype type_wanted, + int ignore_count, + enum auto_boolean pending_break_support, + struct breakpoint_ops *ops, + int from_tty, + int enabled) +{ + return create_new_breakpoint (gdbarch, arg, cond_string, thread, + parse_condition_and_thread, tempflag, + type_wanted, ignore_count, + pending_break_support, + ops, from_tty, enabled, 0); +} + /* Set a breakpoint. ARG is a string describing breakpoint address, condition, and thread. @@ -11372,7 +11419,7 @@ save_breakpoints (char *filename, int from_tty, ALL_BREAKPOINTS (tp) { /* Skip internal and momentary breakpoints. */ - if (!user_settable_breakpoint (tp)) + if (!user_settable_breakpoint (tp) || tp->number < 0) continue; /* If we have a filter, only save the breakpoints it accepts. */ @@ -11410,7 +11457,7 @@ save_breakpoints (char *filename, int from_tty, ALL_BREAKPOINTS (tp) { /* Skip internal and momentary breakpoints. */ - if (!user_settable_breakpoint (tp)) + if (!user_settable_breakpoint (tp) || tp->number < 0) continue; /* If we have a filter, only save the breakpoints it accepts. */ diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 9f7600a..da4461a 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -24,9 +24,21 @@ #include "value.h" #include "vec.h" +#if HAVE_PYTHON +#include "python/python.h" +#include "python/python-internal.h" +#endif + struct value; struct block; +/* Walk the following statement or block through all breakpoints. + ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current + breakpoint. */ + +extern struct breakpoint *breakpoint_chain; +#define ALL_BREAKPOINTS(B) for (B = breakpoint_chain; B; B = B->next) + /* This is the maximum number of bytes a breakpoint instruction can take. Feel free to increase it. It's just used in a few places to size arrays that should be independent of the target architecture. */ @@ -557,7 +569,14 @@ struct breakpoint breakpoints, we will use this index to try to find the same marker again. */ int static_trace_marker_id_idx; - }; + + /* With a Python scripting enabled GDB, store a reference to the + Python object that has been associated with this breakpoint. + This is always NULL for a GDB that is not script enabled. It + can sometimes be NULL for enabled GDBs as not all breakpoint + types are tracked by the Python scripting API. */ + PyObject *py_bp_object; +}; typedef struct breakpoint *breakpoint_p; DEF_VEC_P(breakpoint_p); @@ -870,6 +889,18 @@ extern int create_breakpoint (struct gdbarch *gdbarch, char *arg, int from_tty, int enabled); +extern int create_new_breakpoint (struct gdbarch *gdbarch, char *arg, + char *cond_string, int thread, + int parse_condition_and_thread, + int tempflag, + enum bptype type_wanted, + int ignore_count, + enum auto_boolean pending_break_support, + struct breakpoint_ops *ops, + int from_tty, + int enabled, + int internal); + extern void insert_breakpoints (void); extern int remove_breakpoints (void); diff --git a/gdb/defs.h b/gdb/defs.h index 9e4800c..643338e 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -1240,4 +1240,8 @@ void dummy_obstack_deallocate (void *object, void *data); extern void initialize_progspace (void); extern void initialize_inferiors (void); +#ifndef HAVE_PYTHON +typedef int PyObject; +#endif + #endif /* #ifndef DEFS_H */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 0b24718..415efc0 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -22552,7 +22552,7 @@ Return the symbol table's source absolute file name. Python code can manipulate breakpoints via the @code{gdb.Breakpoint} class. -@defmethod Breakpoint __init__ spec @r{[}type@r{]} @r{[}wp_class@r{]} +@defmethod Breakpoint __init__ spec @r{[}type@r{]} @r{[}wp_class@r{]} @r{[}internal@r{]} Create a new breakpoint. @var{spec} is a string naming the location of the breakpoint, or an expression that defines a watchpoint. The contents can be any location recognized by the @@ -22560,7 +22560,12 @@ watchpoint. The contents can be any location recognized by the command. The optional @var{type} denotes the breakpoint to create from the types defined later in this chapter. This argument can be either: @code{BP_BREAKPOINT} or @code{BP_WATCHPOINT}. @var{type} -defaults to @code{BP_BREAKPOINT}. The optional @var{wp_class} +defaults to @code{BP_BREAKPOINT}. The optional @var{internal} argument +allows the breakpoint to become invisible to the user. The breakpoint +will neither be reported when created, nor will it be listed in the +output from @code{info breakpoints} (but will be listed with the +@code{maint info breakpoints} command). The @var{internal} argument +has no effect with watchpoints. The optional @var{wp_class} argument defines the class of watchpoint to create, if @var{type} is defined as @code{BP_WATCHPOINT}. If a watchpoint class is not provided, it is assumed to be a @var{WP_WRITE} class. @@ -22638,6 +22643,13 @@ determine the actual breakpoint type or use-case. This attribute is not writable. @end defivar +@defivar Breakpoint visible +This attribute holds the breakpoint's visibility flag---the identifier used to +determine whether the breakpoint is visible to the user when set, or +when the @samp{info breakpoints} command is run. This attribute is +not writable. +@end defivar + The available types are represented by constants defined in the @code{gdb} module: diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index 0c70cbf..a9a02f7 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -34,17 +34,6 @@ typedef struct breakpoint_object breakpoint_object; static PyTypeObject breakpoint_object_type; -/* A dynamically allocated vector of breakpoint objects. Each - breakpoint has a number. A breakpoint is valid if its slot in this - vector is non-null. When a breakpoint is deleted, we drop our - reference to it and zero its slot; this is how we let the Python - object have a lifetime which is independent from that of the gdb - breakpoint. */ -static breakpoint_object **bppy_breakpoints; - -/* Number of slots in bppy_breakpoints. */ -static int bppy_slots; - /* Number of live breakpoints. */ static int bppy_live; @@ -68,7 +57,7 @@ struct breakpoint_object exception if it is invalid. */ #define BPPY_REQUIRE_VALID(Breakpoint) \ do { \ - if (! bpnum_is_valid ((Breakpoint)->number)) \ + if ((Breakpoint)->bp == NULL) \ return PyErr_Format (PyExc_RuntimeError, _("Breakpoint %d is invalid."), \ (Breakpoint)->number); \ } while (0) @@ -77,7 +66,7 @@ struct breakpoint_object exception if it is invalid. This macro is for use in setter functions. */ #define BPPY_SET_REQUIRE_VALID(Breakpoint) \ do { \ - if (! bpnum_is_valid ((Breakpoint)->number)) \ + if ((Breakpoint)->bp == NULL) \ { \ PyErr_Format (PyExc_RuntimeError, _("Breakpoint %d is invalid."), \ (Breakpoint)->number); \ @@ -115,18 +104,6 @@ static struct pybp_code pybp_watch_types[] = {NULL} /* Sentinel. */ }; -/* Evaluate to true if the breakpoint NUM is valid, false otherwise. */ -static int -bpnum_is_valid (int num) -{ - if (num >=0 - && num < bppy_slots - && bppy_breakpoints[num] != NULL) - return 1; - - return 0; -} - /* Python function which checks the validity of a breakpoint object. */ static PyObject * bppy_is_valid (PyObject *self, PyObject *args) @@ -500,6 +477,21 @@ bppy_get_type (PyObject *self, void *closure) return PyInt_FromLong (self_bp->bp->type); } +/* Python function to get the visibility of the breakpoint. */ + +static PyObject * +bppy_get_visibility (PyObject *self, void *closure) +{ + breakpoint_object *self_bp = (breakpoint_object *) self; + + BPPY_REQUIRE_VALID (self_bp); + + if (self_bp->bp->number < 0) + Py_RETURN_FALSE; + + Py_RETURN_TRUE; +} + /* Python function to get the breakpoint's number. */ static PyObject * bppy_get_number (PyObject *self, void *closure) @@ -566,16 +558,21 @@ static PyObject * bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs) { PyObject *result; - static char *keywords[] = { "spec", "type", "wp_class", NULL }; + static char *keywords[] = { "spec", "type", "wp_class", "internal", NULL }; char *spec; int type = bp_breakpoint; int access_type = hw_write; + PyObject *internal = NULL; + int internal_bp = 0; volatile struct gdb_exception except; - if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|ii", keywords, - &spec, &type, &access_type)) + if (! PyArg_ParseTupleAndKeywords (args, kwargs, "s|iiO", keywords, + &spec, &type, &access_type, &internal)) return NULL; + if (internal && PyObject_IsTrue (internal)) + internal_bp = 1; + result = subtype->tp_alloc (subtype, 0); if (! result) return NULL; @@ -589,13 +586,13 @@ bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs) { case bp_breakpoint: { - create_breakpoint (python_gdbarch, - spec, NULL, -1, - 0, - 0, bp_breakpoint, - 0, - AUTO_BOOLEAN_TRUE, - NULL, 0, 1); + create_new_breakpoint (python_gdbarch, + spec, NULL, -1, + 0, + 0, bp_breakpoint, + 0, + AUTO_BOOLEAN_TRUE, + NULL, 0, 1, internal_bp); break; } case bp_watchpoint: @@ -634,6 +631,7 @@ PyObject * gdbpy_breakpoints (PyObject *self, PyObject *args) { PyObject *result; + struct breakpoint *b; if (bppy_live == 0) Py_RETURN_NONE; @@ -641,16 +639,24 @@ gdbpy_breakpoints (PyObject *self, PyObject *args) result = PyTuple_New (bppy_live); if (result) { - int i, out = 0; - - for (i = 0; out < bppy_live; ++i) - { - if (! bppy_breakpoints[i]) - continue; - Py_INCREF (bppy_breakpoints[i]); - PyTuple_SetItem (result, out, (PyObject *) bppy_breakpoints[i]); - ++out; - } + int i = 0; + ALL_BREAKPOINTS (b) + { + /* Not all breakpoints will have a companion Python object. + Only breakpoints that were created via bppy_new, or + breakpoints that were created externally and are tracked by + the Python Scripting API. */ + if (b->py_bp_object) + { + if (PyTuple_SetItem (result, i, (PyObject *) b->py_bp_object) != 0) + { + Py_DECREF (result); + return NULL; + } + Py_INCREF (b->py_bp_object); + ++i; + } + } } return result; } @@ -667,9 +673,7 @@ gdbpy_breakpoint_created (int num) breakpoint_object *newbp; struct breakpoint *bp = NULL; PyGILState_STATE state; - - if (num < 0) - return; + int error = 0; bp = get_breakpoint (num); if (! bp) @@ -682,21 +686,6 @@ gdbpy_breakpoint_created (int num) && bp->type != bp_access_watchpoint) return; - if (num >= bppy_slots) - { - int old = bppy_slots; - - bppy_slots = bppy_slots * 2 + 10; - bppy_breakpoints - = (breakpoint_object **) xrealloc (bppy_breakpoints, - (bppy_slots - * sizeof (breakpoint_object *))); - memset (&bppy_breakpoints[old], 0, - (bppy_slots - old) * sizeof (PyObject *)); - } - - ++bppy_live; - state = PyGILState_Ensure (); if (bppy_pending_object) @@ -710,9 +699,19 @@ gdbpy_breakpoint_created (int num) { newbp->number = num; newbp->bp = bp; - bppy_breakpoints[num] = newbp; + newbp->bp->py_bp_object = (PyObject *)newbp; Py_INCREF (newbp); } + else + { + PyErr_SetString (PyExc_RuntimeError, + _("Error while creating breakpoint from GDB.")); + gdbpy_print_stack (); + error = 1; + } + + if (! error) + ++bppy_live; /* Just ignore errors here. */ PyErr_Clear (); @@ -726,15 +725,25 @@ static void gdbpy_breakpoint_deleted (int num) { PyGILState_STATE state; + struct breakpoint *b = NULL; state = PyGILState_Ensure (); - if (bpnum_is_valid (num)) - { - bppy_breakpoints[num]->bp = NULL; - Py_DECREF (bppy_breakpoints[num]); - bppy_breakpoints[num] = NULL; - --bppy_live; - } + ALL_BREAKPOINTS (b) + { + if (b->number == num) + { + breakpoint_object *bp_obj = + ((breakpoint_object *)b->py_bp_object); + + if (bp_obj) + { + bp_obj->bp = NULL; + --bppy_live; + Py_DECREF (bp_obj); + } + break; + } + } PyGILState_Release (state); } @@ -816,6 +825,8 @@ or None if no condition set."}, "Commands of the breakpoint, as specified by the user."}, { "type", bppy_get_type, NULL, "Type of breakpoint."}, + { "visible", bppy_get_visibility, NULL, + "Whether the breakpoint is visible to the user."}, { NULL } /* Sentinel. */ }; diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp index 7da94c4..9acc433 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint.exp @@ -117,6 +117,33 @@ gdb_test "end" gdb_py_test_silent_cmd "python blist = gdb.breakpoints()" "Get Breakpoint List" 0 gdb_test "python print blist\[len(blist)-1\].commands" "print \"Command for breakpoint has been executed.\".*print result" +# Start with a fresh gdb. +clean_restart ${testfile} + +if ![runto_main] then { + fail "Cannot run to main." + return 0 +} + +# Test invisible breakpooints. +delete_breakpoints +set ibp_location [gdb_get_line_number "Break at multiply."] +gdb_py_test_silent_cmd "python ibp = gdb.Breakpoint(\"$ibp_location\", internal=False)" "Set invisible breakpoint" 0 +gdb_py_test_silent_cmd "python ilist = gdb.breakpoints()" "Get Breakpoint List" 0 +gdb_test "python print ilist\[0\]" "" "Check invisible bp obj exists" +gdb_test "python print ilist\[0\].location" "py-breakpoint\.c:$ibp_location*" "Check breakpoint location" +gdb_test "python print ilist\[0\].visible" "True" "Check breakpoint visibility" +gdb_test "info breakpoints" "py-breakpoint\.c:$ibp_location.*" "Check info breakpoints shows visible breakpoints" +delete_breakpoints +gdb_py_test_silent_cmd "python ibp = gdb.Breakpoint(\"$ibp_location\", internal=True)" "Set invisible breakpoint" 0 +gdb_py_test_silent_cmd "python ilist = gdb.breakpoints()" "Get Breakpoint List" 0 +gdb_test "python print ilist\[0\]" "" "Check invisible bp obj exists" +gdb_test "python print ilist\[0\].location" "py-breakpoint\.c:$ibp_location*" "Check breakpoint location" +gdb_test "python print ilist\[0\].visible" "False" "Check breakpoint visibility" +gdb_test "info breakpoints" "No breakpoints or watchpoints.*" "Check info breakpoints does not show invisible breakpoints" +gdb_test "maint info breakpoints" "py-breakpoint\.c:$ibp_location.*" "Check maint info breakpoints shows invisible breakpoints" + + # Watchpoints # Start with a fresh gdb. clean_restart ${testfile} diff --git a/gdb/varobj.c b/gdb/varobj.c index 56cb8ae..2f2e469 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -39,8 +39,6 @@ #if HAVE_PYTHON #include "python/python.h" #include "python/python-internal.h" -#else -typedef int PyObject; #endif /* Non-zero if we want to see trace of varobj level stuff. */