LINUX.ORG.RU

Gdb, точки наблюдения, mpi-программа

 ,


0

1

Привет,

Отлаживаю программу с помощью GDB. Требуется устанавливать много точек наблюдения. Устанавливаю с помощью команды watch:

(gdb) watch point

На 6 точке выдает:

Could not insert hardware watchpoint 1.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.

Вроде как это ограничение связанно с x86 архитектурой, если я правильно понял.

Можно ли как нибудь обойти данное ограничение?



Последнее исправление: Antonavt (всего исправлений: 2)

Можно (ох и медленно же будет) установить переменную gdb can-use-hw-watchpoints в 0. А как иначе можно обойти аппаратное ограничение?

io ★★
()

Решение связанное с задание

(gdb) set can-use-hw-watchpoints 0
не очень помогло так как требуется отладить mpi-программу и когда программа доходит до MPI_init, gbd удаляет все заданные точки и пишет:
Watchpoint number deleted because the program has left the block in which its expression is valid.
0xb7fec28b in _dl_fixup (l=0xb7fff918, reloc_arg=(optimized out))
    at dl-runtime.c:119
119 dl-runtime.c: Нет такого файла

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

Как я понимаю gdb пытается зайти в функцию _dl_fixup. Но не понимаю почему он туда хочет зайти, при проходе программы в gdb без точек останова с командой

set can-use-hw-watchpoints 0
mpi_init проходит нормально

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

_dl_fixup является частью /lib/ld-linux.so.2, который обеспечивает загрузку программы:

(gdb) b _dl_fixup
Function "_dl_fixup" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (_dl_fixup) pending.
(gdb) b main
Breakpoint 2 at 0x80483bd: file fix.c, line 5.
(gdb) run
Starting program: /tmp/fix 

Breakpoint 1, _dl_fixup (l=0x6048f8, reloc_arg=8) at dl-runtime.c:76
76	  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
(gdb) bt
#0  _dl_fixup (l=0x6048f8, reloc_arg=8) at dl-runtime.c:76
#1  0x005f99f0 in _dl_runtime_resolve () at ../sysdeps/i386/dl-trampoline.S:37
#2  0x08048321 in _start ()
(gdb) info shared
From        To          Syms Read   Shared Object Library
0x005e5830  0x005fd0bf  Yes         /lib/ld-linux.so.2
0x0061daa0  0x0073c1f4  Yes         /lib/libc.so.6

gdb имеет одно дурацкое свойство - останавливаться в тех процедурах/файлах где есть отладочные символы и повод (в данном случае watch), поэтому установка отладочной информации для системных библиотек иногда приводит к неудобствам в отладке.

Обход в данном случае простой: сначала дойти до main (b main... run) и потом устанавливать watch. Вообще сообщение Watchpoint number deleted because the program has left the block in which its expression is valid означает, что что-то для watch было выбрано не оптимально.

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

Не помогло

Вот такая программа:

#include <stdio.h>
#include "mpi.h"

int main(int argc, char* argv[])
{
	int size = -1;
	int rank = -1;
	
	MPI_Init(&argc,&argv);

	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);

	printf("%d from %d\n", rank, size);
	
	MPI_Finalize();
	return 0;
}
Делаю так:
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/anton/mpich2/programs/test...done.
(gdb) b main
Breakpoint 1 at 0x804859d: file ./test.cpp, line 6.
(gdb) r
Starting program: /home/anton/mpich2/programs/test 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=1, argv=0xbffff1f4) at ./test.cpp:6
6		int size = -1;
(gdb) set can-use-hw-watchpoints 0 
(gdb) wa rank
Watchpoint 2: rank
(gdb) n
7		int rank = -1;
(gdb) n
Watchpoint 2: rank

Old value = -1210269708
New value = -1
main (argc=1, argv=0xbffff1f4) at ./test.cpp:9
9		MPI_Init(&argc,&argv);
(gdb) n 
Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
0xb7fec28b in _dl_fixup (l=0xb7fff918, reloc_arg=<optimized out>)
    at dl-runtime.c:119
(gdb) 
Не подходит вариант обхода, при этом если установить точку просмотра после MPI_Init тоже самое происходит на какой нибудь из MPI-функций идущих потом

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

Основная проблема в данном случае то, что rank лежит в стеке и не является глобальным объектом. Поэтому легко теряет «фокус» watch. Можно поступить двумя способами: вынести его из процедуры и сделать глобальным объектом; можно встать на вызов MPI_Init, вычислить адрес rank (p &rank или присвоить $-переменной) и поставить watch на адрес (watch *(int*)адрес). В любом случае уже не будет потери фокуса.

io ★★
()
Последнее исправление: io (всего исправлений: 1)
Ответ на: комментарий от Antonavt

Это после чего, какие команды отработали? Кто мешает использовать CTRL-C чтобы посмотреть где завис?

io ★★
()
Ответ на: комментарий от io
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/anton/mpich2/programs/test...done.
(gdb) set can-use-hw-watchpoints 0 
(gdb) b main
Breakpoint 1 at 0x804859d: file ./test.cpp, line 6.
(gdb) r
Starting program: /home/anton/mpich2/programs/test 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=1, argv=0xbffff1f4) at ./test.cpp:6
6		int size = -1;
(gdb) p &size
$1 = (int *) 0xbffff148
(gdb) wa *((int *) 0xbffff148)
Watchpoint 2: *((int *) 0xbffff148)
(gdb) n
Watchpoint 2: *((int *) 0xbffff148)

Old value = 134514201
New value = -1
main (argc=1, argv=0xbffff1f4) at ./test.cpp:7
7		int rank = -1;
(gdb) n
9		MPI_Init(&argc,&argv);
(gdb) n
^C
Program received signal SIGINT, Interrupt.
0xb7fedddb in _dl_name_match_p (name=0xb7dfd3d9 "libpthread.so.0", map=0xb7fdc850) at dl-misc.c:306
306     dl-misc.c: Нет такого файла или каталога.

Вот вывод

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

HW точек в этом случае должно хватать. Лучше set can-use-hw-watchpoints 0 нафиг иначе все будет казаться (!) как зависон.

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

Спасибо, но в моей задаче требуется делать больше 6 точек наблюдения(так скажем такое условие)

Как ускорить то что Вы предложили вариантов нет?

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

Если нужно столько глобально - то ничего разумного особо сделать нельзя. Если HW не используется или не хватает, то замедление на порядки. Как вариант, если есть достаточные знания по структуре, можно использовать breakpoint-ы (достаточно дешево по сравнению с soft-watch) с commands для переключения watch и т.п. Можно менять набор watchpoint-ов и делать несколько прогонов. Заметим, что и сами watchpoint-ы могут иметь commands с набором if и вычислений. Но все зависит от задачи. Сценариев отладки можно придумать много. Обычно 1-2 watch хватало.

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