Segmentation Fault Accessing Singleton C++ - c++

Overview
I am writing a helper class to make calls to Redis easier with the xRedis drivers in C++, but I am continually receiving a segmentation fault upon requesting or sending any information to the instance.
I think this has to do with the way I'm storing the xRedis and RedisDBIdx instances, and possibly the way I'm storing the RedisAdmin instance within the main application, but I'm unable to see the right way to set these up after several attempts.
Relevant Code is below, and a few notes on debugging steps I have taken myself.
Debugging Notes
Redis Server is started successfully, and log output shows successful connection to server on instance startup
The call fails whether a set or exists command is sent to the server
GDB Output shows below, and logs show the same happenning on either exists or set calls:
Program received signal SIGSEGV, Segmentation fault.
RedisPool::GetConnection (this=0x0, cahcetype=0, dbindex=0, ioType=0) at src/xRedisPool.cpp:124
124 || (ioType>SLAVE)
Code
redis_admin.h
#include "xredis/xRedisClient.h"
#include <string.h>
#include <string>
class xRedisAdmin
{
xRedisClient xRed;
public:
xRedisAdmin(RedisNode conn_list[], int conn_list_size);
~xRedisAdmin();
const char * load ( const char * key );
bool save ( const char * key, const char * msg );
bool exists ( const char * key );
bool del ( const char * key );
};
redis_admin.cpp
xRedisAdmin::xRedisAdmin(RedisNode conn_list[], int conn_list_size)
{
enum {
CACHE_TYPE_1,
CACHE_TYPE_2,
CACHE_TYPE_MAX,
};
xRed.Init(CACHE_TYPE_MAX);
bool bret = xRed.ConnectRedisCache(conn_list, conn_list_size, CACHE_TYPE_1);
//Log results
}
//Exists
bool xRedisAdmin::exists(const char * key)
{
RedisDBIdx d(&xRedis);
char szKey[256] = {0};
sprintf(szKey, key);
return xRed.exists(d, szKey);
}
//Save
bool xRedisAdmin::save(const char * key, const char * val)
{
RedisDBIdx d(&xRed);
char szKey[256] = {0};
sprintf(szKey, key);
bool ret_val = xRed.set(d, szKey, val);
//Log output
return ret_val;
}
Main.cpp
xRedisAdmin *xRed;
void example_callback() {
bool bRet = xRed->save("key", "c_str");
}
int main()
{
xRedisAdmin x (RedisList1, conn_list_size);
xRed = &x;
example_callback();
return 0;
}

As it turns out, this is what I get for violating the Rule of Threes.
I did not have a copy constructor for the Redis Admin, and the xRed object inside it became null on assignment because of this. Use of new & delete, rather than creating in the main method, did resolve the issue. proved the solution to the issue
Thanks all who commented and gave me answers & support!
Alex

Related

Sending string through queue in Freertos

I want to create a task with push button and the task sends a string to a queue and creates another task (this can also be separate task with lower priority) which reads the queue and blink led if its variable is same with the string in the queue. Otherwise system should stay in the idle mode. Im quite new with freertos and Led doesnot blink with below codes eventhough there is no compilation error. I also want to replace the datatype from char to string if it is possible. (select and zyRxBuff come from different sources, it is written as below for simplicity)
#include "main.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
The handlers ;
QueueHandle_t myQueue = NULL;
TaskHandle_t QTASK1 = NULL;
TaskHandle_t QTASK2 = NULL;
Prototypes ;
void Qsender(void* p);
void Qreceiver(void* p);
Main block;
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET)
{
xTaskCreate(Qsender, "SendingTask", 200, NULL, 1, &QTASK1);
vTaskStartScheduler();
}
while (1) {};
}
Sender Function;
void Qsender(void* p)
{
char select[10]= "BlinkLed";
myQueue = xQueueCreate(1, sizeof(select));
xQueueSend(myQueue, (void*) &select, (TickType_t)10);
if (myQueue != 0)
{
xTaskCreate(Qreceiver, "ReceivingTask", 200, NULL, 1, &QTASK2);
}
}
Receiver Function;
void Qreceiver(void* p)
{
char myRxBuff[10];
char zyRxBuff[10]="BlinkLed";
xQueueReceive(myQueue, &myRxBuff, (TickType_t)50);
if ( myRxBuff == zyRxBuff)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
HAL_Delay(500);
}
}
Idle function;
void vApplicationIdleHook(void){__WFI();};
Nothing is happening because the program is likely executing too quickly for things to work. When your program starts it initializes everything in a fraction of a second, and if the button is not pressed then nothing happens. Then your main loop does nothing. At a minimum, you should put the button watching in a task, and that task should have a while or for loop that doesn't end.
Create a more simple system first - like, two tasks, a button-reader, and a light-emitter. The button-reader task simply checks if the button is pressed and inserts an item into the queue. The light-emitter check if there is something in the queue.
It should also be noted, that all RTOS really don't like creating and ending tasks all the time. If you're going to do so, you should read up on how tasks are created and destroyed. (https://www.freertos.org/a00125.html) Letting a task go out of context doesn't automatically clean it up, you need to use vTaskDelete - With your current functions, you'll need to clean up the QReceiver with your QSender task, which is a violation of the SOLID principals. Additionally, your QReceiver will need to send a message back that it's done. If you can get them statically working first, it will be a lot easier to get them dynamically working later.
I also noticed that you're comparing strings by address and not by content.
Qsender is sending BlinkLed
void Qsender(void* p){
char select[10]= "BlinkLed";
myQueue = xQueueCreate(1, sizeof(select));
xQueueSend(myQueue, (void*) &select, (TickType_t)10);
if (myQueue){
xTaskCreate(Qreceiver, "ReceivingTask", 200, NULL, 1, &QTASK2);
}
}
However in Qreceiver you're comparing the address of myRxBuff and zyRxBuff, when you should be doing a string-compare
void Qreceiver(void* p){
char myRxBuff[10];
char zyRxBuff[10]="BlinkLed";
xQueueReceive(myQueue, &myRxBuff, (TickType_t)50);
if ( myRxBuff == zyRxBuff){ // Offending Line
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
HAL_Delay(500);
}
}
void Qreceiver(void* p){
char myRxBuff[10];
char zyRxBuff[10]="BlinkLed";
xQueueReceive(myQueue, &myRxBuff, (TickType_t)50);
if ( strcmp(myRxBuff, zyRxBuff) == 0){ // Should compare content now
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
HAL_Delay(500);
}
}

How to register custom exception in Intel SGX?

I'm having difficulty to get my custom exception handler to work.
This is the Enclave code:
#include "Enclave_DivideZero_t.h"
#include "sgx_trts_exception.h"
#include "sgx_trts.h"
#include <string>
static char buf[200] = "Handler not called";
int divide_by_zero_handler(sgx_exception_info_t* info) {
buf[0] = '1';
return EXCEPTION_CONTINUE_EXECUTION;
}
void Enclave_DivideByZero() {
Ocall_printf(buf);
if (sgx_register_exception_handler(1, divide_by_zero_handler) == NULL) {
Ocall_printf("register failed");
} else {
Ocall_printf("register success");
}
int a(1);
int b(3/(a-a));
(void) a;
(void) b;
Ocall_printf(buf);
}
We used buf as an indication of whether the handler has been actually executed. However, the output is this:
Enclave created!
[Ocall printf] - Handler not called
[Ocall printf] - register success
[Ocall printf] - Handler not called <-- should be: "1andler not called" ("1andler" instead of "Handler")
Also, here is the App code (i.e. the untrusted code)
#include "stdafx.h"
#include "sgx_urts.h"
#include "Enclave_DivideZero_u.h"
#define ENCLAVE_FILE _T("Enclave_DivideZero.signed.dll")
sgx_status_t createEnclave(sgx_enclave_id_t *eid) {
sgx_status_t ret = SGX_SUCCESS;
sgx_launch_token_t token = {0};
int updated = 0;
ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, eid, NULL);
return ret;
}
void Ocall_printf( char* str) {
printf("[Ocall printf] - %s\n", str);
}
int _tmain(int argc, _TCHAR* argv[]) {
sgx_enclave_id_t eid;
sgx_status_t res = createEnclave(&eid);
if (res != SGX_SUCCESS) {
printf("App: error-, failed to create enclave.\n");
return -1;
} else {
printf("Enclave created!\n");
}
Enclave_DivideByZero(eid);
return 0;
}
The Problem: As you can see from the output indicates that the handler is registered successfully, but is not executed.
1- Why the registration doesn't work?
2- I tried to put the registeration with the App code, and for this I had to add the handler in the edl, the problem for this is passing the sgx_exception_info_t *info param, which is not clear which flags it needs (i.e. [in, .. <'flags'>]). So, is it correct to define it inside the Enclave?
p.s. I ran the code with Prerelease Mode.
[EDIT] I documented the project + code that I conducted on SGX here
So the question is a bit old now, but I got stuck at the same place, so maybe someone can still use my insight.
In trts_veh.cpp, where it is checked whether the exception was handled, it says in a comment that the "instruction triggering the exception will be executed again". This leads to the exception handling loop, as you noticed yourself.
However, you can increase the rip yourself, as it is stored in the pointer to the sgx_exception_info_t, by using "info->cpu_context.rip += 2;". Adding this inside your exception handler should do the trick.

Trying to open up a url address with an executable

I'm trying to open a user input url using ShellExecute in my c++ project but am finding difficulty in creating a main function within the project.
Currently I have
#include<Windows.h>
#include<stdlib.h>
#include<shellApi.h>
int findIE(const char*);
int main()
{
const char* url;
findIE(url);
return 0;
}
/**
* Open the default browser to the specified URL.
*
* \param url WebAddress to open a browser to.
*
* \returns
* If the function succeeds, it returns a value greater than 32.
* Otherwise,it returns an error code as defined in the ShellExecute documentation.
*
* \remarks
* The function uses the headerfiles: windows.h, stdlib.h, shellapi.h.
* The url is converted into a unicode string before being used.
**/
int findIE(const char* cUrl)
{
ShellExecute(NULL, "open", cUrl, NULL, NULL, SW_SHOWDEFAULT);
return 0;
}
I try going to my executable and running it but nothing is showing up...Can I get some advice on my next steps?
The program should be run:
findIE.exe websitename.com
Then open up the default browser to websitename.com
Thanks for responding!
The program should be run:
findIE.exe websitename.com
Ah, then you need to pass command line arguments to main.
At the very least:
int main( int argc, char ** argv )
{
if ( argc >= 2 )
{
findIE( argv[1] );
}
return 0;
}
You need to initialize the variable 'url'.
for example:
int main()
{
const char* url = "www.google.com"
findIE(url);
return 0;
}
And if you want to use user input you will have to take the constness of the char variable away.

how to send packet back?

I'm writing a new Agent which can be used in one host connected with at least four node.
And the host with traffic generator will send packet to client,after a delay
it will be sended to host again. And the information calculation will be in host.
However, in my test.tcl (only two nodes) the packet receive in client seems didn't
send back to host.
Could somebody give me a hand?
Did the send function any obvious wrong?
Should I assign the ip header or the target_ or anything variables to send back my packet?
AgentCPU.h
#ifndef ns_cpu_h
#define ns_cpu_h
#include <tclcl.h>
#include "agent.h"
#include "config.h"
#include "packet.h"
#include "trafgen.h"
#define SAMPLERATE 8000
struct hdr_task {
int total_time;
int size_;
int number;
int& size() { return size_;}
static int offset_;
inline static int& offset() { return offset_; }
inline static hdr_task* access (const Packet* p) {
return (hdr_task*) p->access(offset_);
}
};
class AgentCPU : public Agent {
public:
AgentCPU();
virtual void recv(Packet *, Handler *);
virtual void sendmsg(int nbytes, const char *flags = 0);
private:
double busy_time_;
float execute_time_;
float execute_time_exp;
double record_packet_Time_;
int npkts_;
};
#endif
AgentCPU.cc
#include "AgentCPU.h"
#include "packet.h"
#include "random.h"
#include "ip.h"
int hdr_task::offset_;
static class TASKHeaderClass : public PacketHeaderClass {
public:
TASKHeaderClass()
:PacketHeaderClass("PacketHeader/TASKHEAD",sizeof(hdr_task)) {
bind_offset(&hdr_task::offset_);
}
} class_task_hdr;
static class CPUClass : public TclClass {
public:
CPUClass() : TclClass("Agent/AgentCPU") {}
TclObject* create(int, const char*const*) {
return (new AgentCPU());
}
} class_cpu_agent;
AgentCPU::AgentCPU() : Agent(PT_TASK)
{
npkts_=0;
record_packet_Time_=0.0;
bind("packetSize_",&size_);
bind("record_packet_Time_",&record_packet_Time_);
bind("npkt_",&npkts_);
}
void AgentCPU::sendmsg(int nbytes, const char* flags)
{
Packet *pkt =allocpkt();
test++;
hdr_cmn *ch = hdr_cmn::access(pkt);
hdr_ip *iph= hdr_ip::access(pkt);
hdr_task *task= hdr_task::access(pkt);
task->number=Random::exponential(5000);
task->state=0;
task->total_time=0;
target_->recv(pkt);
idle();
}
void AgentCPU::recv(Packet* pkt, Handler*)
{
hdr_task *task= hdr_task::access(pkt);
if(task->state==1)
{
if(task->number >2500)
{
task -> total_time += 2500;
task -> number -=2500;
task -> state=0;
// printf("exe 2500 and the packet exe number is %d\n",task->number);
target_->recv(pkt, (Handler*)0);
}
else
{
task ->total_time += task->number ;
task ->number =0;
++npkts_;
record_packet_Time_+= task ->total_time;
Tcl& tcl =Tcl::instance();
Packet::free(pkt);
}
}
else if (task->state==0)
{
int hold_time =Random::exponential(2000);
task->total_time += hold_time;
task->state=1;
Scheduler& s =Scheduler::instance();
double delay = Random::exponential(0.2);
s.schedule(target_,pkt,delay);
}
}
I had tried to modyfied the saddr() and daddr() field in ip header
when I traced the recv packet two field , and the value is 0 and 1
I think they are represent the two node.
So I exchange the two value so the src address and the dest address will exchange
and the packet will be send back to host.
But it results in Seg fault ..
I have solved this problem
I added ip header for the packet I received
hdr_ip* ip=hdr_ip::access(pkt);
ip.daddr()=1; // this int represent the node in your tcl script
However, I have another problem
It will crash when use my tcl script
after use valgrind , the program which can help you detect the memory leak
I know how stupid this question is ,
I guess is the trace format cause this error
ie. I didnt impelment the correct "Trace::format" for my new Packet type
And I didnt comment the trace file code in my tcl script like this
set nf [open out.nam w]
$nf nametrace-all $nf
...
...
And when I comment these code (include the procedure "finish")
All things work! The packet can send to specified node And no Segment Fault
Hope this can help someone who has the same question like me

Problem compiling C++ program after adding one argument to a function

All I did was I added a single more argument (iterations) to this function:
/**
* saveImage : save the last image received.
* #param pName name of the file
*/
void GVMsample::saveImageLocal(const std::string& pName, const std::string& pImageFormat, const int &iterations) {
// Check that a video module has been registered.
if (!fRegisteredToVim) {
throw ALError(getName(), "saveImageLocal()", "No video module is currently "
"registered! Call registerToVIM() first.");
}
#ifdef GENERICVIDEOMODULE_IS_REMOTE_ON
// If this module is running in remote mode, we shouldn't use saveImageLocal.
throw ALError(getName(), "saveImageLocal()", "Module is run in remote mode, "
"use saveImageRemote instead !");
#else
ALImage* imageIn = NULL;
for ( int iter = 0; iter < iterations; iter++ )
{
// Now you can get the pointer to the video structure.
imageIn = (ALImage*) (fCamProxy->call<int>("getImageLocal", fGvmName));
if (!imageIn) {
throw ALError(getName(), "saveImageLocal", "Invalid image returned.");
}
fLogProxy->info(getName(), imageIn->toString());
// You can get some image information that you may find useful.
const int width = imageIn->fWidth;
const int height = imageIn->fHeight;
const int nbLayers = imageIn->fNbLayers;
const int colorSpace = imageIn->fColorSpace;
const long long timeStamp = imageIn->fTimeStamp;
const int seconds = (int)(timeStamp/1000000LL);
// Set the buffer we received to our IplImage header.
fIplImageHeader->imageData = (char*)imageIn->getFrame();
saveIplImage(fIplImageHeader, pName, pImageFormat, seconds);
// send image over UDP to the PC
// we will use udt
}
// Now that you're done with the (local) image, you have to release it from the V.I.M.
fCamProxy->call<int>("releaseImage", fGvmName);
#endif
}
The functions is defined like this in the header file:
/**
* saveImage : save the last image received.
* #param pName name of the file
*/
void saveImageLocal(const std::string& pName, const std::string& imageFormat, const int &iterations);
And I am getting this error:
When I take that argument away it compiles ok again.
As the error says, the prototype on line 51 of gvnsample.h is wrong. You forgot to update it, or you modified the wrong file.
Ok. I have figured out the problem. I was editing the right file. But...
I was editing the file in Windows 7 in a folder shared with Ubuntu 10.10. I was then trying to compile the program in Ubuntu through VirtualBox.
The problem was for some reason I need to reboot the virtual machine or else the files in the shared folder don't get updated when I rewrite them in Windows (when I rewrite a file in Ubuntu the changes are visible in Windows right away but the other way around reboot is needed - strange).