Получение отслеживаний стека в системах Unix, автоматически

Отключить развертывание при сохранении в окне свойств / запуска проекта. Вот что сработало для меня наконец. Почему, черт возьми, NetBeans это за пределами меня.

Примечание. Мне удалось скомпилировать файл, в котором он жаловался, используя щелчок правой кнопкой мыши в NetBeans. По-видимому, это не совсем компилировалось, когда я использовал Build & amp; Компиляция, поскольку это не давало никаких ошибок. Но после этого ошибки просто переместились в другой файл класса java. Тогда я не смог скомпилировать его, поскольку он был недоступен. Я также попытался удалить каталоги сборки и dist в файлах проекта NetBeans, но это тоже не помогло.

7
задан jschmier 11 March 2011 в 19:08
поделиться

4 ответа

Если Вы находитесь в системах с BSD backtrace доступная функциональность (Linux, OSX 1.5, BSD, конечно), можно сделать это программно в обработчике сигналов.

Например (backtrace код, полученный из примера IBM):

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

void sig_handler(int sig)
{
    void * array[25];
    int nSize = backtrace(array, 25);
    char ** symbols = backtrace_symbols(array, nSize);

    for (int i = 0; i < nSize; i++)
    {
        puts(symbols[i]);;
    }

    free(symbols);

    signal(sig, &sig_handler);
}

void h()
{
    kill(0, SIGSEGV);
}

void g()
{
    h();
}

void f()
{
    g();
}

int main(int argc, char ** argv)
{
    signal(SIGSEGV, &sig_handler);
    f();
}

Вывод:

0   a.out                               0x00001f2d sig_handler + 35
1   libSystem.B.dylib                   0x95f8f09b _sigtramp + 43
2   ???                                 0xffffffff 0x0 + 4294967295
3   a.out                               0x00001fb1 h + 26
4   a.out                               0x00001fbe g + 11
5   a.out                               0x00001fcb f + 11
6   a.out                               0x00001ff5 main + 40
7   a.out                               0x00001ede start + 54

Это не получает бонусные очки для дополнительных функций (кроме не требования GUI), однако, оно действительно имеет преимущество того, чтобы быть очень простым, и не требующий никаких дополнительных библиотек или программ.

7
ответ дан 6 December 2019 в 06:26
поделиться

К ВАШЕМУ СВЕДЕНИЮ,

предложенное решение (использующий backtrace_symbols в обработчике сигналов) опасно повреждается. НЕ ИСПОЛЬЗУЙТЕ ЕГО -

Да, след и backtrace_symbols произведут след и переведение его к символьным именам, однако:

  1. backtrace_symbols выделяет память с помощью malloc, и Вы используете свободный освободить его - Если Вы откажете из-за повреждения памяти, то Ваша malloc арена, очень вероятно, будет повреждена и вызовет двойной отказ.

  2. malloc и свободный защищают malloc арену с блокировкой внутренне. Вы, возможно, дали сбой посреди malloc/free со взятой блокировкой, который вызовет, они функционируют или что-либо, что называет их к тупику.

  3. Вы используете, помещает, какое использование стандартный поток, который также защищен блокировкой. Если Вы дали сбой посреди printf, у Вас еще раз есть мертвая блокировка.

  4. На платформах на 32 бита (например, Ваш нормальный ПК 2-летних назад), ядро посадит обратный адрес к внутренней функции glibc вместо Вашей дающей сбой функции в Вашем стеке, таким образом, единственная самая важная информация, Вы интересуетесь - в котором функция сделала отказ программы, будет на самом деле повреждена на тех платформа.

Так, код в примере является худшим видом несправедливости - Похоже, что это работает, но это действительно приведет Вас к сбою неожиданными способами в производстве.

BTW, заинтересованный тем, чтобы делать правильно его? проверьте это.

С наилучшими пожеланиями, Gilad.

15
ответ дан 6 December 2019 в 06:26
поделиться

Вот пример того, как получить еще некоторую информацию с помощью demangler. Поскольку Вы видите, что этот также регистрирует stacktrace в файл.

#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <cxxabi.h>

void sig_handler(int sig)
{
    std::stringstream stream;
    void * array[25];
    int nSize = backtrace(array, 25);
    char ** symbols = backtrace_symbols(array, nSize);
    for (unsigned int i = 0; i < size; i++) {
        int status;
        char *realname;
        std::string current = symbols[i];
        size_t start = current.find("(");
        size_t end = current.find("+");
        realname = NULL;
        if (start != std::string::npos && end != std::string::npos) {
            std::string symbol = current.substr(start+1, end-start-1);
            realname = abi::__cxa_demangle(symbol.c_str(), 0, 0, &status);
        }
        if (realname != NULL)
            stream << realname << std::endl;
        else
            stream << symbols[i] << std::endl;
        free(realname);
    }
    free(symbols);
    std::cerr << stream.str();
    std::ofstream file("/tmp/error.log");
    if (file.is_open()) {
        if (file.good())
            file << stream.str();
        file.close();
    }
    signal(sig, &sig_handler);
}
4
ответ дан 6 December 2019 в 06:26
поделиться

Решение Dereks является, вероятно, лучшим, но здесь является альтернативой так или иначе:

Недавняя версия ядра Linux позволяет Вам передавать дампы ядра по каналу к сценарию или программе. Вы могли записать сценарий, чтобы поймать дамп ядра, собрать любую дополнительную информацию, Вы нуждаетесь и отправляете все по почте назад. Это - глобальная установка, хотя, таким образом, она относилась бы к любой программе катастрофического отказа в системе. Это также потребует корневым правам настроить. Это может быть настроено через/proc/sys/kernel/core_pattern файл. Набор это к чему-то как '|/home/myuser/bin/my-core-handler-script'.

Люди Ubuntu используют эту функцию также.

2
ответ дан 6 December 2019 в 06:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: