Skip to content

fix(inspector): Fix app crashes on second debugger attach#835

Merged
mbektchiev merged 12 commits intoreleasefrom
tdermendzhiev/fix-crash-on-debugging
Jan 3, 2018
Merged

fix(inspector): Fix app crashes on second debugger attach#835
mbektchiev merged 12 commits intoreleasefrom
tdermendzhiev/fix-crash-on-debugging

Conversation

@tdermendjiev
Copy link
Copy Markdown
Contributor

@tdermendjiev tdermendjiev commented Dec 11, 2017

Introduction

We identified a couple of issues with the way connections are handled between the Inspector and the backend. On one side, the sockets were not handled correctly using the Dispatch API resulting in faulty connections upon subsequent connection attempts.
On the other side, there was an issue with the way Backend Dispatchers were handled via RefPtrs. For example, the DomainBackendDispatcher adopts a pointer to the dispatcher created by the DomainInspectorAgent, which also has a pointer to it. Adopting this pointer does not increase the refcount which in turn breaks the underlying object's (RefCountedBase) state.
The third amendment is in the way backend dispatchers are handled by the Agents in the didCreateFrontendAndBackend and willDestroyFrontendAndBackend calls. We now create a single instance of each dispatcher and leave it alive until the owning Agent is destroyed. This is the behaviour as seen in the vanilla WebKit source.

Fixes #832

  • After the debugger frontend is detached certain RefPtr properties are cleaned up and recreated on a subsequent connection which is causing a crash due to improper reference management. Making the m_backendDispatcher property persist between different connections fixes the bug.

  • Every time the debugger is detached the IO channel should be closed in order the next connection to be successful. Otherwise the connection attempt will fail with a bad descriptor error.

  • 153d45f addresses an issue with debugger delay killing the already existing listen connection at an inappropriate time. We do not need this delay to cancel the listen connection as we immediately close it after a successful frontend connection.

@ns-bot
Copy link
Copy Markdown

ns-bot commented Dec 11, 2017

Can one of the admins verify this patch?

@tdermendjiev tdermendjiev self-assigned this Dec 11, 2017
@ginev ginev force-pushed the tdermendzhiev/fix-crash-on-debugging branch 2 times, most recently from b626581 to 153d45f Compare December 12, 2017 08:43
Copy link
Copy Markdown
Contributor

@mbektchiev mbektchiev left a comment

Choose a reason for hiding this comment

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

Great job!

@mbektchiev mbektchiev added this to the 3.4.1 milestone Dec 13, 2017
@ginev
Copy link
Copy Markdown
Contributor

ginev commented Dec 18, 2017

@KristinaKoeva - could you please take a look at this PR and comment on the following questions:

  • why do we recreate the backend dispatchers when didCreateFrontendAndBackend is called and not use the pattern as seen in the WebKit's original source as pointed in Introduction section of the first comment?
  • regarding the handling of connection sockets - can you update us on why there is a 30s delay which closes the listening socket if no inspector is present?

tdermendjiev and others added 4 commits December 19, 2017 18:15
After the debugger frontend is detached certain RefPtr properties are cleaned up and recreated on a subsequent connection which is causing a crash due to improper reference management. Making the *m_backendDispatcher* property persist between different connections fixes the bug.
… session

Every time the debugger is detached the IO channel should be closed in
order the next connection to be successful.
Otherwise the connection attempt will fail with a bad descriptor error.
@mbektchiev mbektchiev force-pushed the tdermendzhiev/fix-crash-on-debugging branch from 153d45f to 429ef7f Compare December 19, 2017 16:26
@KristinaKoeva
Copy link
Copy Markdown
Contributor

The original webkit source was not the same at the time we wrote this logic :)
Take a look here - WebKit/WebKit@d81c28d

The delay is there because otherwise you will have an open socket for as long as the application lives.

Did the webkit update broke the second attach attempt ?

@ginev ginev changed the base branch from master to release December 20, 2017 08:54
@ginev
Copy link
Copy Markdown
Contributor

ginev commented Dec 20, 2017

@KristinaKoeva - thanks. This is helpful. The issue with the RefPtr objects comes because of the fact that we recreate the DomainBackendDispatcher each time. It registers with the main Backend Dispatcher's HashMap of dispatchers and chains its supplemental dispatchers. The first iteration of this is OK but the second one causes us to find an invalid RefPtr from the HashMap and chain it to our DomainBackendDispatcher here: https://github.com/NativeScript/ios-runtime/blob/master/src/NativeScript/inspector/DomainBackendDispatcher.cpp#L31-L33

Refactor connection and disconnection logic:

* Separate error and connection handlers
* Separate listen socket and data socket handling and disconnection
* Add method for checking whether there's an active frontend connection
* Reject any new connections when there's an active one
The code was deleted in one of the previous refactorings
* VM locks in TNSRuntime+Inspector
* Move catch scope declarations in locked sections
* Synchronize dispatch IO channel and global inspector variable access across worker threads - all callbacks may be called in an arbitrary thread and we need to make sure that they don't run simultaneously.
* Guard against deadlocks by always releasing the inspector lock before dealing with JSC VM
@mbektchiev mbektchiev force-pushed the tdermendzhiev/fix-crash-on-debugging branch from 69066e4 to 64a8a9b Compare December 22, 2017 14:50
if (inspector) {
return nil;
// Keep a working copy for calling into the VM after releasing inspectorLock
TNSRuntimeInspector* tempInspector = nil;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Move declaration to assignment line.

Comment thread src/debugging/TNSDebugging.h Outdated
//
// [inspector pause];
// });
// CFRunLoopWakeUp(runloop);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Delete commented block.

Comment thread src/debugging/TNSDebugging.h Outdated
tempInspector = inspector;
}

[tempInspector dispatchMessage:message];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Check whether inspector is null

@mbektchiev
Copy link
Copy Markdown
Contributor

run ci

…ous ones

This is consistent with the behavior of `AttachRequest` notification and it is more natural
for the last connection attempt to succeed instead of fail due to an already existing one.
@mbektchiev
Copy link
Copy Markdown
Contributor

run ci (after git clean -fdx in workspace)

…side of the VM lock

Native call is made outside of the VM lock by design.
For more information see #215 and it's corresponding PR.
This creates a racing condition which might corrupt the internal state of the VM but
a fix for it is outside of this PR's scope, so I'm leaving it as it has always been till now.

We could address the issue by reimplementing the feature with a new VM or a JSWorker.
self->_inspectorController->pause();
}

- (bool)hasFrontends {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We might delete this method as it's never called.

* Remove unused `hasFrontends` method
* Delete forgotten clearing of `m_frontendDispatcher`
* Remove commented code for delegating `pause` to the main loop
@ginev
Copy link
Copy Markdown
Contributor

ginev commented Jan 2, 2018

It might be good to rename this to be receiver as it rights to the io channel and is analogous to the sender block here.

@ginev ginev closed this Jan 2, 2018
@ginev ginev reopened this Jan 2, 2018
@ns-bot
Copy link
Copy Markdown

ns-bot commented Jan 2, 2018

Can one of the admins verify this patch?

@mbektchiev
Copy link
Copy Markdown
Contributor

run ci

@mbektchiev mbektchiev force-pushed the tdermendzhiev/fix-crash-on-debugging branch from d186dc7 to bb70e82 Compare January 3, 2018 08:27
@mbektchiev mbektchiev force-pushed the tdermendzhiev/fix-crash-on-debugging branch from bb70e82 to c59d709 Compare January 3, 2018 09:02
Copy link
Copy Markdown
Contributor

@mbektchiev mbektchiev left a comment

Choose a reason for hiding this comment

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

@mbektchiev mbektchiev merged commit 906abd3 into release Jan 3, 2018
@mbektchiev mbektchiev deleted the tdermendzhiev/fix-crash-on-debugging branch January 3, 2018 09:16
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.

5 participants