Отладка функций Visual Studio

#c #logging #windbg #trace

#c #ведение журнала #windbg #трассировка

Вопрос:

Я работаю над версией 2008. Я хочу получить следующую информацию для всех моих методов:

1) Время при вводе вызова

2) Время завершения вызова и возвращаемое значение.

GDB позволяет мне устанавливать точку останова при каждом входе и выходе функции и запускать скрипт в точке останова, а затем продолжать отладку. Я устал искать решения, чтобы сделать что-то подобное на VS. Я даже думал написать скрипт для разбора всего моего кода и записи fprintf при входе и выходе, но это очень сложно. Отчаянно ищу помощь.

Ответ №1:

используя windbg, вы также можете установить для каждой записи функции и запустить скрипт. Например, следующая команда добавит точку останова для всех функций вашего модуля, отобразит название функции, текущее время, будет выполняться до завершения функции, отобразит время и продолжит.

 bm yourmodule!* "kcL1;.echotime;gu;.echotime;gc"
  

Комментарии:

1. Могу ли я распечатать возвращаемое значение. Я компилирую большой исходный код с большим количеством DLL-файлов. Должен ли я указывать здесь exe-файл?

2. .войдите в систему и . logclose для перенаправления выходных данных в файл.

3. возвращаемое значение в регистре $retreg

Ответ №2:

По сути, это профилирование на уровне функций на основе времени (TBP). В этом вам могут помочь несколько инструментов:

Я предлагаю вам сначала попробовать с AMD CodeAnalyst. Если у вас нет Visual Studio Premium или Ultimate edition.

Комментарии:

1. Я не хочу профилировать код. Я уже использовал автономный профилировщик для VS 2008. Кстати, у меня есть профессиональный. Я хочу, чтобы выходные данные были похожи на выходные данные strace. например. Временная метка foo -> rv. Выдает ли AMD Code Analyst мне этот вывод?

Ответ №3:

Я предполагаю, что вы подаете в суд на c . Вы можете определить класс временной трассировки, который отображает временные метки

 /* define this in a header file */
class ShowTimestamp {
private:
    static int level_;   // nested level for function call tree

private:
    const char *func_;
public:
    ShowTimestamp(const char* f) : func_(f) {
        std::cout << func_ << ":" << (level_  ) << ":begint" << GetTickCount64() << std::endl;
    }

    ~ShowTimestamp() {
        std::cout << func_ << ":" << (--level_) << ":endt" << GetTickCount64() << std::endl;
    }
};

#ifndef NO_TRACE_TIMER
  #define TIMESTAMP_TRACER     ShowTimestamp _stt_(__FUNCTION__); 
#elif
  #define TIMESTAMP_TRACER
#endif
  

Level_ следует объявлять в CPP-файле отдельно.

 // You need to define the static member in a CPP file         
int ShowTimestamp::level_ = 0;
  

В своем коде вы можете сделать

 int Foo(int bar) {
  TIMESTAMP_TRACER 

  // all the other things.
  ......

  return bar;
}
  

Если вы больше не хотите отслеживать таймер, вы можете просто определить NO_TRACE_TIMER

Комментарии:

1. ShowTimestamp можно было бы доработать, чтобы добавить отступ для вызовов вложенных функций.

2. 1 для вызовов вложенных функций. Похоже, что нет другого способа, кроме как вставлять инструкции в каждую функцию.

Ответ №4:

Visual Studio для этого не подходит; вам пришлось бы использовать WinDbg. У него есть свой собственный язык сценариев, который позволил бы вам делать то, что вы ищете. К сожалению, я ничего не знаю о его языке сценариев; вам придется прочитать файл справки (который на самом деле более или менее полезен, на этот раз).