Getting offset and back with aligned pointer in Visual Studio - c++

I'm porting an application to Visual Studio 2012 (in C++11), which currently compiles and runs correctly on gcc on several platforms.
When I tried to run it, something odd (at least to me) happened. After some moments I isolated the problem, and came up to this:
// This one succeeds
assert(jumper.fst == (left_prog->buffer - program->buffer));
// This one fails!
assert(left_prog->buffer == (jumper.fst + program->buffer));
The program->buffer and left_prog->buffer are of type Instruction *, and jumper.fst has type ptrdiff_t.
It wouldn't return to the original value; upon some testing, I realized that this had something to do with the aligment. My Program type is aligned (I've written my own allocator), and this was causing the problem. After I multiplied the aligment by sizeof(Instruction), it worked as expected.
Could someone please explain to me why this is happening? Is this behaviour documented somewhere? Am I using undefined behaviour here?
(As I said, I already fixed the code by changing the aligment value, making it a multiple of sizeof(Instruction), I just want to know why this happened.)

Related

Access voilation reading location

I am trying to debugg the project on MSVS 2010.
Implementation - c++; when i am degubbing the source code, i get the following failure reported by MSVS.
Failure reported:
"First chance exception at 0x00000013fb5b9ee in unit.exe: 0xc00000005 access voilation reading location 0x00000000000000c."
the problem lies in obtaining address.
int base = (*(abc::g_runc1.m_paulsenderpin.m_lastchunk_p)).xcpp::cxcppoutput::m_baseaddress;
my project is very big to include the source code,
In short it can be described as:
- paul is a module with sender pin connected to c1.
- xcpp is the interface
this source code and the project is correct and works without failure on ARM compiler, but on MSVS it gives access violation error.
On msdn there are some posts about permission set by assembly, and which avoids to read the addressed location. if so, how to change it... ?
or is there any better option to find the problem...?
Any help is appreciated.
Your code is trying to access location that actually isn't owned by it's process. No data of user applications can be located at addresses so close to zero. As your expressions is too long to simply find where is the member containing zero reference, my tip is m_last chunk_p, and the m_baseaddress seems to be member at offset 12.
There is one simple explanation why does your code work fine when it's compiled by something that works with ARM: ARM uses aligned memory access, so class and structure members are aligned to full blocks, although they don't always use whole space allocated for them. Therefore you use bigger pointer or wrong memset parameters somewhere in your code and your pointer gets overwritten.
Problem may also disappear when you compile it with another version of (possibly another) compiler (or non machine with different processor architecture 32/64), as the size of fundamental types isn't always the same.
You should try to check what pointed is actually zero (or possibly 12) in your expression and try to set a watch on it. Be sure you use sizeof properly everywhere.
The Problem lies with the memory addressing, in ARM debugger 32 bits and MSVS10 48 bits of addressing, because of it the MSB byte is lost and so cannot find the correct memory address...!!!

Debugging runtime stack error occurring once end of main function is reached

I've converted some legacy Fortran code to C using the f2c converter (f2c), and I've created a Visual Studio 10 solution on Windows 7 (64-bit). I've also had to link my C++ program (test.cpp, containing my main function) with the f2c library (built on my system using nmake).
The program runs, but once the end of the main function is reached, I receive the following Debug error:
Stack around the variable 'qq' was corrupted
Stack around the variable 'pf' was corrupted
Stack around the variable 'ampls' was corrupted
I am wondering if this might be due to a "correction" made by the f2c converter in the converted C (from Fortran) file:
/* Parameter adjustments */
--x1;
--xabs;
--ximag;
--xreal;
--work4;
--work3;
--work2;
--work1;
--ampls;
--pf;
--qq;
--tri;
This seems a bit odd, since all of these variables are C arrays, and I think that the f2c program is simply doing some pointer arithmetic so that index 0 in the array becomes index 1, in a similar fashion to Fortran.
I don't know if this could also be due to something going wrong with the converted code accessing an element of the array that has not been allocated.
What is the best way to debug this error and fix it?
Potential reasons:
This error is usually related to writing outside the bounds of an array (dynamic or static array). This error can occur by writing\getting a value in a -ve index or index >= size_of_array.
This error also accurs if your pointer is not set to its correct location. (e.g. ptr = 0, ptr = 55, points to deleted (released; or has been free) memory, or any invalid address)
Best way to debug your error in my mind is to debug your prorgam step-by-step and watch those pointer values. There must be some wrong with them.
What you say could be true. I would suggest to create a very small program that uses an array and decrements the pointer exactly as f2c does. Something like
int aa[10];
int *pa = aa;
--pa;
pa[1] = ...
That is, test the suspected code in the small scale. You might isolate the cause to the problem this way. (Finding a workaround is a different story)
Are you compiling with the debug versions of the crt? That might give you some more information.
Also, is it possible that your library is built as C and your application is written as C++?
Those errors you mention are sometimes because of different calling conventions. You do state it's a 64bit application, so it shouldn't be an issue (all 64bit apps use the same calling convention), but it's worth looking into.
Is it possible to add all the fortran converted code to visual studio and not do a seperate make?

Different Unallocated Memory Behaviour Between Visual Studio Versions

i'm having a weird situation. i'm trying to implement a 10+ years old pci camera device SDK to my camera management software. Manifacturer no longer in business and i have no chance to get official help. So here I am, looking for some help to my ugly problem.
SDK comes with Visual Studio 6.0 samples. One of the include files has a structure ending with a one byte array like below;
typedef struct AVData {
...
BYTE audioVideoData[1];
}AVDATA, *PAVDATA;
But this single byte allocated byte array receives video frames and weird enough, it works fine with Visual Studio 6.0 version. If I try it with Visual Studio 2005/2008/2010, i start getting Memory Access Violation error messages which actully makes sense since it shouldn't be possible to allocate space to a fixed size array afterwards, no? But same code runs fine with VS 6.0?! It's probably caused by either compiler or c++ runtime differences but i'm not very experienced on this subject so it's hard to tell the certain reason for me.
I tried changing the size to an expected maximum number of bytes like below;
typedef struct AVData {
...
BYTE audioVideoData[20000];
}AVDATA, *PAVDATA;
This helped it get working but from time to time i get memory access violation problems when trying to destroy the decoder object of the library.
There is something definitely wrong with this. I don't have the source codes of the SDK, only the DLL, Lib and Header files. My questions are:
1) Is it really legal to allocate space to a fixed size array in Visual Studio 6.0 version?
2) Is there any possible way (a compiler option etc.) to make the same code work with newer VS versions / C++ runtimes?
3) Since my workaround of editing the header file works up to a point but still having problems, do you know any better way to get around of this problem?
IIRC its an old trick to create a struct that is variable in size.
consider
struct {
int len;
char name[1];
} s;
the 'name' can now be of variable length if the appropriate allocation is done and it will be sequentially laid out in memory :
char* foo = "abc";
int len = strlen(foo);
struct s* p = malloc( sizeof(int) + len + 1 );
p->len = len;
strcpy(p->name, foo );
I think the above should work fine in newer versions of visual studio as well, maybe it is a matter of packing, have you done #pragma pack(1) to get structs on byte boundaries? I know that VS6 had that as default.
A one-element array in a C structure like this often means that the size is unknown until runtime. (For a Windows example, see BITMAPINFO.)
Usually, there will be some other information (possibly in the struct) that tells you how large the buffer needs to be. You would never allocate one of these directly, but instead allocate the right size block of memory, then cast it:
int size = /* calculate frame size somehow */
AVDATA * data = (AVDATA*) malloc(sizeof(AVDATA) + size);
// use data->audioVideoData
The code almost certainly exhibits undefined behaviour in some way, and there is no way to fix this except to fix the interface or source code of the SDK. As it is no longer in business, this is impossible.

Memory error: Dereference null pointer/ SSE misalignment

I'm compiling a program on remote linux server. The program compiled. However when I run it the program ends abruptly. So I debugged the program using DDT. It spits out the following error:
Process 0:
Memory error detected in ClassName::function (filename.cpp:6462).
Thread 1 attempted to dereference a null pointer or execute an SSE instruction with an
incorrectly aligned memory address (the latter may sometimes occur spuriously if guard
pages are enabled)
Tip: Use the stack list and the local variables to explore your program's current
state and identify the source of the error.
Can anyone please tell me what exactly this error means?
The line where the program stops looks like this:
SumUtility = ParaEst[0] + hhincome * ParaEst[71] + IsBlack * ParaEst[61] + IsBachAss * (ParaEst[55]);
This is within a switch case.
These are the variable types
vector<double> ParaEst;
double hhincome;
int IsBlack, Is BachAss;
Thanks for the help!
It means that:
ParaEst is NULL or a bad Pointer
ParaEst's individual array values are not aligned to 16-byte boundaries, required for SSE.
hhincome, IsBlack, or IsBachAss are not aligned to 16-byte boundaries and are SSE type values.
SumUtility is not aligned to 16-bytes and is a SSE type field.
If you could post the assembly code of the exact line that failed along with the register values of that assembler line, we could tell you exactly which of the above conditions have failed. It would also help to see the types of each variable shown to help narrow root the cause.
Ok... The problem finally got fixed.
The issue was that the expression where the code was breaking down was in a newly defined function. However for some weird reason running the make-file did not incorporate these changes and was still compiling using the previously compiled .o file. This resulted in garbage values being assigned to the variables within this new function. To top things off the program calls this function as a first step. Hence there was this systematic breakdown. The technical aspect of this was what Michael alluded to.
After this I would always recommend to use a make clean option in the make file. The issue of why running the make file is failing to compile the modified source file is an issue that definitely warrants further discussion.
Thanks for the responses!!

What are possible consequences of format/argument type mismatches in c++ fprintf function calls?

We have a legacy c++ .dll compiled for windows under visual studio. We have been running into issues where we get different results when we compile the program using different compiler options.
I have done a pretty simple port so that I can compile it under linux using g++. I just wanted to see what kind of warnings gcc would throw at me and possibly try to run it using valgrind to look for possible erros.
So that is the background. Here is the question. We have a bunch of fprintf function calls that print to a log file. When compiled under g++, I get warnings like this.
../f11.cpp:754:128: warning: format ‘%i’ expects type ‘int’, but argument 8 has type ‘long unsigned int’
Obviously this is a bad thing we need to fix, but I am just curious about the potential consequences of ignoring this warning? Are the consequences only limited to the output in the log file, or could this cause things like buffer overruns or any other type of situation where we are overwriting memory without knowing it?
By definition, it's undefined behavior to have mismatching format strings and argument types.
So anything is allowed to happen. But more likely, you'll get completely garbled and non-sense output - especially if the sizes of the operands you pass don't match what's expected from the format strings.
It is possible for a buffer overrun to happen - if printf() ends up reading past the parameters, it will be reading stack garbage. But it will only reading it. It won't be writing to it, so it shouldn't corrupt anything. (with one exception - %n, see comments)
But then again, it's undefined behavior. Anything is possible.
You are getting such warnings because of code like
long x;
printf ("x=%i\n", x);
On a 64 bits x86-64 Linux machine, what is probably happenning is that printf implementation would call va_arg(arglist, int) for the x argument. Since int is 32 bits and long is 64 bits, the 64 bits value is probably truncated to its 32 lower bits, which in that particular case probably don't harm much.
If it is a scanf ("%i", &x); things become much much uglier. Probably, only 32 bits out of 64 of the long x get changed, and that will break the code later.
But as everyone responded, this is undefined behavior. you'll feel sorry if you don't fix it or at the very least, add a big fat /* FIXME */ comment for the person working on the code in a few weeks or months.