LINUX.ORG.RU

Как бы увидеть стек исключения?

 ,


1

2

Тут много говорили про отладку. Я как то привык отлаживаться printf-ом, точнее у меня есть макрос который при вызове

int a=1; double b = 2.5;
WOUT(a, b, a*b);
выводит
#"test.cpp" l123: a=1, b=2.5, a*b=5

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

Но таки хочется видеть стек, оттуда где упало и доверху. Мысль следующая - втыкаем по коду шняжки типа

FRAME(a, b, a*b);
При этом создаются некоторые объекты в текущей области видимости с неудобоваримыми именами. Есть глобальный список, куда попадает информация о файле, номере строки и значения перечисленных выражений. При выходе из области видимости объекты по деструктору выносят из списка соответствующие им записи.

При генерации исключения (у меня для этого тоже макрос есть;-)), перед генерацией содержимое списка вываливается на stderr.

В релиз-моде FRAME определяется так, что ничего не происходит.

М.б. что то похожее уже есть? Или это можно сделать симпатишней...

★★★★★

Это лишь малая часть того, что может отладчик.

В твоём случае main.c:

int a = 1;
double b = 2.5;

void somefunc() {
                                b = b * b + (a = ((a % 2 == 0) ? a * 2 + 1 : a + 3));
}

int main() {
  somefunc();
  somefunc();
  ...

Скрипт для gdb:

break main
run
while 1
        s
        bt
        printf "\na = %d, b = %f\n", a, b
end

Запускаем

$ gdb -x 1.gdb ./a.out 

получаем http://paste.debian.net/8285/

Т.е. вывод переменных и стека в каждой строчке и безо всяких макросов.

ziemin ★★
()
Ответ на: комментарий от ziemin

Во первых, у меня код это питон и библиотеки (свои) на плюсах прицепленные через свиг. Как то отладчик с этим не особо дружил... может с тех пор как я это изучал что то улучшилось.

Во вторых, я ХЗ куда брекпойнт ставить;-) Хотя это конечно вопрос мировоприятия, м.б. поработав с отладчиком привыкну.

В третьих, вроде как из под отладчика оно зело тормозит?

AIv ★★★★★
() автор топика
Ответ на: комментарий от AIv

С дебагом надо so собирать, тогда всё будет хорошо. gdb в качестве процесса даешь python

Reset ★★★★★
()
Ответ на: комментарий от AIv

В третьих, вроде как из под отладчика оно зело тормозит?

Не замечал.

Во вторых, я ХЗ куда брекпойнт ставить

Можно останавливаться на исключениях вроде: catch throw

По питону не знаю, но вот что гуглится: http://wiki.python.org/moin/DebuggingWithGdb

ziemin ★★
()

Возьми уже какой-нибудь трейсер. UST например

vasily_pupkin ★★★★★
()
Ответ на: комментарий от ziemin

Ок, спасибо! С 2009 вроде они стали поддерживать питон. Буду курить gdb, а эту фенечку я таки сделал;-)

AIv ★★★★★
() автор топика
Ответ на: комментарий от val-amart

Уууу, там жуть с ружьем... в общем я писал это не зная про c++0x, поэтому пришлось перегружать оператор запятая. Сейчас конечно через variadic template оно куда симпатишнее будет, руки пока не дошли.

хидер:

//------------------------------------------------------------------------------
	class debug_info{
		int pos, N, line; char* names[256];
	public:
		Ostream& stream;

		debug_info( Ostream& Astream, const char* args, const char* file, int line );
		~debug_info();
		const char* expr(){ if( pos<N ) return names[pos]; else return 0; }
		void next(){ if( pos < N ) stream.printf( names[pos++] );	else raise( "debug_info()::next() names vector overflow, N=%i", N ); }

#ifndef SWIG
		debug_info& operator , ( bool v ){ next(); stream.printf( "=%s", v?"True":"False" ); return *this; }
		debug_info& operator , ( char v ){ next(); stream.printf( "=%c", v ); return *this; }
		debug_info& operator , ( int  v ){ next(); stream.printf( "=%d",  v ); return *this; }
		debug_info& operator , ( long v ){ next(); stream.printf( "=%ld", v ); return *this; }
		debug_info& operator , ( size_t v ){ next(); stream.printf( "=%ld", v ); return *this; }
		debug_info& operator , ( float v  ){ next(); stream.printf( "=%g", v ); return *this; }
		debug_info& operator , ( double v ){ next(); stream.printf( "=%g", v ); return *this; }
		debug_info& operator , ( const char* v ){ next(); stream.printf( "=%s", v && strlen(v)?v:"\"\"" ); return *this; }
#endif //SWIG
	};

	template< class T > debug_info& operator, ( debug_info& S, T* ptr ){ S.next(); S.stream.printf("=>%0x", ptr ); return S; }
//	template< class T > void write_debug_info( debug_info& S, const T& v ){ S,v; }
#define WOUT( args... ) { ::aiv::debug_info _tmp_debug_info_obj( ::aiv::mystdout, #args, __FILE__, __LINE__ ); _tmp_debug_info_obj,args; }
#define WERR( args... ) { ::aiv::debug_info _tmp_debug_info_obj( ::aiv::mystderr, #args, __FILE__, __LINE__ ); _tmp_debug_info_obj,args; }
#define WSTR( stream, file, line, args... ) { ::aiv::debug_info _tmp_debug_info_obj( stream, #args, file, line ); _tmp_debug_info_obj,args; }
//------------------------------------------------------------------------------
сишник:
debug_info::debug_info(Ostream& Astream, const char* S, const char* file, int Aline):pos(0),N(0),line(Aline),stream(Astream){
	int i=0, p=0, len = strlen(S), brc=0, brp=0, brf=0;
	do{
		if( S[i]=='(' ) brc++; if( S[i]==')' ) brc--;
		if( S[i]=='[' ) brp++; if( S[i]==']' ) brp--;
		if( S[i]=='{' ) brf++; if( S[i]=='}' ) brf--;
		if( brc || brp || brf ) continue;
		if( S[i]==',' ){ names[N] = new char[ i-p+1 ]; strncpy( names[N], S+p, i-p ); names[N++][i-p]=0; p=i+1; }
		if( N>255 ) raise( "show_ifo::debug_info( \"%s\" ) --- names vector overflow", S );
	} while( ++i < len );
	names[N] = new char[ i-p+1 ]; strncpy( names[N], S+p, i-p ); names[N++][i-p]=0; p=i+1;
	if( file && line ) stream.printf( "#%s %i: ", file, line );
	else if( file ) stream.printf( file );
}
debug_info::~debug_info(){ 
	if(line) stream.printf("\n"); 
	for( int i=0; i<N; i++ ) delete [] names[i]; 
	if( pos != N) raise( "debug_info::~debug_info() --- not all expressions out, pos=%i != N=%i", pos, N );
}

Ostream класс потока вывода, raise тоже макрос, ну с ним все понятно;-)

Дальше для любого объекта перегружаем

debug_info& operator, (debug_info& S, T obj)
и он тоже начинает выводиться.

AIv ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Видать меня в гугле забанили;-( КРоме того, что она есть, я ничего найти не смог.

А она (или кто то еще) может узнать, в какой функции я сижу (сигнатура, файл, строка)?

AIv ★★★★★
() автор топика
Ответ на: комментарий от AIv

Видать меня в гугле забанили;-(

http://www.gnu.org/software/libc/manual/html_node/Backtraces.html

http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my...

А она (или кто то еще) может узнать, в какой функции я сижу (сигнатура, файл, строка)?

Да. Но для Си++ придется пропустить вывод через c++filt

tailgunner ★★★★★
()

При генерации исключения (у меня для этого тоже макрос есть;-)), перед генерацией содержимое списка вываливается на stderr.

Дык, не поможет если исключение не своё? В смысле кидается либой.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Дык, не поможет если исключение не своё? В смысле кидается либой.

Увы да...

AIv ★★★★★
() автор топика
Ответ на: комментарий от unfo

Да, спасибо (и ему тоже спасибо). Но я пока невкурил... ;-(

AIv ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.