{"id":97947,"date":"2025-07-14T10:00:00","date_gmt":"2025-07-14T17:00:00","guid":{"rendered":"https:\/\/opensource.microsoft.com\/blog\/?p=97947"},"modified":"2025-08-26T14:10:41","modified_gmt":"2025-08-26T21:10:41","slug":"hyperlight-debugging-hardware-protected-guests","status":"publish","type":"post","link":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/","title":{"rendered":"Hyperlight: Debugging hardware-protected guests"},"content":{"rendered":"\n<p>As we explained in an <a href=\"https:\/\/opensource.microsoft.com\/blog\/2024\/11\/07\/introducing-hyperlight-virtual-machine-based-security-for-functions-at-scale\/\" target=\"_blank\" rel=\"noreferrer noopener\">article introducing the project<\/a>, <a href=\"https:\/\/aka.ms\/hyperlight-dev\" target=\"_blank\" rel=\"noreferrer noopener\">Hyperlight<\/a> enables host applications to run small, embedded functions using hardware-based (hypervisor) protection to ensure the application host cannot be attacked by untrusted code in the guest function. <a href=\"https:\/\/opensource.microsoft.com\/blog\/2025\/02\/11\/hyperlight-creating-a-0-0009-second-micro-vm-execution-time\/\" target=\"_blank\" rel=\"noreferrer noopener\">It can do so at incredible speed<\/a>, creating a new \u201cmicro virtual machine\u201d <em>or micro-VM <\/em>in less than 2 milliseconds, which means when used per-request it can protect <em>each request from the others<\/em> in addition to the host application. Furthermore, because the micro-VM does not contain an operating system but only a function process, it can be as small as needed, dramatically reducing host resource requirements.<\/p>\n\n\n\n<p>This usage of hypervisors is brand new and still a little harder to use; up until now, for example, it was very hard to debug\u2014something that developers need to understand how their code runs inside the micro-VM.<\/p>\n\n\n\n<p>We are happy to announce that now, you can interactively debug Hyperlight guest micro-VMs. This article describes how to attach the GNU Debugger (GDB) at runtime to step through the code in your guest micro-VM and what debugging features are supported.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-16018d1d wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/opensource.microsoft.com\/blog\/2024\/11\/07\/introducing-hyperlight-virtual-machine-based-security-for-functions-at-scale\/\" target=\"_blank\" rel=\"noreferrer noopener\">Learn more about Hyperlight<\/a><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"why-debug-anyway\">Why debug anyway?<\/h2>\n\n\n\n<p>Modern development includes interactive, step-by-step debugging as one of the core tenets of usability. Languages and platforms are harder to use if logging or \u201c<a href=\"https:\/\/tedspence.com\/the-art-of-printf-debugging-7d5274d6af44\" target=\"_blank\" rel=\"noreferrer noopener\">printf debugging<\/a>\u201d must be used.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69e5017eab870&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-2.webp\" alt=\"Hyperlight hello-world application logging example.\" class=\"wp-image-97955 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-2.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\"><em>Hyperlight hello-world application logging example<\/em><\/figcaption><\/figure>\n\n\n\n<p>With logging or printf debugging, you must rerun the program each iteration, transforming the developer \u201cinner loop\u201d into \u201ccoffee time\u201d. You put your programmer hat on, get a cup of coffee, and prepare to dig in.<br><br>It\u2019s vastly better to attach to the running process, set breakpoints, inspect memory, and step through the code so that you can fix the issue. Just as important, from a newcomer\u2019s perspective, is stepping through the guest code to check what happens at runtime because it provides a better idea of how things work.<\/p>\n\n\n\n<p>Let\u2019s use GDB to interactively debug a function running in a Hyperlight micro-VM guest.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-challenge\">The challenge<\/h2>\n\n\n\n<p>For the purposes of this article, you\u2019ll use the GNU Project Debugger as your debugger (though you can also use the LLVM Debugger, or LLDB, using the same instructions).<\/p>\n\n\n\n<p>To start a debug session for an application running on an operating system, you attach to the process. Then the debugger takes over and uses the operating system to inspect its memory and send signals to stop or continue execution.<\/p>\n\n\n\n<p>However, Hyperlight does not run an operating system in the micro-VM and therefore must attach to the guest code in a different way. Hyperlight conducts the debug session through the running host application. The following diagram shows how we do this.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69e5017eac974&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image.webp\" alt=\"Hyperlight and Debugger interaction diagram.\" class=\"wp-image-97948 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\"><em>Hyperlight and Debugger interaction diagram<\/em><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"gdb-debugging-support\">GDB debugging support<\/h2>\n\n\n\n<p>As the know-it-all Wikipedia says: <a href=\"https:\/\/en.wikipedia.org\/wiki\/GNU_Debugger\" target=\"_blank\" rel=\"noreferrer noopener\">\u201cThe GNU Debugger is a portable debugger that runs on many Unix-like systems and works for many programming languages &#8230;\u201d.<\/a><\/p>\n\n\n\n<p>Being one of the most used debuggers out there, Hyperlight introduces support to enable guest debugging using GDB. LLDB works as well; please see the repo documentation for more information about using LLDB.<\/p>\n\n\n\n<p>Hyperlight allows debugging for guests created by all hypervisors (KVM, MSHV, and HyperV on Windows) and includes support for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Adding and removing breakpoints.<\/li>\n\n\n\n<li>Reading and writing memory and registers.<\/li>\n\n\n\n<li>Stepping through instructions.<\/li>\n\n\n\n<li>Resuming execution of guest.<\/li>\n\n\n\n<li>Interrupting an executing guest.<\/li>\n<\/ul>\n\n\n\n<p>For more information on how to set up VSCode to use GDB and LLDB, follow the guides in the Hyperlight repository <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight\/tree\/main\/docs\" target=\"_blank\" rel=\"noreferrer noopener\">documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"example\">Example<\/h2>\n\n\n\n<p>Let\u2019s debug a guest running in a Hyperlight sandbox using the example described in our previous post: <a href=\"https:\/\/opensource.microsoft.com\/blog\/2025\/02\/11\/hyperlight-creating-a-0-0009-second-micro-vm-execution-time\/\" target=\"_blank\" rel=\"noreferrer noopener\">Hyperlight: Achieving 0.0009 second micro-VM execution time<\/a>.<\/p>\n\n\n\n<p>You need to clone the <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight-kubeconNA2024-demo\/tree\/c5274ad\" target=\"_blank\" rel=\"noreferrer noopener\">repository containing the demo<\/a>, open it in Visual Studio Code, and start a devcontainer when prompted. This starts a development container that is provisioned with everything needed to run this demo.<\/p>\n\n\n\n<p>Open a terminal in the dev container and run the demo-main application that uses the already built guest binary demo-guest-debug.<\/p>\n\n\n\n<p><strong>cd demo-main<br>cargo run &#8211;features gdb<\/strong><\/p>\n\n\n\n<p>After the application starts running the HTTP server, you will be prompted to open the browser. You can either do that, or open another terminal in VSCode and issue an HTTP request using the <strong>\/hyperlight\/hello-world\/cold<\/strong> route. The other routes in this host application do not start the debugging process, <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight-kubeconNA2024-demo\/blob\/c5274ad8eb9931a6d851b44a5b68f17629e58437\/demo-main\/src\/hyperlight\/hello_world.rs#L25-L34\" target=\"_blank\" rel=\"noreferrer noopener\">which you can see here<\/a>.<\/p>\n\n\n\n<p><strong>curl <a href=\"http:\/\/127.0.0.1:3030\/hyperlight\/hello-world\/cold\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/127.0.0.1:3030\/hyperlight\/hello-world\/cold<\/a><\/strong><a href=\"http:\/\/127.0.0.1:3030\/hyperlight\/hello-world\/cold\"><br><br><\/a>Notice that it hangs? This is because the web server host application has started the Hyperlight sandbox, but the host is waiting for the debugger to attach before it handles the request.<br>Let\u2019s not make it wait. In the top left corner, go to the <strong>Activity Bar <\/strong>and select <strong>Run and Debug<\/strong> activity (or press Ctrl+Shift+D). Select <strong>Remote GDB attach<\/strong> from the dropdown list and click on the green play button to initiate a debug session using GDB in VSCode. <\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69e5017eadb9a&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-3.webp\" alt=\"V S Code Activity Bar showing the Remote G D B attach activity in the dropdown list.\" class=\"wp-image-97956 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-3.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>After pressing the green play button, the debugger attaches. At this point, the micro-VM sandbox has been created, and the debugger has automatically stopped at the guest <strong>entrypoint<\/strong> function. This function enables the guest to create and configure the micro-VM sandbox. You can think of the <strong>entrypoint <\/strong>function as a kind of \u201cmain()\u201d function for the micro-VM.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69e5017eaeb55&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-7.webp\" alt=\"V S Code screenshot of the automatically set breakpoint at the entrypoint function.\" class=\"wp-image-97961 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-7.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>You can now play around with the debugger and the functions, but typically we want to focus on the guest functions. Let\u2019s set a breakpoint in the first function a guest implements that executes inside the micro-VM. Once blocked on <strong>entrypoint<\/strong>, navigate to the<strong> demo-guest\/src\/main.rs<\/strong> file and set a breakpoint on the <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight-kubeconNA2024-demo\/blob\/c5274ad\/demo-guest\/src\/main.rs#L49\" target=\"_blank\" rel=\"noreferrer noopener\">hyperlight_main<\/a> implementation. Press <strong>Continue (F5) <\/strong>so that you continue executing until you block on <strong>hyperlight_main<\/strong>.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69e5017eafad5&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-4.webp\" alt=\"V S Code screenshot of a debugger breakpoint on a function.\" class=\"wp-image-97957 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-4.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>Before you finish stepping through the function (or you can restart the debugging session if you need to), set a breakpoint in the <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight-kubeconNA2024-demo\/blob\/c5274ad8eb9931a6d851b44a5b68f17629e58437\/demo-guest\/src\/main.rs#L36\" target=\"_blank\" rel=\"noreferrer noopener\">simple_print_output<\/a> and <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight-kubeconNA2024-demo\/blob\/c5274ad8eb9931a6d851b44a5b68f17629e58437\/demo-guest\/src\/main.rs#L26\" target=\"_blank\" rel=\"noreferrer noopener\">print_output<\/a> functions and then continue the execution so that the guest stops at <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight-kubeconNA2024-demo\/blob\/c5274ad8eb9931a6d851b44a5b68f17629e58437\/demo-guest\/src\/main.rs#L36\" target=\"_blank\" rel=\"noreferrer noopener\">simple_print_output<\/a>. This function is the first \u201cguest HTTP request processing function\u201d that we wanted Hyperlight to protect while handling the HTTP request. This function, however, merely calls <ins><a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight-kubeconNA2024-demo\/blob\/c5274ad8eb9931a6d851b44a5b68f17629e58437\/demo-guest\/src\/main.rs#L27\" target=\"_blank\" rel=\"noreferrer noopener\">a <em>host callback function<\/em>, HostPrint<\/a><\/ins>. (The debugger can\u2019t be set on that function, as it\u2019s implemented in the <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight\/blob\/v0.4.0\/src\/hyperlight_host\/src\/sandbox\/uninitialized.rs#L253\" target=\"_blank\" rel=\"noreferrer noopener\">hyperlight-host crate<\/a> and can be used by any function unless overridden.)<\/p>\n\n\n\n<p>Note, however, that when you <strong>Continue (F5)<\/strong>, the guest function turns around and calls the print_output function.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69e5017eb0b1f&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-8.webp\" alt=\"V S Code screenshot blocking on the &ldquo;call_host_function&rdquo; function.\" class=\"wp-image-97962 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-8.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>Let\u2019s now step over this function by pressing the <strong>Step Over<\/strong> button (notice the red rectangle in the picture above) and at the same time look at the terminals below and notice the <strong>Hello, World! I am executing inside of a VM : )<\/strong> message being printed on the terminal running the host application. You can continue the execution and see the HTTP request returning a message signaling the guest has successfully run.<\/p>\n\n\n\n<p>That\u2019s it! You have successfully debugged your first Hyperlight sandbox.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-the-example-enables-debugging\">How the example enables debugging<\/h2>\n\n\n\n<p>Now that you have successfully debugged a guest running in Hyperlight sandbox, let\u2019s explain how it was configured to allow debugging.<\/p>\n\n\n\n<p>Let\u2019s open the demo-main\/src\/hyperlight\/hello-world.rs file and have a look at the cold function that handles the route we have hit by using the curl command.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69e5017eb1c12&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image aligncenter size-large wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-10-1024x583.webp\" alt=\" V S Code screenshot of code that is enabled when the &ldquo;g d b&rdquo; option is used.\" class=\"wp-image-97984 webp-format\" srcset=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-10-1024x583.webp 1024w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-10-388x221.webp 388w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-10-768x437.webp 768w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-10-450x256.webp 450w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-10-650x370.webp 650w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-10.webp 1248w\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-10-1024x583.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>The first thing you\u2019ll notice is the first red rectangle above being greyed out, which means it is not compiled, right? That is true but remember we ran cargo run &#8211;features gdb in a previous step, which enables this area of code.<\/p>\n\n\n\n<p>You can see the four highlighted areas above. The first one is the configuration for the Sandbox\u2014this tells Hyperlight that the Sandbox expects a debugging session on port 8080 by setting the DebugInfo { port: 8080 } in the SandboxConfiguration.<\/p>\n\n\n\n<p>This configuration is provided to the UninitializedSandbox::new and later, when the evolve and call_guest_function_by_name methods are called, the host application waits for the guest to be debugged.<\/p>\n\n\n\n<p>The next important piece of information is the debugger that needs to use the port that the sandbox was configured with to establish a debugging session. You can check .vscode\/launch.json out and see the configurations needed by VSCode to run <strong>GDB<\/strong> and <strong>LLDB<\/strong> to debug a Hyperlight Sandbox.<\/p>\n\n\n\n<p>This is all you need to do to enable debugging of a sandbox in your application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"technical-deep-dive\">Technical deep dive<\/h2>\n\n\n\n<p>Hyperlight expects a sandbox to provide a DebugInfo to the <a href=\"https:\/\/docs.rs\/hyperlight-host\/0.4.0\/hyperlight_host\/sandbox\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">SandboxConfiguration<\/a> for it to enable debugging in the specific sandbox. If a DebugInfo is provided and the `gdb` feature is enabled when a new sandbox is created, a separate thread (let\u2019s call it gdb thread) is spawned.<\/p>\n\n\n\n<p>The GDB debugger uses a text-based protocol to exchange messages between the client and the target being debugged. The GDB thread listens for an incoming TCP connection from a debugger to start the GDB protocol communication.<\/p>\n\n\n\n<p>To understand the GDB protocol Hyperlight uses the `<a href=\"https:\/\/github.com\/daniel5151\/gdbstub\" target=\"_blank\" rel=\"noreferrer noopener\">gdbstub<\/a>` rust crate. This crate allows Hyperlight to run an event loop which invokes callbacks corresponding to the commands received. The callbacks are implemented through traits that Hyperlight uses to provide functionality for each supported feature.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69e5017eb2cf2&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-1.webp\" alt=\"Trait implemented by the HyperlightSandboxTarget to specify what support is provided.\" class=\"wp-image-97951 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-1.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\"><em>Trait implemented by the HyperlightSandboxTarget to specify what support is provided<\/em><\/figcaption><\/figure>\n\n\n\n<p>Between the GDB thread and the sandbox, there is a communication channel that allows the commands from GDB to be sent over to the sandbox. The sandbox processes the command and sends back a response to the GDB thread.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69e5017eb3cd5&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image aligncenter size-full wp-lightbox-container\"><img decoding=\"async\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-6.webp\" alt=\"Sequence diagram showing the process of adding a breakpoint.\" class=\"wp-image-97959 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2025\/07\/image-6.webp\"><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\"><em>Sequence diagram for adding a breakpoint<\/em><\/figcaption><\/figure>\n\n\n\n<p>Having instantiated a vCPU using KVM, the vCPU handle is a <a href=\"https:\/\/docs.rs\/kvm-ioctls\/latest\/kvm_ioctls\/struct.VcpuFd.html\" target=\"_blank\" rel=\"noreferrer noopener\">VcpuFd<\/a> type. When a command that resumes execution is received, the sandbox calls the run method on the vCPU handle and waits for it to finish.<\/p>\n\n\n\n<p>For the sandbox to start processing messages again, the vCPU needs to exit with a <a href=\"https:\/\/docs.rs\/kvm-ioctls\/latest\/kvm_ioctls\/enum.VcpuExit.html#variant.Debug\" target=\"_blank\" rel=\"noreferrer noopener\">VcpuExit<\/a>::Debug reason. The sandbox tries to figure out why the vCPU stopped and sends an event to the GDB thread to notify the reason.<\/p>\n\n\n\n<p>The other commands that do not resume execution only change the guest memory or the vCPU registers. These changes affect the vCPU after it resumes execution following a debugging command.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"in-conclusion\">In conclusion<\/h2>\n\n\n\n<p>This article explains what Hyperlight guest debugging is and why it is needed. Additionally, we show how to set up an example using a KVM guest, and we go deeper into detail explaining how it works under the hood.<\/p>\n\n\n\n<p>To experiment with the example, please check out the <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight-kubeconNA2024-demo\/tree\/c5274ad8eb9931a6d851b44a5b68f17629e58437\" target=\"_blank\" rel=\"noreferrer noopener\">repository<\/a> and follow the instructions in this article to set up a debugging session on a guest. More information on this can be found in the <a href=\"https:\/\/github.com\/hyperlight-dev\/hyperlight\/blob\/v0.4.0\/docs\/how-to-debug-a-hyperlight-guest.md\" target=\"_blank\" rel=\"noreferrer noopener\">repository docs<\/a>. The information present in this guide also applies to HyperV on Windows and Linux guest applications\u2014the only differences lie in the way each hypervisor is instructed to enable debugging of the vCPU due to different hypervisor APIs.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can now interactively debug Hyperlight guest micro-VMs. Attach the GNU Debugger at runtime to step through the code.<\/p>\n","protected":false},"author":6266,"featured_media":95467,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"msxcm_post_with_no_image":false,"ep_exclude_from_search":false,"_classifai_error":"","_classifai_text_to_speech_error":"","footnotes":""},"post_tag":[400,227],"content-type":[340],"topic":[],"programming-languages":[],"coauthors":[2608],"class_list":["post-97947","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-vs-code","tag-windows","content-type-tutorials-and-demos","review-flag-1593580428-734","review-flag-1593580419-521","review-flag-1-1593580432-963","review-flag-2-1593580437-411","review-flag-new-1593580248-669","review-flag-vm-1593580807-312"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Hyperlight: Debugging hardware-protected guests | Microsoft Open Source Blog<\/title>\n<meta name=\"description\" content=\"Find out how you can step through code in your guest micro-VM by attaching the GNU Debugger at runtime to debug Hyperlight guest micro-VMs.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Hyperlight: Debugging hardware-protected guests | Microsoft Open Source Blog\" \/>\n<meta property=\"og:description\" content=\"Find out how you can step through code in your guest micro-VM by attaching the GNU Debugger at runtime to debug Hyperlight guest micro-VMs.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/\" \/>\n<meta property=\"og:site_name\" content=\"Microsoft Open Source Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-07-14T17:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-08-26T21:10:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1170\" \/>\n\t<meta property=\"og:image:height\" content=\"640\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Doru Bl\u00e2nzeanu\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@OpenAtMicrosoft\" \/>\n<meta name=\"twitter:site\" content=\"@OpenAtMicrosoft\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Doru Bl\u00e2nzeanu\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 min read\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/\"},\"author\":[{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/author\/doru-blanzeanu\/\",\"@type\":\"Person\",\"@name\":\"Doru Bl\u00e2nzeanu\"}],\"headline\":\"Hyperlight: Debugging hardware-protected guests\",\"datePublished\":\"2025-07-14T17:00:00+00:00\",\"dateModified\":\"2025-08-26T21:10:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/\"},\"wordCount\":1780,\"publisher\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.webp\",\"keywords\":[\"VS Code\",\"Windows\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/\",\"name\":\"Hyperlight: Debugging hardware-protected guests | Microsoft Open Source Blog\",\"isPartOf\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.webp\",\"datePublished\":\"2025-07-14T17:00:00+00:00\",\"dateModified\":\"2025-08-26T21:10:41+00:00\",\"description\":\"Find out how you can step through code in your guest micro-VM by attaching the GNU Debugger at runtime to debug Hyperlight guest micro-VMs.\",\"breadcrumb\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#primaryimage\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.webp\",\"contentUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.webp\",\"width\":1170,\"height\":640},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/opensource.microsoft.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Hyperlight: Debugging hardware-protected guests\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#website\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/\",\"name\":\"Microsoft Open Source Blog\",\"description\":\"Open dialogue about openness at Microsoft \u2013 open source, standards, interoperability\",\"publisher\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/opensource.microsoft.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\",\"name\":\"Microsoft Open Source Blog\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"contentUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"width\":259,\"height\":194,\"caption\":\"Microsoft Open Source Blog\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/OpenAtMicrosoft\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Hyperlight: Debugging hardware-protected guests | Microsoft Open Source Blog","description":"Find out how you can step through code in your guest micro-VM by attaching the GNU Debugger at runtime to debug Hyperlight guest micro-VMs.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/","og_locale":"en_US","og_type":"article","og_title":"Hyperlight: Debugging hardware-protected guests | Microsoft Open Source Blog","og_description":"Find out how you can step through code in your guest micro-VM by attaching the GNU Debugger at runtime to debug Hyperlight guest micro-VMs.","og_url":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/","og_site_name":"Microsoft Open Source Blog","article_published_time":"2025-07-14T17:00:00+00:00","article_modified_time":"2025-08-26T21:10:41+00:00","og_image":[{"width":1170,"height":640,"url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.png","type":"image\/png"}],"author":"Doru Bl\u00e2nzeanu","twitter_card":"summary_large_image","twitter_creator":"@OpenAtMicrosoft","twitter_site":"@OpenAtMicrosoft","twitter_misc":{"Written by":"Doru Bl\u00e2nzeanu","Est. reading time":"7 min read"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#article","isPartOf":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/"},"author":[{"@id":"https:\/\/opensource.microsoft.com\/blog\/author\/doru-blanzeanu\/","@type":"Person","@name":"Doru Bl\u00e2nzeanu"}],"headline":"Hyperlight: Debugging hardware-protected guests","datePublished":"2025-07-14T17:00:00+00:00","dateModified":"2025-08-26T21:10:41+00:00","mainEntityOfPage":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/"},"wordCount":1780,"publisher":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#organization"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#primaryimage"},"thumbnailUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.webp","keywords":["VS Code","Windows"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/","url":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/","name":"Hyperlight: Debugging hardware-protected guests | Microsoft Open Source Blog","isPartOf":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#primaryimage"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#primaryimage"},"thumbnailUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.webp","datePublished":"2025-07-14T17:00:00+00:00","dateModified":"2025-08-26T21:10:41+00:00","description":"Find out how you can step through code in your guest micro-VM by attaching the GNU Debugger at runtime to debug Hyperlight guest micro-VMs.","breadcrumb":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#primaryimage","url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.webp","contentUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO20b_Garrett_Preeti_Jayesh_Aline_001_v2.webp","width":1170,"height":640},{"@type":"BreadcrumbList","@id":"https:\/\/opensource.microsoft.com\/blog\/2025\/07\/14\/hyperlight-debugging-hardware-protected-guests\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/opensource.microsoft.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Hyperlight: Debugging hardware-protected guests"}]},{"@type":"WebSite","@id":"https:\/\/opensource.microsoft.com\/blog\/#website","url":"https:\/\/opensource.microsoft.com\/blog\/","name":"Microsoft Open Source Blog","description":"Open dialogue about openness at Microsoft \u2013 open source, standards, interoperability","publisher":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/opensource.microsoft.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/opensource.microsoft.com\/blog\/#organization","name":"Microsoft Open Source Blog","url":"https:\/\/opensource.microsoft.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","contentUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","width":259,"height":194,"caption":"Microsoft Open Source Blog"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/OpenAtMicrosoft"]}]}},"msxcm_display_generated_audio":false,"msxcm_animated_featured_image":null,"distributor_meta":false,"distributor_terms":false,"distributor_media":false,"distributor_original_site_name":"Microsoft Open Source Blog","distributor_original_site_url":"https:\/\/opensource.microsoft.com\/blog","push-errors":false,"_links":{"self":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/97947","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/users\/6266"}],"replies":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/comments?post=97947"}],"version-history":[{"count":17,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/97947\/revisions"}],"predecessor-version":[{"id":97995,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/97947\/revisions\/97995"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/media\/95467"}],"wp:attachment":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/media?parent=97947"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/post_tag?post=97947"},{"taxonomy":"content-type","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/content-type?post=97947"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/topic?post=97947"},{"taxonomy":"programming-languages","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/programming-languages?post=97947"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/coauthors?post=97947"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}