mbed Region m_data_2 overflowed with stack and heap - arm

I am writing an application for Mbed OS that will run on a K64F board. I have different threads running, using the RTOS capabilities of the system.
I need to handle a relatively big string for showing results in a JSON format. I have definned it as a char array. Initially it was defined to be 256 chars long and was working correclty, but when I have increased the size to 2048 to actually fit the needs of the app
char rData[2048];
I get this error on compilation:
c:/program files (x86)/gnu tools arm embedded/6.2 2016q4/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: ./BUILD/K64F/GCC_ARM/02_device.elf section `.heap' will not fit in region `m_data_2'
c:/program files (x86)/gnu tools arm embedded/6.2 2016q4/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: Region m_data_2 overflowed with stack and heap
c:/program files (x86)/gnu tools arm embedded/6.2 2016q4/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: region `m_data_2' overflowed by 22944 bytes
collect2.exe: error: ld returned 1 exit status
[ERROR] c:/program files (x86)/gnu tools arm embedded/6.2 2016q4/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: ./BUILD/K64F/GCC_ARM/02_device.elf section `.heap' will not fit in region `m_data_2'
c:/program files (x86)/gnu tools arm embedded/6.2 2016q4/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: Region m_data_2 overflowed with stack and heap
c:/program files (x86)/gnu tools arm embedded/6.2 2016q4/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: region `m_data_2' overflowed by 22944 bytes
collect2.exe: error: ld returned 1 exit status
I have not found any reference on how to increase the space reserved for this need.
What am I missing?

Declare the variable on the heap, not on the stack:
char* rData = (char*)malloc(2048);
// potentially, don't always malloc 2048 bytes, but only the amount you need
Don't forget to call free(rData) when you're done.

Related

STM32 ST-LinkV2 st-flash1.6.1 won't upload - Windows 10

I am trying to write a binary to a STM32F413ZH Nucleo development board. I am running Windows 10.
I using the bare metal project examples from this github-page. I can succesfully compile any of the example projects but I can't write the binary to the microcontroller.
I am using the makefile which is included in the example projects. To build I write "make" and to write the binary I write "make burn". This gives the following error message:
$ make burn
st-flash 1.6.1
2020-10-21T17:06:17 INFO common.c: F1xx Medium-density: 20 KiB SRAM, 64 KiB flash in at least 1 KiB pages.
mmap() size_t overflow for file Debug/dac.bin
2020-10-21T17:06:17 ERROR common.c: map_file() == -1
stlink_fwrite_flash() == -1
make: *** [burn] Error -1
Can anyone explain why it doesn't work?

Application is getting killed without any reason. Suspecting high BSS. How to debug it?

I have been running my application successfully in CentOs6.6. Recently, the hardware(motherboard and RAM) was updated and my application is getting killed now without any reason at all.
[root#localhost PktBlaster]# ./PktBlaster
Killed
File and ldd output
[root#localhost PktBlaster]# file PktBlaster
PktBlaster: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
[root#localhost PktBlaster]# ldd PktBlaster
not a dynamic executable
Output of strace
[root#localhost PktBlaster]# strace ./PktBlaster
execve("./PktBlaster", ["./PktBlaster"], [/* 30 vars */] <unfinished ...>
+++ killed by SIGKILL +++
Killed
GDB
[root#localhost PktBlaster]# gdb PktBlaster
(gdb) break main
Breakpoint 1 at 0x43d664: file VTP.c, line 544.
(gdb) run
Starting program: /root/Veryx/PktBlaster/PktBlaster
During startup program terminated with signal SIGKILL, Killed.
While debugging, observed that the bss memory is huge(~6GB). The system has 4GB RAM and I think this could be the reason for the issue.
[root#localhost PktBlaster_1Gig]# size build/unix/bin/PktBlaster
text data bss dec hex filename
375551 55936 6747541120 6747972607 19235e3ff build/unix/bin/PktBlaster
The application contains many .h files and many datastructures and so it is difficult for me to identify why BSS is been raised to 6GB.
Could anyone please suggest how to identify which file is causing this? or any other easier way to debug this?
It seems that problem really is huge BSS size.
I have asked you to show output of LD_DEBUG=all /lib64/ld-linux-x86-64.so.2 /path/to/exe in comments.
/lib64/ld-linux-x86-64.so.2 is runtime linker which is used by OS to load your binary in process memory during execve system call. Runtime linker is responsible for parsing executable format, loading all sections and dependencies in memory, performing all required relocations and so on.
Setting environment variable LD_DEBUG to all we instruct runtime linker to generate debug output.
[root#localhost PktBlaster]# LD_DEBUG=all /lib64/ld-linux-x86-64.so.2
/root/Veryx/PktBlaster/PktBlaster
851: file=/root/Veryx/PktBlaster/PktBlaster [0]; generating link map
/root/Veryx/PktBlaster/PktBlaster: error while loading shared
libraries: /root/Veryx/PktBlaster/PktBlaster: cannot map zero-fill
pages: Cannot allocate memory
Searching for this error message in source code of runtime linker(glibc-2.17 elf/dl-load.c, lines ~1400) we see:
1393 if (zeroend > zeropage)
1394 {
1395 /* Map the remaining zero pages in from the zero fill FD. */
1396 caddr_t mapat;
1397 mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage,
1398 c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED,
1399 -1, 0);
1400 if (__builtin_expect (mapat == MAP_FAILED, 0))
1401 {
1402 errstring = N_("cannot map zero-fill pages");
1403 goto call_lose_errno;
1404 }
dl-loader is in process of loading BSS segment, which by optimizations is stored in binary format as just number of bytes, that must be initialized to zero. Loader tries to allocate through mmap zero initialized memory block(MAP_ANONYMOUS) and get error from the OS:
15 #define ENOMEM 12 /* Out of memory */
From man 2 mmap:
ENOMEM No memory is available, or the process's maximum number of
mappings would have been exceeded.
So it seems that for whatever reason OS cannot fulfill loader request for memory. Either some limits are used(systemd, process limit, some security LKM, whatever) or simply there are not enough free memory in kernel.
To determine what object file generates most part of the BSS - use
objdump -j '.bss' -t *.o

Memory map shows space allocated to mystery variables _powers_ and _npowers_

I've been looking at the memory map for my code (written in c and compiled by the XC16 compiler), and see significant space allocated to powers, npowers, and dpowers in the .data segment.
Does anyone know what this allocation is used for?
My code uses the floating point library, as well as printf/scanf - could this be working space for these functions?
Here are two snippets from the map file:
section address alignment gaps total length (dec)
------- ------- -------------- -------------------
...
.data._powers_ 0x20b2 0 0xb0 (176)
.data._npowers_ 0x2162 0 0xb0 (176)
.data.dpowers 0x2212 0 0x140 (320)
...and...
.data._powers_ 0x20b2 0xb0
.data._powers_
0x20b2 0xb0 c:/program files (x86)/microchip/xc16/v1.24/bin/bin/../../lib\libc-coff.a(powers.epo)
0x20b2 _powers_
.data._npowers_
0x2162 0xb0
.data._npowers_
0x2162 0xb0 c:/program files (x86)/microchip/xc16/v1.24/bin/bin/../../lib\libc-coff.a(powers.epo)
0x2162 _npowers_
.data.dpowers 0x2212 0x140
.data.dpowers 0x2212 0xa0 c:/program files (x86)/microchip/xc16/v1.24/bin/bin/../../lib\libc-coff.a(doprnt_cdfFnopsuxX.EPo)
.data.dpowers 0x22b2 0xa0 c:/program files (x86)/microchip/xc16/v1.24/bin/bin/../../lib\libc-coff.a(doprnt.epo)
You would have to look at the source for the version of libc to get a categorical answer. I did look at the source for one and found that, in that implementation, dpowers was a table of constants (powers of 10) used for output (doprnt). I suspect the others are similar.
Note - while constants, these are not in a read-only section due to language limitations.

C Program Written in VS2012 Works w/ Win7/8/2008R2/2012, but not 2003/XP/32bit?

I have to start by saying that I am very much a programming noob. I do not understand all the compiler options or nuances of the IDE, not by a longshot. But I am trying to teach myself more about native programming languages. (I'm decent with C#, but that is much easier than C as I am discovering.)
Today, I wrote this small program in C. It is a console/command line program. I used Visual Studio 2012 and my development machine alternates between Windows 7 and 8, 64 bit. To start, what I did was create a new VC++ project, and I chose a Blank Project. Then I created a new app.c file. I also created a *.rc file to give the executable some extra properties like "File Version" and "Company Name" when you browse the file properties in Windows Explorer. Then I went to the properties of the project, chose Configuration Properties -> C/C++ -> Code Generation and I changed Runtime Library to "Multi-threaded (/MT) so that I wouldn't have to distribute the msvcr100.dll file along with my executable.
In the app.c file, I placed the following code:
#include <stdio.h>
#include <string.h>
#include <Windows.h>
#include <WtsApi32.h>
#pragma comment(lib, "WtsApi32.lib")
void main(int argc, char *argv[])
{
char *helpMsg = "blah";
char *hostName, *connState = "";
char *addrFamily = "";
HANDLE hHost = NULL;
...stuff and so forth and so on...
}
Then I built/compiled the program, and the executable works just fine on Windows 7, 8, Server 2008R2, Server 2012, all 64 bit. But when I try to run the program on Server 2003 (and I am guessing WinXP, etc., as well,) I am greeted with the Windows dialog box:
"Foo.exe is not a valid Win32 application."
So my question is, is there something obvious/simple that I am missing that will allow this executable to also work on earlier XP/2003/32bit platforms that I am missing? I do not believe that I am using any 64-bit exclusive features in my program. But I figured that since I did choose "Blank Project" instead of "Win32 Console Application" that I may be missing some setting.
Edit: Here is the dumpbin.exe /headers output when run against my exe:
Microsoft (R) COFF/PE Dumper Version 11.00.50727.1
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file C:\users\me\Release\foo.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (x86)
5 number of sections
50F604BC time date stamp Tue Jan 15 19:39:08 2013
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
102 characteristics
Executable
32 bit word machine
OPTIONAL HEADER VALUES
10B magic # (PE32)
11.00 linker version
7800 size of code
A200 size of initialized data
0 size of uninitialized data
16A7 entry point (004016A7) _mainCRTStartup
1000 base of code
9000 base of data
400000 image base (00400000 to 00414FFF)
1000 section alignment
200 file alignment
6.00 operating system version
0.00 image version
6.00 subsystem version
0 Win32 version
15000 size of image
400 size of headers
0 checksum
3 subsystem (Windows CUI)
8140 DLL characteristics
Dynamic base
NX compatible
Terminal Server Aware
100000 size of stack reserve
1000 size of stack commit
100000 size of heap reserve
1000 size of heap commit
0 loader flags
10 number of directories
0 [ 0] RVA [size] of Export Directory
D374 [ 3C] RVA [size] of Import Directory
11000 [ 538] RVA [size] of Resource Directory
0 [ 0] RVA [size] of Exception Directory
0 [ 0] RVA [size] of Certificates Directory
12000 [ C04] RVA [size] of Base Relocation Directory
9160 [ 38] RVA [size] of Debug Directory
0 [ 0] RVA [size] of Architecture Directory
0 [ 0] RVA [size] of Global Pointer Directory
0 [ 0] RVA [size] of Thread Storage Directory
CF98 [ 40] RVA [size] of Load Configuration Directory
0 [ 0] RVA [size] of Bound Import Directory
9000 [ 118] RVA [size] of Import Address Table Directory
0 [ 0] RVA [size] of Delay Import Directory
0 [ 0] RVA [size] of COM Descriptor Directory
0 [ 0] RVA [size] of Reserved Directory
SECTION HEADER #1
.text name
7670 virtual size
1000 virtual address (00401000 to 0040866F)
7800 size of raw data
400 file pointer to raw data (00000400 to 00007BFF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
Execute Read
SECTION HEADER #2
.rdata name
49E2 virtual size
9000 virtual address (00409000 to 0040D9E1)
4A00 size of raw data
7C00 file pointer to raw data (00007C00 to 0000C5FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
Read Only
Debug Directories
Time Type Size RVA Pointer
-------- ------ -------- -------- --------
50F604BC cv 61 0000CFE0 BBE0 Format: RSDS, {582D0FF2-59C1-4633-AF2A-E4A4AD6BFA2C}, 1, C:\Users\me\Release\users.pdb
50F604BC feat 10 0000D044 BC44 Counts: Pre-VC++ 11.00=0, C/C++=116, /GS=116, /sdl=0
SECTION HEADER #3
.data name
2C04 virtual size
E000 virtual address (0040E000 to 00410C03)
E00 size of raw data
C600 file pointer to raw data (0000C600 to 0000D3FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read Write
SECTION HEADER #4
.rsrc name
538 virtual size
11000 virtual address (00411000 to 00411537)
600 size of raw data
D400 file pointer to raw data (0000D400 to 0000D9FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
Read Only
SECTION HEADER #5
.reloc name
235C virtual size
12000 virtual address (00412000 to 0041435B)
2400 size of raw data
DA00 file pointer to raw data (0000DA00 to 0000FDFF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
42000040 flags
Initialized Data
Discardable
Read Only
Summary
3000 .data
5000 .rdata
3000 .reloc
1000 .rsrc
8000 .text
I have also tried going to Project Properties -> Linker -> System: Minimum Required Version and changing that to 5.00 and 1.00 or whatever, but it has no effect. dumpbin.exe still reports the OS version as 6.00. I have even used editbin.exe /version 5.00 on the exe and no errors were reported... and yet dumpbin.exe still reports 6.00 for the OS version.
VS2012 originally shipped without supporting XP/2003. The updated CRT and runtime support libraries are using too many Windows api functions that are not available on those operating systems. This created quite a stir among its customers, to put it mildly, and they re-engineered the libraries to dynamically bind to these functions and limp along it they are missing. This was made available in Update 1, you'll need to use Project + Properties, General, Platform Toolset = v110_xp to build programs that use those libraries.
Note how it changes a linker setting, the important one, Linker > System > Minimum Required Version = "5.01". Which ensures that the executable file is marked to be compatible with the XP sub-system version. You'll also build against SDK version 7.1, the last one that is still compatible with XP.
When you use the default toolset (v110) then you target sub-system 6.00 and SDK version 8. Version 6.00 was the last major kernel revision, started with Vista.
A brief overview of the new api functions being used to give you a (very rough) idea what is missing in the XP version:
FlsAlloc, FlsFree, FlsGetValue, FlsSetValue : safe thread-local storage
InitializeCriticalSectionEx, CreateSemaphoreEx : safety
SetThreadStackGuarantee : stability
CreateThreadPoolTimer, SetThreadPoolTimer, WaitForThreadPoolTimerCallbacks, CloseThreadPoolTimer : cheaper timers
CreateThreadPoolWait, SetThreadPoolWait, CloseThreadPoolWait : cheaper waits?
FlushProcessWriteBuffers, GetCurrentProcessorNumber, GetLogicalProcessorInformation : threading
FreeLibraryWhenCallbackReturns : stability?
CreateSymbolicLink : functionality
InitOnceExecuteOnce : unknown
SetDefaultDllDirectories : unknown
EnumLocalesEx, CompareStringEx, GetDateFormatEx, GetLocalInfoEx, GetTimeFormatEx, GetUserDefaultLocaleName, IsValidLocaleName, LCMapStringEx : better locale support
I figured it out myself. (But thank you Hans for steering me in the right direction.) For some reason, even with Update 1 and even after setting my toolset to v110_xp, and setting the minimum required version to 5.01 in the Linker options, the resulting dumpbin app.exe /headers still reports a minimum operating system version of 6.0.
So I simply ran
editbin.exe app.exe /SUBSYSTEM:CONSOLE,5.01 /OSVERSION:5.1
And the executable now runs just fine on older operating systems. I'm thinking there still might be a little bit of a bug somewhere in Visual Studio.
The MSVC Team Blog says that when using MSBuild or DEVENV from the command-line with the v110_xp platform toolset, no other changes are necessary. This information is incorrect/incomplete. The /SUBSYSTEM linker argument and associated "Minimum Required Version" must also be set appropriately.
The MSDN documentation for /ENTRY states that, if the /SUBSYSTEM argument is not specified that the SUBSYSTEM and ENTRY POINT are determined automatically. My hunch is that when this happens, the SUBSYSTEM's "Minimum Required Version" argument is also automatically overridden.
The v110_xp toolset automatically specifies the SUBSYSTEM's MRV ("5.1" (WindowsXP)) but not the SUBSYSTEM. As such, the MRV will be overridden, for example, by the linker to "6.0". Running the application will then cause WindowsXP to show the error message stating that the application "is not a valid Win32 application."

In a compressed PE must the virtual size of the data section match the raw size?

In working with a compressed PE (Windows console EXE) that has a file alignment and section alignment of 4 bytes, I notice that if virtual size and raw size of the sections match, then the program loads, but if virtual size of the data section, the last section, does not match then Windows refuses to load it, even though by the specification you should be able to have a virtual size larger than a raw size.
Is this some kind of hidden constraint on compressed PEs?
I have pasted a dumpbin /headers of the exe below:
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file ba42x.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (x86)
2 number of sections
50AABC14 time date stamp Mon Nov 19 18:09:08 2012
0 file pointer to symbol table
0 number of symbols
60 size of optional header
10F characteristics
Relocations stripped
Executable
Line numbers stripped
Symbols stripped
32 bit word machine
OPTIONAL HEADER VALUES
10B magic # (PE32)
2.03 linker version
BD0 size of code
5000 size of initialized data
0 size of uninitialized data
CC entry point (004000CC)
CC base of code
C9C base of data
400000 image base (00400000 to 00403FFF)
4 section alignment
4 file alignment
4.00 operating system version
0.00 image version
4.00 subsystem version
0 Win32 version
4000 size of image
CC size of headers
0 checksum
3 subsystem (Windows CUI)
0 DLL characteristics
10000 size of stack reserve
1000 size of stack commit
0 size of heap reserve
0 size of heap commit
0 loader flags
0 number of directories
SECTION HEADER #1
.text name
BD0 virtual size
CC virtual address (004000CC to 00400C9B)
BD0 size of raw data
CC file pointer to raw data (000000CC to 00000C9B)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
E0000020 flags
Code
Execute Read Write
SECTION HEADER #2
.data name
3102 virtual size
C9C virtual address (00400C9C to 00403D9D)
3102 size of raw data
C9C file pointer to raw data (00000C9C to 00003D9D)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read Write
Summary
3104 .data
BD0 .text
For example if you change the virtual size of the above .data section to 3106 the program will not load, even though the size of initialized data (0x5000) is more than enough to accomodate the additional memory.
No, there are not special constraints related to compressed images, since as long as your image is PE compliant, the loader does not care about the compression. Compression is handled by the stub, not the loader.
Can you provide your image for further analysis?
Just by looking at the output of dumpbin, the image looks unusual..There are no directory at all, pretty strange. It looks like the issue with the loader is not directly related to the alignement, but malformation of the image file. Did you try to have a look at your image file using other PE tools (e.g. PeStudio, CFF Explorer..?)

Resources