c++ and global variables changed in functions - c++11

I have these variable defined as global variables outside any function
//testing parameters (init to all nonfail)
int serverRandom = 0; //nonzero == fail > gotofail for first sha1 methode
SSLBuffer sigpar= 0; //nonzero == fail > gotofail for second sha1 methode
string hashOut = "nonfail"; //"fail" == error condition > gotofail for third sha1 methode
These variables are used in this function:
static OSStatus SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, uint8_t *signature, uint16_t signatureLen)
{
OSStatus err;
cout << "initval:"<< serverRandom<< signedParams<< hashOut<<endl;
if ((err = SSLHashSHA1::update(&hashCtx, &serverRandom)) != 0)
cout << "firstfail" <<endl;
goto fail;
if ((err = SSLHashSHA1::update(&hashCtx, &signedParams)) != 0)
cout <<"secondfail"<<endl;
goto fail;
//goto fail;
if ((err = SSLHashSHA1::final(&hashCtx, &hashOut)) != 0)
cout << "thirdfail" << endl;
goto fail;
cout << "nonfail" << endl;
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
Note that the global variables ServerRandom and hashout are accessed directly in that function while the sigpar variable is given to the signedParams arguments of the sslVerify function.
Now, I wrote a unit test to test each failing case seperatly via this function
void unittest(){
//all tests passing
cout << "-------------nonfail-------------" << endl;
result = SSLVerifySignedServerKeyExchange(&ctx,isrsa,sigpar,&sig,siglen);
//first test fail
cout << "-------------firstfail-------------" << endl;
serverRandom = 1;
result = SSLVerifySignedServerKeyExchange(&ctx,isrsa,sigpar,&sig,siglen);
serverRandom = 0;
//second test fail
cout << "-------------secondfail-------------" << endl;
sigpar= 1;
result = SSLVerifySignedServerKeyExchange(&ctx,isrsa,sigpar,&sig,siglen);
sigpar= 0;
//third test fail
cout << "-------------thirdfail-------------" << endl;
hashOut = "fail";
result = SSLVerifySignedServerKeyExchange(&ctx,isrsa,sigpar,&sig,siglen);
hashOut = "nonfail";
}
Now it works perfectly for the first fail case eg. outputting the firstfail line. After that It does not work anymore as it just outputs the ---------secondfail-------- & ------thirdfail------- without outputting the failchecks (secondfail/thirdfail).
note that the initval inside sslverify...() shows the correct values, however the update/final function after the first testcause show 0 as a value for the respective values they recieve.

well, it was easy to solve in the end:
in the SSLVerifySignedServerKeyExchange() I just forgot to add {} around the multi-line if's after I added the cout<< so it would always goto fail after the first if

Related

Problem with multiple controllers in OMNeT++ SDN

I'm trying to build multiple controllers. The original code that connect all switches to one controller is as follows:
void OFA_switch::connect()
{
socket.renewSocket();
int connectPort = par("connectPort");
/*
const char *connectAddress= par("connectAddress");
EV << "connectAddress = " << connectAddress << " connectPort =" << connectPort << endl;
if (getParentModule()->getParentModule()->getSubmodule("controller") != NULL)
{
// multiple controllers; full path is needed for connect address
connectAddress = (getParentModule()->getParentModule())->getSubmodule("controller")->getFullPath().c_str();
cModule *ctl = getSystemModule()->getSubmodule("controller");
if(ctl != NULL) {
EV << "ctl->getFullPath() = " << ctl->getFullPath().c_str() << endl;
connectAddress = ctl->getFullPath().c_str();
}
EV << "After: connectAddress = " << connectAddress << endl;
}
*/
L3Address ctlIPAddr;
EV << "connect L3Address = " << L3AddressResolver().tryResolve("controller", ctlIPAddr) << endl;
// EV << "result: connectAddress = " << ctlIPAddr << endl;
// socket.connect(L3AddressResolver().resolve(connectAddress), connectPort);
socket.connect(ctlIPAddr, connectPort);
}
I'm trying to make some switches connected to controller1 while the other switches connected to controller2, so I tried to adapt the following code to:
void My_OFA_switch::connect() {
socket.renewSocket();
int connectPort = par("connectPort");
const char *connectAddress = par("connectAddress");
EV << "connectAddress = " << connectAddress << " connectPort =" << connectPort << endl;
const char *connectAddr;
cModule *ctl;
if (strcmp (connectAddress, "controller1")==0)
{ connectAddr = (getParentModule())->getSubmodule("controller1")->getFullPath().c_str();
ctl = getSystemModule()->getSubmodule("controller1");
}
else if (strcmp (connectAddress, "controller2")==0)
{ connectAddr = (getParentModule())->getSubmodule("controller2")->getFullPath().c_str();
ctl = getSystemModule()->getSubmodule("controller2");
}
if(ctl != NULL) {
EV << "ctl->getFullPath() = " << ctl->getFullPath().c_str() << endl;
connectAddr = ctl->getFullPath().c_str();
}
L3Address ctlIPAddr;
EV << "connect L3Address = " << L3AddressResolver().tryResolve(connectAddr, ctlIPAddr) << endl;
socket.connect(ctlIPAddr, connectPort);
}
Also, there is a file Switch.cc which represents the controller behavior
"in ini file :
*.controller.behavior = "Switch" "that contain:
void Switch::initialize() {
cModule *ITModule =
getParentModule()->getSubmodule("ofa_controller");
controller = check_and_cast<OFA_controller *>(ITModule);
getParentModule()->subscribe("PacketIn",this); }
Should I change something here?
But when I run it the following runtime error appears and immediately close the simulation:
Simulation run has encountered a problem. Finished with error.
And in console it appeared:
Simulation terminated with exit code: -1073741819
Working directory: D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/myws/openflow/scenarios
Command line: ../openflow.exe -m -n ..;../../inet/src;../../inet/examples;../../inet/tutorials;../../inet/showcases --image-path=../images;../../inet/images -l ../../inet/src/INET My_2Domain_Ctrl.ini
Environment variables:
PATH=;D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/myws/inet/src;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\mingw64\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin;;D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/ide/jre/bin/server;D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/ide/jre/bin;D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/ide/jre/lib/amd64;.;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\mingw64\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\local\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin;C:\Windows\System32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin\site_perl;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin\vendor_perl;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\tools\win64\usr\bin\core_perl;D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2;
OMNETPP_ROOT=D:/omnet/OpenFlowOmnet/omnetpp-5.6.2-src-windows/omnetpp-5.6.2/
OMNETPP_IMAGE_PATH=D:\omnet\OpenFlowOmnet\omnetpp-5.6.2-src-windows\omnetpp-5.6.2\images
I really appreciate any guidance and help because I must do a lot of work and I'm running out of time.
enter image description here
One has to remember that strcmp() returns 0 if the contents of both strings are equal. And in C++ zero means false.
So if you want to do something when connectAddress is equal to "controller1", you should write:
if (strcmp (connectAddress, "controller1") == 0) {
// ...
}
Generally, in order to deal with a runtime exception in OMNeT++ do:
Set debug-on-errors=true in your omnetpp.ini.
Build the project in debug mode.
Start the simulation in debug (i.e. Run | Debug).
The simulation will stop in the line that causes an error and in the stack trace you may see the referenced calls.
Reference: Learn OMNeT++ with TicToc - Runtime errors

C++ Struct attributes can change within function, but remain unchanged outside scope of function

I'm working on a self imposed challenge which involves implementing a linked list and an append function for it, which is giving me issues seemingly related to variable scope.
The append function loops through each link element until it reads a NULL value and then changes the data value associated with that link to the function input. The test outputs within the function seem to show it is working as intended, but when performing the same test outside the function, even after it is called gives a different output.
template <class T>
struct atom{
T data;
atom<T>* link = NULL;
};
template <class T>
void append_LL(atom<T> first, T input_data){
atom<T>* current_node = &first;
atom<T>* next_node = current_node->link;
int i = 0;
while (i < 4 && next_node != NULL) {
current_node = next_node;
next_node = next_node->link;
i ++;
}
current_node->data = input_data;
current_node->link = (atom<T>*)malloc(sizeof(atom<T>));
cout << "leaving node as: " << current_node->data << endl; //outputs 5
cout << "input nodes data: " << first.data << endl; //outputs 5
}
int main() {
int dd = 5;
atom<int> linked_list;
linked_list.data = 999;
append_LL(linked_list, dd);
cout << linked_list.data << endl; //outputs 999
}
Because you are not sending the same atom. You see the program is making a copy of the linked_list in the main function and sending that copy to the function.
If you want to modify the same linked_list then change
void append_LL(atom<T> first, T input_data){
to
void append_LL(atom<T> &first, T input_data){
That way you are sending the really atom not a copy of it.

Serial Communication data problem between Windows and embedded System (STM32) (C/C++)

I currently try to set up communication between a Windows program and a µC.
I'll show you the code to initialize the port:
int serialCommunication::serialInit(void){
//non overlapped communication
hComm = CreateFile( gszPort.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);
if (hComm == INVALID_HANDLE_VALUE){
cout << "Error opening port." << endl;
return 0;
}
else{
cout << "Opened Port successfully." << endl;
}
if (SetCommMask(hComm, EV_RXCHAR) == FALSE){
cout << "Error setting communications mask." << endl;
return 0;
}
else{
SetCommMask(hComm, EV_RXCHAR);
cout << "Communications mask set successfully." << endl;
}
if (GetCommState(hComm, &dcbSerialParams) == FALSE){
cout << "Error getting CommState." << endl;
return 0;
}
else{
GetCommState(hComm, &dcbSerialParams);
cout << "CommState retrieved successfully" << endl;
}
dcbSerialParams.BaudRate = CBR_115200; // Setting BaudRate = 115200
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8
dcbSerialParams.StopBits = ONESTOPBIT; // Setting StopBits = 1
dcbSerialParams.Parity = NOPARITY; // Setting Parity = None
if (SetCommState(hComm, &dcbSerialParams) == FALSE){
cout << "Error setting CommState" << endl;
return 0;
}
else{
SetCommState(hComm, &dcbSerialParams);
cout << "CommState set successfully" << endl << endl;
cout << "+---CommState Parameters---+" << endl;
cout << "Baudrate = " << dcbSerialParams.BaudRate << endl;
cout << "ByteSize = " << static_cast<int>(dcbSerialParams.ByteSize) << endl; //static Cast, um int auszugeben und kein char
cout << "StopBits = " << static_cast<int>(dcbSerialParams.StopBits) << endl; //static Cast, um int auszugeben und kein char
cout << "Parity = " << static_cast<int>(dcbSerialParams.Parity) << endl; //static Cast, um int auszugeben und kein char
cout << "+--------------------------+" << endl;
}
/*------------------------------------ Setting Timeouts --------------------------------------------------*/
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (SetCommTimeouts(hComm, &timeouts) == FALSE){
cout << "Error setting timeouts" << endl;
return 0;
}
else{
SetCommTimeouts(hComm, &timeouts);
cout << "Timeouts set successfully." << endl;
cout << "+--------------------------+" << endl;
return 1;
}
My Read function looks like this:
void serialCommunication::serialRead(void){
bool readStatus;
bool purgeStatus = 0;
bool correctData = 0;
cout << "Waiting for Data..." << endl; // Programm waits and blocks Port (like Polling)
readStatus = WaitCommEvent(hComm, &dwEventMask, 0);
if (readStatus == FALSE){
cout << "Error in setting WaitCommEvent." << endl;
}
else{
cout << "Data received." << endl;
do{
readStatus = ReadFile(hComm, &TempChar, sizeof(TempChar), &NoBytesRead, 0);
SerialBuffer += TempChar; // add tempchar to the string
}while (NoBytesRead > 0);
SerialBuffer.pop_back(); // Delete last sign in buffer, otherwise one "0" too much shows up, for example "23900" instead of "2390"
cout << endl << SerialBuffer << endl;
SerialBuffer = ""; // Reset string
}
So at some point, my µC sends the String "Init complete...!\r\n" after initializing some things. This works well.Init complete proof
Now after that, the communcation produces errors. I am getting Data I should not receive. The µC can only send data, if a specific string is sent to it by the PC. While debugging I could detect, that the µC never receives this specific string and therefore never sends data. In the following picture, I show you what gibberish I am receiving constantly though.
Receiving Gibberish
/EDIT: I am constantly receiving the same gibberish
The funny thing is, I even receive that data, when the µC is completely switched off (Serial Cables are still connected). So there has to be some data at the port, which just is not deleted. I tried to restart the PC aswell, but it didn't help either.
I will also show you my while loop on PC:
while (testAbbruch != 1){
pointer = acMessung(anzahlMessungen, average); // measurement with external multimeter
cout << endl;
cout << "Average: " << average << endl << endl;
if (average >= 30){
testAbbruch = 1; // there won't be a next while iteration
befehl = "stopCalibration\r\n";
serialTest.serialWrite(befehl);
serialTest.serialRead();
}
else{
cout << "Aktion: ";
std::getline (cin, befehl);
befehl = "increment"; //for debugging
if (befehl == "increment"){
befehl.append("\r\n"); // adding it, so the µC can detect the string correctly
serialTest.serialWrite(befehl);
serialTest.serialRead(); // µC has to answer
}
else if(befehl == "decrement"){
befehl.append("\r\n"); // adding it, so the µC can detect the string correctly
serialTest.serialWrite(befehl);
serialTest.serialRead(); // µC has to answer
}
befehl = ""; // string leeren für nächsten Aufruf
}
}
I know my program is far from perfect, but if I understood the serial Communication with Windows correctly, the buffer is deleted while reading.
Is there any clue you could give me?
EDIT// I just wrote a program that expects one of two inputs: One input is called "increment" the other one is called "decrement". Those inputs are sent to the µC via the serial communication port. Every time I try to send "increment" and instantly after that I am reading from the port, I receive the weird data from this picture. Now, every time I try to send "decrement" and instantly after that I am reading from the port, I receive the weird data from that picture.
//
So my guess is that the data somehow is changed and then looped back to the PC? But why and how?!

How to get source location of #includes using clang libtooling?

Is there any way to get clang::SourceLocation for every #include in file by its clang::FileID or clang::FileEntry or something?
What about using source manager's GetIncludedLoc function which takes fileid as parameter.
SourceManager.GetIncludedLoc(fileid)
Thank's #Hemant for your answer, you're right
I Already found that by myself (in clang 3.8 it is called getIncludeLoc)
but forgot to write here.
I used this to find the location after all #includes where i can put my own.
Here's the function (For sure not the best way) I wrote for this, hope it helps someone
SourceLocation getIncludeLocation(FileID fileID, SourceManager &sm, unsigned carriages) {
return SourceLocation();
set<unsigned> lines;
if (fileID.isInvalid())
for (auto it = sm.fileinfo_begin(); it != sm.fileinfo_end(); it++) {
SourceLocation includeLoc = sm.getIncludeLoc(sm.translateFile(it->first));
if (includeLoc.isValid() && sm.isInFileID(includeLoc, fileID)) {
lines.insert(sm.getSpellingLineNumber(includeLoc));
}
}
unsigned pos(0);
if (!lines.empty()) {
bool first = true;
for (unsigned line :lines) {
if (first)
first = false;
else if ((line - pos) > carriages)
break;
pos = line;
//cout << "Include line:" << pos << endl;
}
//cout << console_hline('-') << endl;
}
cout << sm.getFileEntryForID(fileID)->getName() << endl;
return sm.translateFileLineCol(sm.getFileEntryForID(fileID), ++pos, 1);
}
Also some information about includes can be get by
Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
and
Lexer::ComputePreamble(StringRef Buffer, const LangOptions &LangOpts, unsigned MaxLines = 0)

StackWalk64() returns a single frame

When trying to obtain the call stack of a thread of some process, I always get a single same frame, although it is for sure has more (at least 5 frames).
StackWalk64() always succeeds on the first call - return a frame with:
AddrPC.Offset = 18446744072850558156
But, immediately on the second call it fails with error id 998-ERROR_NOACCESS (it might be that this error is not because of this call, as MSDN says).
Moreover, trying to resolve this address into its symbol name with SymFromAddr() fails with error 126-ERROR_MOD_NOT_FOUND (after successful SymInitialize(m_processHandler,NULL,TRUE) call).
Here is the code:
#ifdef _M_IX86
//
// Disable global optimization and ignore /GS waning caused by
// inline assembly.
//
#pragma optimize( "g", off )
#pragma warning( push )
#pragma warning( disable : 4748 )
#endif
bool EchoProfiler::getThreadStackTrace(__in HANDLE h_thread, __out vector<DWORD64> &framesVec)
{
CONTEXT threadContext;
if (GetThreadContext(h_thread, &threadContext) == 0)
{
cout << "Error: GetThreadContext() failed with error ID " << GetLastError() << endl;
return false;
}
//initialize stack frame
DWORD MachineType;
STACKFRAME64 StackFrame;
ZeroMemory( &StackFrame, sizeof( STACKFRAME64 ) );
MachineType = IMAGE_FILE_MACHINE_I386;
StackFrame.AddrPC.Offset = threadContext.Eip;
StackFrame.AddrPC.Mode = AddrModeFlat;
StackFrame.AddrFrame.Offset = threadContext.Ebp;
StackFrame.AddrFrame.Mode = AddrModeFlat;
StackFrame.AddrStack.Offset = threadContext.Esp;
StackFrame.AddrStack.Mode = AddrModeFlat;
PVOID contextRec = (MachineType == IMAGE_FILE_MACHINE_I386) ? NULL : &threadContext;
int i=0;
// enumerate all the frames in the stack
for (i=1 ; ; i++)
{
if (StackWalk64( MachineType, targetProcessHandler, h_thread, &StackFrame,
contextRec, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL ) == false)
{
// in case it failed or we have finished walking the stack.
cout << "Error: StackWalk64() failed with error ID " << GetLastError() << endl;
i--;
break;
// return false;
}
if ( StackFrame.AddrPC.Offset != 0 )
{
// Valid frame.
cout << "Frame #" << i << " address - " << StackFrame.AddrPC.Offset << endl;
framesVec.push_back(StackFrame.AddrPC.Offset);
}
else
{
// Base reached.
break;
}
}
//cout << "StackWalk64 found " << i << " stack frames:" << endl;
//i = 1;
//for (FramesConstItr itr=framesVec.begin() ; itr != framesVec.end() ; itr++ , i++)
// cout << i << " - " << *itr << endl;
return true;
}
#ifdef _M_IX86
#pragma warning( pop )
#pragma optimize( "g", on )
#endif
what could it be?
Solution:
I missed the part said that the context structure must be initialize properly.
Adding the following solved my problem:
memset(&threadContext, 0, sizeof(CONTEXT));
threadContext.ContextFlags = CONTEXT_FULL;
Thanks
For anyone running into this issue in the future, I also suffered from it in our own local codebase when getting stack information from a different process to the current one. The cause was that we were missing PROCESS_VM_READ when getting a handle on the process using OpenProcess().

Resources