I have a callback implementation in which an unknown third party calls a function pointer in my code.
However, an issue in a lot languages is triggering code after a function returns. For instance, when a callback is called and I have to delete the calling object (and, in this case, re-initialize it), returning from the callback would cause an exception.
Assuming I cannot hook and that I do not own/cannot modify the code calling the callback, what is the best way to execute code after a function returns?
The only real way I can think of doing this is to set up some sort of state machine and have a worker thread check the state. However, the issue I foresee with this is that of a race condition, where a callback is called between the time the reset callback returns and the point the calling object is reset.
Is there any sort of functionality I'm not aware of, or would this be the most efficient way of achieving such a result?
It requires c++11 or newer though. But this is how i would do it.
You can rewrite it to use function pointers instead so that it works on older c++ versions
#include <functional>
#include <iostream>
#define CONCACT_IMPL(x , y) x##y
#define CONCAT(x, y) CONCACT_IMPL(x, y)
#define deffered(x) auto CONCAT(__deffered, __COUNTER__) = Defer(x);
struct Defer {
Defer(std::function<void(void)> pFunc) : func(pFunc) {};
std::function<void(void)> func;
virtual ~Defer(){
func();
}
};
int main() {
deffered([] () {
std::cout << "deffered" << std::endl;
});
std::cout << "now" << std::endl;
}
outputs -->
now
deffered
Related
I'm new to LLVM and I'm stuck on something that might seem basic.
I'm writing a LLVM pass to apply some transformations to global variables before they are use.
I would like to detect somehow when is the first usage of a global variable to only apply the transformation there, and not in all places where the global variable is used. But it must be the first time it is used otherwise the program crashes.
I have been reading about the AnalysisManager, and I would say that I want something similar to DominatorTree which is used for basic blocks in a function.
So the idea is to get the DominatorTree of a GlobalVariable to get the first time it is used in the code and apply there my transformation.
Given the following example
int MyGlobal = 30;
void foo()
{
printf("%s\n", MyGlobal);
}
int main()
{
printf("%s\n", MyGlobal);
foo();
}
In the example above, I only want to apply the transformation just before the first printf in the main function
Given the following example
int MyGlobal = 30;
void foo()
{
printf("%s\n", MyGlobal);
}
int main()
{
foo();
printf("%s\n", MyGlobal);
}
For the example above I would like to apply the transformation inside the foo function.
I want to avoid to create a stub function at the beginning of the program to process all globals before start running (This is what actually Im doing)
Does LLVM provide something that can help me doing this? or what should be the best approach to implement it?
I'm a bit confused about the implications of the using declaration. The keyword implies that a new type is merely declared. This would allow for incomplete types. However, in some cases it is also a definition, no? Compare the following code:
#include <variant>
#include <iostream>
struct box;
using val = std::variant<std::monostate, box, int, char>;
struct box
{
int a;
long b;
double c;
box(std::initializer_list<val>) {
}
};
int main()
{
std::cout << sizeof(val) << std::endl;
}
In this case I'm defining val to be some instantiation of variant. Is this undefined behaviour? If the using-declaration is in fact a declaration and not a definition, incomplete types such as box would be allowed to instantiate the variant type. However, if it is also a definition, it would be UB no?
For the record, both gcc and clang both create "32" as output.
Since you've not included language-lawyer, I'm attempting a non-lawyer answer.
Why should that be UB?
With a using delcaration, you're just providing a synonym for std::variant<whatever>. That doesn't require an instantiation of the object, nor of the class std::variant, pretty much like a function declaration with a parameter of that class doesn't require it:
void f(val); // just fine
The problem would occur as soon as you give to that function a definition (if val is still incomplete because box is still incomplete):
void f(val) {}
But it's enough just to change val to val& for allowing a definition,
void f(val&) {}
because the compiler doesn't need to know anything else of val than its name.
Furthermore, and here I'm really inventing, "incomplete type" means that some definition is lacking at the point it's needed, so I expect you should discover such an issue at compile/link time, and not by being hit by UB. As in, how can the compiler and linker even finish their job succesfully if a definition to do something wasn't found?
I have to create a LLVM analysis pass for an exam project which consist of printing the independent path of a function using the baseline method.
Currently, I am struggling on how can I build the baseline path traversing the various basic block. Furthermore, I know that basic block are already organized in a CFG but checking the documentation I can't find any useful method to build a linked list of basic block representing a path from the entry point to the end point of a function. I am not an expert with the LLVM environment and I want to ask if someone with more knowledge knows how to build this kind of path.
Thank you everyone.
Update: i followed the advice of the answer to this post and i made this code for building a path:
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/CFG.h"
#include <set>
#include <list>
using namespace llvm;
using namespace std;
void Build_Baseline_path(BasicBlock *Start, set<BasicBlock *> Explored, list<BasicBlock *> Decision_points, list<BasicBlock *>Path) {
for (BasicBlock *Successor : successors(Start)) {
Instruction *Teriminator = Successor->getTerminator();
const char *Instruction_string = Teriminator->getOpcodeName();
if (Instruction_string == "br" || Instruction_string == "switch") {
errs() << "Decision point found" << "\n";
Decision_points.push_back(Successor);
}
if (Instruction_string == "ret") {
if (Explored.find(Successor) == Explored.end()) {
errs() << "Added node to the baseline path" << "\n";
Path.push_back(Successor);
return;
}
return;
}
if (Explored.find(Successor) == Explored.end()) {
Path.push_back(Successor);
Build_Baseline_path(Successor,Explored,Decision_points,Path);
}
}
}
This is a code that wrote in another file .cpp and i include it in my Function Pass, but when i run the pass with this function, everything is blocked and seems like that my pc is crashing when i run this pass. I tried to comment the call of this function in the pass to see if the problem is somewhere else, but everything works fine so the problem is in this code, what is wrong in this code? I am sorry but i am a novice with c++, i can't figure out how to solve this.
First off, there isn't a single end point. At least four kinds of instructions may be end points: return, unreachable and in some cases call/invoke (when the called function throws and the exception isn't caught in this function).
Accordingly, there are many possible paths. The number of possible paths is not even sure to be countable, depending on how you treat loops.
If you regard loops in a simplistic way and ignore exceptions, then it's simple to construct a list of paths. There exists an iterator called successors() which you can use as in this answer. You can use successors() in a recursive function to process successors, and when you reach a return or something like that, you act on the path you've built.
I've got a program that is to become part of an already existing, larger product which is built using C++ Builder 2010.
The smaller program does not (yet) depend on C++ Builder. It works fine in MS Visual Studio, but with C++ Builder it produces strange access violations.
Please let me explain this.
Depending on the code and on compiler settings, access violations happen or do not happen. The access violations are reproducible: When the program is built then the access violation does never occur or it does always occur at the same place. If the program is rebuilt with the same settings, it will show the same behavior. (I'm really glad about that).
The access violation happens at places where the delete operator is called. This can happen (depending on compiler settings and exact code) inside certain destructors, including destructors of own classes and inside the destructor of std::string.
The following things make the access violation less likely:
Build with "Debug" settings (instead of "Release").
No compiler optimizations.
Compiler switch "Slow exception epilogues".
Static RTL instead of dynamic.
Derive exceptions from std::exception instead of Borland's Exception class.
Use less "complicated" expressions (e.g. use "string s = "..." + "..."; throw SomeException(s);" instead of "throw
SomeException(string("...") + "...");")
Use try... __finally with manual cleanup instead of automatic variables with destructors.
Use a small console application instead a VCL windows application.
The program makes use of several C++ features, including exceptions, STL, move constructors etc. and it of course uses the heap.
I already tried some tools, none of them reported problems:
Borland's CodeGuard.
Microsoft Application Verifyer.
pageheap/gflags.
As already mentioned, there is absolutely no problem when building with MS Visual Studio.
Use of precompiled headers and incremental linking (which both seem to me are prone to errors) are disabled.
Neither the C++ Builder compiler ("enable all warnings") nor the one of Visual Studio (/W4) produces a warning that might be related to this issue.
I do not have access to another version of C++ Builder.
As the program will become part of a larger product, it is not an option to switch to a different compiler, and it is not an option to tune the compiler settings until the access violation does no longer happen. (I fear if this really should a compiler bug, the bug might show up again.)
Putting this together, I'm guessing this might result from heap corruption that is related to some compiler bug. However, I was not able to find a bug on qc.embarcadero.com. I'm guessing further this is related to cleanup code that is executed upon stack rewinding when an exception has been thrown. But, well, maybe it's only a stupid code bug.
Currently, I do not have any idea how to proceed. Any help appreciated. Thank you in advance!
tl;dr I believe the bug is that code is generated to delete the std::string from both branches of the ternary operator during stack unwinding, however only one of them was actually created of course.
Here is a simpler MCVE, which shows the problem via outputs in XE5:
#include <vcl.h>
#include <tchar.h>
#include <stdio.h>
using namespace std;
struct S
{
S() { printf("Create: %p\n", this); }
S(S const &) { printf("Copy: %p\n", this); }
void operator=(S const &) { printf("Assign: %p\n", this); }
~S() { printf("Destroy: %p\n", this); }
char const *c_str() { return "xx"; }
};
S rX() { return S(); }
int foo() { return 2; }
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
try
{
throw Exception( (foo() ? rX() : rX()).c_str() );
}
catch (const Exception& e)
{
}
getchar();
return 0;
}
This version shows the problem via output strings on the console. Check the edit history for this post to see a version that uses std::string and causes the segfault instead.
My output is:
Create: 0018FF38
Destroy: 0018FF2C
Destroy: 0018FF38
In the original code, the segfault comes from the bogus Destroy ending up calling delete on the bogus value it obtains by trying to retrieve the internal data pointer for a std::string which was actually never created at that location.
My conjecture is that the code generation for stack unwinding is bugged and tries to delete the temporary string from both branches of the ternary operator. The presence of the temporary UnicodeString does have something to do with it; as the bug did not occur in any variations where I tried to avoid that temporary.
In the debugger you can see the call stack and it is during global stack unwinding that this happens.
Phew, that was so simple that it took me some time:
#include <vcl.h>
#include <tchar.h>
#include <string>
using namespace std;
struct B
{
B(const char* c) { }
string X() const { return "xx"; }
int Length() const { return 2; }
};
struct C
{
void ViolateAccess(const B& r)
{
try
{
throw Exception(string("aoei").c_str());
}
catch (const Exception&) { }
throw Exception(((string) "a" + (r.Length() < 10 ? r.X() : r.X() + "...") + "b").c_str());
}
};
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
try
{
C c;
c.ViolateAccess("11");
}
catch (const Exception& e) { }
return 0;
}
(Preemptive comment: No, this code does not make any sense.)
Create a new console application and make sure to use the VCL. It might depend on the project settings whether there will be an access violation or not; my debug builds always crashed, release builds didn't.
Crashes with C++ Builder 2010 and XE3 trial.
Thus, bug in compiler or in VCL or in STL or whatever.
I'm trying to go through the tutorial with luabind here, http://www.rasterbar.com/products/luabind/docs.html, however i'm having trouble loading the library. I'm currently using version 5.1 of lua, so I believe I would use package.loadlib instead of loadlib. I made a simple dll which is this:
#include <iostream>
#include <luabind\luabind.hpp>
void greet()
{
std::cout << "Hello world!\n";
}
extern "C" int init(lua_State* L)
{
luabind::open(L);
luabind::module(L)
[
luabind::def("greet", &greet)
];
return 0;
}
This builds just fine. However I get an error in lua when I try to run this code:
package.loadlib("LuaTestLib.dll", "init")
greet()
It states that greet is nil. How do I load the functions from the dll properly?
From the first two sentences of package.loadlib's documentation:
Dynamically links the host program with the C library libname. Inside this library, looks for a function funcname and returns this function as a C function.
(emphasis added)
This doesn't execute funcname. It simply returns it as a function for you to call. You still have to call it:
package.loadlib("LuaTestLib.dll", "init")()