{"id":2128,"date":"2020-05-10T08:52:38","date_gmt":"2020-05-10T15:52:38","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=2128"},"modified":"2020-05-11T18:44:12","modified_gmt":"2020-05-12T01:44:12","slug":"debugging-memory-corruption-errors-with-dynamic-stack-checking","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/stack\/","title":{"rendered":"Debugging Memory Corruption Errors with Dynamic Stack Checking"},"content":{"rendered":"<p>This tutorial shows how to use the dynamic stack checking feature of VisualGDB 5.2 to quickly locate code stack overflows before they create hard-to-trace memory corruption errors.<\/p>\n<p>Before you begin, install VisualGDB 5.2 or later.<\/p>\n<ol>\n<li>Start Visual Studio and select the VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/07\/emb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5926\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/07\/emb.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Choose the name and location for your project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-name.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6044\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-name.png\" alt=\"\" width=\"966\" height=\"624\" \/><\/a><\/li>\n<li>We will create a normal embedded project, so proceed with the default settings on the first page:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-msb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6045\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-msb.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page select your device. In this tutorial we will use the STM32F4-Discovery board that has the <strong>STM32F407VG<\/strong> chip. We will use the newlib&#8217;s semihosting functionality to output debug messages to Visual Studio, so set the &#8220;<strong>implementations for _sbrk(), etc<\/strong>&#8221; option to &#8220;<strong>Support Semihosting<\/strong>&#8220;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-device-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6046\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-device-1.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a>Note that the dynamic stack checking is not specific to STM32 devices and will work with all modern ARM Cortex devices.<\/li>\n<li>On the next page select the basic &#8220;LEDBlink&#8221; sample and click &#8220;Next&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-blink-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6047\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-blink-1.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Finally select your debug method. In most of the cases, VisualGDB will automatically detect the debug parameters, as long as you connect your board to the USB port:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-stlink.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6048\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-stlink.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to create the project. Then open VisualGDB Project Properties, go to the Embedded Frameworks page and reference the &#8220;Fixed stack and heap&#8221; framework. Then enter the stack and heap sizes to fill the device RAM almost completely. Pick a large value for the heap that is larger than the device RAM (we will decrease it later):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-heap.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6050\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-heap.png\" alt=\"\" width=\"1177\" height=\"754\" \/><\/a><\/li>\n<li>Replace the contents of the main file with the following code:\n<pre class=\"\">#include &lt;stm32f4xx_hal.h&gt;\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\nvolatile int g_Tick;\r\n\r\nextern \"C\" void SysTick_Handler(void)\r\n{\r\n\u00a0\u00a0 \u00a0HAL_IncTick();\r\n\u00a0\u00a0 \u00a0HAL_SYSTICK_IRQHandler();\r\n    g_Tick++;\r\n}\r\n\r\nint main(void)\r\n{\r\n\u00a0\u00a0\u00a0 HAL_Init();\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 const int bufferCount = 128;\r\n\u00a0\u00a0\u00a0 void *buffers[bufferCount] = { 0, };\r\n    printf(\"Starting...\\n\");\r\n\u00a0\u00a0\u00a0 for (;;)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for (int i = 0; i &lt; bufferCount; i++)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 buffers[i] = malloc(1024);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (!buffers[i])\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 printf(\"Allocated %d buffers\\n\", i);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for (int i = 0; i &lt; bufferCount; i++)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (buffers[i])\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 free(buffers[i]);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 buffers[i] = NULL;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>It will repeatedly try to allocate all of the available memory using <strong>malloc()<\/strong>, display the amount allocated and then free it.<\/li>\n<li>Try building the project. The linker will report a memory overflow showing how many extra bytes did not fit:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-overflow-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6052\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-overflow-1.png\" alt=\"\" width=\"1183\" height=\"759\" \/><\/a><\/li>\n<li>Reduce the heap size on the Embedded Frameworks page by the value shown in the link error (e.g. 20000-75536=124464) and build the project again:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6053\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-built.png\" alt=\"\" width=\"1183\" height=\"759\" \/><\/a><\/li>\n<li>Now you can run the program and check that the memory is repeatedly allocated without any problems:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-allocated.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6054\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-allocated.png\" alt=\"\" width=\"1183\" height=\"759\" \/><\/a><\/li>\n<li>Now we will add code that will corrupt the memory by overrunning the stack. Add 3 functions shown below and call <strong>func1()<\/strong> from the<strong>SysTick_Handler() <\/strong>on 10-th timer interrupt:\n<pre class=\"\">void func3()\r\n{\r\n    char data[2048];\r\n    memset(data, 0xA5, sizeof(data));\r\n}\r\n\r\nvoid func2()\r\n{\r\n    char data[2048];\r\n    memset(data, 0xAA, sizeof(data));\r\n    func3();\r\n}\r\n\r\nvoid func1()\r\n{\r\n    char data[2048];\r\n    memset(data, 0x55, sizeof(data));\r\n    func2();\r\n}\r\n\r\nvolatile int g_Tick;\r\nextern \"C\" void SysTick_Handler(void)\r\n{\r\n    HAL_IncTick();\r\n    HAL_SYSTICK_IRQHandler();\r\n    if (!(g_Tick++ % 10))\r\n        func1();\r\n}\r\n<\/pre>\n<p>Each of the 3 functions will try to use 2KB of memory, quickly adding up to more than the 4KB stack size selected in VisualGDB Project Properties.<\/li>\n<li>Run the project now. You will see how the output quickly stops and if you press the &#8216;break all&#8217; button, you will see that the program is stuck at the hard fault handler caused by the <strong>free()<\/strong> function. If you are using VisualGDB 5.5 or later, open the <strong>Debug-&gt;Live Watch<\/strong> window to observe the state of the heap in real time (only works with newlib-nano):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-crash.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6055\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-crash.png\" alt=\"\" width=\"1183\" height=\"759\" \/><\/a><\/li>\n<li>If the error does not trigger for a long time, try switching to the regular <strong>libc<\/strong> instead of newlib-nano:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-libc.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6056\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-libc.png\" alt=\"\" width=\"928\" height=\"650\" \/><\/a><\/li>\n<li>If this was a real project and we did not know what is corrupting the stack, it could take several hours to pinpoint it using the regular means. The new Dynamic Stack Analysis introduced in VisualGDB 5.2 makes it much easier by inserting stack bounds checking code in each of your functions. Open VisualGDB Project Properties and go to the Dynamic Analysis page (requires Custom edition or higher). Enable the &#8220;Instrument the functions in your program to check for stack overflow&#8221; checkbox:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/12-dynamic.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6057\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/12-dynamic.png\" alt=\"\" width=\"928\" height=\"650\" \/><\/a><\/li>\n<li>Then click &#8220;<strong>Enable stack usage reporting<\/strong>&#8221; and &#8220;<strong>Add reference automatically<\/strong>&#8221; to adjust the necessary project properties and build your project. Most likely you would need to reduce the heap size again to fit the fast semihosting buffer used by the profiler framework:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/14-reduced.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6060\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/14-reduced.png\" alt=\"\" width=\"928\" height=\"650\" \/><\/a><\/li>\n<li>Disable the regular semihosting to avoid conflicts between it and the Fast Semihosting:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/13-nosemihost.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6059\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/13-nosemihost.png\" alt=\"\" width=\"928\" height=\"650\" \/><\/a><\/li>\n<li>If you run your project now, VisualGDB will immediately detect the stack overflow and will show a detailed report:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/15-break-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6061\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/15-break-1.png\" alt=\"\" width=\"1183\" height=\"759\" \/><\/a>Examine the call stack window to see when the overflow happened. In this example it happens when a timer interrupt happens while the <strong>malloc()<\/strong> function is running.<\/li>\n<li>Dynamic checking has a side effect of slowing down your program. If you open the Disassembly view, you will notice that all function calls were replaced with calls to special profiler stubs:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/16-sym.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6062\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/16-sym.png\" alt=\"\" width=\"1183\" height=\"759\" \/><\/a><\/li>\n<li>Each stub invokes the SysprogsStackVerifierHook() function that does the actual stack checking:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/17-hook.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6063\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/17-hook.png\" alt=\"\" width=\"1183\" height=\"759\" \/><\/a><\/li>\n<li>You can exclude some of the functions from stack checks via the Dynamic Analysis page of VisualGDB Project Properties. E.g. we can exclude the offending <strong>func2()<\/strong> function to see how this affects the analysis:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/18-exclude.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6064\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/18-exclude.png\" alt=\"\" width=\"1042\" height=\"759\" \/><\/a><\/li>\n<li>If you run your program now, the overflow won&#8217;t be detected upon entry to <strong>func2()<\/strong>, but will still be caught when <strong>memset()<\/strong> is called:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/19-caught.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6065\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/19-caught.png\" alt=\"\" width=\"1183\" height=\"759\" \/><\/a>When you are done analyzing your project, you don&#8217;t need to rebuild it again. Simply disable the stack checking on the Dynamic Analysis page of VisualGDB Project Properties and VisualGDB will not instrument your functions until you enable this feature again. The profiler framework will be compiled in, but won&#8217;t be activated unless you explicitly start profiling or enable analysis again.<\/li>\n<\/ol>\n<p>You can find the source code shown in this tutorial in our <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/tree\/master\/visualgdb\/ARM\/StackGuardDemo\">GitHub repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use the dynamic stack checking feature of VisualGDB 5.2 to quickly locate code stack overflows<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27],"tags":[53,133,61],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2128"}],"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=2128"}],"version-history":[{"count":7,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2128\/revisions"}],"predecessor-version":[{"id":6067,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2128\/revisions\/6067"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=2128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=2128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=2128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}