Rocksdb: Assertion `last_ref' failed when closing DB while using unique pointers - rocksdb

I keep getting rocksdb_column_family_error_test: /rocksdb/db/column_family.cc:1236: rocksdb::ColumnFamilySet::~ColumnFamilySet(): Assertion `last_ref' failed. when I try to close/delete or go out of scope with rocksdb. It throws SIGABRT. That is, when I use std::unique_pointers for the database and column family handlers. I have attached the test file that I'm using which mimics our production code. Main exception is that in our production code we have a class that handles the database stuff. Either way, SIGABRT is thrown when the database is closed out. I've searched for answers and have found similar issues. The main conclusion to the issues was that the column family handlers were not being released from the database before closing. Also, there seems to have been a bug in previous releases of rocksdb concerning this. Is that bug still there? Am I just doing something incorrectly? Although not in this code, I have also tested with drop/destroy of the default column family too.
Rockdb version.h
#define ROCKSDB_MAJOR 6
#define ROCKSDB_MINOR 2
#define ROCKSDB_PATCH 0
Below is the test file:
#include <gtest/gtest.h>
#include <rocksdb/db.h>
#include <rocksdb/filter_policy.h>
#include <rocksdb/table.h>
namespace testing {
namespace {
static const std::string db_directory = std::string("/tmp/database");
static const std::string kFeaturesColumnFamilyName = "keypoints_and_descriptors";
static const std::string kMatchesColumnFamilyName = "image_pair_matches";
static const std::string kIntrinsicsColumnFamilyName = "camera_intrinsics_prior";
} // namespace
TEST(RocksdbColumnFamilyError, RocksBasicPointers) {
std::unique_ptr<rocksdb::Options> options_;
std::unique_ptr<rocksdb::DB> database_;
std::unique_ptr<rocksdb::ColumnFamilyHandle> intrinsics_prior_handle_;
std::unique_ptr<rocksdb::ColumnFamilyHandle> features_handle_;
std::unique_ptr<rocksdb::ColumnFamilyHandle> matches_handle_;
options_.reset(new rocksdb::Options);
options_->max_background_jobs = 4;
options_->db_write_buffer_size = 1 << 30;
options_->bytes_per_sync = 1 << 20;
options_->compaction_pri = rocksdb::kMinOverlappingRatio;
options_->create_if_missing = true;
options_->level_compaction_dynamic_level_bytes = true;
options_->statistics = rocksdb::CreateDBStatistics();
rocksdb::BlockBasedTableOptions table_options;
table_options.block_cache = rocksdb::NewLRUCache(512 << 20);
table_options.block_size = 16 * 1024;
table_options.cache_index_and_filter_blocks = true;
table_options.pin_l0_filter_and_index_blocks_in_cache = true;
table_options.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false));
options_->table_factory.reset(rocksdb::NewBlockBasedTableFactory(table_options));
std::vector<rocksdb::ColumnFamilyDescriptor> column_descriptors;
column_descriptors.emplace_back(rocksdb::kDefaultColumnFamilyName, *options_);
// Open the DB, creating it if necessary.
rocksdb::DB* temp_db = nullptr;
std::vector<rocksdb::ColumnFamilyHandle*> temp_col_family_handles;
rocksdb::Status status = rocksdb::DB::Open(*options_,
db_directory,
column_descriptors,
&temp_col_family_handles,
&temp_db);
// Take ownership of the database object.
database_.reset(temp_db);
// Create intrinsics_prior_handle_
rocksdb::ColumnFamilyHandle * intrinsics_prior_;
database_->CreateColumnFamily(*options_, kIntrinsicsColumnFamilyName, &intrinsics_prior_);
intrinsics_prior_handle_.reset(intrinsics_prior_);
// Create features_handle_
rocksdb::ColumnFamilyHandle * features_;
database_->CreateColumnFamily(*options_, kFeaturesColumnFamilyName, &features_);
features_handle_.reset(features_);
// Create matches_handle_
rocksdb::ColumnFamilyHandle * matches_;
database_->CreateColumnFamily(*options_, kMatchesColumnFamilyName, &matches_);
matches_handle_.reset(matches_);
/*
* .... proform database operation get stuff, put stuff so on ....
*/
// Drop handles
database_->DropColumnFamily(intrinsics_prior_handle_.get());
database_->DropColumnFamily(features_handle_.get());
database_->DropColumnFamily(matches_handle_.get());
// Destroy handles
database_->DestroyColumnFamilyHandle(intrinsics_prior_handle_.get());
database_->DestroyColumnFamilyHandle(features_handle_.get());
database_->DestroyColumnFamilyHandle(matches_handle_.get());
// Close db
database_->Close(); // Causes SIGABRT
// delete database_.get(); // Causes SIGABRT
// rocksdb::DestroyDB(db_directory, rocksdb::Options()); // Causes SIGABRT // Options doesn't have any affect
rocksdb::DestroyDB(db_directory, *options_); // Causes SIGABRT // Options doesn't have any affect
}
} // namespace testing

In addition to Dropping and Destroying ColumnFamilies that you have created, I think, you also need to Destroy the default column family.
database_->DestroyColumnFamilyHandle(default_family_handle_);
The default family should not be dropped.

Related

Cortex-M0+ : Can't Jump From Bootloader To App

I'm Working on ATSAMC21 (ATSAMC21J18A) with Cortex-M0+, making my CAN bootloader.My IDE is ATMEL studio.
Flashing my app is Ok but when I jump in i, it failed.(I tryed with debug and without)
In dissaseembly it point to the first of these two line:
*FFFFFFFE ?? ?? ??? Memory out of bounds or read error*
*00000000 a0.32 adds r2, #160*
pc disassembly point
My bootloader space in my linker :
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00008000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
My application (or firmware) space in my linker :
MEMORY
{
rom (rx) : ORIGIN = 0x00010000, LENGTH = 0x00030000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
Before jumping,
I disabled irq interrupt, defined my entry point and my stack pointer, and change VTOR.
Here is my code to jump:
void JumpToApp(void) {
uint16_t i;
uint32_t startAddress, applicationStack;
/* Check if WDT is locked */
if (!(WDT->CTRLA.reg & WDT_CTRLA_ALWAYSON)) {
/* Disable the Watchdog module */
WDT->CTRLA.reg &= ~WDT_CTRLA_ENABLE;
}
//stop general IT
__disable_irq();
// Disable SysTick
SysTick->CTRL = 0;
// Disable IRQs & clear pending IRQs
for (i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
// Pointer to the Application Section
void (*application_code_entry)(void);
startAddress = FLASH_APP_VADRESS; //HERE 0x00010000, my start App
applicationStack = (uint32_t) *(volatile unsigned int*) (startAddress);
application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(FLASH_APP_VADRESS + 4)); //HERE 0x00010004
// Rebase the Stack Pointer
__DSB();
__ISB();
__set_MSP(*(uint32_t *)applicationStack); //HERE 0x00010000, my start App
// Rebase the vector table base address
SCB->VTOR = ((uint32_t)startAddress & SCB_VTOR_TBLOFF_Msk);
__DSB();
__ISB();
// Jump to user Reset Handler in the application
application_code_entry();
}
I tried to add +1 at my application_code_entry , like a odd Thumb mode, i see this for Cortex-M3 but it don't work, fail in general IT.
Then I rename main() by main_boot()
and Reset_Handler() by Reset_Handler_Boot() (and by changing in propety flag linker the --entry=Reset_Handler_Boot)
But still not jumping.
I don't know what i'm doing bad.May be there is a long jump to do?
Split the RAM?
If somebody have an idea?
Thank You!!!!!!!!!!!!!!!!!!!
Thank you, (it was a mistake :) )but this hard fault doesn't resolve my jump (in fact i Used directly the adress __set_MSP(*(uint32_t *)(FLASH_APP_VADRESS));
My MSP is not 0x0000000, it's 0x20003240 so is it an offset to apply to my new MSP? (see the picture linked)
Here is my code for testing the MSP
ReadMsp=__get_MSP(); //result 0x20003240, before change it
__DSB();
__ISB();
__set_MSP(*(uint32_t *)applicationStack);
// Rebase the vector table base address TODO: use RAM
SCB->VTOR = ((uint32_t)startAddress & SCB_VTOR_TBLOFF_Msk);
__DSB();
__ISB();
ReadMsp=__get_MSP(); //result is 0xFFFFFFFC , why ???
__DSB();
__ISB();
__set_MSP(0x00010000);
__DSB();
__ISB();
ReadMsp=__get_MSP(); //result is 0x00010000, better than my same #define FLASH_APP_VADRESS or *(uint32_t *)applicationStack in __MSP
//applicationEntry();
// Load the Reset Handler address of the application
//application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(FLASH_APP_VADRESS ));
// Jump to user Reset Handler in the application
application_code_entry();
Should I use (0x20003240 + 0x00010000) for my new MSP?
enter image description here
You are dereferencing the SP stack pointer twice:
applicationStack = (uint32_t) *(volatile unsigned int*) (startAddress);
// ... --^
__set_MSP(*(uint32_t *)applicationStack);
// -^
You need to do that only once. The second time sets SP highly likely to zero, resulting to a fault once the stack is used.
I found the answer !!!
Finally to jump, just like atmel say BUT before I needed to uninitialized some module.
So : ATMEL part :
*// Pointer to the Application Section
void (*application_code_entry)(void);
// Rebase the Stack Pointer
__set_MSP(*(uint32_t *)FLASH_APP_VADRESS);
// Rebase the vector table base address TODO: use RAM
SCB->VTOR = ((uint32_t)FLASH_APP_VADRESS & SCB_VTOR_TBLOFF_Msk);
// Load the Reset Handler address of the application
application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)
(FLASH_APP_VADRESS + 4));
// Jump to user Reset Handler in the application
application_code_entry();*
My part before executing this :
*Flash_Deinit(); //flash uninit
config_TC_Deinit(); //time clock uninit, scheduler
can_deinit0(); // module CAN0
can_deinit1(); // module CAN1
Handle_Wdt_Disable();
__disable_irq();
// Disable SysTick
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
// Disable IRQs & clear pending IRQs
for (i = 0; i < 8; i++) {
NVIC->IP[i] = 0x00000000;
}
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;*
I hope it will help someone !!! :)

How to call DeviceIOControl code asynchronously?

I am trying to call DeviceIO functions asynchronously by using the OVERLAPPED structure as described on MSDN.
I am using the FSCTL_ENUM_USN_DATA control code to enumerate the MFT of NTFS drives but i am not able to run it asynchronously. The file handle is created with FILE_FLAG_OVERLAPPED but there is no difference whether I use the overlapped structure with FILE_FLAG_OVERLAPPED or not. The function does not return immediately. Is seems to be synchronous in both cases.
The example below shows the enumeration of the first 100.000 MFT entries on the C:\ drive.
Since I am not so familiar with the usage of overlapped structures maybe I did something wrong. My question: How can I execute DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA,...) asynchronously? Thanks for any help.
#include "stdafx.h"
#include <Windows.h>
typedef struct {
DWORDLONG nextusn;
USN_RECORD FirstUsnRecord;
BYTE Buffer[500];
}TDeviceIoControlOutputBuffer, *PTDeviceIoControlOutputBuffer;
int _tmain(int argc, _TCHAR* argv[])
{
MFT_ENUM_DATA lInputMftData;
lInputMftData.StartFileReferenceNumber = 0;
lInputMftData.MinMajorVersion = 2;
lInputMftData.MaxMajorVersion = 3;
lInputMftData.LowUsn = 0;
lInputMftData.HighUsn = 0;
TDeviceIoControlOutputBuffer lOutputMftData;
DWORD lOutBytesReturned = 0;
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
OVERLAPPED lOverlapped = { 0 };
lOverlapped.hEvent = hEvent;
LPCWSTR path = L"\\\\.\\C:";
HANDLE hDevice = CreateFile(path, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (hDevice != INVALID_HANDLE_VALUE) {
lOutputMftData.nextusn = 0;
while (lOutputMftData.nextusn < 100000) {
lInputMftData.StartFileReferenceNumber = lOutputMftData.nextusn;
BOOL result = DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA, &lInputMftData, sizeof(lInputMftData), &lOutputMftData, sizeof(lOutputMftData), &lOutBytesReturned, &lOverlapped);
}
}
}
TL:DR - you only get async behavior if the driver that received your request pended it.
When you call DeviceIoControl and pass an overlapped structure, it does not guarantee that the operation will be asynchronous. It means that it can be asynchronous. That depends on the way that the driver that will receive your request is implemented.
When you run DeviceIoControl, it creates a irp and sends it to the driver. DeviceIoControl will promote your thread to kernel mode to create and dispatch the irp. The driver's callback will be called on that thread to handle the request. If the driver decides to handle (and complete) the request immediately, then the request is completed synchronously. In this flow, there is no difference between opening the driver with FILE_FLAG_OVERLAPPED or not.
If the driver decides to pend the request then you will see real async behavior.
DeviceIoControl will return FALSE and GetLastError will return ERROR_IO_PENDING. That means that the irp is pending completion and the event you supplied in the OVERLAPPED struct will be signaled when the irp is completed.
HEVENT hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
OVERLAPPED lOverlapped = { 0 };
lOverlapped.hEvent = hEvent;
...
BOOL result = DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA, &lInputMftData, sizeof(lInputMftData), &lOutputMftData, sizeof(lOutputMftData), &lOutBytesReturned, &lOverlapped);
// If operation is asynchronous, wait for hEvent here or somewhere else

variable in a header file shared between different projects

I have a solution which includes three projects. one is creating static library i.e .lib file. It contains one header file main.h and one main.cpp file. cpp file contains the definition of functions of header file.
second project is .exe project which includes the header file main.h and calls a function of header file.
third project is also a .exe project which includes the header file and uses a variable flag of header file.
Now both .exe projects are creating different instance of the variable. But I want to share same instance of the variable between the projects dynamically. as I have to map the value generated by one project into other project at the same instant.
Please help me as I am nearing my project deadline.
Thanks for the help.
Here are some part of the code.
main.cpp and main.h are files of .lib project
main.h
extern int flag;
extern int detect1(void);
main.cpp
#include<stdio.h>
#include"main.h"
#include <Windows.h>
#include <ShellAPI.h>
using namespace std;
using namespace cv;
int flag=0;
int detect1(void)
{
int Cx=0,Cy=0,Kx=20,Ky=20,Sx=0,Sy=0,j=0;
//create the cascade classifier object used for the face detection
CascadeClassifier face_cascade;
//use the haarcascade_frontalface_alt.xml library
face_cascade.load("E:\\haarcascade_frontalface_alt.xml");
//System::DateTime now = System::DateTime::Now;
//cout << now.Hour;
//WinExec("E:\\FallingBlock\\FallingBlock\\FallingBlock\\bin\\x86\\Debug\\FallingBlock.exe",SW_SHOW);
//setup video capture device and link it to the first capture device
VideoCapture captureDevice;
captureDevice.open(0);
//setup image files used in the capture process
Mat captureFrame;
Mat grayscaleFrame;
//create a window to present the results
namedWindow("capture", 1);
//create a loop to capture and find faces
while(true)
{
//capture a new image frame
captureDevice>>captureFrame;
//convert captured image to gray scale and equalize
cvtColor(captureFrame, grayscaleFrame, CV_BGR2GRAY);
equalizeHist(grayscaleFrame, grayscaleFrame);
//create a vector array to store the face found
std::vector<Rect> faces;
//find faces and store them in the vector array
face_cascade.detectMultiScale(grayscaleFrame, faces, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT|CV_HAAR_SCALE_IMAGE, Size(30,30));
//draw a rectangle for all found faces in the vector array on the original image
for(unsigned int i = 0; i < faces.size(); i++)
{
Point pt1(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
Point pt2(faces[i].x, faces[i].y);
rectangle(captureFrame, pt1, pt2, cvScalar(0, 255, 0, 0), 1, 8, 0);
if(faces.size()>=1)
j++;
Cx = faces[i].x + (faces[i].width / 2);
Cy = faces[i].y + (faces[i].height / 2);
if(j==1)
{
Sx=Cx;
Sy=Cy;
flag=0;
}
}
if(Cx-Sx > Kx)
{
flag = 1;
printf("%d",flag);
}
else
{
if(Cx-Sx < -Kx)
{
flag = 2;
printf("%d",flag);
//update(2);
}
else
{
if(Cy-Sy > Ky)
{
flag = 3;
printf("%d",flag);
//update(3);
}
else
{
if(Cy-Sy < -Ky)
{
flag = 4;
printf("%d",flag);
//update(4);
}
else
if(abs(Cx-Sx) < Kx && abs(Cy-Sy)<Ky)
{
flag = 0;
printf("%d",flag);
//update(0);
}
}
}
}
2nd project's code
face.cpp
#include"main.h"
#include<stdio.h>
int main()
{
detect1();
}
3rd project's code
tetris.cpp
#include"main.h"
int key;
key = flag;
if(key==0)
{
MessageBox(hwnd,"Space2","TetRiX",0);
}
if(key==4)
{
tetris.handleInput(1);
tetris.drawScreen(2);
//MessageBox(hwnd,"Space2","TetRiX",0);
}
You need to look up how to do inter-process communication in the operating system under which your applications will run. (At this point I assume that the processes are running on the same computer.) It looks like you're using Windows (based on seeing a call to "MessageBox") so the simplest means would be for both processes to use RegisterWindowMessage create a commonly-understood message value, and then send the data via LPARAM using either PostMessage or SendMessage. (You'll need each of them to get the window handle of the other, which is reasonably easy.) You'll want to have some sort of exclusion mechanism (mutex or critical section) in both processes to ensure that the shared value can't be read and written at the same time. If both processes can do the "change and exchange" then you'll have an interesting problem to solve if both try to do that at the same time, because you'll have to deal with the possibility of deadlocks over that shared value.
You can also use shared memory, but that's a bit more involved.
If the processes are on different computers you'll need to do it via TCP/IP or a protocol on top of TCP/IP. You could use a pub-sub arrangement--or any number of things. Without an understanding of exactly what you're trying to accomplish, it's difficult to know what to recommend.
(For the record, there is almost no way in a multi-process/multi-threaded O/S to share something "at the same instant." You can get arbitrarily close, but computers don't work like that.)
Given the level of difficulty involved, is there some other design that might make this cleaner? Why do these processes have to exchange information this way? Must it be done using separate processes?

get value as integer from QlineEdit and bindit in sqlite

i tried to entre data from a form " means from QlineEdit as integer "
the programm is compiled successfully but when i open the form and entre data , the programm crach
her's the erreur
Object::connect: No such slot FenArticle::chercheParFamille() in ..\stockmanagement\fenarticle.cpp:113
QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
hers my code
*
#include "fenajoutearticle.h"
#include <QIntValidator>
#include <QValidator>
FenAjouteArticle::FenAjouteArticle(QWidget *parent) :
QWidget(parent)
{
resize(500,450);
setWindowModality(Qt::ApplicationModal);
// init member widgets
//*****************************Signals SLots ******************************//
signalSlots();
//***********************************Base de donnée Traitement***********************************//
db = new QSqlDatabase;
*db = QSqlDatabase::addDatabase("QSQLITE") ;
db->setHostName("localhost");
db->setDatabaseName("gestionstockDB.db");
db->setPassword("");
db->setUserName("");
db->open();
if(!db->open())
QMessageBox::critical(this,"Erreur","Erreur connexion base de données") ;
else{
QSqlQuery *chercheParFamilleQuery = new QSqlQuery("select Famille from Produit");
SelectFamille->clear();
while(chercheParFamilleQuery->next())
SelectFamille->addItem(chercheParFamilleQuery->value(0).toString());
QSqlQuery *chercheParUniteQuery = new QSqlQuery("select Unite from Produit");
selectUnit->clear();
while(chercheParUniteQuery->next())
selectUnit->addItem(chercheParUniteQuery->value(0).toString());
}
// basic layouting
}
void FenAjouteArticle::signalSlots()
{
connect(buttonOkUtilisateur,SIGNAL(clicked()),this,SLOT(ajoutDonne())) ;
connect(buttonAnnulerUtilisateur,SIGNAL(clicked()),this,SLOT(close())) ;
}
//********************* Signal Slots coeurs ***********************************//
void FenAjouteArticle::ajoutDonne()
{
if(db->open())
{
QSqlQuery *ajouterDonneeQuery = new QSqlQuery;
ajouterDonneeQuery->prepare("insert into Produit (Reference,Designation,localisation,Famille,Qte_min,Qte_max,Qte_stock,Unite,Prix_achat,Prix_vente) VALUES(:ref,:design,:local,:fam,:qtmin,:qtmax,:qtstock ,:unite,:pachat,:pvente)");
//QString Stock = champStockInit->text();
ajouterDonneeQuery->bindValue(":ref",champRef->text()); // QlineEdit
ajouterDonneeQuery->bindValue(":design",champDesignation->text()); // QlineEdit
ajouterDonneeQuery->bindValue(":local",champLocalisation->text()); // QlineEdit
ajouterDonneeQuery->bindValue(":fam","fam"); // QcomboBox
ajouterDonneeQuery->bindValue(":qtmin",200); // QlineEdit
ajouterDonneeQuery->bindValue(":qtmax",20); // QlineEdit
ajouterDonneeQuery->bindValue(":qtstock",20); // QlineEdit
ajouterDonneeQuery->bindValue(":unite","unite"); // QlineEdit
ajouterDonneeQuery->bindValue(":pachat",20); // QlineEdit
ajouterDonneeQuery->bindValue(":pvente",champPrixVente->text()); // QlineEdit
ajouterDonneeQuery->exec();
}
}
the DB message with the duplication is caused by (i guess) multiple instances of that class.
set up your database connection at a "global" spot, like main() or inside your main window class. (except you want and need multiple connections, but i dont think this is good when working with sqlite)
when using multiple connections, you need to add them to the QSqlQuery constructor, otherwise it will use the default connection, mostly the first created one.
no slot existing named FenArticle::chercheParFamille() should be message enough. maybe some characters are incorrect or the parameters given differs from declaration.
to the value binding, sqlite should be cool with a string as value for an integer and will use it correct, IF the value is a valid integer.
you could alternatively use:
QString intText = lineEdit->text();
bool test = false;
intText.toInt(&test);
if (test == true)
// it is a valid integer, use it
else
// message or whatever

Error passing pointer in QT

In QT have the following code that starts a thread to send out commands. The thread takes a char * and int as arguments. In the "run" I use the pointer that is given by the constuctor. The code is:
MyThread::MyThread(char * payld, int payld_size)
{
payload_size = payld_size;
payload_p = payld;
}
void MyThread::run()
{
while(...)
{
sendCommand(payload_p, payload_size);
}
}
Unfortunately this doesn´t work and my application crashes when I try to use thread.start(). But when I change it to:
MyThread::MyThread(char * payld, int payld_size)
{
payload_size = payld_size;
payload_p = payld;
for(int i=0; i<payload_size; i++)
{
payload[i] = payld[i];
}
}
void MyThread::run()
{
while(...)
{
sendCommand(payload, payload_size);
}
}
The code does run and only crashes sometimes (looks pretty random to me). Can anybody Explain me why version one doesnt work and version two does? And any ideas on why the second code sometimes crashes? Could it be because the size of payload is not predefined (in the header file I defined it as
char payload[];
When I define it as:
char payload[10];
it seems to work better, but it is annoying to test since the crashes are pretty random.
instead of fiddling with char*, I would switch to QString (since you're using Qt). It takes a bit of learning, but it's almost mandatory to get code working smoothly in this framework. Then declare
QString payload;
and depending on sendCommand implementation, use one of the member functions QString to get the char*, like payload.toLatin1()

Resources