I've searched extensively but there seems not to be a satisfying answer to this question online. So I'm posting again this problem in case someone has found a solution.
I have written a C++ code that is supposed to call some Matlab code. I have compiled all my Matlab files using the following command:
mcc -N -W cpplib:libRTR2 -T link:lib RTR.m -v
I have included the header, DLL and LIB files created by above command in the 'Header Files'for my Visual Studio project. I have also includde mclmcrrt.lib, mclmcrrt.h and mclcppclass.h in the same.
Here is my C++ code:
#define BZZ_COMPILER 3
#include <stdint.h>
#include "./hpp/BzzMath.hpp"
#include "libRTR2.h"
#include <iostream>
#include "mclmcrrt.h"
#include "mclcppclass.h"
double RTRtest(BzzVector &x)
{
x(1);
mwArray out(1,1);
try {
// create input
double a[] = { x[1] };
mwArray in1(1, 1, mxDOUBLE_CLASS, mxREAL);
in1.SetData(a, 1);
// call function
RTR(1, out, in1);
// show result
std::cout << "objFun" << std::endl;
std::cout << out << std::endl;
double F[1];
out.GetData(F, 1);
for (int i = 0; i<1; i++) {
std::cout << F[i] << " " << std::endl;
}
}
catch (const mwException& e) {
std::cerr << e.what() << std::endl;
return -2;
}
catch (...) {
std::cerr << "Unexpected error thrown" << std::endl;
return -3;
}
// cleanup
return out;
}
int optim()
{
if (!mclInitializeApplication(NULL, 0)) {
std::cerr << "could not initialize the application" << std::endl;
mclGetLastErrorMessage();
return -1;
}
if (!libRTR2Initialize()) {
std::cerr << "Could not initialize the library" << std::endl;
return -1;
}
bzzFilePrint("BzzRobustMinimization.txt");
BzzVector Xmin(1, 2000.);
BzzVector Xmax(1, 5000.);
BzzVector X0(1, 2000.);
double F0 = RTRtest(X0);
BzzMinimizationRobust m(X0, F0, RTRtest, Xmin, Xmax);
m();
m.BzzPrint("Results");
libRTR2Terminate();
mclTerminateApplication();
}
int main()
{
mclmcrInitialize();
return mclRunMain((mclMainFcnType)optim, 0, NULL);
}
And when I try to debug it I obtain this error:
Access Violation Error
I know it is related probably to trying to pass a null pointer to one of my functions, but being no expert in C++ I'm struggling to find where the error lies. Any help is greatly appreciated!
Related
I am in a situation where I'm using memmove_s() to copy a buffer in a safer way.
So, at first, I just used the memmove_s() and I tested when destination size is greater than the source size and thrown an exception. Then, I put it inside a try/catch and it didn't catch the exception. The reason is that I am using a C code inside a C++ code. So, I found a Microsoft solution using __try/__except block. However, I got the error Cannot use __try in functions that require object unwinding.
That's a part of my code:
int filter(unsigned int code, struct _EXCEPTION_POINTERS* ep)
{
puts("in filter.");
if (code == ERANGE)
{
cout << "_DestinationSize >= _SourceSize" << endl;
return EXCEPTION_EXECUTE_HANDLER;
}
else
{
cout << "didn't catch the exception, unexpected." << endl;
return EXCEPTION_CONTINUE_SEARCH;
};
}
string GetValue()
{
return string("Value");
}
extern "C" void get_str_value(string src, char* dest, unsigned int destSize)
{
__try
{
auto r = memmove_s((void*)dest, destSize + 1, src.c_str(), src.size() + 1);
cout << "r=" << r << endl;
}
__except (filter(GetExceptionCode(), GetExceptionInformation()))
{
std::cout << "Exception" << std::endl;
}
}
So, is there any way to solve that problem?
I am trying to learn how to embed Octave in my C++ code. When running the second example from here, the code compiles fine, but when running the code, a segmentation fault appears in the first line, when trying to initialize the interpreter. I'm not extremely adept at C++ but even when looking it up I can't find any answers.
The original code had octave::feval instead of feval, that threw a different, namespace error, so I just got rid of that and added the parse.h in the includes. I doubt this is at all related to the issue but that is a modification I did do.
#include <iostream>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/interpreter.h>
int
main (void)
{
// Create interpreter.
octave::interpreter interpreter;
try
{
int status = interpreter.execute ();
if (status != 0)
{
std::cerr << "creating embedded Octave interpreter failed!"
<< std::endl;
return status;
}
octave_idx_type n = 2;
octave_value_list in;
for (octave_idx_type i = 0; i < n; i++)
in(i) = octave_value (5 * (i + 2));
octave_value_list out = feval ("gcd", in, 1);
if (out.length () > 0)
std::cout << "GCD of ["
<< in(0).int_value ()
<< ", "
<< in(1).int_value ()
<< "] is " << out(0).int_value ()
<< std::endl;
else
std::cout << "invalid\n";
}
catch (const octave::exit_exception& ex)
{
std::cerr << "Octave interpreter exited with status = "
<< ex.exit_status () << std::endl;
}
catch (const octave::execution_exception&)
{
std::cerr << "error encountered in Octave evaluator!" << std::endl;
}
return 0;
}
The actual output is supposed to be:
GCD of [10, 15] is 5
I am using Linux Ubuntu 18.04 with Octave 4.2.2
The documentation looked at is a different version than the version I have installed on my computer. I have 4.2, but I was looking at 4.4 docs, which has different code for the task I was trying to accomplish.
This is about C ++ library boost.
The managed_mapped_file :: shrink_to_fit function works differently on Linux and Windows.
On Linux, this function succeeds even if the target instance exists.
However, on Windows, this function will fail if the target instance exists.
Is this correct behavior?
It seems correct to do the same behavior, is this a bug?
I put the sample code below.
Compilation environment
boost:version.1.65.1
Windows
VisualStudio2017
WSL(Ubuntu16.04)
Linux
UbuntuServer17.10,
Clang++5.0,
g++7.2.0
Compile with
clang++-5.0 -std=c++1z ./test.cpp -o test -lpthread
#define BOOST_DATE_TIME_NO_LIB
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <vector>
#include <iostream>
namespace bip = boost::interprocess;
using intAlloc = bip::allocator<int, bip::managed_mapped_file::segment_manager>;
using intVec = std::vector<int, intAlloc>;
int main() {
bip::managed_mapped_file *p_file_vec;
intVec *vecObj;
std::string fileName = "tmp.dat";
size_t fileSize = 1024 * 1024 * 1;
bip::file_mapping::remove(fileName.c_str());
p_file_vec = new bip::managed_mapped_file(bip::create_only, fileName.c_str(), fileSize);
vecObj = p_file_vec->construct<intVec>("myVecName")(p_file_vec->get_allocator<int>());
for (size_t i = 0; i < 10; i++)
{
vecObj->push_back(1 + 100);
}
p_file_vec->flush();
try
{ //Fail when execute on Windows(WSL),but Success on Linux(Ubuntu17.10).
std::cout << "try to shrink:pointer has existed yet!" << std::endl;
bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
std::cout << "success to shrink!" << std::endl;
}
catch (const boost::interprocess::interprocess_exception &ex)
{
std::cerr << "fail to shrink!" << std::endl;
std::cerr << ex.what() << std::endl;;
}
std::cout <<"please pless enter key."<< std::endl;
std::cin.get();
try
{ //Success when execute on Windows(WSL) and Linux(Ubuntu17.10).
delete p_file_vec;
std::cout << "try to shrink:pointer has deleted!" << std::endl;
bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
std::cout << "success to shrink!" << std::endl;
}
catch (const std::exception& ex)
{
std::cerr << "fail to shrink!" << std::endl;
std::cerr << ex.what() << std::endl;;
}
std::cout << "please pless enter key." << std::endl;
std::cin.get();
}
Don't use new and delete in C++ (rule of thumb).
Apart from that
delete p_file_vec;
does NOT delete anything physical. It effectively disconnects from the mapped file. This is also why shrink_to_fit works: the documentation explicitly says:
If the application can find a moment where no process is attached it can grow or shrink to fit the managed segment.
And here
So, in short: the behaviour is correct on both platforms. It's just UNDEFINED what happens in your case when you shrink while the mapped file is in use (on Ubuntu).
Fixed Code:
Live On Coliru
#include <boost/interprocess/managed_mapped_file.hpp>
#include <iostream>
#include <vector>
namespace bip = boost::interprocess;
using intAlloc = bip::allocator<int, bip::managed_mapped_file::segment_manager>;
using intVec = std::vector<int, intAlloc>;
int main() {
std::string const fileName = "tmp.dat";
bip::file_mapping::remove(fileName.c_str());
{
bip::managed_mapped_file file_vec(bip::create_only, fileName.c_str(), 1l << 20);
auto *vecObj = file_vec.construct<intVec>("myVecName")(file_vec.get_allocator<int>());
for (size_t i = 0; i < 10; i++) {
vecObj->push_back(1 + 100);
}
}
try { // Success when execute on Windows(WSL) and Linux(Ubuntu17.10).
std::cout << "try to shrink:pointer has deleted!" << std::endl;
bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
std::cout << "success to shrink!" << std::endl;
} catch (const std::exception &ex) {
std::cerr << "fail to shrink!" << std::endl;
std::cerr << ex.what() << std::endl;
;
}
}
I created a dll file using "mcc" command in matlab from a simple add function like this:
function c = MyAdd(a,b)
c = a + b;
I entered this command:
mcc -t -L C -W lib:libMyAdd -T link:lib MyAdd.m libmmfile.mlib
it makes these files:
libMyAdd.lib
libMyAdd.c
libMyAdd.h
libMyAdd.dll
then i created an empty C++ project in VS and wrote this source code:
#include <iostream>
#include <conio.h>
#include "libMyAdd.h"
int main()
{
double k[4];
mwArray out;
out.GetData(k, 4);
// initialize MCR and lib
if (!mclInitializeApplication(NULL,0)) {
std::cerr << "could not initialize the application" << std::endl;
return -1;
}
if(!libMyAddInitialize()) {
std::cerr << "Could not initialize the library" << std::endl;
_getch();
return -1;
}
try {
// create input
double g[] = {1.0, 2.0, 3.0, 4.0};
double h[] = {5.0, 6.0, 7.0, 8.0};
mwArray in1(2, 2, mxDOUBLE_CLASS, mxREAL);
mwArray in2(2, 2, mxDOUBLE_CLASS, mxREAL);
in1.SetData(g, 4);
in2.SetData(h, 4);
// call function
mwArray out;
MyAdd(1, out, in1, in2);
// show result
std::cout << "in1 + in2 = " << std::endl;
std::cout << out << std::endl;
double k[4];
out.GetData(k, 4);
for(int i=0; i<4; i++) {
std::cout << k[i] << " " << std::endl;
}
} catch (const mwException& e) {
std::cerr << e.what() << std::endl;
return -2;
} catch (...) {
std::cerr << "Unexpected error thrown" << std::endl;
return -3;
}
// cleanup
libMyAddTerminate();
mclTerminateApplication();
return 0;
}
I also added this paths to my include and library directory in project properties->VC++ Directories as well as my additional library directories in linker->general
C:\Program Files\MATLAB\MATLAB Production Server\R2015a\extern\include
C:\Program Files\MATLAB\MATLAB Production Server\R2015a\extern\lib\win64\microsoft
Also, I added followings to Linker->Input->Additional Dependencies:
mclmcrrt.lib
libeng.lib
libmx.lib
libmex.lib
libmat.lib
mclmcr.lib
libMyAdd.lib
And since my matlab version is R2015a(64-bit), i changed the active solution platform to x64 (it was Win32).
the compiler shows no error, but a get a first-chance exception when I compile it (a picture of that uploaded).
what did i do wrong?
any suggestion?[a picture of that uploaded]
the error image
I am trying to use clang+llvm 3.6 to JIT compile several C functions (each can eventually be very large).
Unfortunately I the function pointer that LLVM provides makes the program SEGFAULT.
So far I have following code:
#include <iostream>
#include <clang/CodeGen/CodeGenAction.h>
#include <clang/Basic/DiagnosticOptions.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Basic/SourceManager.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Frontend/FrontendDiagnostic.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Frontend/Utils.h>
#include <clang/Parse/ParseAST.h>
#include <clang/Lex/Preprocessor.h>
#include <llvm/Analysis/Passes.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/Verifier.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/Linker/Linker.h>
int main(int argc, char *argv[]) {
using namespace llvm;
using namespace clang;
static const char* clangArgv [] = {"program", "-x", "c", "string-input"};
static const int clangArgc = sizeof (clangArgv) / sizeof (clangArgv[0]);
// C functions to be compiled (they could eventually be extremely large)
std::map<std::string, std::string> func2Source;
func2Source["getOne"] = "int getOne() {return 1;}";
func2Source["getTwo"] = "int getTwo() {return 2;}";
llvm::InitializeAllTargets();
llvm::InitializeAllAsmPrinters();
std::unique_ptr<llvm::Linker> linker;
std::unique_ptr<llvm::LLVMContext> context(new llvm::LLVMContext());
std::unique_ptr<llvm::Module> module;
/**
* add each C function to the same module
*/
for (const auto& p : func2Source) {
const std::string& source = p.second;
IntrusiveRefCntPtr<DiagnosticOptions> diagOpts = new DiagnosticOptions();
TextDiagnosticPrinter *diagClient = new TextDiagnosticPrinter(llvm::errs(), &*diagOpts); // will be owned by diags
IntrusiveRefCntPtr<DiagnosticIDs> diagID(new DiagnosticIDs());
IntrusiveRefCntPtr<DiagnosticsEngine> diags(new DiagnosticsEngine(diagID, &*diagOpts, diagClient));
ArrayRef<const char *> args(clangArgv + 1, // skip program name
clangArgc - 1);
std::unique_ptr<CompilerInvocation> invocation(createInvocationFromCommandLine(args, diags));
if (invocation.get() == nullptr) {
std::cerr << "Failed to create compiler invocation" << std::endl;
exit(1);
}
CompilerInvocation::setLangDefaults(*invocation->getLangOpts(), IK_C,
LangStandard::lang_unspecified);
invocation->getFrontendOpts().DisableFree = false; // make sure we free memory (by default it does not)
// Create a compiler instance to handle the actual work.
CompilerInstance compiler;
compiler.setInvocation(invocation.release());
// Create the compilers actual diagnostics engine.
compiler.createDiagnostics(); //compiler.createDiagnostics(argc, const_cast<char**> (argv));
if (!compiler.hasDiagnostics()) {
std::cerr << "No diagnostics" << std::endl;
exit(1);
}
// Create memory buffer with source text
std::unique_ptr<llvm::MemoryBuffer> buffer = llvm::MemoryBuffer::getMemBufferCopy(source, "SIMPLE_BUFFER");
if (buffer.get() == nullptr) {
std::cerr << "Failed to create memory buffer" << std::endl;
exit(1);
}
// Remap auxiliary name "string-input" to memory buffer
PreprocessorOptions& po = compiler.getInvocation().getPreprocessorOpts();
po.addRemappedFile("string-input", buffer.release());
// Create and execute the frontend to generate an LLVM bitcode module.
clang::EmitLLVMOnlyAction action(context.get());
if (!compiler.ExecuteAction(action)) {
std::cerr << "Failed to emit LLVM bitcode" << std::endl;
exit(1);
}
std::unique_ptr<llvm::Module> module1 = action.takeModule();
if (module1.get() == nullptr) {
std::cerr << "No module" << std::endl;
exit(1);
}
if (linker.get() == nullptr) {
module.reset(module1.release());
linker.reset(new llvm::Linker(module.get()));
} else {
if (linker->linkInModule(module1.release())) {
std::cerr << "LLVM failed to link module" << std::endl;
exit(1);
}
}
}
llvm::InitializeNativeTarget();
llvm::Module* m = module.get();
std::string errStr;
std::unique_ptr<llvm::ExecutionEngine> executionEngine(EngineBuilder(std::move(module))
.setErrorStr(&errStr)
.setEngineKind(EngineKind::JIT)
.setMCJITMemoryManager(std::unique_ptr<SectionMemoryManager>(new SectionMemoryManager()))
.setVerifyModules(true)
.create());
if (!executionEngine.get()) {
std::cerr << "Could not create ExecutionEngine: " + errStr << std::endl;
exit(1);
}
executionEngine->finalizeObject();
/**
* Lets try to use each function
*/
for (const auto& p : func2Source) {
const std::string& funcName = p.first;
llvm::Function* func = m->getFunction(funcName);
if (func == nullptr) {
std::cerr << "Unable to find function '" << funcName << "' in LLVM module" << std::endl;
exit(1);
}
// Validate the generated code, checking for consistency.
llvm::raw_os_ostream os(std::cerr);
bool failed = llvm::verifyFunction(*func, &os);
if (failed) {
std::cerr << "Failed to verify function '" << funcName << "' in LLVM module" << std::endl;
exit(1);
}
#if 1
func->dump(); // Dump the function for exposition purposes.
// JIT the function, returning a function pointer.
void *fPtr = executionEngine->getPointerToFunction(func); ///// BAD function pointer!!!!
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
int (*funcPtr)();
*(int **) (&funcPtr) = *(int **) fPtr;
int v = (*funcPtr)();
std::cout << "return: " << v << std::endl;
#else // THIS DOES NOT WORK EITHER:
// JIT the function, returning a function pointer.
uint64_t fPtr = executionEngine->getFunctionAddress(funcName); ///// BAD function pointer!!!!
if (fPtr == 0) {
std::cerr << "Unable to find function '" << funcName << "' in LLVM module" << std::endl;
exit(1);
}
int (*funcPtr)();
*(int **) (&funcPtr) = *(int **) fPtr;
int v = (*funcPtr)();
std::cout << "return: " << v << std::endl;
#endif
}
}
Can anyone help me pin-point the problem?
(I'm running this in linux-ubuntu 15.04)
This assignment is incredibly messed up:
*(int **) (&funcPtr) = *(int **) fPtr;
Not only does it violate strict-aliasing to write an int* and then use it as a function pointer on the next line, but a data pointer is often not large enough to hold an entire code pointer.
The safe approach is either
memcpy(funcPtr, fPtr, sizeof funcPtr);
or
funcPtr = reinterpret_cast<decltype(funcPtr)>(fPtr);