{"id":4268,"date":"2018-11-08T15:39:40","date_gmt":"2018-11-08T23:39:40","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=4268"},"modified":"2020-05-05T17:12:35","modified_gmt":"2020-05-06T00:12:35","slug":"analyzing-the-stack-usage-of-your-firmware-with-visualgdb","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/stack\/static\/","title":{"rendered":"Analyzing the Stack Usage of your Firmware with VisualGDB"},"content":{"rendered":"<p>This tutorial shows how to analyze the stack usage of your\u00a0ARM firmware using the VisualGDB&#8217;s static stack analyzer. We will create a basic FreeRTOS-based project\u00a0for the STM32F4-Discovery board, will analyze the stack usage by 2 threads, show how to explore the critical path and how to\u00a0account for cases like\u00a0dynamic function calls.<\/p>\n<p>Before you begin, install VisualGDB 5.4 or later.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/01-newprj1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4269\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/01-newprj1.png\" alt=\"01-newprj\" width=\"920\" height=\"564\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/01-newprj1.png 920w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/01-newprj1-300x184.png 300w\" sizes=\"(max-width: 920px) 100vw, 920px\" \/><\/a><\/li>\n<li>Select &#8220;Create a new project&#8221; -&gt; &#8220;Embedded binary&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/02-binary.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4270\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/02-binary.png\" alt=\"02-binary\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/02-binary.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/02-binary-300x235.png 300w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>On the next of the wizard select your toolchain and the device:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/03-board.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4271\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/03-board.png\" alt=\"03-board\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/03-board.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/03-board-300x235.png 300w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>We will demonstrate the stack analysis under FreeRTOS. Unlike single-threaded projects where the stack automatically utilizes all available space between the end of heap and the end of RAM, RTOS-based projects require explicitly sizing\u00a0the stack for each thread, and hence are more prone to stack overflow.\u00a0Choose the &#8220;LEDBlink (FreeRTOS)&#8221; sample and click &#8220;Next&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/04-sample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4272\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/04-sample.png\" alt=\"04-sample\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/04-sample.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/04-sample-300x235.png 300w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Connect your board to the USB port and let VisualGDB automatically detect the debug settings. Then press &#8220;Finish&#8221; to generate the project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/05-stlink.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4273\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/05-stlink.png\" alt=\"05-stlink\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/05-stlink.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/05-stlink-300x235.png 300w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Once the project is created, built it with Ctrl-Shift-B:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/06-project.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4274\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/06-project.png\" alt=\"06-project\" width=\"977\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/06-project.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/06-project-300x213.png 300w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Note how the RTOS-based projects require setting the stack size for each thread explicitly:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/minsize.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4285\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/minsize.png\" alt=\"minsize\" width=\"1138\" height=\"773\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/minsize.png 1138w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/minsize-300x204.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/minsize-1024x696.png 1024w\" sizes=\"(max-width: 1138px) 100vw, 1138px\" \/><\/a><\/li>\n<li>Once the project is built, open the View-&gt;Embedded Memory Explorer\u00a0and\u00a0switch it to the static stack view:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/07-eme.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4275\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/07-eme.png\" alt=\"07-eme\" width=\"977\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/07-eme.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/07-eme-300x213.png 300w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>The Memory Explorer will display\u00a0a list of all functions in your program and the stack\u00a0usage by each of them:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/08-mainstack.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4276\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/08-mainstack.png\" alt=\"08-mainstack\" width=\"977\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/08-mainstack.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/08-mainstack-300x213.png 300w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a>The stack usage is computed from analyzing the disassembly of each function, so it will also work for library functions. To make it easier account for rare\u00a0scenarios,\u00a0the code responsible for analyzing the stack-related effects\u00a0of each instruction runs in a separate <a href=\"https:\/\/github.com\/sysprogs\/VisualGDBExtensibilityExamples\/tree\/master\/PlatformSpecificStackAnalyzers\/ARM\">open-source plugin<\/a>, so you can tweak it if your project uses\u00a0unconventional ways of\u00a0moving the stack pointer, or is not based on the ARM architecture.<\/li>\n<li>Find the LED_Thread2 in the list and expand the critical path:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/09-criticalpath.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4277\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/09-criticalpath.png\" alt=\"09-criticalpath\" width=\"977\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/09-criticalpath.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/09-criticalpath-300x213.png 300w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a>VisualGDB will show that the\u00a0worst-case stack usage of the <strong>LED_Thread2()<\/strong>\u00a0function is 144 bytes (Max. stack column), that is actually larger than the 128 bytes allocated for the stack.\u00a0Each level of the critical path will show how much stack was already\u00a0used by the callers by the time a certain function was called (Stack on Entry column) and how much stack does each function itself use, not counting any called functions (Own Stack column).<\/li>\n<li>Now we will try to reproduce the\u00a0worst-case scenario in debugger. Set a breakpoint in <strong>LED_Thread2()<\/strong> and try stepping in the functions along the critical path. Under normal circumstances, <strong>LED_Thread2()<\/strong>\u00a0will never run for long enough time to trigger the additional processing in <strong>xTaskResumeAll()<\/strong>\u00a0that lies on the critical path, so the\u00a0stack will never get overflown. However, adding a non-trivial interrupt handler later may affect the timing of the threads, trigger this branch and ultimately lead to a crash. We will simulate it by simply using the &#8220;Set Next Statement&#8221; command to step into the\u00a0block calling\u00a0<strong>xTaskIncrementTick()<\/strong>:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/10-tick.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4278\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/10-tick.png\" alt=\"10-tick\" width=\"977\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/10-tick.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/10-tick-300x213.png 300w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Apply the same trick to step into <strong>uxListRemove()<\/strong> to get the worst-case stack layout in the debugger. Then switch the Embedded Memory Explorer to the Debug Stack view:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-structure.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4279\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-structure.png\" alt=\"11-structure\" width=\"1138\" height=\"773\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-structure.png 1138w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-structure-300x204.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-structure-1024x696.png 1024w\" sizes=\"(max-width: 1138px) 100vw, 1138px\" \/><\/a>The Debug Stack view queries the exact locations of the stack frames in memory from the debugger,\u00a0visualizes them and displays detailed statistics. You can switch between frames to see the\u00a0variables and saved\u00a0registers contributing to the stack usage by each function. The white space between the variables is either lost due to alignment, or\u00a0could not be traced back to specific variables by the gdb debugger.<\/li>\n<li>Now we will modify the LED_Thread1() function to dramatically increase its worst-case stack use. Add the following function to your code:\n<pre class=\"\">void UseStack()\r\n{\r\n  volatile char buf[1024];\r\n  buf[0]++;\r\n}<\/pre>\n<p>Then call it from <strong>LED_Thread1()<\/strong>:<\/p>\n<pre class=\"\">if (rand() == 13)\r\n  UseStack();<\/pre>\n<\/li>\n<li>As\u00a0the call to UseStack() is conditional (and the condition has a very low probability), dynamic analysis would likely not catch this. However as the\u00a0static analysis always considers the worst possible call sequence, it clearly shows that the stack use by <strong>LED_Thread1()<\/strong> has jumped to 1048 bytes:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-rarecase.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4280\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-rarecase.png\" alt=\"12-rarecase\" width=\"1138\" height=\"773\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-rarecase.png 1138w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-rarecase-300x204.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-rarecase-1024x696.png 1024w\" sizes=\"(max-width: 1138px) 100vw, 1138px\" \/><\/a><\/li>\n<li>Now we will complicate our scenario. Add the following global variable to your main file:\n<pre class=\"\">void(*g_pFunc)();<\/pre>\n<p>Update <strong>LED_Thread1()<\/strong> to set <strong>g_pFunc<\/strong> to UseStack() instead of calling it:<\/p>\n<pre class=\"\">if (rand() == 13)\r\n  g_pFunc = &amp;UseStack;<\/pre>\n<\/li>\n<li>Finally call the\u00a0function pointer from <strong>LED_Thread2()<\/strong>:\n<pre class=\"\">if (g_pFunc)\r\n  g_pFunc();<\/pre>\n<\/li>\n<li>The stack analyzer won&#8217;t be able to\u00a0automatically unwind this, so it will show the stack usage for <strong>LED_Thread2()<\/strong> as 144, but will warn that it contains dynamic calls:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-dynamic.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4281\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-dynamic.png\" alt=\"13-dynamic\" width=\"1138\" height=\"773\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-dynamic.png 1138w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-dynamic-300x204.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-dynamic-1024x696.png 1024w\" sizes=\"(max-width: 1138px) 100vw, 1138px\" \/><\/a><\/li>\n<li>One way to handle this automatically would be to extend the <a href=\"https:\/\/github.com\/sysprogs\/VisualGDBExtensibilityExamples\/tree\/master\/PlatformSpecificStackAnalyzers\/ARM\">stack analyzer plugin<\/a> to check for possible values written to a certain variable, but that\u00a0would\u00a0still not cover all the cases. Instead, right-click on <strong>LED_Thread2()<\/strong> and select &#8220;Manually add calls from the selected function&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-addcalls.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4282\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-addcalls.png\" alt=\"14-addcalls\" width=\"1138\" height=\"773\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-addcalls.png 1138w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-addcalls-300x204.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-addcalls-1024x696.png 1024w\" sizes=\"(max-width: 1138px) 100vw, 1138px\" \/><\/a><\/li>\n<li>Check the &#8220;UseStack&#8221; symbol and click &#8220;OK&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-implicit.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4283\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-implicit.png\" alt=\"15-implicit\" width=\"586\" height=\"307\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-implicit.png 586w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-implicit-300x157.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-implicit-390x205.png 390w\" sizes=\"(max-width: 586px) 100vw, 586px\" \/><\/a><\/li>\n<li>VisualGDB will\u00a0now recompute the stack usage for <strong>LED_Thread2()<\/strong> as if it directly called <strong>UseStack()<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-injected.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4284\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-injected.png\" alt=\"16-injected\" width=\"1138\" height=\"773\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-injected.png 1138w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-injected-300x204.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-injected-1024x696.png 1024w\" sizes=\"(max-width: 1138px) 100vw, 1138px\" \/><\/a><\/li>\n<li>VisualGDB stores the\u00a0manually specified calls in a text file called &lt;Project Name&gt;.stackrules. It\u00a0uses\u00a0a very straight-forward format, so you can generate\/update those rules programmatically:\n<pre class=\"\">#This file stores explicit relations between functions\r\n#Format:\r\n#&lt;function&gt;:[&lt;optional stack size override&gt;]\r\n#&lt;tab&gt;&lt;called function&gt;:[&lt;optional stack usage at the time of call&gt;]\r\nLED_Thread2\r\n  UseStack<\/pre>\n<\/li>\n<\/ol>\n<p>You can find the\u00a0source code for the project shown in this tutorial in our <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/tree\/master\/visualgdb\/ARM\/MemoryExplorer\/StaticStackAnalyzerDemo\">tutorial repository on GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to analyze the stack usage of your\u00a0ARM firmware using the VisualGDB&#8217;s static stack analyzer. We will<\/p>\n","protected":false},"author":1,"featured_media":4287,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27],"tags":[53,174,173],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4268"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=4268"}],"version-history":[{"count":4,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4268\/revisions"}],"predecessor-version":[{"id":5999,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4268\/revisions\/5999"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media\/4287"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=4268"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=4268"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=4268"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}