Skip to content
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

Add assertions that non-reentrant functions aren't called reentrantly #1591

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mdouglass
Copy link

@mdouglass mdouglass commented Jun 18, 2021

This is a draft version of this PR and is not ready to merge as-is. I'm opening it to get feedback on it before finishing the work.

While working on nodejs/node#38964 (and related question at #1590), I built this functionality in nghttp2_session.c to detect when the end-user of the library makes reentrant calls to nghttp2 from a callback in violation of the rules at https://nghttp2.org/documentation/programmers-guide.html#remarks. This was very helpful for me in verifying that I had correctly fixed the issue in node.js and thought it might be useful to have in nghttp2 DEBUGBUILDs.

As written, there are two different versions of this change.

  1. At line 213/216 are examples of using a macro to hide the modification of the tracking variable at_callback_depth.
  2. At line 1225/1228/1232 are examples of manually managing the tracking variable.

Option 1 uses a macro with some gcc extensions that I'm not sure are acceptable to the project.

Option 2 is much more prone to error now (as you need to make sure to track on each half of an if statement since the code tends to write if (callback)) and in the future as you need to remember to increment/decrement at_callback_depth in new code.

There's an option 3 that flattens some of the callback code to avoid the if issue. That is, changing:

++session->at_callback_depth;
if (session->callbacks.on_stream_close_callback(
        session, stream_id, error_code, session->user_data) != 0) {
  --session->at_callback_depth;

  return NGHTTP2_ERR_CALLBACK_FAILURE;
}
--session->at_callback_depth;

to this:

++session->at_callback_depth;
rv = session->callbacks.on_stream_close_callback(
        session, stream_id, error_code, session->user_data);
--session->at_callback_depth;
if (rv != 0) {
  return NGHTTP2_ERR_CALLBACK_FAILURE;
}

I should also note that my intention is for this code to only be active in DEBUGBUILDs but that is not done in the draft PR.

I'm happy to polish this up, but was looking for early feedback on the following:

  1. Is there any interest in this change?
  2. Is there a preference between options 1/2/3 or do you have another suggestion about how to inject the tracking variable.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant