Skip to content

mobile: check for pending exceptions after JNI call#24361

Merged
Augustyniak merged 20 commits intomainfrom
checking-for-exceptions-after-headers
Dec 7, 2022
Merged

mobile: check for pending exceptions after JNI call#24361
Augustyniak merged 20 commits intomainfrom
checking-for-exceptions-after-headers

Conversation

@Augustyniak
Copy link
Contributor

@Augustyniak Augustyniak commented Dec 5, 2022

Commit Message: Check for pending exceptions after some of the Java calls from within the JNI layer. At Lyft, we noticed that we have a bunch of crashes related to us not checking for exceptions after on_request_headers or/and on_response_headers methods.
Additional description: I tried to use ENVOY_LOG_EVENT_TO_LOGGER to log when we detect a pending exception but ran into issues with deadlocks. Got rid of the extra logging to unblock my change.
Risk Level: Low, mostly additive change. New code executes for when the library crashes previously.
Testing: Integration test
Docs Changes:
Release Notes:
Platform Specific Features:

@repokitteh-read-only
Copy link

CC @envoyproxy/mobile-maintainers: FYI only for changes made to (mobile/).
envoyproxy/mobile-maintainers assignee is @alyssawilk

🐱

Caused by: #24361 was opened by Augustyniak.

see: more, trace.

Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
This reverts commit 479b7f8936a9e50c25be20ed798347042ebcfda6.

Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
@Augustyniak Augustyniak force-pushed the checking-for-exceptions-after-headers branch from 8ac1784 to f566610 Compare December 6, 2022 13:19
Copy link
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

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

cool, thanks for tackling this!
/wait

// JvmCallbackContext

static void pass_headers(const char* method, envoy_headers headers, jobject j_context) {
static void pass_headers(const char* method, const Envoy::Types::ManagedEnvoyHeaders& headers,
Copy link
Contributor

Choose a reason for hiding this comment

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

I thought these all had to be simple (C) types. can you clue me in on why it's OK use ManagedEnvoyHeaders?

edit: nm I think I see why. if this isn't called from Java layers can we use standard passHeaders naming to make that clear?

Copy link
Contributor Author

@Augustyniak Augustyniak Dec 6, 2022

Choose a reason for hiding this comment

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

I thought these all had to be simple (C) types. can you clue me in on why it's OK use ManagedEnvoyHeaders?

the usage of c types is a self-imposed limitations in many places in our code. Decided to use c++ type in here to make mem management simpler.

edit: nm I think I see why. if this isn't called from Java layers can we use standard passHeaders naming to make that clear?

OK

// TODO(Augustyniak): Pass the name of the filter in here so that we can instrument the origin of
// the JNI exception better.
if (exception_check(env)) {
env->DeleteLocalRef(j_stream_intel);
Copy link
Contributor

Choose a reason for hiding this comment

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

can the DeleteLocalRefs be moved outside of the exception check? alternately if the exception check needs to happen before deletion
bool saw_exception = exception_check(env)
deletelocalRef
deletelocalRef
if (saw_exception) {...

env->DeleteLocalRef(j_stream_intel);
env->DeleteLocalRef(jcls_JvmCallbackContext);

return result;
Copy link
Contributor

Choose a reason for hiding this comment

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

to proxy Ryan, let's do this first, and do
if (!exception) {
return result
}
// handle exception

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thank you @RyanTheOptimist :)

jobject result =
env->CallObjectMethod(j_context, jmid_onComplete, j_stream_intel, j_final_stream_intel);

exception_check(env);
Copy link
Contributor

Choose a reason for hiding this comment

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

comment on why it's Ok to clear without handling?

jni_delete_global_ref(const_cast<void*>(context));
}

bool exception_check(JNIEnv* env) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd be inclined to ABSL_MUST_USE_RESULT for this. or at least make it clear we're clearing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do not think that it always have to be handled explicitly. Per ur suggestion, will change method's name to imply that it clears any pending exceptions

Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>
@Augustyniak Augustyniak force-pushed the checking-for-exceptions-after-headers branch from 0f8783f to bda8425 Compare December 6, 2022 21:38
Signed-off-by: Rafal Augustyniak <raugustyniak@lyft.com>

static void* jvm_on_headers(const char* method, envoy_headers headers, bool end_stream,
envoy_stream_intel stream_intel, void* context) {
static void* jvm_on_headers(const char* method, const Envoy::Types::ManagedEnvoyHeaders& headers,
Copy link
Contributor

Choose a reason for hiding this comment

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

this one isn't called by jvm directly either. optional nit onHeadersFromJvm or something

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's calling a method from the java world tho which I think is why it has a jvm prefix (pass_headers - now renamed to passHeaders- method did not havejvmprefix as it was/is not calling intojvm`).

I do not have a strong opinion in here but will keep the things they are until we figure out new naming patterns for this file - ideally in a separate PR.

@Augustyniak Augustyniak merged commit d3d4a01 into main Dec 7, 2022
@Augustyniak Augustyniak deleted the checking-for-exceptions-after-headers branch December 7, 2022 20:34
jpsim added a commit that referenced this pull request Dec 8, 2022
…-cpp-to-latest-version

* origin/main: (23 commits)
  Reduce Route memory utilization by avoiding RuntimeData instances when not needed (#24327)
  build: fix compile error for mac (#24429)
  postgres: support for upstream SSL (#23990)
  iOS: split `EnvoyEngine.h` into multiple header files (#24397)
  mobile: check for pending exceptions after JNI call (#24361)
  Remove uneccessary `this->` from mobile engine builder (#24389)
  Add setRequestDecoder to ResponseEncoder interface (#24368)
  downstream: refactoring code to remove listener hard deps (#24394)
  lb api: moving load balancing policy specific configuration to extension configuration (#23967)
  ci: Skip docker/examples verification for docs or mobile only changes (#24417)
  ci: run mobile GitHub Actions on every PR (#24407)
  mobile: remove `bump_lyft_support_rotation.sh` script (#24404)
  Add file size to DirectoryEntry (#24176)
  bazel: update to 6.0.0rc4 (#24235)
  bazel: update rules_rust (#24409)
  Ecds config dump recommit (#24384)
  bazel: add another config_setting incompatible flag (#24270)
  listeners: moving listeners to extension directory (#24248)
  mobile: build Swift with whole module optimization (#24396)
  ci: update `actions/setup-java` from v1 to v3.8 (#24393)
  ...

Signed-off-by: JP Simard <jp@jpsim.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants