This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Unexpected address range accesses from bare metal code

Note: This was originally posted on 12th September 2012 at http://forums.arm.com

My test system (Carbon SoCD running a Cortex A9 model) has a memory map with entry point 0xFFFF0000, with a valid memory range from 0xFFFF0000-0xFFFFFFFF, as well as 0x50000000-0x8FFFFFFF where some stack, heap, data, etc. lives. My code is a simple dhrystone app and makes some printf calls to display the app's actions and status. However, I am strangely seeing access to low memory, reads going to 0xA or 0x38 for example. I've tried to debug where these are coming from but whatever is happening is hidden in some system library. Using the disassembly and my .map linker output I see that the code is in flsbuf.o or printf_char_common.o at the time. Depending on whether I comment out certain printf statements, the place/time the out of range access occurs is different. Does anyone have any clues as to what might be happening? Or more information that I can provide to help debug this?

If I comment out all the printfs, none of the out of range accesses occur. Also, if I adjust the system memory to be valid at those low memory addresses, the program executes and completes just fine. So I have a workaround of sorts but I want to make sure this won't be a problem for actual hardware.

Thanks,
Rich
Parents
  • Note: This was originally posted on 20th September 2012 at http://forums.arm.com


    This continues to smell like heap corruption.

    How are you setting the heap boundaries?  And to what values?

    More random thoughts:

    [] 256MB should be plenty of heap (unless there's been a lot more allocation that is shown)

    [] What other code is running before the first printf?  Any special startup code or just the standard library startup?

    [] Are the values printed for Next_Ptr_Glob and Ptr_Glob reasonable? (that is, within you heap and not within your globals or stack)  It's good that they are multiples of 8.

    [] stdout is probably line buffered so flsbuf will be called every "\n" (and every buffer, maybe 512 characters) which explains a bit why changing the format strings changes the timing of the wild access.

    [] the first printf (or puts, etc.) will cause a buffer for stdout to be created (via malloc)

    [] if the "%x"s that you changed to "%d"s are the only "%x"s then the main effect will be that image code gets smaller (possibly affecting the globals and heap base) because the formatting code for %x can be removed.  Also, of course the contents of the buffer are different after the printf.

    It's hard to say if tracking down the problem will ultimately be worthwhile, but if I was in your position I'm the sort of person that tends to get obsessed by this sort of thing until I understand it.  Changing stdout to unbuffered might possibly avoid the problem (like mapping in the low memory) but it might just come back in some worse way.


    Scott, thanks for your continued help. Like you I am mostly obsessed with figuring out what is going on here. Here is some more information.

    The only code running before that first printf (which is in main() ) are some variable declarations, and the assembly init/boot code. This code just does some standard things, including setting up stack and heap. Both are being set up with scatter file. The addresses printed (values of Next_Ptr_Glob and Ptr_Glob) are within that heap range (0x70000000-0x71000000), as defined in the scatter file and reflected in the build output .map file. Most of the code that does this I did not write, it is part of some reference code I used as a base, but I believe it is working correctly. I can see in a file "retarget.c" a function "__value_in_regs struct __initial_stackheap __user_initial_stackheap()" which I believe is setting up the heap from the scatter file values and the comment proceeding this function is "// This function re-implements the C Library semihosted function."

    The use of %x is indeed the only use of %x.

    Something interesting I've found about __heapstats() and __heapvalid(). These functions require stdlib.h but I get a compiler error when I include it because of a malloc() collision. The reference code somewhere does an "extern char *malloc();" and this collides with malloc() defined in stdlib.h. So this makes me think this reference code is somehow providing it's own version of malloc, or using a non-standard one, possibly one that is not entirely working right, but I can't find where it is defined in the source.

    Looking at the disassembly, I see calls to malloc are going to address 0xffff128c. When I look at the map file, at that address I see "0xffff128c   0x0000005e   Code   RO       115 .text            c_2.l(h1_alloc.o)". But, I am pretty new at this and am not sure how to interpret this or if this is significant at all.

    Any thoughts?
Reply
  • Note: This was originally posted on 20th September 2012 at http://forums.arm.com


    This continues to smell like heap corruption.

    How are you setting the heap boundaries?  And to what values?

    More random thoughts:

    [] 256MB should be plenty of heap (unless there's been a lot more allocation that is shown)

    [] What other code is running before the first printf?  Any special startup code or just the standard library startup?

    [] Are the values printed for Next_Ptr_Glob and Ptr_Glob reasonable? (that is, within you heap and not within your globals or stack)  It's good that they are multiples of 8.

    [] stdout is probably line buffered so flsbuf will be called every "\n" (and every buffer, maybe 512 characters) which explains a bit why changing the format strings changes the timing of the wild access.

    [] the first printf (or puts, etc.) will cause a buffer for stdout to be created (via malloc)

    [] if the "%x"s that you changed to "%d"s are the only "%x"s then the main effect will be that image code gets smaller (possibly affecting the globals and heap base) because the formatting code for %x can be removed.  Also, of course the contents of the buffer are different after the printf.

    It's hard to say if tracking down the problem will ultimately be worthwhile, but if I was in your position I'm the sort of person that tends to get obsessed by this sort of thing until I understand it.  Changing stdout to unbuffered might possibly avoid the problem (like mapping in the low memory) but it might just come back in some worse way.


    Scott, thanks for your continued help. Like you I am mostly obsessed with figuring out what is going on here. Here is some more information.

    The only code running before that first printf (which is in main() ) are some variable declarations, and the assembly init/boot code. This code just does some standard things, including setting up stack and heap. Both are being set up with scatter file. The addresses printed (values of Next_Ptr_Glob and Ptr_Glob) are within that heap range (0x70000000-0x71000000), as defined in the scatter file and reflected in the build output .map file. Most of the code that does this I did not write, it is part of some reference code I used as a base, but I believe it is working correctly. I can see in a file "retarget.c" a function "__value_in_regs struct __initial_stackheap __user_initial_stackheap()" which I believe is setting up the heap from the scatter file values and the comment proceeding this function is "// This function re-implements the C Library semihosted function."

    The use of %x is indeed the only use of %x.

    Something interesting I've found about __heapstats() and __heapvalid(). These functions require stdlib.h but I get a compiler error when I include it because of a malloc() collision. The reference code somewhere does an "extern char *malloc();" and this collides with malloc() defined in stdlib.h. So this makes me think this reference code is somehow providing it's own version of malloc, or using a non-standard one, possibly one that is not entirely working right, but I can't find where it is defined in the source.

    Looking at the disassembly, I see calls to malloc are going to address 0xffff128c. When I look at the map file, at that address I see "0xffff128c   0x0000005e   Code   RO       115 .text            c_2.l(h1_alloc.o)". But, I am pretty new at this and am not sure how to interpret this or if this is significant at all.

    Any thoughts?
Children
No data