-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test failure on Python 3.12 beta #298
Comments
As far as I can tell this is simply trying to detect whether the Python object is a negative number, and the commit which added the assertion added the following:
But of course this is private, which makes me wonder how we're intended to detect this? |
Oof, PyLong *zero = PyLong_FromLong(0);
if (zero) handle error;
int is_negative = PyObject_RichCompareBool(literal, zero, Py_LT);
if (is_negative < 0) handle error;
... I don't know if this would have any performance impact. Most importantly, If it is significantly slower, it looks like the internal headers are still installed publicly, so we might be able to use |
We could alternatively rely on the idea that a negative number would be an overflow error for an unsigned integer... And use the "better to ask forgiveness than permission" approach:
This passes tests on 3.11 and 3.12 |
Maybe it's easier to read the function rather than the diff :) bool is_negative = false;
uint64_t uvalue = PyLong_AsUint64(literal);
/* If overflow, it may be negative, assume so and retry */
if (uvalue == (uint64_t)-1 && PyErr_Occurred() &&
PyErr_ExceptionMatches(PyExc_OverflowError)) {
is_negative = true;
PyErr_Clear();
literal = PyNumber_Negative(literal);
if (!literal)
return -1;
uvalue = PyLong_AsUint64(literal);
Py_DECREF(literal);
}
if (uvalue == (uint64_t)-1 && PyErr_Occurred())
return -1;
err = drgn_object_integer_literal(res, uvalue);
if (!err && is_negative)
err = drgn_object_neg(res, res); |
I like it! I was worried about stuff which actually overflows (>= 2^64 or <= -2^64), but I think the second |
Running tests on Python 3.12, we get: test_int (tests.test_language_c.TestLiteral.test_int) ... python3.12: /usr/include/python3.12/object.h:215: Py_SIZE: Assertion `ob->ob_type != &PyLong_Type' failed. Aborted (core dumped) We're relying on an implementation detail to check whether the object is negative. Instead, catch an overflow error, negate and try again. Genuine overflows will still overflow on the second time, but negative numbers will succeed. Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
While this was encountered on a separate branch from main, and it reproduces on main as well. The manylinux Docker image now has 3.12 beta in its list of interpreters, and I got a test failure building wheels:
Git blame for the assertion shows it was added in python/cpython@7559f5f, related to python/cpython#101291.
I found the easiest way to reproduce (if you don't already have Python3.12 beta installed) was on Arch:
The coredump generated by the assertion shows the failure in
DrgnObject_literal
.The text was updated successfully, but these errors were encountered: