GH-93249: relax overly strict assertion on bounds->ar_start (GH-93961) (GH-94032)

(cherry picked from commit 1603a1029f)

Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>

Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2022-06-20 09:42:51 -07:00 committed by GitHub
parent e6ad59934e
commit 26329e49ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 2 deletions

View file

@ -4,6 +4,7 @@ from collections import namedtuple
from io import StringIO from io import StringIO
import linecache import linecache
import sys import sys
import types
import inspect import inspect
import unittest import unittest
import re import re
@ -1129,7 +1130,7 @@ boundaries = re.compile(
class BaseExceptionReportingTests: class BaseExceptionReportingTests:
def get_exception(self, exception_or_callable): def get_exception(self, exception_or_callable):
if isinstance(exception_or_callable, Exception): if isinstance(exception_or_callable, BaseException):
return exception_or_callable return exception_or_callable
try: try:
exception_or_callable() exception_or_callable()
@ -1851,6 +1852,31 @@ class BaseExceptionReportingTests:
report = self.get_report(exc) report = self.get_report(exc)
self.assertEqual(report, expected) self.assertEqual(report, expected)
def test_KeyboardInterrupt_at_first_line_of_frame(self):
# see GH-93249
def f():
return sys._getframe()
tb_next = None
frame = f()
lasti = 0
lineno = f.__code__.co_firstlineno
tb = types.TracebackType(tb_next, frame, lasti, lineno)
exc = KeyboardInterrupt()
exc.__traceback__ = tb
expected = (f'Traceback (most recent call last):\n'
f' File "{__file__}", line {lineno}, in f\n'
f' def f():\n'
f'\n'
f'KeyboardInterrupt\n')
report = self.get_report(exc)
# remove trailing writespace:
report = '\n'.join([l.rstrip() for l in report.split('\n')])
self.assertEqual(report, expected)
class PyExcReportingTests(BaseExceptionReportingTests, unittest.TestCase): class PyExcReportingTests(BaseExceptionReportingTests, unittest.TestCase):
# #

View file

@ -768,6 +768,11 @@ next_code_delta(PyCodeAddressRange *bounds)
static int static int
previous_code_delta(PyCodeAddressRange *bounds) previous_code_delta(PyCodeAddressRange *bounds)
{ {
if (bounds->ar_start == 0) {
// If we looking at the first entry, the
// "previous" entry has an implicit length of 1.
return 1;
}
const uint8_t *ptr = bounds->opaque.lo_next-1; const uint8_t *ptr = bounds->opaque.lo_next-1;
while (((*ptr) & 128) == 0) { while (((*ptr) & 128) == 0) {
ptr--; ptr--;
@ -811,7 +816,7 @@ static void
retreat(PyCodeAddressRange *bounds) retreat(PyCodeAddressRange *bounds)
{ {
ASSERT_VALID_BOUNDS(bounds); ASSERT_VALID_BOUNDS(bounds);
assert(bounds->ar_start > 0); assert(bounds->ar_start >= 0);
do { do {
bounds->opaque.lo_next--; bounds->opaque.lo_next--;
} while (((*bounds->opaque.lo_next) & 128) == 0); } while (((*bounds->opaque.lo_next) & 128) == 0);