Exception when reading output of process - c++

my problem is the following:
I have a UI created in Visual Studio with C++/CLI.
Now I have a button event that creates a process which runs a C++ Console Application with Parameters.
This works fine, the console application gets executed with parameters with no errors and im also seeing the console window with the right output.
But I still get an exception:
StandardOut has not been redirected or the process hasn't started yet.
I think this has something to do with the Streamreader and some DataReceivedEvents but I have no clue.
This is my code:
try {
String^ parameters = tbLoadXML->Text + " " + tbNumberAnts->Text + " " + tbIteration->Text + " " + tbReduction->Text + " " + tbPheromoneDeposit->Text + " " + tbPheromoneReduction->Text + " " + tbAlpha->Text + " " + tbBeta->Text + " " + reduce.ToString() + " " + algorithm.ToString() + " " + probabilityalgorithm.ToString() + " " + numbercities.ToString();
Process^ process = gcnew Process();
process->StartInfo->UseShellExecute = false;
process->StartInfo->CreateNoWindow = true;
process->StartInfo->RedirectStandardOutput = true;
process->Start("TSPACO.exe", parameters);
StreamReader^ reader = process->StandardOutput;
String^ output = reader->ReadToEnd();
textBox1->Text += output;
process->WaitForExit();
process->Close();
}
catch (Exception^ ex) {
MessageBox::Show(ex->Message);
}
I also tried a while-loop:
while (!process->StandardOutput->EndOfStream)
{
textBox1->Text += process->StandardOutput->ReadLine();
}
But nothing really works - I have no idea why.

So I figured out a solution for my problem - I have no clue why this works but I think the trick is to create a ProcessStartInfo-Object with all the needed properties and then just use the default method of Process::Start without any parameters:
ProcessStartInfo^ startInfo = gcnew ProcessStartInfo();
startInfo->FileName = "TSPACO.exe";
startInfo->Arguments = parameters;
startInfo->UseShellExecute = false;
startInfo->CreateNoWindow = true;
startInfo->RedirectStandardOutput = true;
Process^ process = gcnew Process();
process->StartInfo = startInfo;
process->Start();
StreamReader^ reader = process->StandardOutput;
String^ output = reader->ReadToEnd();
textBox1->Text += output;
process->WaitForExit();
process->Close();

Related

LoadLibrary Dll injector taking path input and "scrambling it"

I've created a GUI DLL injector in QT Creator using the MinGW 32bit compiler and keep getting this reoccurring issue where I'll click inject and it won't inject the DLL but it will however scramble my DLL path.
Example: Example Screenshot
The first path is the DLL after converting it the correct type
Last DLL is the DLL after the process
The address is the address where the DLL is located in the target process
0 is GetLastError()
The code DLL path conversion:
QString fileInput = ui->filesCmb->currentText(); //gets dll
dllPath = fileInput.toStdString().c_str(); //converts dll to string
qDebug() << dllPath << "\n";
The injection Process code:
QString methodChosen = ui->methodCmb->currentText();
QString targetProcess = ui->processTxt->text();
const wchar_t* tgtProc = (const wchar_t*)targetProcess.utf16();
if (methodChosen == "Manual Map") {
ui->statusTxt->setPlainText("Method not added[" + methodChosen + "]");
} else if (methodChosen == "LdrLoadDLL") {
ui->statusTxt->setPlainText("Method not added[" + methodChosen + "]");
} else {
ui->statusTxt->setPlainText("File input: " + fileInput + "\n" + "Method: " + methodChosen + "\n" + "Target Process: " + targetProcess + "\n" + "Dll path: " + dllPath + "\n");
DWORD pid = getPid(tgtProc);
dwordToQstring = QString::number(pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);
if (!pHandle || pHandle == INVALID_HANDLE_VALUE) {
ui->statusTxt->setPlainText("Couldn't get handle[" + dwordToQstring + "]");
}
LPVOID pDllPath = VirtualAllocEx(pHandle, 0, strlen(dllPath) + 1, MEM_COMMIT, PAGE_READWRITE); // allocate memeory within our target process to fit our dll
if (pDllPath != nullptr) {
WriteProcessMemory(pHandle, pDllPath, (LPVOID)dllPath, strlen(dllPath) + 1, 0); //writes our dll to the allocated memory
HANDLE hLoad = CreateRemoteThread(pHandle, 0, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA"), pDllPath, 0, 0); //creates a thread in the target process to allow out code to run
if (hLoad != nullptr) {
WaitForSingleObject(hLoad, INFINITE); //maybe waits for our dll code to execute?
ui->statusTxt->setPlainText("File input: " + fileInput + "\n" + "Method: " + methodChosen + "\n" + "Target Process: " + targetProcess + "\n" + "PID: " + dwordToQstring + "\n" + "INJECTED");
qDebug() << "LastDLL=>" << dllPath << "\n";
qDebug() << &pDllPath;
qDebug() << GetLastError();
VirtualFreeEx(pHandle, pDllPath, strlen(dllPath) + 1, MEM_RELEASE); // free the memory allocated for out dll
}
}
}
I haven't tried a lot of solutions only a few different conversion techniques, but they didn't change anything, any idea on what is causing this weird output?.
Thanks in advance.
EDIT: Thought I had fixed it but it seems to occur completely randomly sometimes it works sometimes it doesn't really confused.

Unable to find/read config file .conf - FileIOException

I'm trying to open and read a .conf file in my program using libconfig::readFile(), but it gives me always a FileIOException. I think that the program is unable to locate the file but I don't know where the problem is.
This is the .conf file code:
controlLoopPeriod = 100.0; # ms
saturationMax = [10.0];
saturationMin = [-10.0];
task = { Linear_Velocity = {
type = 0; # 0 equality, 1 inequality
gain = 1.0;
enable = true;
saturation = 10.0;
};
};
priorityLevels = ( { name = "PL_JPosition";
tasks = ["Joint_Position"];
lambda = 0.0001;
threshold = 0.01;
}
);
actions = ( { name = "jPosition";
levels = ["PL_JPosition"];
}
);
states = { State_move = {
minHeadingError = 0.05;
maxHeadingError = 0.2;
};
};
This is where I'm trying to open the file and read it:
bool RobotPositionController::LoadConfiguration() {
libconfig::Config confObj;
// Inizialization
std::string confPath = "home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot";
confPath.append("/conf/");
confPath.append(fileName_);
std::cout << "PATH TO CONF FILE : " << confPath << std::endl;
// Read the file. If there is an error, report it and exit.
try {
confObj.readFile(confPath.c_str());
} catch (const libconfig::FileIOException& fioex) {
std::cerr << "I/O error while reading file: " << fioex.what() << std::endl;
return -1;
} catch (const libconfig::ParseException& pex) {
std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() << " - " << pex.getError() << std::endl;
return -1;
}
conf_->ConfigureFromFile(confObj);
ConfigureTaskFromFile(tasksMap_, confObj);
ConfigurePriorityLevelsFromFile(actionManager_, tasksMap_, confObj);
// Set Saturation values for the iCAT (read from conf file)
iCat_->SetSaturation(conf_->saturationMin, conf_->saturationMax);
ConfigureActionsFromFile(actionManager_, confObj);
//insert states in the map
statesMap_.insert({ states::ID::jPos, stateJPosition_ });
ConfigureSatesFromFile(statesMap_, confObj);
//insert command in the map
commandsMap_.insert({ commands::ID::jPos, commandJPosition_ });
return true;
}
Thanks in advance for any type of help.
It looks to me you are missing a / at the beginning of your home path.
I.e., change:
std::string confPath = "home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot";
For:
std::string confPath = "/home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot";
I take it you have checked the .conf file exists at:
/home/nimblbot/tpik_ctr_algo/ctrl_rob_nimblbot/conf

Sqlite C API in multiprocess

I'm testing Sqlite C Api for multiprocess concurrency and I'm hitting a bug that I don't understand.
The test is simple: 1 database, 1 table of 1000 rows with 2 columns. Column 1 are uuids, column 2 is a status set to 0. I'm launching then 2 workers that concurrently select 2 uuids at status 0 and update them to 1 until no uuids are left to be updated.
Here the code in the main loop of the worker:
std::vector<std::string> uuids;
res = sqlite3_exec(database,
"BEGIN IMMEDIATE TRANSACTION;", nullptr, nullptr, nullptr);
if (res != SQLITE_OK)
{
Log("Worker: Failed to begin transaction, wait for other worker to finish");
std::this_thread::sleep_for(std::chrono::milliseconds(5));
continue;
}
Log("Worker: Begin Transaction");
// SELECT UUIDS
std::string selectString = "SELECT " + m_uuidStr + " FROM " + m_tableStr + " WHERE " + m_statusStr + "=" + std::to_string(0) + " LIMIT " + std::to_string(2);
// Log("Worker: SelectString = " + selectString);
auto selectStatement = selectString.c_str();
res = sqlite3_exec(database,
selectStatement,
fill_uuids,
&uuids, nullptr);
if (res != SQLITE_OK)
{
Log("Worker: Failed to select uuids");
return 3;
}
if (uuids.empty())
{
sqlite3_exec(database, "ROLLBACK;", nullptr, nullptr, nullptr);
Log("Worker: nothing more to update");
break;
}
// UPDATE UUIDS
std::stringstream ss;
ss << '\"' << uuids[0] << '\"';
for (int i = 1; i < uuids.size(); ++i)
ss << ", \"" << uuids[i] << '\"';
Log("Worker: UUIDs selected = " + ss.str());
std::string updateString = "UPDATE " + m_tableStr
+ " SET " + m_statusStr + "=" + std::to_string(1)
+ " WHERE (" + m_uuidStr + " in (" + ss.str() + ")) AND (" + m_statusStr + "=" + std::to_string(0) + ");";
auto updateStatement = updateString.c_str();
// BIG CRASH HERE WITH IMMEDIATE TRANSACTION ///
res = sqlite3_exec(database,
updateStatement,
nullptr, nullptr, nullptr);
if (res != SQLITE_OK)
{
Log("Worker: Failed to update uuids, err = " + std::string(err));
return 4;
}
// COMMIT CHANGES
res = sqlite3_exec(database,
"COMMIT;", nullptr, nullptr, nullptr);
if (res != SQLITE_OK)
{
Log("Worker: Failed to commit, err = " + std::string(err));
return 5;
}
Log("Worker: Transaction ended");
When using immediate transactions, one of the worker crashes with a negative error code (-1073741819 but I doubt it helps) when executing the UPDATE statement. When using exclusive transactions, I don't have any crash. The version with immediate transactions works with a unique worker. The database is open using the flags SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, Sqlite is compiled with option SQLITE_THREADSAFE=1.
There are no other process accessing the database while the workers are running. In that respect I don't understand why immediate transactions causes a crash and exclusive transactions do not, as the behavior should be similar (since no thread/process is creating reading statement during the worker execution).
I'm very new to Sqlite so maybe there's an obvious mistake lying in my code. Any help is appreciated.

C++ MySQL Connector PrepareStatement Bad_Access

At runtime in loop by twice, crashed by Bad_Access in while calling PrepareStatement by requesting query.
So I checked the all ResultSet memory and release it all but there is no idea
any idea solve this problem?
Description about member value;
PrepareStatement* pstmt;
ResultSet* res;
and the full code
bool laskdjlaskdj12::RaspBerry::grup_pw_chk(const Json::Value j){
//check the id and group is valid
try{
string group = j["Group"].asString();
const char* id = j["id"].asCString();
string grp;
string pub;
BIO* tmp; //BIO structor to change the RSA* structor
if(group == "NULL"){
group = "";
}
//request the Client is existence
pstmt = con->prepareStatement("SELECT * FROM `raspberry_cli` WHERE `Cli_id` = (?) AND `Cli_Group` = (?)");
pstmt->setString(1, id);
pstmt->setString(2, group);
res = pstmt->executeQuery();
//if query reply is NULL
if(res->next() == false){
std::cout<<"[INFO] : There is no query about raspberry_cli"<<std::endl;
return false;
}
//if query Reply
grp = res->getString("Cli_Group");
pub = res->getString("Cli_Pub");
//if There is no group in Raspberry_pi
if(ras.grp.compare(grp) == false){
//sql의 버퍼 flush
this->SQL_Flush();
return false;
}
// if the group is equal
else{
//save the client information
acc_cli.S_id = id;
acc_cli.S_Group = grp;
//save the client public_key
tmp = BIO_new_mem_buf(pub.c_str(), -1);
acc_cli.Pub_key = PEM_read_bio_RSA_PUBKEY(tmp, NULL, 0, NULL);
//if public key is not wright in section
if(acc_cli.Pub_key == NULL){
return false;
}
delete[] tmp;
//flush SQL_flush = delete ResultSet
this->SQL_Flush();
return true;
}
}catch(sql::SQLException& e){
std::cout << "# ERR: SQLException in " << __FILE__;
std::cout << "(" << __FUNCTION__ << ") on line "<< __LINE__ << std::endl;
std::cout << "# ERR: " << e.what();
std::cout << " (MySQL error code: " << e.getErrorCode();
std::cout << ", SQLState: " << e.getSQLState() << " )" << std::endl;
return false;
}
The Detal StackTrace is this
* thread #1: tid = 0x2778b, 0x00000001000e29c3 RaspBerry`list_add(root=0x0000000100903e38, element=0x00000001009043e8) + 19 at list.c:33, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x00000001000e29c3 RaspBerry`list_add(root=0x0000000100903e38, element=0x00000001009043e8) + 19 at list.c:33 [opt]
frame #1: 0x00000001000de27f RaspBerry`mysql_stmt_init(mysql=0x0000000102802220) + 143 at libmysql.c:1568 [opt]
frame #2: 0x0000000100168f41 RaspBerry`sql::mysql::NativeAPI::MySQL_NativeConnectionWrapper::stmt_init(this=0x0000000100a00580) + 33 at mysql_native_connection_wrapper.cpp:421 [opt]
frame #3: 0x000000010011c415 RaspBerry`sql::mysql::MySQL_Connection::prepareStatement(this=0x0000000100a00550, sql=0x00007fff5fbfe138) + 53 at mysql_connection.cpp:1137 [opt]
* frame #4: 0x0000000100073071 RaspBerry`laskdjlaskdj12::RaspBerry::grup_pw_chk(this=0x00007fff5fbfeba0, j=const Json::Value # 0x00007fff5fbfea30) + 881 at RaspBerry.cpp:438
frame #5: 0x000000010007c222 RaspBerry`main(argc=1, argv=0x00007fff5fbff7f8) + 3474 at main.cpp:81
frame #6: 0x00007fffced8b255 libdyld.dylib`start + 1
frame #7: 0x00007fffced8b255 libdyld.dylib`start + 1
Find the answer
pstmt = con->prepareStatement("SELECT * FROM `raspberry_cli` WHERE `Cli_id` = (?) AND `Cli_Group` = (?)");
pstmt->setString(1, id);
pstmt->setString(2, group);
res = pstmt->executeQuery();
[delete pstmt;] //===================> This part is missing
in this section i didn't delete pstmt(sql::preparestatement*)
so the sql have send that malloc error.
So Be careful about allocating memory.

QProcess and firefox

I have an issues trying to launch firefox through QProcess.
Here is the function I used to launch commands (such as firefox, mkdir, ...)
double launch_nowait(string cmd, bool display) {
string command_name = "";
string command_param = "";
bool first_space = false;
for (int p = 0; p < cmd.size(); p++) {
if (!first_space && cmd[p] == ' ') first_space = true;
else {
if (!first_space) command_name += cmd[p];
else command_param += cmd[p];
}
}
cout << "NOWAIT [" << command_name << "][" << command_param << "]" << endl;
QProcess* process;
//process->setWorkingDirectory(".");
//process->waitForFinished();
process->start(QString::fromStdString(command_name), QStringList() << QString::fromStdString(command_param));
return 0;
}
I tried several things such as :
removing parameters,
changing the navigator to chrome
adding a wait
setting the working directory
But it always ends with a seg fault.
The strange thing is that when I use this function to create a directory it works fine.
Thanks for your help,