Working code throwing exception when new lines added. Debugging tips? - c++

I'm working on a proprietary code base, so I have to abstract this.
I'm trying to set the value of DataType_T*** myData in MyApplication. I'm using a shared c++ library (which I denote library A) to set the value. The shared c++ library is just a simple wrapper class around a C API.The C API is included in library A as a shared library (which I denote library B).
So MyApplication calls GetData(myData) in A which calls GetData(myData) in B.
MyApplication has the following code:
void OnButtonPress(){
const DataType*** myData;
GetData(myData);
DataTypeVal1 val1 = (*myData)[0]->val1; // just grabbing some info.
}
GetData(myData): works, and properly sets myData.
Me: types some new code
void OnButtonPress(){
const DataType*** myData;
GetData(myData);
const void* strData = (*myData)[0]->strData; // just grabbing some info now that we have the pointer.
//Add lots more new code that does this over and over for each member of myData
String^ str = gcnew String(static_cast<const char*>(strData));
}
GetData(myData): throws a write access violation.
Me: ". . . . . . .what."
Could the exception be getting thrown because of some sort of dll unloading?
Is there a possibility that the linking process changes when I type new code?
I haven't encountered an issue like this before, so I don't really know how to debug this.
Got suggestions?
Thanks.
Solved.
I found my undefined behavior.

I think you want something like this:
const DataType** myData;
GetData(&myData);
const void* strData = myData[0]->strData;
Because in the original code you're just passing a pointer by value; an uninitialized pointer, and then accessing that same uninitialized value.
ed: fixed up the third line

Related

Setting a value of a struct and then reading it (access violation exception)

I've a problem in my program. I'm getting a exception that crashes the program. Firstly, i innitialize my struct object in my class header. Like so:
struct Settings {
DWORD AccesibilityMode;
bool Raw;
DWORD Type;
};
Settings * thread_settings = new Settings(); //Here im getting the pointer of the newly created
object
Now i've innitialized what i need. Going on, now i need to set the variables of the struct pointer to the specific settings that i want (The struct is going to be used as a option/settings thingy). The struct pointer is private so i wrote a getter-method that returns the address of the pointer. It's written like this (in my .cpp file of the class):
Client::Settings* Client::Thread_Settings() {
return thread_settings;
}
Now, the method is a pointer that is accessible everywhere. I'm creating a object of the class and calling the address. Then im setting the vars like so (still no error to this point).
(object already defined)
client.Thread_Settings()->AcessibilityMode = 1; //Normally i have macros that are setted to these values
client.Thread_Settings()->Raw = false;
client.Thread_Settings()->Type = 33;
Lastly, the main function executes a method from the same class as the object struct pointer. These methods have if-statements that are checking the defined variables in the struct. These if lines are written like this:
if (thread_settings->Recv_BufferAccesibilityMode == 1 /*normally instead for 1 i've a macro*/ ) {
...... //rest of code
}
Now, i've got an access violation error that reads some unwritten memory (checked in an assembler) sometimes on 0x11C and sometimes at 0x12C. The error in vs19 looks loke this:
Exception thrown: read access violation.
this->thread_settings was 0x11C.
Do anyone have any thoughts? Appreciate any help :D

Correct __bridge usage with ARC and C++ interop? (how to avoid memory leaks?)

I have a bit of pure C++ code which is reading from Objective-C data structures with the help of a function pointer to a method in an Objective C class. I'm treating the Objective-C class instance to read from as an opaque pointer. For example, the C++ method that does the reading has a signature like this:
typedef void(*DataGetterFunc)(void * dataSource, int key, int * outValue);
...
void readData(void * dataSource, DataGetterFunc dataReadingFunc);
When I call the C++ method from Objective-C, I do the following:
MYDataStructure * objectiveCData;
cppObject->readData((__bridge void*)objectiveCData, DataGetterFuncImpl);
Finally, DataGetterFuncImpl dereferences the Objective-C class like so:
void DataGetterFuncImpl(void * dataSource, int key, int * outValue)
{
MYDataStructure * objCData = (__bridge MYDataStructure*)dataSource;
...
}
Originally in DataGetterFuncImpl I was using __bridge_transfer, but then I was getting EXC_BAD_ACCESS the next time ARC called retain on MYDataStructure, So I assumed it was being over-released by the use of __bridge_transfer and changed it to just __bridge.
Are there any memory leaks I should look for by just using __bridge, or do I need to use some combination of __bridge_retain and __bridge_transfer in this case?
When you're using __bridge to convert to or from objc, owership is just not affected. That means, that while you're using the object in C++ you must make sure that there's still a strong reference around.
If you, on the other hand, use __bridge_retain to convert to void* and __bridge_transfer to convert back to id (or any other retainable object type), you must make sure that each __bridge_retain is matched by exactly one __bridge_transfer later.

Populate global function pointers in shared library (Solaris, Sun Studio)

I am creating a small C++ wrapper shared library around a Fortran 95 library. Since the Fortran symbols contain . in the symbol name, I have to use dlsym to load the Fortran function into a C++ function pointer.
Currently, I have a bunch of global function pointers in header files:
// test.h
extern void (*f)(int* arg);
and I populate them in the corresponding C++ file:
// test.cc
void (*f))(int* = reinterpret_cast<void(*)(int*>(dlsym(RTLD_DEFAULT, "real_f.symbol_name_");
Questions:
If I do it this way, when are these pointers populated?
Can I assume them to be loaded in my executable that loads this library?
In particular, can I use these functions in statically created objects in my executable or other libraries? Or does this suffer from the static initalization order fiasco?
If the above way is not correct, what is the most elegant way of populating these pointers such that they can be used in static objects in executables and other libraries?
I am using the Sun Studio compiler on Solaris, if that makes a difference, but I would also be interested in a solution for GCC on Linux.
Where does the line
f = reinterpret_cast<void(*)(int*)>(dlsym(RTLD_DEFAULT, "real_f.symbol_name_"));
occur in test.cc? The pointer will be initialized when the line is
executed (which of course depends on when the function which contains it
is called). Or did you mean to write
void (*f)(int* ) = reinterpret_cast<void(*)(int*>(dlsym(RTLD_DEFAULT, "real_f.symbol_name_");
? In this case, the pointer will be initialized during static
initialization. Which means that you still have order of initialization
issues if you try to use the pointers in the constructor of a static
object.
The classical solution for this would be to use some sort of singleton:
struct LibraryPointers
{
void (*f)(int* );
// ...
static LibraryPointers const& instance()
private:
LibraryPointers();
};
LibraryPointers const&
LibraryPointers::instance()
{
static LibraryPointers theOneAndOnly;
return theOneAndOnly;
}
LibraryPointers::LibraryPointers()
: f( reinterpret_cast<void(*)(int*)>(dlsym(RTLD_DEFAULT, "real_f.symbol_name_")) )
, // initialization of other pointers...
{
}
Then wrap the library in a C++ class which uses this structure to get
the addresses of the pointers.
And one last remark: the reinterpret_cast you are trying to do isn't
legal, at least not formally. (I think that both Sun CC and g++ will
accept it, however.) According to Posix, the correct way to get a
pointer to function from dlsym would be:
void (*f)(int* );
*reinterpret_cast<void**>(&f) = dlsym(...);
This doesn't lend itself to initializations, however.

C++ Struct initialisation problem

This c++ code is working fine , however memory validator says that I am using a deleted pointer in:
grf->filePath = fname; Do you have any idea why ? Thank you.
Dirloader.h
// Other code
class CDirLoader
{
public:
struct TKnownGRF
{
std::string filePath;
DWORD encodingType;
DWORD userDataLen;
char *userData;
};
// Other Code
CDirLoader();
virtual ~CDirLoader();
Dirloader.cpp
// Other code
void CDirLoader::AddGroupFile(const std::string& _fname)
{
// Other code including std::string fname = _fname;
TKnownGRF *grf = new TKnownGRF;
grf->filePath = fname;
delete grf; // Just for testing purposes
P.S.: This is only an code extract. Of course if I define a struct TKnownGRF inside .cpp and use it as an actual object, gfr.filepath = something, instead of pointer grf->filepath=something, than it is ok, but I do need to have it inside *.h in CDirLoader class, due to many other vector allocations.
Since the function returns void
void CDirLoader::AddGroupFile(const std::string& _fname)
the question is what are you going to do with grf?
Are you going to delete it? If so, then, why do a new? you can just declare a TKnownGRF variable on the stack! In that case, _fname is not contributing to the logic of this method.
I guess that the class CDirLoader has a member variable of type TKnownGRF, say grf_, and that need to be used in the AddsGroupFile() method, e.g.:
grf_.filepath = _fname;
Does this happen to be using an older version of STL, say, VC6, and running multithreaded? Older versions of STL's string class used a reference counted copy on write implementation, which didn't really work in a multithreaded environment. See this KB article on VC 6.
Or, it's also possible that you are looking at the wrong problem. If you call std::string::c_str() and cache the result at all, the cached result would probably be invalidated when you modified the original string. There are a few cases where you can get away with that, but it's very much implementation specific.

Pointer object in C++

I have a very simple class that looks as follows:
class CHeader
{
public:
CHeader();
~CHeader();
void SetCommand( const unsigned char cmd );
void SetFlag( const unsigned char flag );
public:
unsigned char iHeader[32];
};
void CHeader::SetCommand( const unsigned char cmd )
{
iHeader[0] = cmd;
}
void CHeader::SetFlag( const unsigned char flag )
{
iHeader[1] = flag;
}
Then, I have a method which takes a pointer to CHeader as input and looks
as follows:
void updateHeader(CHeader *Hdr)
{
unsigned char cmd = 'A';
unsigned char flag = 'B';
Hdr->SetCommand(cmd);
Hdr->SetFlag(flag);
...
}
Basically, this method simply sets some array values to a certain value.
Afterwards, I create then a pointer to an object of class CHeader and pass it to
the updateHeader function:
CHeader* hdr = new CHeader();
updateHeader(hdr);
In doing this, the program crashes as soon as it executes the Hdr->SetCommand(cmd)
line. Anyone sees the problem, any input would be really appreciated
When you run into a crash, act like a crime investigator: investigate the crime scene.
what is the information you get from your environment (access violation? any debug messages? what does the memory at *Hdr look like? ...)
Is the passed-in Hdr pointer valid?
Then use logical deduction, e.g.:
the dereferencing of Hdr causes an access violation
=> passed in Hdr points to invalid memory
=> either memory wasn't valid to start with (wrong pointer passed in), or memory was invalidated (object was deleted before passing in the pointer, or someone painted over the memory)
...
It's probably SEGFAULTing. Check the pointers.
After
your adding some source code
your comment that the thing runs on another machine
the fact that you use the term 'flag' and 'cmd' and some very small datatypes
making me assume the target machine is quite limited in capacity, I suggest testing the result of the new CHeader for validity: if the system runs out of resources, the resulting pointer will not refer to valid memory.
There is nothing wrong with the code you've provided.
Are you sure the pointer you've created is the same same address once you enter the 'updateHeader' function? Just to be sure, after new() note the address, fill the memory, sizeof(CHeader), with something you know is unique like 0XDEAD, then trace into the updateHeader function, making sure everything is equal.
Other than that, I wonder if it is an alignment issues. I know you're using 8 bit values, but try changing your array to unsigned ints or longs and see if you get the same issue. What architecture are you running this on?
Your code looks fine. The only potential issue I can see is that you have declared a CHeader constructor and destructor in your class, but do not show the implementation of either. I guess you have just omitted to show these, else the linker should have complained (if I duplicate this project in VC++6 it comes up with an 'unresolved external' error for the constructor. It should also have shown the same error for the destructor if you had a... delete hdr; ...statement in your code).
But it is actually not necessary to have an implementation for every method declared in a class unless the methods are actually going to get called (any unimplemented methods are simply ignored by the compiler/linker if never called). Of course, in the case of an object one of the constructor(s) has to be called when the object is instantiated - which is the reason the compiler will create a default constructor for you if you omit to add any constructors to your class. But it will be a serious error for your compiler to compile/link the above code without the implementation of your declared constructor, so I will really be surprised if this is the reason for your problem.
But the symptoms you describe definitely sounds like the 'hdr' pointer you are passing to the updateHeader function is invalid. The reason being that the 1st time you are dereferencing this pointer after the updateHeader function call is in the... Hdr->SetCommand(cmd); ...call (which you say crashes).
I can only think of 2 possible scenarios for this invalid pointer:
a.) You have some problem with your heap and the allocation of memory with the 'new' operator failed on creation of the 'hdr' object. Maybe you have insufficient heap space. On some embedded environments you may also need to provide 'custom' versions of the 'new' and 'delete' operator. The easiest way to check this (and you should always do) is to check the validity of the pointer after the allocation:
CHeader* hdr = new CHeader();
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
The normal behaviour when 'new' fails should actually be to throw an exception - so the following code will cater for that as well:
try{
CHeader* hdr = new CHeader();
} catch(...) {
//handle or throw specific exception i.e. AfxThrowMemoryException() for MFC
}
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
}
b.) You are using some older (possibly 16 bit and/or embedded) environment, where you may need to use a FAR pointer (which includes the SEGMENT address) for objects created on the heap.
I suspect that you will need to provide more details of your environment plus compiler to get any useful feedback on this problem.