Is there a way to use boost context make_fcontext/jump_fcontext with a shared stack to share coroutine memory by saving/restoring the stack ?
It seems that make_fcontext and jump_fcontext write on the stack themselves and I get crashes when trying to save/restore stack on yield/resume, but it is really hard for me to get what happens as make_fcontext/jump_fcontext are pure assembly code.
Here is the coroutine methods which trigger segmentation fault (the same code works very well if I use a different stack for each coroutine and I don't use the saveStack/restoreStack)
void resume()
{
if (yielded)
{
restoreStack();
yielded = false;
}
else
{
running = true;
thisContext = boost::context::make_fcontext(
(char*)sharedStackPtr + sharedStackSize ,
sharedStackSize,
my_entry_func);
}
boost::context::jump_fcontext(&yieldContext, thisContext, reinterpret_cast<intptr_t>(this));
}
void yield()
{
yielded = true;
saveStack();
boost::context::jump_fcontext(&thisContext, yieldContext, 0);
}
void restoreStack()
{
char* stackTop = (char*)sharedStackPtr + sharedStackSize ;
memcpy(stackTop - savedStackSize, savedStackPtr, savedStackSize);
}
void saveStack()
{
char dummy = 0;
char* stackPointer = &dummy;
char* stackTop = (char*)sharedStackPtr + sharedStackSize ;
assert((stackPointer < stackTop) && (stackPointer >= sharedStackPtr ));
savedStackSize = stackTop - stackPointer;
if (savedStackPtr == nullptr)
{
savedStackPtr = coroutine_stack_alloc(savedStackSize);
}
else
{
savedStackPtr = coroutine_stack_realloc(savedStackPtr, savedStackSize);
}
memcpy(savedStackPtr, stackPointer, savedStackSize);
}
Any idea ? Is there something I do wrong somewhere ?
make_fcontext() must be applied to a stack inorder to initialize the stack before it can be used with jump_fcontext(). Ofcourse you could re-use a stack by applying make_fcontext() after the execution context is finished.
Related
I'm using custom classes to manage a vending machine. I can't figure out why it keeps throwing a stack overflow error. There are two versions to my program, the first is a basic test to see whether the classes etc work, by pre-defining certain variables. The second version is what it should be like, where the variables in question can change each time the program is ran (depending on user input).
If anyone can suggest ways of avoiding this recursion, or stack overflow, I'd great. Below is the code for the three classes involved;
class Filling
{
protected:
vector<Filling*> selection;
string fillingChosen;
public:
virtual float cost()
{
return 0;
}
virtual ~Filling(void)
{
//needs to be virtual in order to ensure Condiment destructor is called via Beverage pointer
}
};
class CondimentDecorator : public Filling
{
public:
Filling* filling;
void addToPancake(Filling* customerFilling)
{
filling = customerFilling;
}
~CondimentDecorator(void)
{
delete filling;
}
};
class Frosted : public CondimentDecorator
{
float cost()
{ //ERROR IS HERE//
return (.3 + filling->cost());
}
};
Below is the code used to call the above 'cost' function;
void displayCost(Filling* selectedFilling)
{
cout << selectedFilling->cost() << endl;
}
Below is part of the code that initiates it all (main method);
Filling* currentPancake = NULL;
bool invalid = true;
do
{
int selection = makeSelectionScreen(money, currentStock, thisState);
invalid = false;
if (selection == 1)
{
currentPancake = new ChocolateFilling;
}
else if...
.
.
.
.
else
invalid = true;
} while (invalid);
bool makingSelection = true;
CondimentDecorator* currentCondiment = NULL;
do
{
int coatingSelection = makeCoatingSelectionScreen(money, currentStock, thisState);
if (coatingSelection == 1)
currentCondiment = new Frosted;
else if (coatingSelection == 2)...
.
.
.
else if (coatingSelection == 0)
makingSelection = false;
currentCondiment = thisSelection;
currentCondiment->addToPancake(currentPancake);
currentPancake = currentCondiment;
displayCost(currentPancake);
//Below is the code that DOES work, however it is merely meant to be a test. The
//above code is what is needed to work, however keeps causing stack overflows
//and I'm uncertain as to why one version works fine and the other doesn't
/*currentCondiment = new Frosted;
currentCondiment->addToPancake(currentPancake);
currentPancake = currentCondiment;
displayCost(currentPancake);
currentCondiment = new Wildlicious;
currentCondiment->addToPancake(currentPancake);
currentPancake = currentCondiment;
displayCost(currentPancake);*/
} while (makingSelection);
displayCost(currentPancake);
delete currentPancake;
The infinite recursion happens when you call displayCostwith a Frosted whose filling is a Frosted as well. And that happens right here:
currentCondiment->addToPancake(currentPancake);
currentPancake = currentCondiment;
displayCost(currentPancake);
You set the filling of currentCondiment to currentPancake, then call displayCost with currentCondiment.
In the process you also leak the memory that was originally assigned to currentPancake.
Btw currentCondiment = thisSelection; also leaks memory.
Idea: Use smart pointers like std::unique_ptr to get rid of the leaks.
Hy all :)
I am using 1.5.4-all (2014-10-22) in my VC++ project (Microsoft Visual C++ Compiler 18.00.21005.1 for x86 platform).
My problem is that I get the following error message after some time. The time, after which the error occurs differ quiet a lot - sometimes it happens after 30 secs and sometimes after 5 minutes.
I could locate the source for the error in the LinearHashTable.h file at line 214:
I have the following method where a Shot (struct) is added to the table:
void ShotSimulationService::SimulateShot(Shot shot) {
MutexThreadLock.lock();
shots.insert(ShotsSetType::ValueType(SimulationShot(shot)));
errorCount = 0;
MutexThreadLock.unlock();
}
The call of SimulateShot is from another thread than the handling of the following code:
void ShotSimulationService::Update(WebcamService* observable) {
if (shots.empty()) {
return;
}
try {
Mat frame = observable->GetLastImage().clone();
ShotsSetType::Iterator iter = shots.begin();
vector<Shot> deleteShots;
errorCount++;
while (iter != shots.end()){
if (iter->SimulateStartExplosion()) {
//simulate gun explosion
OverlayImage(frame, gunShotImg, iter->startPoint);
}
//simulate explosion
SimulationShot::SimulationHitStatus status = iter->status;
if (status == SimulationShot::SimulationHitStatus::UNKNOWN) {
if (detectionService.HasShotHitPlayer(frame, *iter)) {
iter->status = SimulationShot::HIT_PLAYER;
iter->SetCurrentPointAsEndoint();
//Notify that player was hit
playerHitQueue.enqueueNotification(new PlayerHitNotification(iter->hitPlayer));
}
}
if (iter->SimulateEndExplosion()) {
if (status == SimulationShot::HIT_PLAYER) {
int explosionx = iter->endPoint.x - robotExplosionHalfXSize > 0 ? iter->endPoint.x - robotExplosionHalfXSize : 0;
int explosionY = iter->endPoint.y - robotExplosionHalfYSize > 0 ? iter->endPoint.y - robotExplosionHalfYSize : 0;
OverlayImage(frame, robotExplosionImg, Point2i(explosionx, explosionY));
}
else {
// status == SimulationShot::HIT_WALL or UNKNOWN
int explosionx = iter->endPoint.x - wallExplosionHalfXSize > 0 ? iter->endPoint.x - wallExplosionHalfXSize : 0;
int explosionY = iter->endPoint.y - wallExplosionHalfYSize > 0 ? iter->endPoint.y - wallExplosionHalfYSize : 0;
OverlayImage(frame, robotExplosionImg, Point2i(explosionx, explosionY));
if (status != SimulationShot::HIT_WALL) {
iter->status = SimulationShot::HIT_WALL;
}
}
if (iter->IsSimulationFinished()) {
deleteShots.push_back(*iter);
}
}
else {
//simulate bullet
OverlayImage(frame, cheeseImg, iter->GetNextShotPoint());
}
++iter;
}
//delete finished simulations
MutexThreadLock.lock();
for each (Shot shot in deleteShots)
{
shots.erase(shot);
}
MutexThreadLock.unlock();
}
catch (cv::Exception& e) {
Logger& logger = Logger::get("Test");
logger.error(e.what());
}
}
The Update method is called quiet often - always when a new webcam frame is available.
The callstack of the error starts in the following line:
if (iter->SimulateEndExplosion()) {
In the method SimulateEndExplosion only members of the struct were used:
bool SimulateEndExplosion() {
if (status == HIT_PLAYER) {
currPercentage = 1.0;
return true;
}
if (currPercentage < 1.0) {
return false;
}
++endExplosionCtr;
return endExplosionCtr <= maxEndExplosions;
}
Does anybody have an idea why this problem occurs?
Any help and any feedback is welcome!! I have absolutly no idea what is going wrong here :(
Thanks!
Iterating in one thread and inserting in another without protecting the operations with mutex in both threads will cause this problem; when you insert, iterator will be invalidated and you will get the assertion failure. You should protect both insertion and iteration with mutex.
Also, the way you are using mutex is not safe because mutex will not be unlocked if an exception is thrown between lock() and unlock(). Use ScopedLock instead and RAII will do the job automatically and safely in all cases:
void ShotSimulationService::SimulateShot(Shot shot) {
Mutex::ScopedLock lock(MutexThreadLock);
shots.insert(ShotsSetType::ValueType(SimulationShot(shot)));
errorCount = 0;
// unlock will be called by ScopedLock destructor
}
I'm trying to implement the bintree, but I have problems in the insert method.
If I add the first element, the program dont crash but, when I introduce 2 or more element the program crash.
This is the code
template <typename T>
void Arbol<T>:: insertar( T c){
if(laraiz==0)
{
laraiz=new celdaArbol;
laraiz->elemento=c;
laraiz->padre=laraiz->hizqu=laraiz->hder=0;
}
else {
celdaArbol *com=laraiz;
bool poner=false;
while(poner==false){
if(c>com->elemento){
if(com->hder==0){
com->hder= new celdaArbol;
com->hder->elemento=c;
com->hder->padre=com;
poner=true;
}
else{
com=com->hder;
}
}
else {
if(com->hizqu==0){
com->hizqu= new celdaArbol;
com->hizqu->elemento=c;
com->hizqu->padre=com;
poner=true;
}
else {
com=com->hizqu;
}
}
}
}
}
I think that the problem is in the else:
else{
com=com->hizqu; //com=com->hder;
}
Because I saw in the debugger that the program enter several times in the section and should not do.
According to this code:
laraiz->padre=laraiz->hizqu=laraiz->hder=0;
You do not properly intialize pointers hizqu and hder to nullptr in constructor of celdaArbol class. And you do not initialize them in either branch of if(c>com->elemento){ so they seem to have garbage values.
Also your code can become more readable and less error prone if you use proper C++ constructions:
celdaArbol *com=laraiz;
while( true ){
celdaArbol *&ptr = c > com->elemento ? com->hder : com->hizqu;
if( ptr ) {
com = ptr;
continue;
}
ptr = new celdaArbol;
ptr->elemento=c;
ptr->padre=com;
ptr->hder = ptr->hizqu = nullptr;
break;
}
This code is logically equal to yours, except it shorter, easier to read, avoid duplication and fixes your bug.
For every leaf node (except the root of the tree), you never initialize the left child or right child node to be anything but an unspecified value.
You probably meant to initialize them as nullptr.
Here's one example:
if (com->hizqu==0){
com->hizqu = new celdaArbol;
com->hizqu->elemento = c;
com->hizqu->padre = com;
poner = true;
// What is the value of com->hizqu->hizqu?
// What is the value of com->hizqu->hder?
}
How can I find the current depth inside a recursive function in C++ without passing in the previous level? i.e. is it possible to know how many times the function was called without using a parameter to keep track of the level and passing that number in as a parameter each time the function is called?
For example my recursive function looks like this:
DoSomething(int level)
{
print level;
if (level > 10)
return;
DoSomething(++level);
}
main
{
DoSomething(0);
}
Building on the answer already given by JoshD:
void recursive()
{
static int calls = 0;
static int max_calls = 0;
calls++;
if (calls > max_calls)
max_calls = calls;
recursive();
calls--;
}
This resets the counter after the recursive function is complete, but still tracks the maximum depth of the recursion.
I wouldn't use static variables like this for anything but a quick test, to be deleted soon after. If you really need to track this on an ongoing basis there are better methods.
You could use a static variable in the function...
void recursive()
{
static int calls = 0;
calls++;
recursive();
}
Of course, this will keep counting when you start a new originating call....
If you want it to be re-entrant and thread-safe, why not:
void rec(int &level) // reference to your level var
{
// do work
rec(++level); // go down one level
}
main()
{
//and you call it like
int level=0;
rec(level);
cout<<level<<" levels."<<endl;
}
No static/global variables to mess up threading and you can use different variables for different recursive chains for re-entrancy issues.
You can use a local static variable, if you don't care about thread-safety.
Although, this will only give you a proper count the first time you run your recursive routine. A better technique would be a RAII guard-type class which contains an internal static variable. At the start of the recursive routine, construct the guard class. The constructor would increment the internal static variable, and the destructor would decrement it. This way, when you create a new stack-frame the counter increments by one, and when you return from each stack-frame the counter would decrement by one.
struct recursion_guard
{
recursion_guard() { ++counter; }
~recursion_guard() { --counter; }
static int counter;
};
int recursion_guard::counter = 0;
void recurse(int x)
{
recursion_guard rg;
if (x > 10) return;
recurse(x + 1);
}
int main()
{
recurse(0);
recurse(0);
}
Note however, that this is still not thread-safe. If you need thread-safety, you can replace the static-storage variable with a thread-local-storage variable, either using boost::thread_specific_ptr or the C++0x thread local facilities.
You could also pass in the level as a template parameter, if it can be determined at compile-time. You could also use a function object. This is by far and away the best option - less hassle, and static variables should be avoided wherever possible.
struct DoSomething {
DoSomething() {
calls = 0;
}
void operator()() {
std::cout << calls;
calls++;
if (calls < 10)
return operator()();
return;
}
int calls;
};
int main() {
DoSomething()(); // note the double ().
std::cin.get();
}
convert level to an instance variable of a new object (typically a template) capable of containing the arguments and (possibly) the function. then you can reuse the recursion accumulator interface.
You can also try using a global variable to log the depth.
var depth = 0;
DoSomething()
{
print ++depth;
if (depth > 10)
return;
DoSomething();
}
main
{
DoSomething(0);
}
I came here when I sensed that some recursion is required, because I was implementing a function that can validate the chain of trust in a certificate chain. This is not X.509 but instead it is just the basics wherein the issuer key of a certificate must match the public key of the signer.
bool verify_chain(std::vector<Cert>& chain,
Cert* certificate,
unsigned char* pOrigin = nullptr, int depth = 0)
{
bool flag = false;
if (certificate == nullptr) {
// use first element in case parameter is null
certificate = &chain[0];
}
if (pOrigin == nullptr) {
pOrigin = certificate->pubkey;
} else {
if (std::memcmp(pOrigin, certificate->pubkey, 32) == 0) {
return false; // detected circular chain
}
}
if (certificate->hasValidSignature()) {
if (!certificate->isRootCA()) {
Cert* issuerCert = certificate->getIssuer(chain);
if (issuerCert) {
flag = verify_chain(chain, issuerCert, pOrigin, depth+1);
}
} else {
flag = true;
}
}
if (pOrigin && depth == 1) {
pOrigin = nullptr;
}
return flag;
}
I needed to know the recursion depth so that I can correctly clean up pOrigin. at the right stack frame during the unwinding of the call stack.
I used pOrigin to detect a circular chain, without which the recursive call can go on forever. For example,
cert0 signs cert1
cert1 signs cert2
cert2 signs cert0
I later realized that a simple for-loop can do it for simple cases when there is only one common chain.
bool verify_chain2(std::vector<Cert> &chain, Cert& cert)
{
Cert *pCert = &cert;
unsigned char *startkey = cert.pubkey;
while (pCert != nullptr) {
if (pCert->hasValidSignature()) {
if (!pCert->isRootCA()) {
pCert = pCert->getIssuer(chain);
if (pCert == nullptr
|| std::memcmp(pCert->pubkey, startkey, 32) == 0) {
return false;
}
continue;
} else {
return true;
}
} else {
return false;
}
}
return false;
}
But recursion is a must when there is not one common chain but instead the chain is within each certificate. I welcome any comments. Thank you.
Does anybody know of a better/ faster way to get the call stack than "StackWalk"?
I also think that stackwalk can also be slower on methods with a lot of variables...
(I wonder what commercial profilers do?)
I'm using C++ on windows. :)
thanks :)
I don't know if it's faster, and it won't show you any symbols, and I'm sure you can do better than that, but this is some code I wrote a while back when I needed this info (only works for Windows):
struct CallStackItem
{
void* pc;
CallStackItem* next;
CallStackItem()
{
pc = NULL;
next = NULL;
}
};
typedef void* CallStackHandle;
CallStackHandle CreateCurrentCallStack(int nLevels)
{
void** ppCurrent = NULL;
// Get the current saved stack pointer (saved by the compiler on the function prefix).
__asm { mov ppCurrent, ebp };
// Don't limit if nLevels is not positive
if (nLevels <= 0)
nLevels = 1000000;
// ebp points to the old call stack, where the first two items look like this:
// ebp -> [0] Previous ebp
// [1] previous program counter
CallStackItem* pResult = new CallStackItem;
CallStackItem* pCurItem = pResult;
int nCurLevel = 0;
// We need to read two pointers from the stack
int nRequiredMemorySize = sizeof(void*) * 2;
while (nCurLevel < nLevels && ppCurrent && !IsBadReadPtr(ppCurrent, nRequiredMemorySize))
{
// Keep the previous program counter (where the function will return to)
pCurItem->pc = ppCurrent[1];
pCurItem->next = new CallStackItem;
// Go the the previously kept ebp
ppCurrent = (void**)*ppCurrent;
pCurItem = pCurItem->next;
++nCurLevel;
}
return pResult;
}
void PrintCallStack(CallStackHandle hCallStack)
{
CallStackItem* pCurItem = (CallStackItem*)hCallStack;
printf("----- Call stack start -----\n");
while (pCurItem)
{
printf("0x%08x\n", pCurItem->pc);
pCurItem = pCurItem->next;
}
printf("----- Call stack end -----\n");
}
void ReleaseCallStack(CallStackHandle hCallStack)
{
CallStackItem* pCurItem = (CallStackItem*)hCallStack;
CallStackItem* pPrevItem;
while (pCurItem)
{
pPrevItem = pCurItem;
pCurItem = pCurItem->next;
delete pPrevItem;
}
}
I use Jochen Kalmbachs StackWalker.
I speedet it up this way:
The most time is lost in looking for the PDB files in the default directories and PDB Servers.
I use only one PDB path and implemented a white list for the images I want to get resolved (no need for me to look for user32.pdb)
Sometimes I dont need to dive to the bottom, so I defined a max deep
code changes:
BOOL StackWalker::LoadModules()
{
...
// comment this line out and replace to your pdb path
// BOOL bRet = this->m_sw->Init(szSymPath);
BOOL bRet = this->m_sw->Init(<my pdb path>);
...
}
BOOL StackWalker::ShowCallstack(int iMaxDeep /* new parameter */ ... )
{
...
// define a maximal deep
// for (frameNum = 0; ; ++frameNum )
for (frameNum = 0; frameNum < iMaxDeep; ++frameNum )
{
...
}
}
Check out http://msdn.microsoft.com/en-us/library/bb204633%28VS.85%29.aspx - this is "CaptureStackBackTrace", although it's called as "RtlCaptureStackBackTrace".