{"id":652,"date":"2022-09-28T10:56:59","date_gmt":"2022-09-28T17:56:59","guid":{"rendered":"https:\/\/sysprogs.com\/tutorials\/?p=652"},"modified":"2022-09-28T10:56:59","modified_gmt":"2022-09-28T17:56:59","slug":"using-live-watch-to-monitor-kernel-mode-code-in-real-time","status":"publish","type":"post","link":"https:\/\/sysprogs.com\/VisualKernel\/tutorials\/livewatch\/","title":{"rendered":"Using Live Watch to Monitor Kernel-Mode Code in Real Time"},"content":{"rendered":"<p>This tutorial shows how to use Live Watch to monitor the state of your kernel-mode code without having to stop it in the debugger.<\/p>\n<p>Before you begin, install Visual Studio and VisualKernel 4.0 or later.<\/p>\n<ol>\n<li>Start Visual Studio and open the Linux Kernel Module Wizard:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/01-newprj-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-628\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/01-newprj-1.png\" alt=\"\" width=\"1014\" height=\"675\" \/><\/a><\/li>\n<li>Enter the name and location for your project:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/02-prjname-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-653\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/02-prjname-1.png\" alt=\"\" width=\"1014\" height=\"675\" \/><\/a><\/li>\n<li>Select the project template you would like to use. In this tutorial we will create a basic RAM disk and will show how to monitor its read\/write count without setting any breakpoints, hence select &#8220;Ramdisk&#8221; and click &#8220;Next&#8221;:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/03-ramdisk.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-654\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/03-ramdisk.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Select the target you would like to use. Live Watch transfers data via the network interface, so it supports most of the kernel targets:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/04-vm-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-655\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/04-vm-1.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Proceed with the default selection of storing the sources on the Windows side: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/05-source.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-656\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/05-source.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Finally, select the debug settings that work for your target and click &#8220;Finish&#8221; to create the project: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/06-debug-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-657\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/06-debug-1.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Once the project has been created, you can build it by pressing Ctrl-Shift-B: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/07-build-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-658\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/07-build-1.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Once the build succeeds, try setting a breakpoint in the <strong>BasicRamDisk_SubmitBIO()<\/strong> function and press F5 to begin debugging. Once the triggers, use the Call Stack window to see the context of the call. In this example, the first I\/O operation submitted to the disk comes from the <strong>disk_scan_partitions()<\/strong> function trying to scan the partition table:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/08-scan.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-659\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/08-scan.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Press F5 to continue debugging. Then, right-click on the project node in Solution Explorer and select &#8220;Open a new SSH window&#8221;:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/09-ssh-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-660\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/09-ssh-1.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Once the window opens, run &#8220;sudo dmesg&#8221; to view the commands necessary to test out the RAM disk:\n<pre class=\"\">sudo mkfs \/dev\/LiveWatchDemoDisk1\r\nsudo mkdir \/mnt\/ramdisk\r\nsudo mount \/dev\/LiveWatchDemoDisk1 \/mnt\/ramdisk<\/pre>\n<p>Run the commands from the <strong>dmesg<\/strong> output and make sure the disk is initialized and mounted:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/10-ramdisk.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-661\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/10-ramdisk.png\" alt=\"\" width=\"905\" height=\"523\" \/><\/a><\/li>\n<li>Using the debugger to see what is going on could be useful in many scenarios, however it stops the target while you are examining its state. Live Watch avoids this by sampling the values of different variables over the UDP connection without having to stop the target. In order to test it out, add the following 2 variables to the <strong>BasicRamDisk.c<\/strong> file:\n<pre class=\"\">static uint64_t s_BytesIn;\r\nstatic uint64_t s_BytesOut;<\/pre>\n<p>Then, update the <strong>BasicRamDisk_Transfer()<\/strong> function to increment either <strong>s_BytesIn<\/strong> or <strong>s_BytesOut<\/strong> depending on the direction of the transfer:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/11-instrument.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-662\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/11-instrument.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Start the debug session, open the <strong>Debug-&gt;Windows-&gt;Live Watch<\/strong> window and switch it to the <strong>Globals<\/strong> view. Observe how the values of <strong>s_BytesIn<\/strong> and <strong>s_BytesOut<\/strong> are immediately shown both in the Live Watch window and directly in the code:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/12-live.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-663\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/12-live.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a>You can read more about various Live Watch modes and settings on <a href=\"https:\/\/visualgdb.com\/documentation\/livevars\/\">this page<\/a>.<\/li>\n<li>Click the &#8220;Plot&#8221; column for both variables, then try copying some data to the RAM disk. Note how the data is actually written when you run the &#8220;sync&#8221; command (00:42 below). Try unmounting the disk, remounting it and comparing the copied file. Observe how the number of read bytes now matches the number of written ones:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/13-graph.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-664\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/13-graph.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>You can also use Live Watch to observe and plot various variables from the kernel itself. Expand the [vmlinux] node in Live Watch and type &#8220;^jiffies&#8221; in the filter: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/14-jiffies.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-665\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/14-jiffies.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Click the plot column to plot the value of <strong>jiffies<\/strong> (system clock):<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/15-plot2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-666\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/15-plot2.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a>Note that because the value of <strong>jiffies<\/strong> is much larger than the values of <strong>s_BytesIn<\/strong> or <strong>s_BytesOut<\/strong>, it completely eclipsed both of them on the graph.<\/li>\n<li>Click the settings button and enable the &#8220;scale each variable independently&#8221; checkbox. See how the values are now properly visible:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/16-scale.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-667\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/16-scale.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>You can configure VisualKernel to show the graphs in separate horizontal spaces (i.e. under each other), so that similar changes to multiple graphs won&#8217;t obscure each other:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/17-spaces.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-668\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/17-spaces.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use Live Watch to monitor the state of your kernel-mode code without having to stop<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59],"tags":[61],"_links":{"self":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/652"}],"collection":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/comments?post=652"}],"version-history":[{"count":1,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/652\/revisions"}],"predecessor-version":[{"id":669,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/652\/revisions\/669"}],"wp:attachment":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/media?parent=652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/categories?post=652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/tags?post=652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}