Skip to content

Conversation

@mattip
Copy link
Member

@mattip mattip commented Dec 14, 2018

PR #12524 introduced a refcount issue. Changing the interface to PyUFuncOverride_GetOutObjects so that *out_kwd_obj is never a borrowed reference should fix it.

PyObject *seq = PySequence_Fast(*out_kwd_obj, "Could not convert object to sequence");
PyObject *seq;
int ret;
Py_INCREF(*out_kwd_obj);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is necessary, and it think it leaks if seq == NULL.

I think you should:

  • Remove this line
  • Add *out_kwd_obj = NULL in the error path below
  • Replace Py_SETREF(*out_kwd_obj, seq); with *out_kwd_obj = seq

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the calling convention for PyUFuncOverride_GetOutObjects is that *out_kwd_obj is a borrowed reference, who will decref seq?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the missing decref if seq == NULL

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, nvrmind. I didn't read your comment correctly. Fixing as per your reccomendation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you can now reorder these to eliminate the ret variable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed, if it errors then it produced no new reference

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Member

@eric-wieser eric-wieser Dec 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can never be null here, so plain DECREF is fine.

Edit: This becomes true if you return None rather than NULL

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems simpler to me to return NULL in out_kwd_obj. Is there a style guide ref for things like that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no reference to give here, but I've might exist. One argument I can give in favor is that it allows you to eliminate the branching that happens inside XDECREF.

I might need to remind myself tomorrow about why this argument exists in the first place though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this argument exists in the first place

We need it to hang on to a reference to the result of PySequence_Fast.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think to make refcounting easier, it would be tidier to return a new reference to Py_None here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@charris charris added this to the 1.16.0 release milestone Dec 14, 2018
@charris
Copy link
Member

charris commented Dec 16, 2018

Be good to finish this up, I'd like to release 1.12.0rc1 tomorrow.

@eric-wieser
Copy link
Member

seems a little late for me to release 1.12.0rc1 ;)

seq = PySequence_Fast(*out_kwd_obj,
"Could not convert object to sequence");
if (seq == NULL) {
return -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably set *out_kwd_obj = NULL here just to be safe.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@charris
Copy link
Member

charris commented Dec 17, 2018

Restart tests.

@charris charris closed this Dec 17, 2018
@charris charris reopened this Dec 17, 2018
@charris charris closed this Dec 17, 2018
@charris charris reopened this Dec 17, 2018
@charris charris merged commit 38236fb into numpy:master Dec 17, 2018
@charris
Copy link
Member

charris commented Dec 17, 2018

Thanks Matti, Eric.

@charris charris removed the 09 - Backport-Candidate PRs tagged should be backported label Dec 17, 2018
@charris charris removed this from the 1.16.0 release milestone Dec 17, 2018
@mattip mattip deleted the pypy-fixes2 branch May 20, 2019 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants