I am using a boost::shared_ptr to point to a plugin class. Plugin is a map <string, shared_ptr>. The first time I find a certain plugin in the map, it works fine. However, any subsequent time I try to find a particular plugin, I get a SIGSEGV error. When stepping through my code, I get to foundPlugin = a->second->onCommand(command);and find that a->second is not accessible anymore. This error only happens when I am running in Linux, however. I have no issues while running in Windows. Is there some sort of issue with boost::shared_ptr and linux? I have tried using std::shared_ptr, but I have to use a boost::dll::import function that returns a boost::shared_ptr, and I haven't found an alternative for that yet. Any insight is greatly appreciated!
I load plugins like this:
bool PluginManager::loadPlugin(std::string pluginPath, std::string
pluginName, std::string pluginType)
{
bool couldLoad = false;
boost::filesystem::path libPath = boost::filesystem::current_path();
boost::shared_ptr<my_plugin_api> plugin;
std::cout << "Loading the plugin " << pluginName << std::endl;
if (pluginName == "")
{
pluginName = "plugName";
}
try
{
plugin = boost::dll::import<my_plugin_api>(
libPath / pluginName,
pluginType,
dll::load_mode::append_decorations
);
Plugin.insert(std::pair<std::string,boost::shared_ptr<my_plugin_api>>
(pluginName, plugin));
std::cout << "Loading the plugin " << pluginName << " (SUCCESS)" <<
std::endl;
couldLoad = true;
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return couldLoad;
}
After much more testing, I feel like my problems are in the above section of code. the boost::dll::import function acts as if it finds a .so, but does not return anything in the boost::shared_ptr, which in turn causes the second snippet of code to fail. Any ideas of why this boost::dll::import function might be acting weirdly in Linux?
bool PluginManager::onCommand(const char* command, const char* pluginName)
{
bool foundPlugin = false;
auto a = Plugin.find(pluginName);
if (a == Plugin.end())
{
std::cerr << "plugin " << pluginName << " not found" << std::endl;
}
else
{
foundPlugin = a->second->onCommand(command);
}
return foundPlugin;
}
Related
I'm trying to delete Windows Defender's scans history and backup history using C++, but I have no clue how I can do it.
I'm using this code:
std::string wdefenderhistory = "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\History"; //defender history
std::string wdefenderbackupstore = "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\BackupStore"; //defender backups
if (std::filesystem::exists(wdefenderhistory)) {
std::filesystem::remove_all(wdefenderhistory);
}
if (std::filesystem::exists(wdefenderbackupstore)) {
std::filesystem::remove_all(wdefenderbackupstore);
}
I tried already with std::fs::remove() and std::remove(), but nothing works.
Any way to force deleting a folder with admin rights without using system() / ShellExecute() syntax?
Started the program as admin, etc etc - nothing works, so I'm asking there.
std::fs::remove_all() is also giving me a memory error:
I'm sure for 99% that error code will be 0x5
I noticed that some folders in directory (only CacheManager and everything under it needs) does not needs the "admin" perms,
so i solved the problem with:
code is deleting every folder w/o admin privilege and keeps C:\..\History path :)
std::string wdefenderhistory = "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\History"; //defender history
std::string wdefenderbackupstore = "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\BackupStore"; //defender backups
if (std::filesystem::exists(wdefenderhistory)) {
const std::filesystem::path defenderhist{ "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\History" };
for (auto const& dir_entry : std::filesystem::recursive_directory_iterator{ defenderhist })
{
try {
const std::filesystem::path cachemanager{ "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\History\\CacheManager" };
for (auto const& dir_entryy : std::filesystem::recursive_directory_iterator{ cachemanager })
{
if (dir_entry != dir_entryy && dir_entry != cachemanager) {
std::filesystem::remove_all(dir_entry);
}
}
}
catch (std::filesystem::filesystem_error const& ex) {
std::cout
<< "what(): " << ex.what() << '\n'
<< "path1(): " << ex.path1() << '\n'
<< "path2(): " << ex.path2() << '\n'
<< "code().value(): " << ex.code().value() << '\n'
<< "code().message(): " << ex.code().message() << '\n'
<< "code().category(): " << ex.code().category().name() << '\n';
}
}
}
Please mark this thread as solved because i dont know how to do it, thank you
While using a class to hold my window class and Vulkan class, this error VK_ERROR_FEATURE_NOT_PRESENT is returned when I use vkCreateDevice however, when I put the same code the class is running into the main class, it works completely fine. I also had a similar problem with getting the instance extensions via SDL_Vulkan_GetInstanceExtensions.
working main.cpp
window.createWindow();
engine.window = window.window;
try {
engine.initialize();
}
catch (XiError error) {
std::cout << "Error " << error.code << ": " << error.definition << std::endl;
}
window.instance = engine.getVkInstance();
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(engine.physicalDevice, &deviceProperties);
std::cout << deviceProperties.deviceName << ", Driver Version " << deviceProperties.driverVersion << std::endl;
try {
window.createSurface();
}
catch (XiError error) {
std::cout << "Error " << error.code << ": " << error.definition << std::endl;
}
window.mainLoop();
vkDestroyDevice(engine.logicalDevice, nullptr);
vkDestroySurfaceKHR(engine.instance, window.surface, nullptr);
vkDestroyInstance(engine.instance, nullptr);
SDL_DestroyWindow(window.window);
SDL_Quit();
not working main.cpp
try {
app.run();
}
catch (XiError error) {
std::cout << "Error " << error.code << ": " << error.definition << std::endl;
}
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(app.engine.physicalDevice, &deviceProperties);
std::cout << deviceProperties.deviceName << ", Driver Version " << deviceProperties.driverVersion << std::endl;
app.window.mainLoop();
app.shutDown();
app.run()
window.createWindow();
engine.window = window.window;
engine.createVulkanInstance();
window.instance = engine.getVkInstance();
window.createSurface();
engine.getPhysicalDevices();
engine.selectPhysicalDevice();
engine.createLogicalDevice();
window.mainLoop();
app.shutDown()
vkDestroyDevice(engine.logicalDevice, nullptr);
vkDestroySurfaceKHR(engine.instance, window.surface, nullptr);
vkDestroyInstance(engine.instance, nullptr);
SDL_DestroyWindow(window.window);
SDL_Quit();
window engine and app are pre-defined by my own classes
I've tried manually adding the different required and supported extensions, and it works, but it feels hacky and is quite a large bulk of code. If this is a weird out of scope error, I've really no idea. if any other code is needed I'll be happy to provide it and the GitHub can also be found here: https://github.com/XiniaDev/Xinia-Engine
I think your problem is that requiredFeatures in XiEngine is not initialised. You set a few values to true, but I think you need a memset(&requiredFeatures, 0, sizeof(requiredFeatures)); or similar at the start of XiEngine::XiEngine to fix it.
I want to create an opentelemetry tracing configuration that writes the exporter logs to a file. For that, I used the OStreamSpanExporter class that takes a ref to a std::ostream object (by default, the ctor argument is std::cout). So here is what I did:
#include <fstream>
namespace trace_sdk = opentelemetry::sdk::trace;
std::ofstream file_handle(log_trace_output_file_.c_str());
auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(new opentelemetry::exporter::trace::OStreamSpanExporter(file_handle));
auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
auto provider = nostd::shared_ptr<opentelemetry::trace::TracerProvider>(
new trace_sdk::TracerProvider(std::move(processor)));
// Set the global trace provider
opentelemetry::trace::Provider::SetTracerProvider(provider);
This compiles nicely. Before you ask, we checked that log_trace_output_file_.c_str() is not empty. However I encounter segmentation fault as soon as I start creating spans... Do you know what I might have been doing wrong here ? Thank you.
Ok, I realised that because of the std::move when declaring the processor, we were giving away the ownership thus we were trying to access a stream that was nullptr...
Here is what I ended up doing:
main.cpp
auto trace_provider = new TraceProvider(vm["trace-provider"].as<std::string>(), vm["trace-output-log-file"].as<std::string>());
trace_provider->InitTracer();
TraceProvider.hpp
class TraceProvider {
public:
TraceProvider(std::string exporter_backend_str, std::string log_trace_output_file = std::string());
~TraceProvider();
void InitTracer();
private:
std::string exporter_backend_str_;
std::string log_trace_output_file_;
std::shared_ptr<std::ofstream> log_trace_output_file_handle_ = nullptr;
void initSimpleTracer();
};
TraceProvider.cpp
TraceProvider::TraceProvider(std::string exporter_backend_str, std::string log_trace_output_file) {
exporter_backend_str_ = exporter_backend_str;
exporter_backend_ = string_to_trace_exporter(exporter_backend_str);
log_trace_output_file_ = log_trace_output_file;
if (exporter_backend_ == Exporter::SIMPLE) {
try {
if (log_trace_output_file_.compare("") != 0) {
log_trace_output_file_handle_ = std::make_shared<std::ofstream>(std::ofstream(log_trace_output_file.c_str()));
} else {
throw std::runtime_error("You chose the Simple trace exporter but you specified an empty log file.");
}
} catch(std::exception const& e) {
std::cout << "Exception: " << e.what() << "\n";
}
}
}
TraceProvider::~TraceProvider() {
// If it exists, close the file stream and delete the ptr
if (log_trace_output_file_handle_ != nullptr) {
std::cout << "Closing tracing log file at: " << log_trace_output_file_ << std::endl;
log_trace_output_file_handle_.get()->close();
log_trace_output_file_handle_.reset();
log_trace_output_file_handle_ = nullptr;
}
}
void TraceProvider::InitTracer() {
switch (exporter_backend_) {
case Exporter::SIMPLE:
initSimpleTracer();
break;
case Exporter::JAEGER:
initJaegerTracer();
break;
default:
std::stringstream err_msg_stream;
err_msg_stream << "Invalid tracing backend: " << exporter_backend_str_
<< "\n";
throw po::validation_error(po::validation_error::invalid_option_value,
err_msg_stream.str());
}
}
void TraceProvider::initSimpleTracer() {
std::unique_ptr<trace_sdk::SpanExporter> exporter;
if (log_trace_output_file_.compare("") != 0)
exporter = std::unique_ptr<trace_sdk::SpanExporter>(new opentelemetry::exporter::trace::OStreamSpanExporter(*log_trace_output_file_handle_.get()));
} else {
exporter = std::unique_ptr<trace_sdk::SpanExporter>(new opentelemetry::exporter::trace::OStreamSpanExporter);
}
auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
auto provider = nostd::shared_ptr<opentelemetry::trace::TracerProvider>(
new trace_sdk::TracerProvider(std::move(processor), resources));
// Set the global trace provider
opentelemetry::trace::Provider::SetTracerProvider(provider);
// Set global propagator
context::propagation::GlobalTextMapPropagator::SetGlobalPropagator(
nostd::shared_ptr<context::propagation::TextMapPropagator>(
new opentelemetry::trace::propagation::HttpTraceContext()));
std::cout << "Simple (log stream) exporter successfully initialized!"
<< std::endl;
}
We have written some functions in golang and a c wrapper on top of that to invoke those functions. We first build golang code to create an archive file and then we build the wrapper code in c to be consumed as a DLL.
After loading this DLL using LoadLibraryA(path_to_dll) in my program I am seeing that the inherit flags for fd 0, 1, and 2 are getting changed from 1 to 0. This does not happen immediately after loading the DLL though. I had added sleep in my code after the load library call and seems like it takes a few milliseconds after loading the library to change the flag values.
I am using GetHandleInformation((HANDLE) sock, &flags) to get the inherit flag value.
Any idea/pointers on what could be causing this? Thanks!
Updates:
I was able to find out the exact line in the go code that is flipping the inherit flag values. The global variable reqHandler in below k8sService.go code is causing this. Any idea why the use of this global variable is flipping the inherit flag values?
my-lib/k8sService.go (go code)
package main
import "C"
import (
"my-lib/pkg/cmd"
)
func main() {
}
var reqHandler []*cmd.K8sRequest
my-lib/pkg/cmd/execute.go
import (
"my-lib/pkg/dto"
)
type K8sRequest struct {
K8sDetails dto.K8sDetails
}
my-lib/pkg/dto/structs.go
package dto
// K8sDetails contains all the necessary information about talking to the cluster. Below struct has few more variables.
type K8sDetails struct {
// HostName of the cluster's API server
HostName string `json:"hostname"`
// Port on which the API server listens on to
Port int `json:"port"`
}
We have a C wrapper on top of the above k8sService.go. We first build golang code to create an archive file and then with this archive file and wrapper code in C we build the target DLL. Below is the sample program which loads this DLL and also prints the inherit flag values before and after loading the DLL.
#include <windows.h>
#include <iostream>
#include <io.h>
#include "wrapper/cWrapper.h"
void printInheritVals() {
typedef SOCKET my_socket_t;
my_socket_t fd0 = _get_osfhandle(0);
my_socket_t fd1 = _get_osfhandle(1);
my_socket_t fd2 = _get_osfhandle(2);
std::cout << "fd0: " << fd0 << std::endl;
std::cout << "fd1: " << fd1 << std::endl;
std::cout << "fd2: " << fd2 << std::endl;
DWORD flags;
int inherit_flag_0 = -1;
int inherit_flag_1 = -1;
int inherit_flag_2 = -1;
if (!GetHandleInformation((HANDLE) fd0, &flags)) {
std::cout << "GetHandleInformation failed" << std::endl;
} else {
inherit_flag_0 = (flags & HANDLE_FLAG_INHERIT);
}
if (!GetHandleInformation((HANDLE) fd1, &flags)) {
std::cout << "GetHandleInformation failed" << std::endl;
} else {
inherit_flag_1 = (flags & HANDLE_FLAG_INHERIT);
}
if (!GetHandleInformation((HANDLE) fd2, &flags)) {
std::cout << "GetHandleInformation failed" << std::endl;
} else {
inherit_flag_2 = (flags & HANDLE_FLAG_INHERIT);
}
std::cout << "inherit_flag_0: " << inherit_flag_0 << std::endl;
std::cout << "inherit_flag_1: " << inherit_flag_1 << std::endl;
std::cout << "inherit_flag_2: " << inherit_flag_2 << std::endl;
}
int main()
{
printInheritVals(); // In output all flag values are 1
HINSTANCE hGetProcIDDLL = LoadLibraryA(PATH_TO_DLL);
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}
std::cout << "Library loaded" << std::endl;
printInheritVals(); // In output all flag values are 1
Sleep(1000);
printInheritVals(); // In output all flag values are 0
return EXIT_SUCCESS;
}
This is a bug in the golang.org/x/sys/windows package. The same issue used to be in the built-in syscall package as well, but it was fixed in Go 1.17.
Something in your project must be importing the golang.org/x version of the package instead of the built-in one, and so the following code executes to initialize the Stdin, Stdout, and Stderr variables:
var (
Stdin = getStdHandle(STD_INPUT_HANDLE)
Stdout = getStdHandle(STD_OUTPUT_HANDLE)
Stderr = getStdHandle(STD_ERROR_HANDLE)
)
func getStdHandle(stdhandle uint32) (fd Handle) {
r, _ := GetStdHandle(stdhandle)
CloseOnExec(r)
return r
}
The fix for that code would be to remove the CloseOnExec call, which is what clears HANDLE_FLAG_INHERIT on the given file handle.
How to solve that in your project is less clear. I think you can vendor golang.org/x/sys module in your project, perhaps with a replace directive in your go.mod. Apply the fix in your local copy.
Meanwhile, I encourage you to also report the bug. The documentation instructs you to report the issue on the main Go project at GitHub, prefixing the title with x/sys.
I'm running into some trouble with the copy_file function. My program is very simple, I'm just attempting to copy a text file from one spot to another.
The following code brings up a "Debug Error!" because abort() was called.
int main()
{
path src_path = "C:\\src.txt";
path dst_path = "C:\\dst.txt";
cout << "src exists = " << exists( src_path ) << endl; // Prints True
boost::filesystem::copy_file( src_path, dst_path );
return 0;
}
If I look at some other examples of code on Stackoverflow I cannot notice what I'm doing wrong. I feel like I'm missing something obvious here.
I have Boost v1.47 installed and I'm using Visual C++ 2010.
I'm guessing that the target file exists.
The docs:
template <class Path1, class Path2> void copy_file(const Path1& from_fp, const Path2& to_fp);
Requires: Path1::external_string_type and Path2::external_string_type are the same type.
Effects: The contents and attributes of the file from_fp resolves to are copied to the file to_fp resolves to.
Throws: basic_filesystem_error<Path> if from_fp.empty() || to_fp.empty() || !exists(from_fp) || !is_regular_file(from_fp) || exists(to_fp)
A simple test like so:
#include <iostream>
#include <boost/filesystem.hpp>
int main()
{
using namespace boost::filesystem;
path src_path = "test.in";
path dst_path = "test.out";
std::cout << "src exists = " << std::boolalpha << exists( src_path ) << std::endl; // Prints true
try
{
boost::filesystem::copy_file( src_path, dst_path );
} catch (const boost::filesystem::filesystem_error& e)
{
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
Prints:
src exists = true
Error: boost::filesystem::copy_file: File exists: "test.in", "test.out"
on the second run :)
I think if you are using boost::filesystem2 it should be
boost::filesystem2::copy(src_path,dest_path);
copy_file should have been deprecated.