stack overflow by using to big structure? (C) ARM M3 - struct

is it possible that a structure in a main.c is so big, that its values cant be stored correctly?
How can I check what the reason is?
myStructure.x= 122; myStructure.a= 2;
reading out
printf("%d", myStructure.a); "a"
I declared it globally and then its values were stored correctly.
What is the difference declaring it globally?
It was on a microcontroller ARM M3.
Thank you.
I tried to debug it step by step. But there was no clue why it behaves like that. Just writing wrong values..
So I just the same structure but this time globally. And it worked.
I checked the code and I saw that this global variable is once declared extern
Minimal example:
file1.c
extern originalStruct myGlobalStruct;
file2.c
originalStruct{
int a;
int z;
}
main.c
int main(){
originalStruct myLocalStr;
//reading sensor data:
myLocalStr.a=readInSensor();
myLocalStr.z= readInSensor();
//
myGlobalStruct.a=readInSensor();
myGlobalStruct.z= readInSensor();
//show Struct Values:
// (also with gdb debugger)
printStruct(myLocalStr);// doesnt delivier the right values
printStruct(myGlobalStr); // does deliver the right values
return 1;}

Maybe you have not declared the stack correctly. You have to define the stack in the linker script.

Related

variable does not properly update

Xilinx SDK 2016.1 freeRTOS823_xlinx OS platform
My code seemed to work fine until I introduced some freeRTOS elements. The general functionality of my code as follows:
In the Interrupt subroutine, I assign a value to a variable focusPosition that is read from the IP register of the Zynq Soc:
// separate file
u32 focusPosition=0;
static void ISR(void *CallbackRef)
{
focusPosition = XRb_focus_Get_position_o(CallbackRef);
}
Then I printf the value to the console in the main function:
// separate file
extern u32 focusPosition;
main{
...
while(1){
sleep(1);
xil_printf("%d\n",focusPosition);
}
}
The code prints the correct value, however, when I try to implement some additional lines in the code, like xTaskCreate() xEventGroupCreate(), something messes up all the memory and the printed value stays constant, which is not correct.
How can simple addition of the code that has nothing to do with the variable have any influence on that variable? As far as I understand, the xTaskCreate() and xEventGroupCreate() are created on the heap. I tired pocking around to see if Xil_DCacheDisable() would help, but no. Any ideas? Is my focusPosition variable properly defined/declared?
You should declare focusPosition as volatile otherwise the compiler does not expect it to be modified outside of the while loop so may optimize the code. Adding extra code may of caused this to happen. Any variable modified in an interrupt but used elsewhere should be declared volatile.

Making a virtual file in Linux

I'm working with some existing software that I cannot change, and it loads its config data from a bunch of config files, all following the same naming scheme - let's say, file_param1.conf, file_param2.conf, file_param3.conf etc. The difference between the content of the files is just param1 vs param2 vs param3, so a typical config file will look like
foo=bar
x=param1
or
foo=bar
x=param2
Is there any examples anywhere on creating a virtual fs in Linux that would let me on access of file_param1.conf generate the file dynamically with the appropriate param variable? I know about scriptfs but not about any tutorials on using it.
(Posting as an answer because this is too long for a comment.)
You might find it easier to use an LD_PRELOAD library and interpose on the open()/fopen()/open64() or whatever exact library call(s) your existing software uses to access your configuration file and replacing the application-supplied file name with one that points to the file you want to use.
This code is off the top of my head and I haven't tried compiling it:
#include <dlfcn.h>
// don't want to #include anything else or we're likely to get
// the vararg prototype for open()
int strcmp( const char *s1, const char *s2 );
// typedef a function pointer
typedef int ( *open_func_ptr_t )( const char *, int, mode_t );
static open_func_ptr_t real_open = NULL;
int open( const char *pathname, int flags, mode_t mode )
{
// find the real open() call
if ( real_open == NULL )
{
real_open = ( open_func_ptr_t ) dlsym( RTLD_NEXT, "open" );
}
if ( 0 == strcmp( pathname, "/path/to/config/file" );
{
pathname = "/path/to/replacement/config/file";
}
return( real_open( pathname, flags, mode ) );
}
That code relies on the fact that although open() is declared as a varargs function because of the restrictions placed on current C code, originally C didn't have prototypes so all functions were de facto vararg functions. The open() call only accesses the mode argument when needed, so open() doesn't always need to be passed a mode argument. With current C, the only way to do that is with a vararg function. That makes #include files problematic with this code as any declaration of open() will be the vararg one and that will cause the code to not compile. You might need to replace mode_t with int (or whatever it's typedef'd to) in order to compile.
Compile that with cc [-m64|-m32] -shared source.c -ldl -o mylib.so. You need the -ldl to link in dlsym(), and you need the proper -m64 or -m32 option to get a 64- or 32-bit library to match your application.
Then set LD_PRELOAD to your .so file:
LD_PRELOAD=/path/to/mylib.so
export LD_PRELOAD
Then run your application with the LD_PRELOAD set. You also need to be real careful that any child processes spawned by your application are all the same 32- or 64-bit as the shared object LD_PRELOAD is set to. If you nave mixed 32- and 64-bit processes to deal with, read the man page for ld.so and pay particular attention the the $PLATFORM section.
Note also that the code is not reentrant because of the race condition modifying real_open and might have problems with multithreaded access to open().

Suppress anonymous structs warning with Clang - "-fms-extensions" doesn't work

I have an Xcode project that I compile with Clang using some 3rd party library with Visual Studio C code.
In the 3rd party library anonymous structs are used in header files (I can't really change that). Thus I get this warning:
"myfile.h:47:17: Anonymous structs are a GNU extension"
As described here, I tried to pass "-fms-extensions" in the C flags of my Xcode project:
http://clang.llvm.org/docs/UsersManual.html#microsoft-extensions
No luck. Any idea how to get rid of that warning?
Adding -Wno-microsoft did not work for me.
Using this small test program
typedef struct test_struct
{
struct
{
int a;
int b;
};
int x;
} Test;
int main(int argc, char **argv)
{
Test test;
test.a = 0;
}
using -Wno-gnu disables the warning
Version is Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
You can simply use -Wno-microsoft to hide the warning.

Will the linker compare the access level when finding a member function at linking time?

Accidently, I encounter a linking error.
The program is somewhat like this:
//a.h
class A
{
int a;
#ifdef AAA
public:
#endif
int getA();
}
//a.cpp
include "a.h"
int A::getA()
{
return a;
}
//test.cpp
#include "a.h"
int main()
{
A a;
a.getA();
return 0;
}
These three files are in two project, a.h and a.cpp in a project A in which the AAA macro is undefined, test.cpp in a project Test in which AAA macro is defined. And project Test denpends on project A.
Then I encounter a link error. I did this test on visual studio 2008.
So my question is this:"Will the link compare the access level when finding a member function symbol at linking time?"
In my previous opinion, the access level only take effect in compilation. But in this case,
it seems that the access level may also make effect in linking time.
The linker is innocent. C++ compilers mangel names and incorporates things as access modifiers, overloads (i.e. return and argument types), template(? not quite sure) etc... in the final to produce something unambigious that also forms whatever the linker considers a valid identifier (at least [a-zA-Z_][a-zA-Z0-9_]*, as C requires no mangling). The linker only sees that mangled name, and it can't report anything except "you call this function but it's not defined anywhere". public A::getA() a different name as private A::getA().
The solution? Don't use the preprocessor for such batshit things. Or convince the VS developers to intercept such error messages and translate them into something more meanignful (but since they didn't in the past and sane code rarely encounters this problem, that's unlikely).

vc++ problem in situation export/import global variables in dlls

Precondition
environment : VC2005
I encountered this problem when discovered circular dependency in my project(two dll references each other), so divide either of one dll to two dll's.
explain with example :
typedef struct { <br>
char myFileName[MAX_PATH];
} MyStructure;
Before :
MyHeader.h
MyStructure globalStruct;
After:
MyCommon.h
#ifdef _MYGLOBAL_
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif
API extern MyStructure globalStruct;
MyGlobal.c
API MyStructure globalStruct;
MySpecific.c
API MyStructure globalStruct;
failed code after changed: (this code run in specific dll)
handle = LoadLibrary(globalStruct.myFileName);
I confirmed globalStruct.myFileName values are same(at lease real words).
I can't access the value directly with debugger after changed. so, to see value in debugger, I copyed to temp local char[] variable. And then, I found before value and after value are different in tailing dummy char's.
before:
d:[my path] '0'(char end null) '0' '0' ...
after:
d:[my path] '0'(char end null) '-3' '-3' '-3' ...
thank you for your reading.
self-solved my problem.
This is because dll does not re-compiled after my circular dependency removal work.
So, this problem is not related import/export global variable but dll re-compile issue.
Sorry for my ugly question.

Resources