- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用函数跟踪构建我自己的异常类(我想知道调用异常的所有函数的文件和行号,以及这些函数被调用的总次数)
函数跟踪似乎在构建它时起作用,但是当我试图正确使用它时,我被段错误所困扰。我已经找到了其中的一些错误(愚蠢的错误,例如忘记返回任何内容或删除 & 符号)但是这个错误让我很痛苦 - 而且我还无法弄清楚我是如何获得我所看到的调试语句的。
我希望我的代码需要大量改进(对于我绝对不应该做的事情的任何建议或严厉评论,我将不胜感激)但是任何人都可以帮助我弄清楚这里发生了什么。我试图利用我的 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/
昨晚我因为这个问题脑子崩溃了。在确保没有来 self 的 eclipse 错误检查的明显错误之后,我开始调试我的程序。顺便说一下,我正在使用 Jre7。无论如何,每次我进入我的类调用(我们称之为“a”
(前言:我对 C/C++ 还很陌生,我真的不知道 native 代码中的调试实际上是如何工作的。) 一些消息来源说 gdb 和 lldb 可以调试 any program compiled to ma
我正在尝试从 Visual Studio 2012 外部调试 T4Scaffolding.Core Nuget 包。我使用的是安装了 Powershell 3.0 的 Powershell ISE,并
如何调试汇编代码?我在 Linux 上使用 gdb。我知道我可以看寄存器。有哪些调试汇编代码的方法? 最佳答案 您当然可以使用 breakpoints就像 C 或任何其他编译语言一样。 This ar
如何在每次通话时打印列表或 haskell 中的内容,例如: funct a list = funct (a + 1) (a : list) print list her
让我用我对 Makefiles 或 make 知之甚少的评论作为这个问题的前缀。 有一个非常大的项目,每晚自动构建。它以 Debug 和 Release 模式构建,Debug 用于 Valgrind
我正在创建一个计算每周工资的程序,那么任何加类工资都是该周正常工资的 1.5 倍。我的代码如下: #include int main() { double payrate; double h
我使用的是 Visual Studio 2010 Express Developer 版本。开发网站。我在我的 .aspx 页面中使用 JavaScript。 如何在 Javascript 中放置断点
我最近开始修补 Project Euler 问题,并尝试用 Javascript 解决它们。这样做我往往会产生许多无限循环,现在我想知道是否有比终止 Firefox 或 Chrome 中的选项卡更好的
有没有办法在程序执行期间生成一个交互式 python 控制台(最好是 iPython)而不暂停主程序并且能够检查和修改程序变量?类似于浏览器为 JavaScript 提供的功能。 我知道 pdb.se
我正在使用 FFmpeg @ Android 并希望能够进入 FFmpeg 代码(Eclipse + Seqouya),同时编译 FFmpeg 我使用 --disable-stripping --en
我从使用互操作调用 win32 api 函数的 .net 进程中得到一个异常。 我有一个调试器,我想查看 LastError 的值。 是否可以从 Visual Studio 调试器中查看 LastEr
我正在尝试通过 VBA 创建一个宏,以在 IE 的多个选项卡中打开一组指定的链接。目前我正在使用下面的代码,如果我试图打开 3 个或更少的选项卡,它大部分时间都可以工作。任何超过 3 的代码都会在“N
好的,这似乎是一个愚蠢的问题,因为 MonoDevelop 越来越成熟,所以我确定我只是想念它,但我环顾四周,所有关于这个主题的问题似乎都是关于远程调试或 Mac 上的调试。 我使用的是 Ubuntu
如何调试 Rscripts是从命令行运行的? 我目前正在使用 getopt传递命令行选项的包,当有错误时,我很难: 看看到底出了什么问题; 在 R 中交互式调试(因为脚本需要命令行选项。) 有没有人有
支持 PDF 和网络上的信息很少。我碰巧在博客中看到一篇文章,提到 $.write() 或 $.writeln() 将向 javascript 控制台写入一个字符串。相当有用。有谁知道这个 $ 对象是
PyCharm 1.5 中是否可以使用 Firefox 和 Chrome 支持的 JavaScript 调试? 如果是这样,它能否与 Python/Django 调试器一起有效运行? 如果没有,有没有
我确定这以前发生在人们身上,某些东西在 Debug模式下工作,你在发布时编译,但有些东西坏了。 这发生在我在嵌入式 XP 环境中工作时,我发现最好的方法确实是编写一个日志文件来确定它会出错的地方。 您
我目前正在为即将到来的项目评估 Flow3。 AOP 模式和依赖注入(inject)将非常适合我们的目的。 现在我想不通的是如何在 Controller Action 中调试一些结果。 public
最初,我有一个包含测试服务器的 Django 应用程序。要调试此设置,我只需添加 import pdb; pdb.set_trace()代码中的任何位置,并且有一个断点将我扔到终端中的交互式调试器中(
我是一名优秀的程序员,十分优秀!