From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id EAqkAHLizWryrz8AWB0awg (envelope-from ) for ; Tue, 13 Oct 2026 03:49:06 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QaYgBBG/; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id CA9FD1E051; Tue, 13 Oct 2026 03:49:05 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 607651E047 for ; Tue, 13 Oct 2026 03:49:04 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6438E4BA23FA for ; Tue, 13 Oct 2026 07:48:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6438E4BA23FA Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QaYgBBG/ Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 496944BA23FD for ; Tue, 13 Oct 2026 07:48:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 496944BA23FD Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 496944BA23FD Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791877688; cv=none; b=tLebUnKIwOmBXDOvFTQN0cTZ0KsRT2Wo/81qktQf8b8MYgYDAgb85lxeIbfrbZnINDkn+nZe/RROWo+e4C20KwcxvZ3zYkapmGdZ6ekevKgZ+04KuV+aYLfjfR7cp0m4k+6EbFYK6n/LbpUzPfa46zMr21CB1e04ZaGldy9sHIs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791877688; c=relaxed/simple; bh=8oD32rItSf62rCRrJHjtR2GeYCn49GVmngVeIFiRfTA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=LKkHLn9t63ILK7mkvYjp1ZEQtuI9HHGcmebcOQqmpUmU5+/3KH4+W1Gqz/e1UaX9MzX7K54FlzHwC3U+0wup0spZo95fj5yNGamXCImxkxjQZQKcqHHBGXhEx9ULQ/Rmr4DRG2JCaAX6yB5T3Ar5gsPbtZyXaVS9CDofZ+aPTkU= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QaYgBBG/ DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 496944BA23FD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1791877687; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bCTNMmYoZs6sk0yFU2yqW5Ff8xVbLLaeljPUaPgkTJ4=; b=QaYgBBG/yZXJH2chkC8ckYPw99v2y1fjJ+J08JcmNzJ9ep3Yl+8Xv/oJv3c5ziCC+ElS5l /Zhu8b3fJCdTsIJMIjRqvoDhdgm4hiSOyJBQFVAOBUKd2FCOiklKrg/HAtN+CnUqoy+lkP 4unsiBwSDAt7I/PmemMREhIudJMJBVA= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-32-4S19pXg-NJ2r3mho6PIYag-1; Tue, 13 Oct 2026 07:48:06 +0000 X-MC-Unique: 4S19pXg-NJ2r3mho6PIYag-1 X-Mimecast-MFC-AGG-ID: 4S19pXg-NJ2r3mho6PIYag_1791877685 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4a1721559b4so28186825e9.1 for ; Tue, 13 Oct 2026 00:48:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791877685; x=1792482485; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=bCTNMmYoZs6sk0yFU2yqW5Ff8xVbLLaeljPUaPgkTJ4=; b=h3t6zv8ocgv5M7g2aNuVu90zh1x4cmztdz78fiUO/smvIoBBUbtiyeHXFcdg+nK7/E u5EpN3kkD9TG5h2E9jFsiI4UQIocHRRb+LQXU2pThq8j4u4yZqbgAgv4juVhgIPyNpoT VmR3tW7nyTGk7i2nPJcWKs1Gd9hzAX9KcKyMJpmSiPWc1pzzZWf5tZvAv1/Ia9lI43qG mZZZl/gRH6CcnXDVccdA9S8JYt0bV2n3f3UhNPup/YX0YPFXyIJUHTl9nS+CEM1kR25s c0P0pVfEbtSPr1KEk+o9xF5tNGKkjFT+T/wIUP3opxV35pSVNGthlHn4yIvbssp4/q76 w60Q== X-Gm-Message-State: AFq9FYLVq+dlJpanj6yesc0OKA0ridTQAK5+eUzZV7Wri9ytTbmbPjp5 CS1Yeq1Ol0j14WkN++m9RU8qSxjfUk5B3rC5y2ZUu9Xc0NlX2PMxaH+dENdSGfLmGhRqcw4seUt rGl59x9pKguFb1anROeuw5mcbc4BsruwldZZE4Aj6OwXaCtzUy/FEelNZKy0yOv+EXMwnMm6uLB c8Y2k8iWgvDUeKg+QDxjGLgBmwGBGKRa0hX7aGQP5BOoRolhUOkQ== X-Gm-Gg: AYBFou3tt3rlEf+bY3NHkN1gsz4E4tPgj2u32WR7wDAF/0xc4AplSGGjIaKHCuql/WO TgyJZmkslOHkufmNPyJJ/8DpnjqInXGnq6sVXBb24jBhyzI8gYixXukA0IUl58lHmOC0vhBD/Lw 3yiNDEYNkZS2XPSoY4cbsr6985ZCOGT5vPeuXlOIicLJcBFdzNr2CDNXOusSchbpbYZYksRmvA1 JnyBRIGUj7Ktxrd4/06zj/q+RkwE7yW0DrBvJUscQea0GX55jvEQaMlWNLn9LpFnJS5MV9wf0gU w5ym/arzljyv+MpPYHZ/SnzJFbjpA4ygo1Z2+rTO+ZlQW3kfjyOi+ka8BOVD2IW0wAGs3kqH20L ahARX4mpXW0GsKP4qAw== X-Received: by 2002:a05:600c:3e8d:b0:4a1:7701:f863 with SMTP id 5b1f17b1804b1-4a18e4aeae4mr213724185e9.15.1791877684723; Tue, 13 Oct 2026 00:48:04 -0700 (PDT) X-Received: by 2002:a05:600c:3e8d:b0:4a1:7701:f863 with SMTP id 5b1f17b1804b1-4a18e4aeae4mr213723785e9.15.1791877684112; Tue, 13 Oct 2026 00:48:04 -0700 (PDT) Received: from redhat.com ([213.175.46.86]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a192d3efb6sm212261605e9.1.2026.10.13.00.48.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Oct 2026 00:48:03 -0700 (PDT) From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= To: gdb-patches@sourceware.org Cc: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Subject: [PATCH] gdb/python: add allow_pending parameter to gdb.Breakpoint constructor Date: Tue, 13 Oct 2026 09:47:50 +0200 Message-ID: <20261013074751.754142-1-thrnciar@redhat.com> X-Mailer: git-send-email 2.55.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: dfGPx1QSgJDaTML59gluuIeM0UMt9h6bJfnxzwEbNe4_1791877685 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org Add a new allow_pending parameter to the gdb.Breakpoint constructor. Setting the new parameter to False causes GDB to raise an error instead of creating a pending breakpoint. By default this parameter is True, which allows pending breakpoints to be created, preserving the existing behaviour. --- gdb/NEWS | 6 ++ gdb/doc/python.texi | 17 +++-- gdb/python/py-breakpoint.c | 16 +++-- gdb/testsuite/gdb.python/py-breakpoint.exp | 82 ++++++++++++++++++++-- 4 files changed, 109 insertions(+), 12 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 5d0c4745653..eb637a21724 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -79,6 +79,12 @@ info locals The new "-shadowed on|off" option overrides the "set print shadowed" setting for a single invocation of the command. +* Python API + + ** The gdb.Breakpoint constructor now takes an optional + 'allow_pending' argument. Setting it to False causes GDB to raise + an error instead of creating a pending breakpoint. + *** Changes in GDB 18 * Support for the Common Trace Format (CTF) has been removed. GDB now diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index ddb347361f7..0b24698a77f 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -6953,7 +6953,7 @@ create both breakpoints and watchpoints. The second accepts separate Python arguments similar to @ref{Explicit Locations}, and can only be used to create breakpoints. -@defun Breakpoint.__init__ (spec @r{[}, type @r{][}, wp_class @r{][}, internal @r{][}, temporary @r{][}, qualified @r{]}) +@defun Breakpoint.__init__ (spec @r{[}, type @r{][}, wp_class @r{][}, internal @r{][}, temporary @r{][}, qualified @r{][}, allow_pending @r{]}) Create a new breakpoint according to @var{spec}, which is a string naming the location of a breakpoint, or an expression that defines a watchpoint. The string should describe a location in a format recognized by the @code{break} @@ -6983,16 +6983,25 @@ the function passed in @code{spec} as a fully-qualified name. It is equivalent to @code{break}'s @code{-qualified} flag (@pxref{Linespec Locations} and @ref{Explicit Locations}). +The optional @var{allow_pending} argument is a boolean that controls whether +the created breakpoint can be pending or not +(@pxref{Set Breaks,,Pending Breakpoints}). The @var{allow_pending} argument is +set to @code{True} by default and is only considered when @var{type} is +@code{gdb.BP_BREAKPOINT} or @code{gdb.BP_HARDWARE_BREAKPOINT}. If +the @var{allow_pending} argument is set to @code{False} and the breakpoint +location cannot be resolved, a @code{gdb.error} exception is raised +instead of creating a pending breakpoint. + @end defun -@defun Breakpoint.__init__ (@r{[} source @r{][}, function @r{][}, label @r{][}, line @r{]}, @r{][} internal @r{][}, temporary @r{][}, qualified @r{]}) +@defun Breakpoint.__init__ (@r{[} source @r{][}, function @r{][}, label @r{][}, line @r{]}, @r{][} internal @r{][}, temporary @r{][}, qualified @r{][}, allow_pending @r{]}) This second form of creating a new breakpoint specifies the explicit location (@pxref{Explicit Locations}) using keywords. The new breakpoint will be created in the specified source file @var{source}, at the specified @var{function}, @var{label} and @var{line}. -@var{internal}, @var{temporary} and @var{qualified} have the same usage as -explained previously. +@var{internal}, @var{temporary}, @var{qualified} and @var{allow_pending} have +the same usage as explained previously. @end defun The available types are represented by constants defined in the @code{gdb} diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index b1615db1be3..7261bd8e25b 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -914,7 +914,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) { static const char *keywords[] = { "spec", "type", "wp_class", "internal", "temporary","source", "function", - "label", "line", "qualified", NULL }; + "label", "line", "qualified", + "allow_pending", nullptr }; const char *spec = NULL; enum bptype type = bp_breakpoint; int access_type = hw_write; @@ -928,13 +929,16 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) char *source = NULL; char *function = NULL; PyObject *qualified = Py_False; + PyObject *allow_pending = Py_True; - if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|siiOOsssOO!", keywords, + if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|siiOOsssOO!O!", + keywords, &spec, &type, &access_type, &internal, &temporary, &source, &function, &label, &lineobj, - &PyBool_Type, &qualified)) + &PyBool_Type, &qualified, + &PyBool_Type, &allow_pending)) return -1; @@ -1022,12 +1026,16 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) const struct breakpoint_ops *ops = breakpoint_ops_for_location_spec (locspec.get (), false); + auto_boolean pending_enabled + = (allow_pending == Py_True + ? AUTO_BOOLEAN_TRUE + : AUTO_BOOLEAN_FALSE); create_breakpoint (gdbpy_enter::get_gdbarch (), locspec.get (), NULL, -1, -1, NULL, false, 0, temporary_bp, type, 0, - AUTO_BOOLEAN_TRUE, + pending_enabled, ops, 0, 1, internal_bp, 0); break; diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp index 8b19a11b1f6..c78a321d055 100644 --- a/gdb/testsuite/gdb.python/py-breakpoint.exp +++ b/gdb/testsuite/gdb.python/py-breakpoint.exp @@ -628,10 +628,82 @@ proc_with_prefix test_bkpt_address {} { } proc_with_prefix test_bkpt_pending {} { + global srcfile testfile + + clean_restart ${testfile} + delete_breakpoints gdb_breakpoint "nosuchfunction" -allow-pending gdb_test "python print (gdb.breakpoints()\[0\].pending)" "True" \ "Check pending status of pending breakpoint" + + delete_breakpoints + with_test_prefix "allow_pending=True" { + gdb_test "python bp1 = gdb.Breakpoint (source=\"$srcfile\",\ + line=\"900\", allow_pending=True)" \ + [multi_line \ + "^No compiled code for line 900 in file \[^\r\n\]+\\." \ + "Breakpoint $::decimal \[^\r\n\]+ pending\\."] \ + "set pending explicit breakpoint by source and missing line" + gdb_test_no_output "python assert(bp1.pending)" \ + "verify pending explicit breakpoint created for missing line" + gdb_test "python bp1 = gdb.Breakpoint (function=\"blah\",\ + allow_pending=True)" \ + [multi_line \ + "Function \"blah\" not defined.*" \ + "Breakpoint $::decimal \[^\r\n\]+ pending\\."] \ + "set pending explicit breakpoint by missing function" + gdb_test_no_output "python assert(bp1.pending)" \ + "verify pending explicit breakpoint created for missing function" + gdb_test "python bp1 = gdb.Breakpoint (\"missing_function\",\ + allow_pending=True)" \ + [multi_line \ + "Function \"missing_function\" not defined.*" \ + "Breakpoint $::decimal \[^\r\n\]+ pending\\."] \ + "set pending breakpoint by missing function" + gdb_test_no_output "python assert(bp1.pending)" \ + "verify pending breakpoint created for missing function" + gdb_test_no_output "python assert(len(gdb.breakpoints()) == 3)" \ + "verify expected number of pending breakpoints were created" + } + + delete_breakpoints + with_test_prefix "allow_pending=False" { + gdb_test "python bp1 = gdb.Breakpoint (source=\"$srcfile\",\ + line=\"900\", allow_pending=False)" \ + [multi_line \ + "Python Exception : No compiled code for\ + line 900 in file \[^\r\n\]+\\." \ + "Error occurred in Python: No compiled code for line 900 in\ + file \[^\r\n\]+\\."] \ + "set invalid explicit breakpoint by source and missing line" + gdb_test "python bp1 = gdb.Breakpoint (function=\"blah\",\ + allow_pending=False)" \ + [multi_line \ + "Python Exception : Function \"blah\" not\ + defined\\." \ + "Error occurred in Python: Function \"blah\" not defined\\."] \ + "set invalid explicit breakpoint by missing function" + gdb_test "python bp1 = gdb.Breakpoint (\"missing_function\",\ + allow_pending=False)" \ + [multi_line \ + "Python Exception : Function\ + \"missing_function\" not defined\\." \ + "Error occurred in Python: Function \"missing_function\" not\ + defined\\."] \ + "set invalid breakpoint by missing function" + gdb_test_no_output "python assert(len(gdb.breakpoints()) == 0)" \ + "verify no pending breakpoints were created" + } + + # Test allow_pending with a non-bool type. + delete_breakpoints + gdb_test "python gdb.Breakpoint (\"multiply\", allow_pending=None)" \ + [multi_line \ + "Python Exception : argument 11 must be bool,\ + not None" \ + "Error occurred in Python: argument 11 must be bool, not None"] \ + "allow_pending non_bool_type" } # Helper proc to install an event listener for a given breakpoint @@ -744,12 +816,14 @@ proc_with_prefix test_bkpt_explicit_loc {} { "set invalid explicit breakpoint by missing source and line" gdb_test "python bp1 = gdb.Breakpoint (source=\"$srcfile\", line=\"900\")" \ [multi_line \ - "^No compiled code for line 900 in file \"$srcfile\"\\." \ + "^No compiled code for line 900 in file \[^\r\n\]+\\." \ "Breakpoint $::decimal \[^\r\n\]+ pending\\."] \ - "set invalid explicit breakpoint by source and invalid line" + "set pending explicit breakpoint by source and missing line" gdb_test "python bp1 = gdb.Breakpoint (function=\"blah\")" \ - "Function \"blah\" not defined.*" \ - "set invalid explicit breakpoint by missing function" + [multi_line \ + "Function \"blah\" not defined.*" \ + "Breakpoint $::decimal \[^\r\n\]+ pending\\."] \ + "set pending explicit breakpoint by missing function" delete_breakpoints gdb_test "catch throw" "Catchpoint .* \\(throw\\)" -- 2.55.0