Russian Qt Forum

Qt => Установка, сборка, отладка, тестирование => Тема начата: burunduk от Апрель 07, 2006, 11:15



Название: Исключения, локализация места возникновения и раскр. стека
Отправлено: burunduk от Апрель 07, 2006, 11:15
При пользовании исключениями каким образом можно получить текущий стек со списками ф-ций, откуда было вызвано исключение ?

Т.е. если у меня есть:
Код:

QByteArray hex2bin(QString data) {
  // если data с неправильным значением hex, то бросить исключение
}

void myfunc() {
  hex2bin("2F017Z");
}

int main() {
  myfunc();
}


то чтобы я не просто получил сообщение вида:

hex2bin error: потому что неверные данные

а более подробную информацию вида:

hex2bin error: потому что неверные данные
myfunc();      <- можно еще и номер строки где вызывалась hex2bin
main();


Название: Исключения, локализация места возникновения и раскр. стека
Отправлено: alex0303 от Апрель 07, 2006, 21:58
Место самого исключения не проблема (__FILE__, __LINE__, etc).
А вот то что Вы просите думаю сильно компиляторно-зависимое.
В release версиях и имён функций то обычно нет! :)


Название: Исключения, локализация места возникновения и раскр. стека
Отправлено: Вудруф от Апрель 10, 2006, 06:48
Руками :)
Можно при вызове всех функций последним параметром передавать место вызова... И во всех функциях отлавливать твои исключения. Изменять линию, добавлять к ней вызвавшую функцию и отправлять выше, пока не поймает кто-нибудь, кто исключение обработает.
Геморно, конечно. Но другого способа я не вижу.


Название: Исключения, локализация места возникновения и раскр. стека
Отправлено: burunduk от Апрель 10, 2006, 09:39
Пусть будет debug-версия.
Хотя бы примеры для основных компиляторов, например для того же MS Visual C++. В mingw тоже непонятно как сделать.

Вот для gcc и Linux мне подсказали на rsdn.ru:

Код:

4 linux: info:/libc/Backtraces
gcc тут не помошник -- это из libc... example code:

#include <execinfo.h>
      #include <stdio.h>
      #include <stdlib.h>


      /* Obtain a backtrace and print it to `stdout'. */
      void
      print_trace (void)
      {
        void *array[10];
        size_t size;
        char **strings;
        size_t i;


        size = backtrace (array, 10);
        strings = backtrace_symbols (array, size);


        printf ("Obtained %zd stack frames.\n", size);


        for (i = 0; i < size; i++)
           printf ("%s\n", strings[i]);


        free (strings);
      }


      /* A dummy function to make the backtrace more interesting. */
      void
      dummy_function (void)
      {
        print_trace ();
      }


      int
      main (void)
      {
        dummy_function ();
        return 0;
      }


Проверял - работает. Только компилить надо с опцией -rdynamic.