gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 07:54:29 24 4
gpt4 key购买 nike

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

函数跟踪似乎在构建它时起作用,但是当我试图正确使用它时,我被段错误所困扰。我已经找到了其中的一些错误(愚蠢的错误,例如忘记返回任何内容或删除 & 符号)但是这个错误让我很痛苦 - 而且我还无法弄清楚我是如何获得我所看到的调试语句的。

我希望我的代码需要大量改进(对于我绝对不应该做的事情的任何建议或严厉评论,我将不胜感激)但是任何人都可以帮助我弄清楚这里发生了什么。我试图利用我的 FunctionTrace 类,并在我认为有用但毫无进展的地方抛出 cout 语句。

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

主要.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;
}

函数跟踪.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();
}

函数跟踪.hpp

#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

数学异常.hpp

#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

gdb 输出

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.

编辑:添加到我错过的 FunctionTrace.hpp 的底部几行

const 了我能看到的所有参数,看看编译器是否会帮助我——仍然没有用

在我返回可能为空的对象之前添加了一些 ifs - 我仍然遇到相同的段错误,但 gdb 输出不同(尽管仍然很奇怪)

进度:像这样改变电话

std::vector<FunctionCallDetails>::iterator fnCallsIter =  fnTraceMgr.getAllFunctionCalls().begin();

std::vector<FunctionCallDetails> fnCalls =  fnTraceMgr.getAllFunctionCalls();
std::vector<FunctionCallDetails>::iterator fnCallsIter = fnCalls.begin();

(并更新 for 循环)已经消除了 seg 错误;不知何故,我的迭代器一直指向某个愚蠢的地方

并撤消最后一步我没有遇到段错误(我以前遇到过)

最佳答案

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

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

关于c++ - 段错误 - 奇怪的调试语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13041820/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com