Title: Exceptions in constructors causes v8 GC to fail with access violations · Issue #635 · nodejs/node-addon-api · GitHub
Open Graph Title: Exceptions in constructors causes v8 GC to fail with access violations · Issue #635 · nodejs/node-addon-api
X Title: Exceptions in constructors causes v8 GC to fail with access violations · Issue #635 · nodejs/node-addon-api
Description: Hey folks, If an exception is thrown from inside a constructor it seems it causes v8 GC to fail with an access violation in this case below. I am starting to think that this is caused by ObjectWrap
Open Graph Description: Hey folks, If an exception is thrown from inside a constructor it seems it causes v8 GC to fail with an access violation in this case below. I am starting to think that this is caused by ObjectWrap...
X Description: Hey folks, If an exception is thrown from inside a constructor it seems it causes v8 GC to fail with an access violation in this case below. I am starting to think that this is caused by ObjectWrap...
Opengraph URL: https://github.com/nodejs/node-addon-api/issues/635
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Exceptions in constructors causes v8 GC to fail with access violations","articleBody":"Hey folks,\r\nIf an exception is thrown from inside a constructor it seems it causes v8 GC to fail with an access violation in this case below. I am starting to think that this is caused by ```ObjectWrap\u003cT\u003e::FinalizeCallback``` being called when it shouldn't be.\r\n\r\nHere is the example code if you want to try it out quickly https://github.com/blagoev/node-addon-examples/commit/351752fab1b93068aaf84a9cc52d086170778f74\r\n\r\nThe highlights are these.\r\n\r\nThere is a static factory function on the exposed object\r\n\r\n```C++\r\nNapi::Value create(const Napi::CallbackInfo\u0026 info) {\r\n\tNapi::EscapableHandleScope scope(info.Env());\r\n\tNapi::Value val = MyObject::constructor.New({}); //this will throw an exception\r\n\r\n\treturn scope.Escape(info.Env().Undefined());\r\n}\r\n```\r\n\r\nthen the ctor throws some error\r\n\r\n```C++\r\nMyObject::MyObject(const Napi::CallbackInfo\u0026 info)\r\n\t: Napi::ObjectWrap\u003cMyObject\u003e(info) {\r\n\tNapi::Env env = info.Env();\r\n\tNapi::HandleScope scope(env);\r\n\tthrow Napi::Error::New(env, \"TEST\");\r\n......\r\n```\r\n\r\nand we have this private field in the class\r\n```C++\r\nstruct Data {\r\n};\r\n\r\nclass MyObject : public Napi::ObjectWrap\u003cMyObject\u003e {\r\nprivate:\r\n\tstd::shared_ptr\u003cData\u003e m_data;\r\n....\r\n```\r\n\r\nand this is the JS code that tries to call that\r\n```JavaScript\r\nvar addon = require('bindings')('addon');\r\ntry {\r\n var obj = addon.MyObject.create();\r\n }\r\n catch (e) {\r\n console.error(\"Incorrect expected exception message:\" + e.message);\r\n }\r\n \r\n global.gc()\r\n global.gc()\r\n global.gc()\r\n```\r\n\r\nthen there is an exception here \r\n\r\n```\r\n\u003e\taddon.node!std::_Ref_count_base::_Decref() Line 845\tC++\r\n \taddon.node!std::_Ptr_base\u003cData\u003e::_Decref() Line 1122\tC++\r\n \taddon.node!std::shared_ptr\u003cData\u003e::~shared_ptr\u003cData\u003e() Line 1403\tC++\r\n \taddon.node!MyObject::~MyObject()\tC++\r\n \taddon.node!MyObject::`scalar deleting destructor'(unsigned int)\tC++\r\n \taddon.node!Napi::ObjectWrap\u003cMyObject\u003e::FinalizeCallback(napi_env__ * __formal, void * data, void * __formal) Line 3433\tC++\r\n \tnode.exe!`anonymous namespace'::v8impl::Reference::SecondPassCallback(const v8::WeakCallbackInfo\u003c`anonymous namespace'::v8impl::Reference\u003e \u0026 data) Line 496\tC++\r\n \t[Inline Frame] node.exe!v8::internal::GlobalHandles::PendingPhantomCallback::Invoke(v8::internal::Isolate *) Line 905\tC++\r\n \tnode.exe!v8::internal::GlobalHandles::InvokeSecondPassPhantomCallbacks(std::vector\u003cv8::internal::GlobalHandles::PendingPhantomCallback,std::allocator\u003cv8::internal::GlobalHandles::PendingPhantomCallback\u003e\u003e * callbacks, v8::internal::Isolate * isolate) Line 772\tC++\r\n \tnode.exe!v8::internal::GlobalHandles::DispatchPendingPhantomCallbacks(bool synchronous_second_pass) Line 881\tC++\r\n \tnode.exe!v8::internal::GlobalHandles::PostGarbageCollectionProcessing(v8::internal::GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) Line 930\tC++\r\n \tnode.exe!v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) Line 1775\tC++\r\n \tnode.exe!v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace space, v8::internal::GarbageCollectionReason gc_reason, const v8::GCCallbackFlags gc_callback_flags) Line 1392\tC++\r\n \t[Inline Frame] node.exe!v8::internal::Heap::CollectAllGarbage(int) Line 1156\tC++\r\n \tnode.exe!v8::Isolate::RequestGarbageCollectionForTesting(v8::Isolate::GarbageCollectionType type) Line 8273\tC++\r\n \tnode.exe!v8::internal::GCExtension::GC(const v8::FunctionCallbackInfo\u003cv8::Value\u003e \u0026 args) Line 26\tC++\r\n \tnode.exe!v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo * handler) Line 95\tC++\r\n \tnode.exe!v8::internal::`anonymous namespace'::HandleApiCallHelper\u003c0\u003e(v8::internal::Isolate * isolate, v8::internal::Handle\u003cv8::internal::HeapObject\u003e new_target, v8::internal::Handle\u003cv8::internal::HeapObject\u003e fun_data, v8::internal::Handle\u003cv8::internal::FunctionTemplateInfo\u003e receiver, v8::internal::Handle\u003cv8::internal::Object\u003e args, v8::internal::BuiltinArguments) Line 111\tC++\r\n \tnode.exe!v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments args, v8::internal::Isolate * isolate) Line 139\tC++\r\n \tnode.exe!v8::internal::Builtin_HandleApiCall(int args_length, v8::internal::Object * * args_object, v8::internal::Isolate * isolate) Line 127\tC++\r\n\r\n```\r\n\r\n**Note: you need to expose v8 GC for that to work with**\r\n```\r\nnode --expose_gc addon.js\r\n```\r\n\r\n\r\n\r\nIt seems to me this is cause the ```ObjectWrap\u003cT\u003e::FinalizeCallback``` is called but the native object did not get constructed correctly (ie the native object's ctor did not complete). Or is it that my assumption is wrong. \r\n\r\ncheers","author":{"url":"https://github.com/blagoev","@type":"Person","name":"blagoev"},"datePublished":"2019-12-16T18:40:26.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":2},"url":"https://github.com/635/node-addon-api/issues/635"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:2f5c244a-eccf-4f63-68f6-8856691756e3 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8960:47423:57F8F7C:7BDA4DD:6A4FF106 |
| html-safe-nonce | 58489a1451eb5dd362441a73a7e8493e9a2568231fb893e52ad9451677de0de6 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4OTYwOjQ3NDIzOjU3RjhGN0M6N0JEQTRERDo2QTRGRjEwNiIsInZpc2l0b3JfaWQiOiIzODYwMTMyMDY4NzM2MzMwMzAiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 045423ef82ed07c2c57eb1393abfd3f157f55a076078544cfd51cff98ad9dd13 |
| hovercard-subject-tag | issue:538584426 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node-addon-api/635/issue_layout |
| twitter:image | https://opengraph.githubassets.com/debca7f20893a225b8626ec2b4b8988b6e1e1c85e20fef708b0dce2d555b0052/nodejs/node-addon-api/issues/635 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/debca7f20893a225b8626ec2b4b8988b6e1e1c85e20fef708b0dce2d555b0052/nodejs/node-addon-api/issues/635 |
| og:image:alt | Hey folks, If an exception is thrown from inside a constructor it seems it causes v8 GC to fail with an access violation in this case below. I am starting to think that this is caused by ObjectWrap... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | blagoev |
| hostname | github.com |
| expected-hostname | github.com |
| None | 19b98c3d9767bb8a56238a89ff8401d1cbdf3bc5c353799aacf49fe6c76b4b7c |
| turbo-cache-control | no-preview |
| go-import | github.com/nodejs/node-addon-api git https://github.com/nodejs/node-addon-api.git |
| octolytics-dimension-user_id | 9950313 |
| octolytics-dimension-user_login | nodejs |
| octolytics-dimension-repository_id | 81384578 |
| octolytics-dimension-repository_nwo | nodejs/node-addon-api |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81384578 |
| octolytics-dimension-repository_network_root_nwo | nodejs/node-addon-api |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | f7e270be010aa4de2871991025fbb97f3afe2bcb |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width