<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>stack overflow and STACK GUARD</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/47040/stack-overflow-and-stack-guard</link><description>I am using nrf52832 SDK14.2 development, now the system will generate some strange exceptions, I am worried about the stack overflow, is there any way to confirm whether the stack overflows, where does the stack overflow? In addition, I saw the STACK</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 19 Dec 2019 14:20:56 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/47040/stack-overflow-and-stack-guard" /><item><title>RE: stack overflow and STACK GUARD</title><link>https://devzone.nordicsemi.com/thread/226406?ContentTypeID=1</link><pubDate>Thu, 19 Dec 2019 14:20:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c44bb063-432c-468a-b8b8-d777a6ead443</guid><dc:creator>Tony Garland</dc:creator><description>&lt;p&gt;Hi Bill,&lt;/p&gt;
&lt;p&gt;Yes, I had used&amp;nbsp;stepi as well at times (also using GDB) and it stepped right through the read from zero, fetching the vector value successfully. &amp;nbsp;One reason why I didn&amp;#39;t suspect the debugger as an influence is that a different region with&amp;nbsp;memory protection to detect impending stack overflow (Nordic&amp;#39;s STACK GUARD) -- which I modified to trigger on both read and write--works as expected, even when stepping. Both reads and writes immediately memory fault.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m confident that there are no other memory regions. &amp;nbsp;My code is running early in the initialization process, immediately after nrf_mpu_init() which clears all memory regions. And immediately after setting up this particular memory region, I test it--before any other code could possibly intervene.&lt;/p&gt;
&lt;p&gt;A bit later, after setting up both regions, the MPU regions read&amp;nbsp;as follows:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;00&amp;gt; MPU-&amp;gt;RNR = 0, RASR = 0x00080013, RBAR = 0x00000000
00&amp;gt; MPU-&amp;gt;RNR = 1, RASR = 0x1029000D, RBAR = 0x2003B201
00&amp;gt; MPU-&amp;gt;RNR = 2, RASR = 0x00000000, RBAR = 0x00000002
00&amp;gt; MPU-&amp;gt;RNR = 3, RASR = 0x00000000, RBAR = 0x00000003
00&amp;gt; MPU-&amp;gt;RNR = 4, RASR = 0x00000000, RBAR = 0x00000004
00&amp;gt; MPU-&amp;gt;RNR = 5, RASR = 0x00000000, RBAR = 0x00000005
00&amp;gt; MPU-&amp;gt;RNR = 6, RASR = 0x00000000, RBAR = 0x00000006
00&amp;gt; MPU-&amp;gt;RNR = 7, RASR = 0x00000000, RBAR = 0x00000007&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Region 0 is the NULL pointer region and region 1 is the stack guard. The other regions are empty/disabled (the RBAR returns the region number on read--the values were set to zero on write by nrf_mpu_init()).&lt;/p&gt;
&lt;p&gt;I&amp;#39;m using a Segger J-LINK debugger and the project is built using Segger Embedded Studio--which uses gcc under-the-hood. &amp;nbsp;The target is custom hardware developed by a client.&lt;/p&gt;
&lt;p&gt;Again - thanks for your time and thoughts on this. &amp;nbsp;I&amp;#39;ve got a working system for the purposes of what I&amp;#39;m trying to accomplish, even if I don&amp;#39;t understand why stepping through reads at 0 acts differently than steeping through reads in the stack guard region.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: stack overflow and STACK GUARD</title><link>https://devzone.nordicsemi.com/thread/226289?ContentTypeID=1</link><pubDate>Thu, 19 Dec 2019 08:23:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d8bdeb4b-0403-4afa-b811-2b29f42e291a</guid><dc:creator>wpaul</dc:creator><description>[quote userid="3697" url="~/f/nordic-q-a/47040/stack-overflow-and-stack-guard/226252"]Not exactly sure what aspect of single-stepping is suppressing the read memory fault, but that seems to be what made me think it wasn&amp;#39;t working.[/quote]
&lt;p&gt;Hm, interesting. I&amp;#39;m not sure what to tell you about that. In my tests, I&amp;#39;ve set a breakpoint right on the instruction that would generate the fault, and then done a &amp;quot;stepi&amp;quot; with GDB, to advance just one instruction further, and in that case I can see the PC jump to the expected exception vector.&lt;/p&gt;
&lt;p&gt;It may have to do with exactly what debugger setup you&amp;#39;re using. In my case, my development environment is a Nordic nRF52840 DK board (rev 1.0.0) with OpenOCD and GDB, using a stock GCC toolchain. The production environment is a custom board with nRF52840 board using an Olimex ARM-USB-OCD-H debugger (since our board didn&amp;#39;t have an on-board J-Link) but the other parts are the same. Either way, the MPU protection worked as expected for both reads and writes.&lt;/p&gt;
&lt;p&gt;I was going to suggest that you check the other MPU regions. According to the ARM docs, if you have two or more MPU regions that overlap, the higher number one takes precedence. So if there&amp;#39;s another region which only blocks writes, that one might override your custom one if it has a higher region number.&lt;/p&gt;
&lt;p&gt;BTW, you should be able to compile the code from my repo using a standard arm-none-eabi GNU toolchain (just make sure it&amp;#39;s in your path and type &amp;#39;make&amp;#39;) and it will boot up and run on an nRF52840 DK board, though not very well, since there will be no graphics or sound. I was going to suggest you try that just to compare against your own code, but it sounds like that&amp;#39;s not necessary now.&lt;/p&gt;
&lt;p&gt;-Bill&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: stack overflow and STACK GUARD</title><link>https://devzone.nordicsemi.com/thread/226258?ContentTypeID=1</link><pubDate>Thu, 19 Dec 2019 04:55:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:be1a7396-90fa-402a-ab93-24a541763377</guid><dc:creator>Tony Garland</dc:creator><description>&lt;p&gt;One other observation, regarding why exception vectors don&amp;#39;t trip the MPU:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;em&gt;&amp;quot;When the MPU is enabled, &lt;strong&gt;accesses to the System Control Space and vector table are always permitted&lt;/strong&gt;. Other areas are accessible based on regions and whether PRIVDEFENA is set to 1.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Source:&amp;nbsp;&lt;a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABDJJGF.html"&gt;http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABDJJGF.html&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: stack overflow and STACK GUARD</title><link>https://devzone.nordicsemi.com/thread/226252?ContentTypeID=1</link><pubDate>Thu, 19 Dec 2019 03:35:02 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:08d3cea6-c41c-4c41-9098-db0fc6ca95eb</guid><dc:creator>Tony Garland</dc:creator><description>&lt;p&gt;Hi Bill,&lt;/p&gt;
&lt;p&gt;I appreciate your timely and detailed response.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve taken a look at your code and have tried to replicate the exact settings and I&amp;#39;m still only seeing memory fault on writes to address 0, but reads do not fault.&lt;/p&gt;
&lt;p&gt;Your code is essentially:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#define mpuConfigureRegion(region, addr, attribs) {                         \
  MPU-&amp;gt;RNR  = ((uint32_t)region);                                           \
  MPU-&amp;gt;RBAR = ((uint32_t)addr);                                             \
  MPU-&amp;gt;RASR = ((uint32_t)attribs);                                          \
}

mpuConfigureRegion (MPU_REGION_6, 0x0, 
    MPU_RASR_ATTR_AP_NA_NA | 
    MPU_RASR_ATTR_NON_CACHEABLE | 
    MPU_RASR_SIZE_1K | 
    MPU_RASR_ENABLE
);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Which, following out the macro values--if&amp;nbsp;I&amp;#39;m not mistaken--becomes:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;  MPU-&amp;gt;RNR  = 6; 
  MPU-&amp;gt;RBAR = 0;
  MPU-&amp;gt;RASR = 0x00080013;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;When I execute the above code (followed by MPU-&amp;gt;CTRL = 0x05), it protects from writes only. I can execute your code snippet just fine:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;uint8_t * blah = (uint8_t *)0;
printf (&amp;quot;moo: %x\n&amp;quot;, blah[0])&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#39;s only when I execute a write that the memory fault triggers. I&amp;#39;m also enabling the individual faults:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;    SCB-&amp;gt;SHCSR |= (
      SCB_SHCSR_USGFAULTENA_Msk |
      SCB_SHCSR_BUSFAULTENA_Msk |
      SCB_SHCSR_MEMFAULTENA_Msk
      );&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;And I do get a memory management-specific fault when I write, but never on a read.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve experimented with slightly different variations of attribute settings (from a previous project running on a STM32F437 MCU that tripped on reads at 0)&amp;nbsp;but&amp;nbsp;the results remain the same--I&amp;#39;m never able to trigger a fault on reading a NULL pointer.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m using an nRF52840 and s140_nrf52_6.1.0_softdevice.hex (and I&amp;#39;m doing this MPU configuration before the SD is enabled--like you seem to do). &amp;nbsp;So I remain puzzled about what is going on.&lt;/p&gt;
&lt;p&gt;Wait a minute... I just realized that I&amp;#39;ve always stepped through this code in the debugger. &amp;nbsp;But, if I let the processor free-run through the fault-generating code (even in the debugger), then it&amp;nbsp;&lt;em&gt;does&lt;/em&gt; generate the memory fault on the read! &amp;nbsp;Wow, wish I had thought of that earlier. &amp;nbsp;Not exactly sure what aspect of single-stepping is suppressing the read memory fault, but that seems to be what made me think it wasn&amp;#39;t working.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: stack overflow and STACK GUARD</title><link>https://devzone.nordicsemi.com/thread/226002?ContentTypeID=1</link><pubDate>Wed, 18 Dec 2019 02:57:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:94dc5451-58f1-4b1e-a00f-3e5f8dd01dea</guid><dc:creator>wpaul</dc:creator><description>[quote userid="3697" url="~/f/nordic-q-a/47040/stack-overflow-and-stack-guard/225984"]My experiments[/quote]
&lt;p&gt;You need to describe your experiments, otherwise I have no idea what you actually did.&lt;/p&gt;
[quote userid="3697" url="~/f/nordic-q-a/47040/stack-overflow-and-stack-guard/225984"]Have you been able to get it to trigger on reads from&amp;nbsp;zero as well?[/quote]
&lt;p&gt;Yes, I did. That&amp;#39;s why I brought it up.&lt;/p&gt;
&lt;p&gt;The code that I used to enable the MPU is here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/netik/dc27_badge/blob/4bba0e58a304671b48755b99113b3d489259760a/software/firmware/badge/nullprot_lld.c#L72"&gt;https://github.com/netik/dc27_badge/blob/4bba0e58a304671b48755b99113b3d489259760a/software/firmware/badge/nullprot_lld.c#L72&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is done with the MPU APIs in ChibiOS, but all of the code for that is in the repo, so you should be able to resolve all the macros and see what values are actually being used.&lt;/p&gt;
&lt;p&gt;This also works for the Cortex-M7 CPU that I&amp;#39;m using now. I use test code like this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint8_t * blah = (uint8_t *)0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf (&amp;quot;moo: %x\n&amp;quot;, blah[0]);&lt;/p&gt;
&lt;p&gt;The result I get with my trap handler support is this:&lt;/p&gt;
&lt;p&gt;********** MEMMANAGE FAULT **********&lt;br /&gt;Data access violation&lt;br /&gt;Memory fault address: 0x00000000&lt;br /&gt;Fault while in thread mode&lt;br /&gt;Floating point context saved on stack&lt;br /&gt;Interrupt is pending&lt;br /&gt;Exception pending: 53&lt;br /&gt;Exception active: 4&lt;br /&gt;PC: 0x0021158C LR: 0x00204FF5 SP: 0x200007E8 SR: 0x61000000&lt;br /&gt;R0: 0x20000F38 R1: 0x20001FE4 R2: 0x00000001 R3: 0x00000000 R12: 0x00000820&lt;/p&gt;
&lt;p&gt;The PC value above is at exactly the instruction that does the load:&lt;/p&gt;
&lt;p&gt;21158c: 7823 ldrb r3, [r4, #0]&lt;/p&gt;
&lt;p&gt;The Nordic SDK has some similar code in it. You can find mine in the badge_vectors.c and badge_fault.S modules in the above github repo. Also, in main.c , I do this:&lt;/p&gt;
&lt;p&gt;/*&lt;br /&gt;&amp;nbsp; * Enable memory management, usage and bus fault exceptions, so that&lt;br /&gt;&amp;nbsp; * we don&amp;#39;t always end up diverting through the hard fault handler.&lt;br /&gt;&amp;nbsp; * Note: the memory management fault only applies if the MPU is&lt;br /&gt;&amp;nbsp; * enabled, which it currently is (for stack guard pages).&lt;br /&gt;&amp;nbsp; */&lt;br /&gt; &lt;br /&gt; SCB-&amp;gt;SHCSR |= SCB_SHCSR_USGFAULTENA_Msk |&lt;br /&gt; SCB_SHCSR_BUSFAULTENA_Msk |&lt;br /&gt; SCB_SHCSR_MEMFAULTENA_Msk;&lt;/p&gt;
&lt;p&gt;-Bill&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: stack overflow and STACK GUARD</title><link>https://devzone.nordicsemi.com/thread/225984?ContentTypeID=1</link><pubDate>Tue, 17 Dec 2019 21:15:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bb21a7dc-4d7c-4341-a489-08d45a187299</guid><dc:creator>Tony Garland</dc:creator><description>&lt;p&gt;wpaul wrote:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;em&gt;If it were me, instead of using RO/RO (0x7) as the protection attributes, I would use NA/NA (0x0). This will trap both reads and writes. Reading past the end of the stack could also be a sign of a bug that is best fixed. I have found that you can get away with doing this even when setting a protection region at address 0x0. When I first tried this I was concerned it might have some impact on exception handling (since the exception vector table is also at address 0x0), but while reads and writes are successfully trapped, exception handling seems unaffected.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I tried&amp;nbsp;setting the MPU with a region at location zero with both read and write access disabled (0x0 for AP field). My experiments show that it still allows reads--only disables writes. &amp;nbsp;So I&amp;#39;m unable to detect reads of NULL pointers. &amp;nbsp;Have you been able to get it to trigger on reads from&amp;nbsp;zero as well?&lt;/p&gt;
&lt;p&gt;- Tony&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: stack overflow and STACK GUARD</title><link>https://devzone.nordicsemi.com/thread/185827?ContentTypeID=1</link><pubDate>Wed, 08 May 2019 06:27:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8b19d075-8053-4901-819a-90fd07f9610e</guid><dc:creator>wpaul</dc:creator><description>&lt;p&gt;The stack guard library uses a feature of the Cortex-M4 processor called the Memory Protection Unit (MPU). You can use the MPU to set attributes and access rights on regions of memory. The stack guard library creates a 256-byte region at the bottom of the stack with access permissions set to read-only (for both privileged and unprivileged accesses). This means that any instruction that tries to write past the bottom of the stack will trigger a memory management fault (as opposed to just silently corrupting the stack memory).&lt;/p&gt;
&lt;p&gt;Be aware that this only applies to the application stack, and I think this will only work if you use the &amp;quot;monolithic&amp;quot; SDK examples. If for example you use the FreeRTOS examples, then each thread will have its own stack.&lt;/p&gt;
&lt;p&gt;if you don&amp;#39;t specifically enable memory manager faults in the System Handler Control and Status Register (SHCSR), then you&amp;#39;ll just get a hard fault instead. This means that you should include both the stack guard library and the hard fault handler so that you will get an informative message on the serial port to let you know what happened.&lt;/p&gt;
&lt;p&gt;Note that you can use this same technique to also trap NULL pointer bugs. You just need to create a protected region at address 0x0. Since address 0x0 corresponds to the start of flash, reading from there is allowed and writing just fails silently, which means a NULL pointer bug could go unnoticed for some time. With the MPU it will show up immediately.&lt;/p&gt;
&lt;p&gt;If it were me, instead of using RO/RO (0x7) as the protection attributes, I would use NA/NA (0x0). This will trap both reads and writes. Reading past the end of the stack could also be a sign of a bug that is best fixed. I have found that you can get away with doing this even when setting a protection region at address 0x0. When I first tried this I was concerned it might have some impact on exception handling (since the exception vector table is also at address 0x0), but while reads and writes are successfully trapped, exception handling seems unaffected.&lt;/p&gt;
&lt;p&gt;You can read more about the MPU in this document:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://infocenter.arm.com/help/topic/com.arm.doc.dui0553b/DUI0553.pdf"&gt;http://infocenter.arm.com/help/topic/com.arm.doc.dui0553b/DUI0553.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;-Bill&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>