Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 分段错误-奇怪的调试语句_C++_Singleton_Segmentation Fault_Stack Trace - Fatal编程技术网

C++ 分段错误-奇怪的调试语句

C++ 分段错误-奇怪的调试语句,c++,singleton,segmentation-fault,stack-trace,C++,Singleton,Segmentation Fault,Stack Trace,我正在尝试使用函数跟踪构建自己的异常类(我想知道异常调用的所有函数的文件和行号,以及这些函数总共被调用的次数) 函数跟踪似乎在构建它时起作用,但当我试图正确使用它时,我被分段错误所困扰。我已经追踪到了其中的一些错误(愚蠢的错误,比如忘记返回任何东西或丢失符号),但是这一个正在折磨我——而且我还不能弄清楚我是如何得到我看到的调试语句的 我希望我的代码需要很多改进(如果有人对我绝对不应该做的事情提出任何建议或尖锐的评论,我将不胜感激),但有人能帮我弄清楚这里发生了什么。我试图利用我的Function

我正在尝试使用函数跟踪构建自己的异常类(我想知道异常调用的所有函数的文件和行号,以及这些函数总共被调用的次数)

函数跟踪似乎在构建它时起作用,但当我试图正确使用它时,我被分段错误所困扰。我已经追踪到了其中的一些错误(愚蠢的错误,比如忘记返回任何东西或丢失符号),但是这一个正在折磨我——而且我还不能弄清楚我是如何得到我看到的调试语句的

我希望我的代码需要很多改进(如果有人对我绝对不应该做的事情提出任何建议或尖锐的评论,我将不胜感激),但有人能帮我弄清楚这里发生了什么。我试图利用我的FunctionTrace类,在我认为有用的地方抛出cout语句,但我一无所获

我包括一个精简的int main()、FunctionTrace.{c,h}pp、mathsception.hpp(还没有.cpp)和gdb的输出(仍在学习使用它)

main.cpp

#include <iostream>
#include "FunctionTrace.hpp"
#include "MathsException.hpp"

using namespace std;

int main(int argc, char* argv[])
{
    LOG_FUNC_CALL
    try
    {
        std::string test = "";
        MathsException oExc(test);
        throw oExc;
    }
    catch(MathsException& iException)
    {
        iException.what();
    }
    return 0;
}
#包括
#包括“FunctionTrace.hpp”
#包括“MathsException.hpp”
使用名称空间std;
int main(int argc,char*argv[])
{
日志函数调用
尝试
{
std::string test=“”;
数学概念oExc(测试);
抛出oExc;
}
捕获(MathSexException和IEException)
{
什么;
}
返回0;
}
FunctionTrace.cpp

#include "FunctionTrace.hpp"
#include <vector>
#include <string>
#include <iostream>
#include <stdio.h>

static int countDebugStatic = 0; //TODO delete me!

int& FunctionCallDetails::getLine(){return lineNumber;}

const char* FunctionCallDetails::getFile(){return file;}

int& FunctionCallDetails::getNoOfTimesCalled(){return noOfTimesCalled;}

FunctionTrace::FunctionTrace(const int iLineNumber, const char* iFile)
{
    FunctionTraceManager& fnTraceMgr = FunctionTraceManager::getInstance();

    int oTimesCalled = ++fnTraceMgr.getAllTimesCalled()[std::make_pair(iLineNumber, iFile)];
    fnTraceMgr.getAllFunctionCalls().push_back(FunctionCallDetails(iLineNumber, iFile, oTimesCalled));
}

std::vector<std::string>& FunctionTraceManager::gatherFunctionCalls()
{
    FunctionTraceManager& fnTraceMgr = FunctionTraceManager::getInstance();
    std::vector<FunctionCallDetails>::iterator fnCallsIter =  fnTraceMgr.getAllFunctionCalls().begin();
    std::vector<std::string> oFnDetails;
    for(; fnCallsIter != fnTraceMgr.getAllFunctionCalls().end(); ++fnCallsIter)
    {
        countDebugStatic++;
        std::cout << "count: " << countDebugStatic << "\n";
        std::string fnDetail = "Function at line: ";
        char lineCalled[11]; //I'd never live long enough to generate this many lines of code in one file
        snprintf(lineCalled, 10, "%d", fnCallsIter->getLine());
        fnDetail += lineCalled;
        fnDetail += ", in file: ";
        fnDetail += fnCallsIter->getFile();
        fnDetail += " called: ";
        char noOfTimesCalled[11]; //log(2^32)/log(10) = 9.~~ (need a null char) 
        snprintf(noOfTimesCalled, 10, "%d", fnCallsIter->getNoOfTimesCalled());
        fnDetail += noOfTimesCalled;
        fnDetail += " times.";
        oFnDetails.push_back(fnDetail);
        std::cout << "fnDetail: " << fnDetail << "\n";
    }
    if(oFnDetails.size() > 0)
    {
        return oFnDetails;
    }
    else
    {
        oFnDetails.push_back("");
        return oFnDetails;
    }
}


FunctionTrace::~FunctionTrace()
{
    FunctionTraceManager& fnTraceMgr = FunctionTraceManager::getInstance();
    fnTraceMgr.getAllFunctionCalls().pop_back();
}
#包括“FunctionTrace.hpp”
#包括
#包括
#包括
#包括
静态int countDebugStatic=0//TODO删除我!
int&FunctionCallDetails::getLine(){return lineNumber;}
const char*FunctionCallDetails::getFile(){return file;}
int&FunctionCallDetails::getNoOfTimesCalled(){return noOfTimesCalled;}
FunctionTrace::FunctionTrace(常量int-iLineNumber,常量char*iFile)
{
FunctionTraceManager&fnTraceMgr=FunctionTraceManager::getInstance();
int oTimesCalled=++fnTraceMgr.getAllTimesCalled()[std::make_pair(iLineumber,iFile)];
fnTraceMgr.getAllFunctionCalls().push_back(FunctionCallDetails(iLineumber、iFile、oTimesCalled));
}
std::vector&FunctionTraceManager::gatherFunctionCalls()
{
FunctionTraceManager&fnTraceMgr=FunctionTraceManager::getInstance();
std::vector::迭代器fnCallsIter=fnTraceMgr.getAllFunctionCalls().begin();
std::向量和细节;
对于(;fnCallsIter!=fnTraceMgr.getAllFunctionCalls().end();++fnCallsIter)
{
countDebugStatic++;

std::cout您正在
FunctionTraceManager::gatherFunctionCalls
中返回对局部变量的引用


引用很像指针,返回引用基本上返回变量的地址。但是,当函数返回时,函数中的局部变量超出范围,这些变量不能被引用(通过指针或引用).这是未定义的行为,有时可能会起作用,但经常会发生奇怪的事情,如程序崩溃。

谢谢你,范围界定的好处也很好(我知道,但这一点我忽略了)…我说我的方法是错误的,而不是用符号表示,对吗?(删除、重新编译和重新运行也会留下似乎完全相同的错误……这也暗示了其他地方的问题)
#ifndef FUNCTION_TRACE_HPP
#define FUNCTION_TRACE_HPP

#include <vector>
#include <string>
#include <map>
#include <iostream>

class FunctionCallDetails
{
    int lineNumber;
    const char* file;
    int noOfTimesCalled;
    public:
        FunctionCallDetails(const int iLineNumber, const char* iFile, int iTimesCalled): lineNumber(iLineNumber), file(iFile), noOfTimesCalled(iTimesCalled){};
        int& getLine();
        const char* getFile();
        int& getNoOfTimesCalled();
};

class FunctionTraceManager
{
    //singleton
    std::vector<FunctionCallDetails> functionCalls;
    std::map<std::pair<const int,const char*>,int> timesCalled;

    FunctionTraceManager(){}
    FunctionTraceManager(FunctionTraceManager const&){}
    ~FunctionTraceManager(){}
    void operator = (FunctionTraceManager const&){}

    public:
        //this method will be the only way to get a FnTraceMgr object, and once statically created, further calls will retrieve the first (and only) FnTraceMgr
        //Object created.
        static FunctionTraceManager& getInstance()
        {
            static FunctionTraceManager fnTraceMgrInstance;
            return fnTraceMgrInstance;
        }
        std::vector<FunctionCallDetails>& getAllFunctionCalls()
        std::map<std::pair<const int,const char*>,int>& getAllTimesCalled()
        {
            if(functionCalls.size() > 0)
            {
                return functionCalls;
            }
            else
            {
                functionCalls.push_back(FunctionCallDetails(-1,"",-1));
                return functionCalls;
            }
        }
        std::map<std::pair<const int,const char*>,int>& getAllTimesCalled(){return timesCalled;}
        std::vector<std::string>& gatherFunctionCalls();
};
class FunctionTrace
{
    public:
        FunctionTrace(const int iLineNumber, const char* iFile);
        ~FunctionTrace();
};

#define LOG_FUNC_CALL FunctionTrace functionTrace(__LINE__,__FILE__);
#endif
#ifndef MATHS_EXCEPTION_HPP
#define MATHS_EXCEPTION_HPP
#include <exception>
#include "FunctionTrace.hpp"



#include <iostream>
class MathsException : public std::exception
{
    std::string errMsg;
    public:
        MathsException() throw() { LOG_FUNC_CALL };
        MathsException(const std::string iMsg): errMsg(iMsg){ LOG_FUNC_CALL }
        MathsException(const char* iMsg): errMsg(iMsg){ LOG_FUNC_CALL }
        std::string appendFunctionTracing()
        {
            LOG_FUNC_CALL
            std::string oStr = "";
            FunctionTraceManager& fnTraceMgr = FunctionTraceManager::getInstance();

            std::cout << "Why am I not seeing this at all !???";
            std::cout << "Why am I only seeing this once !???  fnTraceMgr.gatherFunctionCalls().size(): " << fnTraceMgr.gatherFunctionCalls().size() << "\n";
            std::vector<std::string>::iterator fnCallsIter = fnTraceMgr.gatherFunctionCalls().begin();
            for(; fnCallsIter != fnTraceMgr.gatherFunctionCalls().end(); ++fnCallsIter)
            {
                oStr += *fnCallsIter;
                oStr += "\n";
            }
            oStr += errMsg;
            return oStr;
        }
        void what()
        {
            LOG_FUNC_CALL
            std::cout << appendFunctionTracing();
        }

        ~MathsException() throw(){LOG_FUNC_CALL}
};

#endif
greg@greg-Aspire-5742:~/Documents/MMath/c++projects/2012_revision/Solver$ gdb Solver
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/greg/Documents/MMath/c++projects/2012_revision/Solver/Solver...done.
(gdb) r
Starting program: /home/greg/Documents/MMath/c++projects/2012_revision/Solver/Solver 
Why am I not seeing this at all !???count: 1
fnDetail: Function at line: -1, in file:  called: -1 times.
count: 2
fnDetail: Function at line: 10, in file: main.cpp called: 1 times.
count: 3
fnDetail: Function at line: 35, in file: MathsException.hpp called: 1 times.
count: 4
fnDetail: Function at line: 18, in file: MathsException.hpp called: 1 times.
Why am I only seeing this once !???  fnTraceMgr.gatherFunctionCalls().size(): 4
count: 5
fnDetail: Function at line: -1, in file:  called: -1 times.
count: 6
fnDetail: Function at line: 10, in file: main.cpp called: 1 times.
count: 7
fnDetail: Function at line: 35, in file: MathsException.hpp called: 1 times.
count: 8
fnDetail: Function at line: 18, in file: MathsException.hpp called: 1 times.
count: 9
fnDetail: Function at line: -1, in file:  called: -1 times.
count: 10
fnDetail: Function at line: 10, in file: main.cpp called: 1 times.
count: 11
fnDetail: Function at line: 35, in file: MathsException.hpp called: 1 times.
count: 12
fnDetail: Function at line: 18, in file: MathsException.hpp called: 1 times.

Program received signal SIGSEGV, Segmentation fault.
0xb7f6e478 in std::string::append(std::string const&) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
(gdb) info locals
No symbol table info available.
(gdb) bt
#0  0xb7f6e478 in std::string::append(std::string const&) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#1  0x0804b564 in operator+= (__str=..., this=0xbffff138) at /usr/include/c++/4.6/bits/basic_string.h:925
#2  MathsException::appendFunctionTracing (this=0x80530d8) at MathsException.hpp:27
#3  0x0804989b in what (this=0x80530d8) at MathsException.hpp:36
#4  main (argc=Cannot access memory at address 0x1
) at main.cpp:19
(gdb) info locals
No symbol table info available.
(gdb) up
#1  0x0804b564 in operator+= (__str=..., this=0xbffff138) at /usr/include/c++/4.6/bits/basic_string.h:925
925       { return this->append(__str); }
(gdb) info locals
No locals.
(gdb) up
#2  MathsException::appendFunctionTracing (this=0x80530d8) at MathsException.hpp:27
27              oStr += *fnCallsIter;
(gdb) info locals
functionTrace = {<No data fields>}
oStr = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x80523ac ""}}
fnCallsIter = {_M_current = 0x8053310}
(gdb) up
#3  0x0804989b in what (this=0x80530d8) at MathsException.hpp:36
36          std::cout << appendFunctionTracing();
(gdb) info locals
functionTrace = {<No data fields>}
(gdb) up
#4  main (argc=Cannot access memory at address 0x1
) at main.cpp:19
19      iException.what();
(gdb) info locals
iException = @0x80530d8
functionTrace = {<No data fields>}
(gdb) up
Initial frame selected; you cannot go up.
std::vector<FunctionCallDetails>::iterator fnCallsIter =  fnTraceMgr.getAllFunctionCalls().begin();
std::vector<FunctionCallDetails> fnCalls =  fnTraceMgr.getAllFunctionCalls();
std::vector<FunctionCallDetails>::iterator fnCallsIter =  fnCalls.begin();