{"id":9732,"date":"2013-06-28T10:00:00","date_gmt":"2013-06-28T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/2013\/06\/28\/javascriptnative-interop-debugging-in-visual-studio-2013\/"},"modified":"2022-08-01T08:36:40","modified_gmt":"2022-08-01T16:36:40","slug":"javascriptnative-interop-debugging-in-visual-studio-2013","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/javascriptnative-interop-debugging-in-visual-studio-2013\/","title":{"rendered":"JavaScript\/Native Interop Debugging in Visual Studio 2013"},"content":{"rendered":"<p>Hello, I am Patrick Nelson, a developer on the Visual Studio Debugger Team.<\/p>\n<p>Authoring apps that are using more than one language is not uncommon these days. For example, some developers prefer one language for the UI layer but use another language (or reuse components in another language) for their business logic. When debugging such apps, most of the time you are either debugging one language or the other (and you select which debugger type you want to use through the project properties), but sometimes you need to have the debugger attached to both.\u00a0In\u00a0other words,\u00a0you want to be using both debugger engines at the same time. It is for this reason that in VS2012 Update 1 we enabled and <a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2013\/02\/16\/mixed-native-and-managed-debugging-improvements-for-windows-store-apps.aspx\">blogged about interop debugging between Managed and Native code in the same app<\/a>.<\/p>\n<p>With Visual Studio 2013, we offer the same interop debugging capability for JavaScript and Native code, as I will describe in this blog post.<\/p>\n<p>**Important Notes******<\/p>\n<ul>\n<li>This feature is only present in Visual Studio 2013 it was removed in Visual Studio 2015<\/li>\n<li>The feature only works when debugging on Windows 8.1, it does NOT work\u00a0on Windows 10<\/li>\n<\/ul>\n<h3>Visual Studio 2012 workaround<\/h3>\n<p>Before delving into the VS2013 experience, it is worth pointing out that even with Visual Studio 2012, it is possible to debug both code types of the same app simultaneously by starting debugging in one instance of Visual Studio, and then opening another instance of Visual Studio to attach to the same process but with a different debug engine selected (in the project properties)<\/p>\n<p>There are some disadvantages to using this workaround including:<\/p>\n<ol>\n<li>You need to have two instances of Visual Studio running<\/li>\n<li>The instance of Visual Studio that is debugging JavaScript code will be unresponsive when the Visual Studio that is debugging native code is in break state.<\/li>\n<li>Breakpoints have to be set in the correct instance of Visual Studio<\/li>\n<li>Call stacks are for only one language so it is more difficult to understand the flow between JavaScript and Native code<\/li>\n<\/ol>\n<h3>Visual Studio 2013 experience<\/h3>\n<p>In Visual Studio 2013, we are introducing a new debugger type named \u201cNative with Script\u201d. This new debugger type is really what the name implies. It is essentially the Native debugger with some JavaScript support added. This means the \u201cNative with Script\u201d experience will give you the full Native debugging experience, but does not provide the full script debugging experience you will get with \u201cScript Only\u201d debugging. For example, the Watch window and DataTips do not have the same fidelity. Also note the DOM Explorer and JavaScript Console are not available when debugging Native with Script.<\/p>\n<p>To select this new debugger type, go to project properties \u2013> debugging and for \u201cDebugger Type\u201d select \u201cNative with Script\u201d<\/p>\n<p><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/06\/5518.image_thumb_0F7C995B.png\" alt=\"image\" width=\"552\" height=\"394\" border=\"0\" \/><\/p>\n<p>Now when you start debugging, you\u2019ll notice the active script documents load in the solution view as they do when Script debugging:<\/p>\n<p><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-width: 0px\" title=\"clip_image003\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/06\/7532.clip_image003_thumb_33C6B17E.png\" alt=\"clip_image003\" width=\"244\" height=\"192\" border=\"0\" \/><\/p>\n<p>It is also possible to set breakpoints both in your native code files an in the JavaScript files. When you hit breakpoints, you\u2019ll see call stacks with both Native code and JavaScript code. In addition, it\u2019s possible to view local variables in the \u201cLocals\u201d window when inspecting a JavaScript frame. This works when stopping at a native or JavaScript breakpoint.<\/p>\n<p><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/06\/8272.image_thumb_18F557D1.png\" alt=\"image\" width=\"743\" height=\"460\" border=\"0\" \/><\/p>\n<h3>A Concrete Example<\/h3>\n<p>Say we are debugging an app that crashes on startup. If we debug it with Script Only, all we see is an unhandled exception in WWAHost and the Visual Studio Just-In-Time debugger:<\/p>\n<p><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/06\/0602.image_thumb_1ECFFB6A.png\" alt=\"image\" width=\"225\" height=\"244\" border=\"0\" \/><\/p>\n<p>\u00a0<\/p>\n<p>If we debug with Native only, we get a bit more information. We see a divide by zero first chance exception in FolderInfo.h by looking at the Output window. To see why we are getting the divide by zero error, we can temporarily enable break on divide by zero exception via Debug -> Exceptions:<\/p>\n<p><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/06\/2330.image_thumb_17B0BEF2.png\" alt=\"image\" width=\"464\" height=\"230\" border=\"0\" \/><\/p>\n<p><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/06\/5100.image_thumb_77297F3F.png\" alt=\"image\" width=\"464\" height=\"230\" border=\"0\" \/><\/p>\n<p>Running it again with break on first chance exceptions thrown, we see the divide by zero error is being caused because m_ImageList->Size is zero. Unfortunately, the deep call stack provides no clue as to how we got here except that we came from jscript9.dll:<\/p>\n<p><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/06\/2816.image_thumb_5C7CE326.png\" alt=\"image\" width=\"729\" height=\"451\" border=\"0\" \/><\/p>\n<p>Using Native with Script we get more information. We can now see the JavaScript code on the call stack and see where we were in JavaScript code. We can see the call to folder.SampleImage and inspect the folder parameter via the Locals window. Notice we have the ability to inspect the native object even though we are currently looking at a JavaScript frame:<\/p>\n<p><img decoding=\"async\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/06\/2021.image_thumb_4375D303.png\" alt=\"image\" width=\"730\" height=\"452\" border=\"0\" \/><\/p>\n<p>Here we see that the folder we are looking at is \u201cPictures\u201d and there are no images in that folder. This is the cause of the divide be zero error. If we add a picture to the pictures folder the divide by zero exception goes away. We found and verified a possible fix.<\/p>\n<p>By the way, now is a good time to turn off break on divide by zero exceptions so we don\u2019t get extra noise during future debugging sessions.<\/p>\n<h3>In Closing<\/h3>\n<p>If you want to try this yourself, you can <a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/02\/Sample.zip\">download the sample program I used to create this post<\/a>.<\/p>\n<p>We are actively looking for feedback on both this and other diagnostics features so please stop by our <a href=\"http:\/\/social.msdn.microsoft.com\/Forums\/vstudio\/en-US\/home?forum=vsdebug\">MSDN support forum<\/a> and let us know what you think.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/6\/2019\/02\/Sample.zip\">Sample.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello, I am Patrick Nelson, a developer on the Visual Studio Debugger Team. Authoring apps that are using more than one language is not uncommon these days. For example, some developers prefer one language for the UI layer but use another language (or reuse components in another language) for their business logic. When debugging such [&hellip;]<\/p>\n","protected":false},"author":84,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,225],"tags":[],"class_list":["post-9732","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-git"],"acf":[],"blog_post_summary":"<p>Hello, I am Patrick Nelson, a developer on the Visual Studio Debugger Team. Authoring apps that are using more than one language is not uncommon these days. For example, some developers prefer one language for the UI layer but use another language (or reuse components in another language) for their business logic. When debugging such [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/9732","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/84"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=9732"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/9732\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=9732"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=9732"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=9732"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}