什么是跟踪Visual Studio 2005 c ++多线程程序中函数的进入和退出的快速方法?

时间:2022-11-04 23:17:38

I have intermittent crashes occurring in my ActiveMQ libraries due to the way I'm using the activemq-cpp API. It'd be much easier to debug the issue if I could observe every function being called leading up to the crash. Are there any quick ways to trace the entry and exit of functions in a Visual Studio 2005 c++ multithreaded program?

由于我使用activemq-cpp API的方式,我的ActiveMQ库中发生间歇性崩溃。如果我可以观察导致崩溃的每个被调用的函数,那么调试问题要容易得多。有没有快速的方法来跟踪Visual Studio 2005 c ++多线程程序中的函数的进入和退出?

Thanks in advance!

提前致谢!

3 个解决方案

#1


3  

Use a Tracer object. Something like this:

使用Tracer对象。像这样的东西:


class Tracer
{
public:
  Tracer(const char *functionName) : functionName_(functionName)
  {
    cout << "Entering function " << functionName_ << endl;
  }

  ~Tracer()
  {
    cout << "Exiting function " << functionName_ << endl;
  }

  const char *functionName_;
};

Now you can simply instantiate a Tracer object at the top the function, and it will automatically print "exiting... " when the function exits and the destructor is called:

现在,您可以简单地在函数顶部实例化一个Tracer对象,当函数退出并调用析构函数时,它将自动打印“退出...”:


void foo()
{
  Tracer t("foo");
   ...
}

#2


2  

While the debugger is attached to a process, you can rightclick in the source code and select "breakpoint->add TracePoint", with the text you want (even some macro's are supplied).

当调试器附加到进程时,您可以右键单击源代码并选择“断点 - >添加TracePoint”,并选择所需的文本(甚至提供一些宏)。

The Tracepoint is in fact a BreakPoint with the "When Hit" field on some message printer functionality, and it doesn't actually break the process. I found it mighty useful: it also has a macro $FUNCTION, which does exactly what you need: print the function it is in (provided it has the debug info available...), and a $THREADID.

Tracepoint实际上是一个BreakPoint,在某些消息打印机功能上具有“When Hit”字段,并且它实际上并没有破坏该过程。我发现它非常有用:它还有一个宏$ FUNCTION,它可以完全满足您的需求:打印它所在的函数(前提是它具有可用的调试信息......)和$ THREADID。

#3


2  

All the options above nice and can help you. But i can't see how setting TracePoing with mouse can help you in case you code have thousands of functions.
This kind of thing should be part of your regular programming work. When you writing a function you should think what trace message will help you to debug it.
You need to write/use existing logger that can be spitted to section (reader thread, worker thread, etc... )and different logging levels (error, warning,trace, verbose etc.. ). The good logger should be designed in the way it's not hurt you performance, this usually harm the verbosity, but complex synchronization problems usually can be reproduced unless the logging is very fast, like assigning a string pointer to the array that can be dumped after problem is reproduced. I usually start debugging with full trace dumped to the screen and if i lucky and bug reproduced this way, fixing the bug is trivial because i already have enough information, the fun starts when problem goes away and you need to play with verbosity in order to reproduce the problem.
I actually find debugging more creative and satisfying than code writing, but this is just me :).

以上所有选项都很好,可以帮到你。但我无法看到如果您的代码具有数千个功能,如何使用鼠标设置TracePoing可以帮助您。这种事情应该是你常规编程工作的一部分。编写函数时,您应该考虑哪些跟踪消息可以帮助您进行调试。您需要编写/使用现有的记录器,它可以分配到部分(读取器线程,工作线程等)和不同的日志记录级别(错误,警告,跟踪,详细等)。优秀的记录器应该以不损害性能的方式设计,这通常会损害详细程度,但复杂的同步问题通常可以重现,除非日志记录非常快,比如将一个字符串指针分配给可以在问题后转储的数组转载。我通常开始调试,完全跟踪转储到屏幕上,如果我幸运并以这种方式再现错误,修复错误是微不足道的,因为我已经有足够的信息,当问题消失时,乐趣开始,你需要玩详细的,以便重现问题。我实际上发现调试比代码编写更有创意和满意,但这只是我:)。

#1


3  

Use a Tracer object. Something like this:

使用Tracer对象。像这样的东西:


class Tracer
{
public:
  Tracer(const char *functionName) : functionName_(functionName)
  {
    cout << "Entering function " << functionName_ << endl;
  }

  ~Tracer()
  {
    cout << "Exiting function " << functionName_ << endl;
  }

  const char *functionName_;
};

Now you can simply instantiate a Tracer object at the top the function, and it will automatically print "exiting... " when the function exits and the destructor is called:

现在,您可以简单地在函数顶部实例化一个Tracer对象,当函数退出并调用析构函数时,它将自动打印“退出...”:


void foo()
{
  Tracer t("foo");
   ...
}

#2


2  

While the debugger is attached to a process, you can rightclick in the source code and select "breakpoint->add TracePoint", with the text you want (even some macro's are supplied).

当调试器附加到进程时,您可以右键单击源代码并选择“断点 - >添加TracePoint”,并选择所需的文本(甚至提供一些宏)。

The Tracepoint is in fact a BreakPoint with the "When Hit" field on some message printer functionality, and it doesn't actually break the process. I found it mighty useful: it also has a macro $FUNCTION, which does exactly what you need: print the function it is in (provided it has the debug info available...), and a $THREADID.

Tracepoint实际上是一个BreakPoint,在某些消息打印机功能上具有“When Hit”字段,并且它实际上并没有破坏该过程。我发现它非常有用:它还有一个宏$ FUNCTION,它可以完全满足您的需求:打印它所在的函数(前提是它具有可用的调试信息......)和$ THREADID。

#3


2  

All the options above nice and can help you. But i can't see how setting TracePoing with mouse can help you in case you code have thousands of functions.
This kind of thing should be part of your regular programming work. When you writing a function you should think what trace message will help you to debug it.
You need to write/use existing logger that can be spitted to section (reader thread, worker thread, etc... )and different logging levels (error, warning,trace, verbose etc.. ). The good logger should be designed in the way it's not hurt you performance, this usually harm the verbosity, but complex synchronization problems usually can be reproduced unless the logging is very fast, like assigning a string pointer to the array that can be dumped after problem is reproduced. I usually start debugging with full trace dumped to the screen and if i lucky and bug reproduced this way, fixing the bug is trivial because i already have enough information, the fun starts when problem goes away and you need to play with verbosity in order to reproduce the problem.
I actually find debugging more creative and satisfying than code writing, but this is just me :).

以上所有选项都很好,可以帮到你。但我无法看到如果您的代码具有数千个功能,如何使用鼠标设置TracePoing可以帮助您。这种事情应该是你常规编程工作的一部分。编写函数时,您应该考虑哪些跟踪消息可以帮助您进行调试。您需要编写/使用现有的记录器,它可以分配到部分(读取器线程,工作线程等)和不同的日志记录级别(错误,警告,跟踪,详细等)。优秀的记录器应该以不损害性能的方式设计,这通常会损害详细程度,但复杂的同步问题通常可以重现,除非日志记录非常快,比如将一个字符串指针分配给可以在问题后转储的数组转载。我通常开始调试,完全跟踪转储到屏幕上,如果我幸运并以这种方式再现错误,修复错误是微不足道的,因为我已经有足够的信息,当问题消失时,乐趣开始,你需要玩详细的,以便重现问题。我实际上发现调试比代码编写更有创意和满意,但这只是我:)。