Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как определить место, где возникла ошибка


Автор: xTr1m 16.3.2012, 10:14
Здравствуйте, подскажите пожалуйста. Есть код, который в определенных местах вызывает такую функцию
Код

bool CSomeClass::GetAttr(Instance *object, Attr *attr)
{
    if(0 == object) 
    {
        MessageBox("Null object detected");
        return false;

    //... производим операции
}


Но на самом деле такое сообщение мало чего дает мне как программисту, так как не понятно из какого места оно получилось. Поэтому хочется иметь какой-нибудь механизм распознания. 
Единственное, что мне приходит в голову, это вместо сообщения кидать исключение и в каждом месте его ловить. Тогда я смогу точно определить проблемный кусок кода. Но эта функция будет вызываться в оооочень многих местах и всюду делать try-cath вроде не хочется. Может есть еще способы?

Автор: boostcoder 16.3.2012, 10:24
__FILE__, __LINE__, __FUNCTION__/__PRETTY_FUNCTION__

Добавлено через 1 минуту и 6 секунд
можно еще стек вывести. но это наверняка лишнее)

Автор: xTr1m 16.3.2012, 10:35
Спасибо большое, а вот про стек можно по подробнее. Так как уж больно заманчиво звучит =))

Автор: boostcoder 16.3.2012, 10:41
это зависит от используемого компилятора/ОС. лучше https://www.google.ru/#hl=ru&newwindow=1&sclient=psy-ab&q=print+stack+trace+in+c%2B%2B&oq=print+stack+trace+in+c%2B%2B&aq=f&aqi=g-L1g-jCL1&aql=1&gs_sm=3&gs_upl=11458l21901l0l22345l24l14l0l10l10l0l262l1817l5.8.1l24l0&gs_l=hp.3..0i19j0i18i33i19.11458l21901l0l22345l24l14l0l10l10l0l262l1817l5j8j1l24l0.clfh.1.&pbx=1&bav=on.2,or.r_gc.r_pw.r_qf.,cf.osb&fp=4d274f80b7919f5a&biw=1440&bih=805.

Автор: xTr1m 16.3.2012, 10:57
По поводу __FUNCTION__ , попробовал сделать так
Код

bool CSomeClass::GetAttr(Instance *object, Attr *attr, const char *funcName /*= __FUNCTION__*/)
{
    if(0 == object) 
    {
        MessageBox(funcName);
        return false;
    //... производим операции
}

но получил
Код

error C2457: '__FUNCTION__': predefined macro cannot appear outside of a function body

То есть параметром по умолчанию передать не удалось. Пока вижу два выхода. При каждом вызове функции передавать __FUNCTION__ явно (что конечно не очень).
Или написать макрос на эту функцию. Но макрос тоже как то не совсем.

Автор: boostcoder 16.3.2012, 11:14
Цитата(xTr1m @  16.3.2012,  10:57 Найти цитируемый пост)
Или написать макрос

обычно макросом это и делается.

Автор: xvr 16.3.2012, 11:15
Простой способ. Собираете ваше приложение с отладочной информаций, запускаете. Когда видите MessageBox с "Null object detected" запускаете студию и коннектитесь к своему запущенному приложению, нажимаете в дебагаре break и смотрите стек вызовов

Еще вариант - вместо MessageBox пишете функцию типа error(...), в ней делает что хотите (для вывода ошибки). Загружаете программу под дебагером, ставите точку останова на ваш error и запускаете программу. Когда точка останова сработает - смотрите стек

Автор: xTr1m 16.3.2012, 11:19
xvr, дело в том, что ошибка возникает уже у клиента. И понять почему нереально при текущей архитектуре. А так согласился на вариант с макросом. Спасибо.

Автор: boostcoder 16.3.2012, 11:26
Цитата(xTr1m @  16.3.2012,  11:19 Найти цитируемый пост)
ошибка возникает уже у клиента

в таком случае, обычно создается лог-файл который отправляется разработчику.

Автор: borisbn 16.3.2012, 12:43
xTr1m, посмотри http://stacktrace.sourceforge.net/

Автор: xTr1m 16.3.2012, 14:33
borisbn, штука классная, но такое ощущение, что в svn тамошнем в папке externals чего то не хватает. а именно нет вот этого "#include "../externals/StackWalker/StackWalker.h"". Может еще можно где то взять?

Автор: xTr1m 16.3.2012, 15:08
В недрах интернета удалось найти недостающий класс =))

Автор: borisbn 16.3.2012, 15:13
xTr1m, здорово. А выложи сюда архив со всеми требуемыми для компиляции файлами, пожалуйста.

Автор: xTr1m 16.3.2012, 15:46
Вот тут все в кучу. В проекте примерно так
Код

#include "call_stack.hpp"
...
stacktrace::call_stack st;
cout << st.to_string();

Автор: xvr 16.3.2012, 16:24
Цитата(xTr1m @  16.3.2012,  11:19 Найти цитируемый пост)
xvr, дело в том, что ошибка возникает уже у клиента.

Тогда плсмотрите http://msdn.microsoft.com/en-us/library/windows/desktop/ee416349%28v=vs.85%29.aspx. С помощью minidump'а вы сможете посмотреть, что случилось у клиента

Автор: borisbn 16.3.2012, 16:34
xTr1m, спасибо.

Автор: leniviy 16.7.2012, 19:29
Я попробовал. Плохо работают эти классы, даже в Debug.
Код

#include "stdafx.h"

#include "call_stack.hpp"
#include <iostream>
using namespace std;

static
void foo(int i) {
  if (i) {
    foo(i-1);
  } else {
    stacktrace::call_stack st;
    cout << st.to_string();
  }
}

int _tmain(int argc, _TCHAR* argv[])
{
  foo(5);
    return 0;
}


Код

c:\users\il\documents\visual studio 2005\projects\stacker\stacker\stacker.cpp (12): foo

Автор: xTr1m 16.7.2012, 19:33
забавно, какая то бага похоже. но так работает
Код

using namespace std;

void f7()
{
    stacktrace::call_stack st;
    std::cout << "stack:" << endl << endl << st.to_string() << endl;
}

void f6()
{
    f7();
}

void f5()
{
    f6();
}

void f4()
{
    f5();
}

void f3()
{
    f4();
}

void f2()
{
    f3();
}

void f()
{
    f2();
}

int main (void)
{
    f();

    system("pause");

    return 0;
}


может все дело именно в рекурсии

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)