2017-10-04 3 views
-1

J'ai ajouté une nouvelle classe à une DLL qui fait partie de la solution. Tout fonctionnait bien jusqu'à ce que j'ai commencé à obtenir l'erreur discuté dans this question quand je voudrais lancer la solution avec le débogueur. Cela signifie que le débogueur était en train d'attraper quelque chose de mal, probablement de la corruption de tas bien qu'il ne soit pas précisé exactement où.Comportement probablement non défini mais pourquoi?

J'ai réduit le problème à ma classe ajoutée, si je l'enlève, la solution débogue bien, pas d'erreurs. Mais apparemment, il n'y a rien de mal avec la classe que j'ai ajouté!

J'ai donc commenté ma classe et ajouté une nouvelle classe simple (fictive) Book juste pour voir si elle produira la même erreur mais ce n'est pas le cas! Ensuite, je l'ai fait ressembler à ma classe ajoutée (dérivé de ofstream) et encore il va déboguer correctement, pas d'erreurs. Je l'ai commenté et décommenté ma classe originale, encore une fois l'erreur apparaît quand je le débogue! J'ai écrémé cette classe et laissé seulement le constructeur/destructeur maintenant je peux le déboguer, l'erreur disparaît ici aussi. J'ai ramené le code de suppression (en utilisant annuler ainsi pour restaurer exactement) et cette fois cela fonctionne (quand il n'était pas avant) et débogera bien sans jeter cette erreur de corruption!

Cela ressemble beaucoup à un comportement non défini, mais c'est une classe autonome très légère qui est instanciée correctement, donc un comportement indéfini est-il toujours suspect? Si oui, pourquoi cela provoquerait-il ce comportement dans ce cas?

Voici mes .h et les fichiers .cpp pour référence

class lfstream : public std::ofstream 
{ 
public: 
    lfstream(); 
    ~lfstream(); 

    void log(const std::string &text, int threadID); 
}; 

#ifdef _LOGDLL 
    #define API __declspec(dllexport) 
#else 
    #define API __declspec(dllimport) 
#endif 

API extern lfstream logstream; 

/* 
class Book : public std::ofstream 
{ 
public: 
    Book(); 
    ~Book(); 
    int WordCount(); 
}; 

API extern Book book; 
*/ 

Le fichier .cpp

static char logfname[] = "debug.txt"; 

lfstream::lfstream(): std::ofstream(logfname) 
{ 
} 

lfstream::~lfstream() 
{ 
} 

void lfstream::log(const std::string &text, int threadID) 
{ 
    const time_t ctt = time(0); 
    *this << std::setw(40) << std::left << text << " thread id = " << threadID << "\t" << asctime(localtime(&ctt)); // << std::endl; 
} 

lfstream logstream; 

/* 
Book::Book() : std::ofstream("crash.txt") 
{ 
} 
Book::~Book() 
{ 
} 

int Book::WordCount() 
{ 
    return 50; 
} 

Book book; 
*/ 
+1

Alors, que l'erreur et quelle ligne est à l'origine? Il y a aussi plusieurs problèmes avec votre code: 1) la variable globale 2) tente d'écrire dans le journal à partir de différents threads ('threadID' est là pour une raison, non?) 3) tente d'utiliser' localtime' depuis différents threads peut aussi vous causer des problèmes Aussi les extraits de code donnés sont loin de [mcve] (https://stackoverflow.com/help/mcve) – VTT

+0

@VTT Il s'agit d'une boîte de dialogue de tri qui indique 'windows a déclenché un point d'arrêt dans l'App. exe'. Il ne dit pas ce qui s'est passé et où, mais cela arrive dans les premières étapes du chargement de l'exécutable. J'ai lié un post lié à celui-ci dans mon OP. – zar

+0

"windows a déclenché un point d'arrêt dans theApp.exe" - cela peut signifier que vous avez une fonction réelle qui déclenche un point d'arrêt (comme, par exemple, 'asm {int $ 3}' sur un système x86). – sehe

Répondre

2

Votre code montre que vous attendez d'être appelé sur différents threads.

Nous ne voyons nulle part dans le code la synchronisation de threads ou les sections critiques.

Vous devez protéger contre les conditions de course en utilisant des sections critiques. Avoir une condition de course est Undefined Behaviour.

La solution C++ standard la plus courante utilise un std::mutex avec std::lock_guard pour s'assurer qu'un seul thread peut se trouver dans (a) les sections critiques de votre code.

Sample/idée:

#include <mutex> 
// .... 


static std::mutex s_log_mutex; 

void lfstream::log(const std::string &text, int threadID) 
{ 
    std::lock_guard<std::mutex> lock(s_log_mutex); 
    const time_t ctt = time(0); 
    *this << std::setw(40) << std::left << text << " thread id = " << threadID << "\t" << asctime(localtime(&ctt)); // << std::endl; 
} 
+0

J'ai eu une section critique mais je l'ai enlevée dans le cadre de l'épuration. J'ai commencé à avoir cette erreur pendant que je développais ce module de journal qui est en cours de développement. Comme pour les cas de test actuels, il ne s'exécute que dans un seul thread, mais ce problème commence à apparaître et à apparaître. – zar

+0

Si vous avez UB et ce n'est pas multithread, je peux vous assurer que l'origine de l'UB n'est pas dans le code indiqué. Cela pourrait être dû à des problèmes de liaison subtils, mais à en juger par vos descriptions, cela est très improbable à cette échelle. (Néanmoins, assurez-vous de faire un nettoyage/reconstruction complet.) – sehe

+0

Étant donné que le flux de journalisation est global, essayez-vous de vous connecter depuis l'intérieur des constructeurs/destructeurs d'autres données globales? Vous pourriez rencontrer des problèmes d'initialisation/d'arrêt (voir [SIOF] (https://isocpp.org/wiki/faq/ctors#static-init-order)) – sehe