{"id":1638,"date":"2018-06-19T12:02:18","date_gmt":"2018-06-19T16:02:18","guid":{"rendered":"https:\/\/blogs.mathworks.com\/developer\/?p=1638"},"modified":"2018-06-20T08:26:43","modified_gmt":"2018-06-20T12:26:43","slug":"mex-debugging-vscode","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/developer\/2018\/06\/19\/mex-debugging-vscode\/","title":{"rendered":"MEX Debugging. Redefined."},"content":{"rendered":"<p><em>Folks, today I'd like to introduce a new guest blogger Martijn Aben. Martijn is a support engineer out of our Netherlands office who daydreams about MATLAB's connections to the external world. As part of that he as a great story to tell about how he has integrated with Microsoft's applauded VS Code IDE. Take it away Martijn!<\/em><\/p>\r\n      <p><em><\/em><\/p>\r\n      <p>As a MathWorks Technical Support Engineer specializing, among other things, in the MATLAB \"external interfaces\" areas, I regularly work with MATLAB users having some <em>difficulties<\/em> with their custom written MEX-files. Sometimes the MEX-files do not produce the expected result, and sometimes they completely crash MATLAB. This can happen because MEX-files are native libraries which can manipulate the native memory inside MATLAB and even the smallest memory corruption can easily lead to a whole application crashing. While we can\u2019t debug your MEX-file source code for you, this is not part of the support which we offer, we can help you with strategies to debug your code yourself. We can provide some hints and tips on what kind of issues to look out for, we can answer questions on the mxArray- and MEX APIs, and we can help you choose and setup your debug environment, which is what I\u2019d like to talk about in this post. <\/p>\r\n      <p>Choosing your debug environment on Windows has historically been pretty simple. We supported the Microsoft Visual C++ compilers for creating MEX-files and if you used that compiler, Microsoft Visual Studio was the obvious choice for a debugger. In fact, getting started with this debugger is part of the actual in-product <a href=\"http:\/\/www.mathworks.com\/help\/releases\/R2018a\/matlab\/matlab_external\/debugging-on-microsoft-windows-platforms.html\">documentation<\/a>. <\/p>\r\n      <p>However, in MATLAB R2015b we started to support the MinGW64 compiler which leverages the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">gdb<\/inline> debugger, and there are various different front-ends\/editors\/IDEs which can work with <inline style=\"font-family: monospace, monospace; font-size: inherit;\">gdb<\/inline>. Immediately after the release of MATLAB R2015b, I wrote up a guide on how to debug using Eclipse, which my colleagues turned into a <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/answers\/241291-how-to-debug-mex-file-compiled-with-mingw64-and-g-flags\">MATLAB Answer Article<\/a>. Today in this blog post we are looking into a different tool, which is one of my recent-favorite free development tools: <a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code<\/a> (VS Code). <\/p>\r\n      <h3>Visual Studio Code<\/h3>\r\n      <p>When I first tried Visual Studio Code it was still the preview build. It looked like a nice and sleek code editor but I did not immediately recognize how powerful it can be when extensions are added. I recently rediscovered the tool and its extensibility when doing a little hobby IoT project, which showed me how powerful VS Code really has become. As a MathWorks employee and overall MATLAB fan, I then decided to see whether I could use it for debugging MEX-files as well. <\/p>\r\n      <p>Now before we get to the actual setup and debugging, first a few things you need to know about VS Code. In particular, users of the full-fledged Visual Studio may be wondering how to create a Solution and add Projects to it since these do not exist in VS Code, at least not under those names. To <b><em>create<\/em><\/b> something similar to a <b><em>Project <\/em><\/b>you essentially <b><em>Open<\/em><\/b> a <b><em>Folder<\/em><\/b> and then organize things together in that <b><em>Folder<\/em><\/b>. Want to open additional projects next to the one you already have open? <b><em>Add<\/em><\/b> another <b><em>Folder<\/em><\/b> to your <b><em>Workspace<\/em><\/b>. Want to create something similar to a <b><em>Solution<\/em><\/b> with multiple <b><em>Projects<\/em><\/b>? Open multiple <b><em>Folders<\/em><\/b> in your <b><em>Workspace<\/em><\/b>, then <b><em>Save<\/em><\/b> this <b><em>Workspace<\/em><\/b>. Opening a solution has then become opening a workspace. <\/p>\r\n      <p>Another important thing to note is that out-of-the-box VS Code is a powerful code editor for many languages but really only a debugger for Javascript and Typescript running in Node.js. For other languages and runtimes you will need to install the relevant extension(s). Since MATLAB MEX-files are written in C\/C++ this means we will need an extension, and that extension is aptly named \"C\/C++\". So let's get started by actually installing this extension. Fire up VS Code and head over to the Extensions section in VS Code: <\/p>\r\n      <p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_1.png\"><\/p>\r\n      <p>Find the C\/C++ Extension:<\/p>\r\n      <p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_2.png\"><\/p>\r\n      <p>And install it using that little green <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Install<\/inline> button, to fully complete the installation make sure to click the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Reload<\/inline> option after the extension was downloaded. <\/p>\r\n      <h3>MEX-File Debugging in VS Code<\/h3>\r\n      <p>Now that we have a VS Code installation which can debug C\/C++ code, let's see how we can configure it for the specific task of debugging MEX-files. We go to the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Explorer<\/inline> <img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_3.png\"> section of VS Code and then use <inline style=\"font-family: monospace, monospace; font-size: inherit;\">File<\/inline> -&gt; <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Open Folder...<\/inline> to start a new <b><em>Project<\/em><\/b>. In my example here I actually open the folder in which the source code of my MEX-file is located. After opening that folder, named <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Work<\/inline> in my case, and opening the source code of <inline style=\"font-family: monospace, monospace; font-size: inherit;\">mymex.c<\/inline> in the editor, VS Code will look something like: <\/p>\r\n      <p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_4.png\"><\/p>\r\n      <p>First thing we notice is the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">#include \"mex.h\"<\/inline> statement being underlined and we also see some <inline style=\"font-family: monospace, monospace; font-size: inherit;\">PROBLEMS<\/inline> being reported. You do not actually have to resolve these <inline style=\"font-family: monospace, monospace; font-size: inherit;\">PROBLEMS<\/inline> to be able to debug most parts of your code but you may want to read up on these \"include issues\" in the <a href=\"https:\/\/github.com\/Microsoft\/vscode-cpptools\/blob\/master\/Documentation\/Getting%20started%20with%20IntelliSense%20configuration.md\">VS Code documentation<\/a> and then create a <inline style=\"font-family: monospace, monospace; font-size: inherit;\">c_cpp_properties.json <\/inline>with something like: <\/p><pre>\r\n{\r\n    \"configurations\": [\r\n        {\r\n            \"name\": \"Win32\",\r\n            \"includePath\": [\r\n                \"c:\/ProgramData\/MATLAB\/SupportPackages\/R2018a\/3P.instrset\/mingw_w64.instrset\/x86_64-w64-mingw32\/include\",\r\n                \"c:\/MATLAB\/R2018a\/extern\/include\",\r\n                \"${workspaceRoot}\"\r\n            ],\r\n            \"defines\": [\r\n                \"_DEBUG\",\r\n                \"UNICODE\",\r\n                \"_UNICODE\"\r\n            ],\r\n            \"intelliSenseMode\": \"msvc-x64\",\r\n            \"browse\": {\r\n                \"path\": [\r\n                    \"c:\/ProgramData\/MATLAB\/SupportPackages\/R2018a\/3P.instrset\/mingw_w64.instrset\/x86_64-w64-mingw32\/include\",\r\n                    \"c:\/MATLAB\/R2018a\/extern\/include\",\r\n                    \"${workspaceRoot}\"\r\n                ],\r\n                \"limitSymbolsToIncludedHeaders\": true,\r\n                \"databaseFilename\": \"\"\r\n            }\r\n        }\r\n    ],\r\n    \"version\": 3\r\n}\r\n<\/pre><p>In which we tell VS Code where to find the MinGW64 headers as well as where to find the MATLAB headers. My MATLAB R2018a, which I am working with here, is installed in <inline style=\"font-family: monospace, monospace; font-size: inherit;\">c:\\MATLAB\\R2018a<\/inline>, update your paths accordingly. My MinGW64 support package is installed in the default location so in most cases you should be able to re-use the location shown above. However, just in case you run into problems check the footnote at the end of this post to double check this location. <\/p>\r\n      <p>With VS Code all happy now, let's add a Debug configuration. We go to go to <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Debug<\/inline> -&gt; <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Add Configuration\u2026<\/inline> and select <inline style=\"font-family: monospace, monospace; font-size: inherit;\">C++ (GDB\/LLDB)<\/inline>: <\/p>\r\n      <p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_5.png\"><\/p>\r\n      <p>This will create a new <inline style=\"font-family: monospace, monospace; font-size: inherit;\"> launch.json<\/inline> file for us and it should immediately show a menu to add new configurations. Alternatively you can use the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Add Configuration\u2026<\/inline> button. Since it is faster\/easiest to attach to an already running MATLAB for debugging rather than launching a new one through the debugger, we choose to Add a <inline style=\"font-family: monospace, monospace; font-size: inherit;\">C\/C++: (gdb) <\/inline><b> <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Attach<\/inline><\/b> configuration: <\/p>\r\n      <p> <img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_6.png\"><\/p>\r\n      <p>VS Code then automatically adds a new section to <inline style=\"font-family: monospace, monospace; font-size: inherit;\">launch.json<\/inline>: <\/p><pre>\r\n{ \r\n    \"name\": \"(gdb) Attach\",\r\n    \"type\": \"cppdbg\",\r\n    \"request\": \"attach\",\r\n    \"program\": \"enter program name, for example ${workspaceRoot}\/a.exe\",\r\n    \"processId\": \"${command:pickProcess}\",\r\n    \"MIMode\": \"gdb\",\r\n    \"miDebuggerPath\": \"\/path\/to\/gdb\"\r\n}\r\n<\/pre>\r\n      <p>We need to update the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">program<\/inline> setting to point to MATLAB.exe from the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">bin\/win64<\/inline> directory of our MATLAB installation and <inline style=\"font-family: monospace, monospace; font-size: inherit;\">miDebuggerPath <\/inline>to point to the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">gdb<\/inline> debugger from the MinGW64 Support Package. Also, the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">gdb<\/inline> debugger tends to stop on all first chance SIGSEGVs, so it actually stops on any thrown SIGSEGV even if that SIGSEGV is going to be caught and dealt with correctly. The JVM inside MATLAB throws these SIGSEGVs on purpose and then catches these as part of its JIT process and we do not want to stop in the debugger every time this happens. To tell the debugger to ignore these SIGSEGVs we add <inline style=\"font-family: monospace, monospace; font-size: inherit;\">setupCommands <\/inline>which are essentially <inline style=\"font-family: monospace, monospace; font-size: inherit;\">gdb<\/inline> commands which are automatically run when the debugger is started. All this combined then gives: <\/p><pre>\r\n{ \r\n    \"name\": \"(gdb) Attach\",\r\n    \"type\": \"cppdbg\",\r\n    \"request\": \"attach\",\r\n    \"program\": \"c:\/MATLAB\/R2018a\/bin\/win64\/MATLAB.exe\",\r\n    \"processId\": \"${command:pickProcess}\",\r\n    \"MIMode\": \"gdb\",\r\n    \"setupCommands\": [\r\n        {\r\n            \"text\": \"handle SIGSEGV nostop\"\r\n        },\r\n        {\r\n             \"text\": \"handle SIGSEGV noprint\"\r\n        }\r\n    ],\r\n    \"miDebuggerPath\": \"c:\/ProgramData\/MATLAB\/SupportPackages\/R2018a\/3P.instrset\/mingw_w64.instrset\/bin\/gdb.exe\"\r\n}\r\n<\/pre>\r\n      <p>From there I usually delete the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">(gdb) Launch <\/inline>configuration which had been added by default as well. That should complete the setup of our project, now we can get to the actual debugging. <\/p>\r\n      <h3>Actual Debugging<\/h3>\r\n      <p>If you paid closed attention in the screenshots above, you could see that I had already compiled <inline style=\"font-family: monospace, monospace; font-size: inherit;\">mymex.c<\/inline> into <inline style=\"font-family: monospace, monospace; font-size: inherit;\">mymex.mexw64<\/inline>, I had <em>prepared this earlier<\/em> in MATLAB with: <\/p><pre class=\"matlab-code\" id=\"matlabcode\" style=\"background-color: #F7F7F7;font-family: monospace;font-weight:normal;border-style: solid; border-width: 1px ;border-color:#E9E9E9;padding-top:5px;padding-bottom:5px;line-height:150%;\">mex <span style=\"color:rgb(160, 32, 240);\">-g<\/span> <span style=\"color:rgb(160, 32, 240);\">mymex.c<\/span>\r\n<\/pre><p>Where the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">-g<\/inline> flag disabled optimizations and made sure symbolic information which we need for debugging was added. You will likewise need to build your mex files with this debug information using the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">-g<\/inline> flag. <\/p>\r\n      <p>So really all we need to do now is place a breakpoint somewhere in the code:<\/p>\r\n      <p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_7.png\"><\/p>\r\n      <p>Switch to the debug view <img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_8.png\"><\/p>\r\n      <p><em>Make sure MATLAB is actually running<\/em> (we configured VS Code to <em>attach<\/em> the debugger to an already running MATLAB after all) and we then hit the play button: <\/p>\r\n      <p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_9.png\"><\/p>\r\n      <p>Which shows a dialog with running processes where we then choose MATLAB:<\/p>\r\n      <p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_10.png\"> <\/p>\r\n      <p>VS Code should now be attached to MATLAB and we should see some lines like<\/p><pre>\r\n[New Thread 18404.0x473c]\r\n[New Thread 18404.0x3294]\r\n<\/pre>\r\n      <p>in the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">Debug Console<\/inline> which shows us that the debugger is definitely doing <em>something<\/em> and is logging information about what MATLAB is doing. We can then switch to our MATLAB session and run the MEX-file: <\/p><pre class=\"matlab-code\" id=\"matlabcode\" style=\"background-color: #F7F7F7;font-family: monospace;font-weight:normal;border-style: solid; border-width: 1px ;border-color:#E9E9E9;padding-top:5px;padding-bottom:5px;line-height:150%;\">mymex([1 2 pi 21])\r\n<\/pre><p>When we do that we will see VS Code will stop on our breakpoint, stepping (F10) a few lines we can then see:<\/p>\r\n      <p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_11.png\"><\/p>\r\n      <ol>\r\n         <p>1. We were able to successfully obtain a pointer to the native input data and the first element had value 1<\/p>\r\n         <p>2. The size of the input was indeed a 1x4 vector.<\/p>\r\n      <\/ol>\r\n      <p>We can also step through our <inline style=\"font-family: monospace, monospace; font-size: inherit;\">for<\/inline>-loop and see: <\/p>\r\n      <p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_12.png\"><\/p>\r\n      <ol>\r\n         <p>1. How <inline style=\"font-family: monospace, monospace; font-size: inherit;\">i<\/inline> updates with each iteration, here we are at <inline style=\"font-family: monospace, monospace; font-size: inherit;\">i = 3<\/inline>. <\/p>\r\n         <p>2. Inspect certain elements in our array in the <inline style=\"font-family: monospace, monospace; font-size: inherit;\">DEBUG CONSOLE<\/inline>. The screenshot shows that the fourth element in the input is indeed 21, just like we passed in from MATLAB. <\/p>\r\n      <\/ol>\r\n      <p>To find out what else you can do, read the <a href=\"https:\/\/code.visualstudio.com\/docs\/editor\/debugging#_debug-actions\">Debugging Documentation of VS Code<\/a>. <\/p>\r\n      <h3>Conclusion<\/h3>\r\n      <p>I realize we did not actually debug and fix any bugs in any super advanced real-world MEX-files here today, but I did show you how you can get started on debugging MEX-files using one of my recent-favorite free development tools and I hope this has inspired you to give this workflow a try if you ever need to debug one of your MinGW64 MEX-files. Happy hunting for those bugs! <\/p>\r\n      <p>Oh, and for you Linux users out there, while the story above is about MinGW64 and Windows, since VS Code is available for Linux as well, you can also apply this workflow on Linux to debug your GCC MEX-files. Obviously some of the paths will be somewhat different, but I am sure you can figure it out; let us know though if you have any further questions on that. <\/p>\r\n      <h3><em>Footnote<\/em><\/h3>\r\n      <ol>\r\n         <p><em>While configuring VS Code we needed the location of the MinGW64 include directory as well as the location of the <\/em><em> <inline style=\"font-family: monospace, monospace; font-size: inherit;\">gdb<\/inline><\/em><em> debugger. When MinGW64 is installed through the support package these locations may be somewhat hidden from you; also the exact locations may vary with different support package versions for different MATLAB releases. So how do you determine those locations? Well, <\/em><em> <inline style=\"font-family: monospace, monospace; font-size: inherit;\">gdb.exe<\/inline><\/em><em> is typically found in the same directory as gcc\/g++ which is the actual compiler used for compilation, and you can easily see where the compiler is located if you add the verbose <\/em><em> <inline style=\"font-family: monospace, monospace; font-size: inherit;\">-v<\/inline><\/em><em> flag when compiling your code: <\/em><em> <inline style=\"font-family: monospace, monospace; font-size: inherit;\">mex -g -v mymex.c<\/inline><\/em><em>. In the verbose output, the last few lines show the literal calls that are being made to gcc\/g++. If you also want to find the include directory you go one directory up from gcc\/g++ and then into <\/em><em> <inline style=\"font-family: monospace, monospace; font-size: inherit;\">x86_64-w64-mingw32<\/inline><\/em><em> where there will be a directory named <\/em><em> <inline style=\"font-family: monospace, monospace; font-size: inherit;\">include<\/inline><\/em><em>.<\/em><\/p>\r\n      <\/ol>","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/developer\/files\/VisualStudioCodeDebug18a_7.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>Folks, today I'd like to introduce a new guest blogger Martijn Aben. Martijn is a support engineer out of our Netherlands office who daydreams about MATLAB's connections to the external world. As... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/developer\/2018\/06\/19\/mex-debugging-vscode\/\">read more >><\/a><\/p>","protected":false},"author":90,"featured_media":1622,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[28,10],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/1638"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/users\/90"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/comments?post=1638"}],"version-history":[{"count":4,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/1638\/revisions"}],"predecessor-version":[{"id":1652,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/1638\/revisions\/1652"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/media\/1622"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/media?parent=1638"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/categories?post=1638"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/tags?post=1638"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}