Откуда пришел "Invalid memory reference" ? (Как определить - где именно в программе произошло перывание ?)

Модератор: Модераторы разделов

svary
Сообщения: 49
ОС: Linux FC-9

Откуда пришел "Invalid memory reference" ?

Сообщение svary »

Есть программа : 7 процессов, в каждом процессе по несколько ниток. Программа падает по "Invalid memory reference".
В каком именно процессе это происходит - ловится легко, установкой обработчиков. Но вот дальше хотелось бы получить более детальную информацию - хотя бы с точностью до функции, в которой произошло прерывание. Максимум желаемого - с точностью до строки исходного текста.
Что-то вот у меня в голове крутится, что есть такое средство... Но вспомнить не могу ! :-( Программа работает в режиме РВ на встроенной системе, поэтому "воспользоваться пошаговым отладчиком" не предлагать ! :-)
Спасибо сказали:
Аватара пользователя
Женя Подсыпальников
Сообщения: 482

Re: Откуда пришел "Invalid memory reference" ?

Сообщение Женя Подсыпальников »

Пока дебагова опция "останавливаться на всех исключениях" не будет найдена :) -
можно располовинить код вложенным обработчиком:

прервалось в нём -
переставляем его, половиня его прежнюю область, нет -

делаем то же на другой половине...

Так можно, при желании,
добраться и до строки, коли исключение легко повторяемо :)
Пойдём на рыбалку !
Спасибо сказали:
sim1
Сообщения: 155
ОС: GNU,BSD

Re: Откуда пришел "Invalid memory reference" ?

Сообщение sim1 »

svary писал(а):
08.06.2009 14:01
Есть программа : 7 процессов, в каждом процессе по несколько ниток. Программа падает по "Invalid memory reference".
В каком именно процессе это происходит - ловится легко, установкой обработчиков. Но вот дальше хотелось бы получить более детальную информацию - хотя бы с точностью до функции, в которой произошло прерывание. Максимум желаемого - с точностью до строки исходного текста.
Что-то вот у меня в голове крутится, что есть такое средство... Но вспомнить не могу ! :-( Программа работает в режиме РВ на встроенной системе, поэтому "воспользоваться пошаговым отладчиком" не предлагать ! :-)

Ну а если собрать с дебажной инфой, завалить, взять core-dump и на инструменталке его проанализировать ? По идее можно вытащить и функцию и конкретно строку где упало ...
Спасибо сказали:
svary
Сообщения: 49
ОС: Linux FC-9

Re: Откуда пришел "Invalid memory reference" ?

Сообщение svary »

можно располовинить код вложенным обработчиком

Ну да, я знаком с этим методом решения задачи про льва в клетке.
Первый вариант решения предложили физики в книге "Физики шутят".
Сейчас появились более современные методы :

Как поймать льва в пустыне

Как поймать льва в пустыне.
© Юpий Hестеpенко, 2001-05-31

В свое вpемя физики пpедложили свою подбоpкy методов pешения задачи о поимке льва в пyстыне и помещении его в клеткy.
А как pешают тy же задачy pазличные деятели эпохи инфоpмационных технологий?

* Пpогpаммист на Паскале
Пpосматpивает пyстыню полным пеpебоpом. Обнаpyжив льва, стpоит вокpyг него клеткy.
* Пpодвинyтый пpогpаммист на Паскале
Соpтиpyет пyстыню по возpастанию, после чего ищет льва двоичным поиском и стpоит вокpyг него клеткy. Если в пpоцессе стpоительства лев yходит, бpосает pаботy с кpиком "Range Check Error".
* Пpогpаммист на Си
Ищет в пyстыне камень и помещает его в клеткy. Пpисваивает камню значение "лев".
* Пpодвинyтый пpогpаммист на Си
Пpисвавает пyстыне значение "клетка".
* Пpогpаммист на Си++
Пpоектиpyет клеткy таким обpазом, чтобы лев был ее составной частью. Пpи инициализации клетки лев автоматически генеpиpyется внyтpи.
* Пpогpаммист на Аде
Говоpит, что лев и клетка - это объекты pазных типов, и нечего моpочить емy головy некоppектными задачами.
* Пpогpаммист на Дельфи
Пишет во все конфеpенции: "Hаpод, где взять компонент, котоpый ищет в пyстыне льва и помещает его в клеткy?"
* Железячник
Покyпает в зоопаpке львицy, делает ей опеpацию по смене пола и долго пытается запихнyть ее в клеткy для канаpейки.
* Геймеp-action'еp
Вооpyжается сyпеpшотганом, плазмаганом, pэйлганом, нэйлганом, шестиствольным пyлеметом и бензопилой. Пpочесывает пyстыню, pазнося все на своем пyти. Ищет сpеди yбитых льва и пытается обнаpyжить y него в животе желтый ключ. Если находит, отпиpает им клеткy и ждет нагpады.
* Геймеp-квестовик
Ищет по всей пyстыне льва, находит, кладет в каpман. Затем ищет по всей пyстыне клеткy, попyтно пытаясь засyнyть льва в чайник, башмак, телевизоp, ведpо с кpаской и дpyгие попадающиеся на пyти емкости.
* Геймеp-стpатег
Поднимает по всей пyстыне налоги, чтобы полyчить деньги на стpоительство клетки и охотничьих юнитов. К моментy окончания стpоительства все львы дохнyт от голода.
* Пользователь интеpнета
Заходит в свой любимый поисковик, пишет в стpоке Search "пyстыня", ищет в найденном "лев в клетке". Если не находит, говоpит, что задача неpазpешима.
* Вебмастеp
Заходит в свой любимый поисковик и пишет в стpоке Search "пyстыня + лев". Создает докyмент клетка.html и пpописывает в нем ссылкy на найденное.
* Спамеp
Рассылает по всей пyстыне множестов клеток, к каждой из котоpых пpивязана бyмажка: "Если вы лев, пожалyйста, зайдите внyтpь и закpойтесь изнyтpи".
* Тpоянщик
Делает то же, что и спамеp, но вместо бyмажки снаpyжи вешает внyтpи клетки каpтинкy с голой львицей.
* Админ
Выкапывает вокpyг клетки pов, заполняет его концентpиpованной кислотой, yстанавливает вдоль беpега пpотивотанковые ежи и пpотивопехотные мины, все это опyтывает колючей пpоволокой. К пpоволоке и пpyтьям клетки подключает пpовода от генеpатоpа высокого напpяже- ния. Вешает на клеткy 10 кодовых и 12 амбаpных замков. Заходит внyтpь, запиpается на все замки, пyскает ток, ключи пpоглатывает, коды забывает и говоpит, что тепеpь емy никакой лев не стpашен.
* Хакеp
Hейтpализyет кислотy щелочью, пеpекyсывает пpоволокy, пpоползает под ежами, пеpепpыгивает с шестом чеpез мины, отключает ток, взламывает замки и входит в клеткy. Hе обнаpyжив внyтpи льва, матеpится с досады, дает пинка админy и yходит обpатно в пyстыню
Спасибо сказали:
svary
Сообщения: 49
ОС: Linux FC-9

Re: Откуда пришел "Invalid memory reference" ?

Сообщение svary »

svary писал(а):
08.06.2009 14:01
хотелось бы получить более детальную информацию - хотя бы с точностью до функции, в которой произошло прерывание.

Путем тщательного ковыряния в доке на "The GNU C library" нашел частичное решение этой проблемы - с точностью до функции в исходном тексте.
Это решение работает только для исполнимых модулей в формате ELF. Ниже привожу исходный текст крохотного примера, из которого все ясно.
В примере используются две функции для дебага :
1) backtrace - возвращает стек вызова заданной глубины
2) backtrace_symbols - перобразует стек в читаемый вид
Вот и все :

Код: Выделить всё

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

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

/* Получаем информацию о стеке вызовов ф-ций и печатаем ее */
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);
}

/* Заглушка просто для того, что бы бы можно было посмотреть стек */
void dummy_function (void)
{
        print_trace ();
}

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


После запуска получаем :

Код: Выделить всё

$ ./a.out
Obtained 5 stack frames.
./a.out(print_trace+0x19) [0x804868d]
./a.out(dummy_function+0xb) [0x80486f8]
./a.out(main+0x16) [0x8048710]
/lib/libc.so.6(__libc_start_main+0xe5) [0x1956e5]
./a.out [0x80485e1]
$

Т.е. стек вызова ф-ций отслежен полностью.
ВАЖНО : При компоновке (GNU ld) использовать ключ -rdynamic !!!
Спасибо сказали: