Доброго здравия!
Unified Parallel C (UPC) — это расширение языка C, разработанное для высокопроизводительных вычислений на крупномасштабных параллельных машинах. Язык представляет единую программную модель для систем с общей и разделенной памятью. Количество параллелизма фиксируется на старте программы, обычно с одним потоком на ядро процессора.
» Официальный сайт UPC
» Официальный сайт Berkeley UPC
В прошлой статье Установка в среде Windows и Linux описано, как выполнить установку UPC, но остался не раскрытым важный вопрос использования отладки. Очень часто наступает крах программы, если где-то неправильно выделена память или происходит превышение размерности массива
Что можно сделать в данной ситуации, чтобы бы сузить место поиска? Об этом в текущей статье.
Долгое время я избегал изучение отладки, т.к. уже нужно было заняться программированием. Вместо отладки я достаточно подробно логировал через printf действия каждого потока. Однако, дело омрачается тем, что программа UPC переводится на С и в общем случае оказывается не интерпретируемой. Если какая-то строчка была успешно выполнена (по логам), а следующего лога не произошло, то не факт, что ошибка между логируемыми строками! Очень часто ошибка «будущего» влияет на текущую ситуацию и вызывает крах программы совсем в другом месте.
Если в порядке с английским, полную информацию по отладке можно найти на официальной странице Debugging Berkeley UPC applications.
Если у вас есть почтовый ящик в домене университета, то вы можете запросить студенческую лицензию рекомендуемого TotalView, если нет, то можно воспользоваться штатным отладчиком С.
Нужно обратить внимание, что после перевода на С функция main() превратится в user_main().
Первое, чтобы воспользоваться специальным режимом отладки, необходимо запускать upcc c параметром
Существует несколько точек входа в отладку. Можно остановить поток с определенным номером с помощью параметра
Далее необходимо запустить gdb еще в одном сеансе консоли из папки с выходными файлами компиляции и указать PID потока
Чтобы продолжить выполнение программы, необходимо выполнить следующий код:
Программа услужливо сообщает строчку с ошибкой:
Чтобы посмотреть подробнее текущую точку останова, можно воспользоваться командой:
Кто бы мог подумать. Пойду разбираться с индексами и выделенной памятью )) Чтобы узнать стек вызова, можно воспользоваться командой bt
Стек вызова нужно рассматривать с низу. Пользовательская программа начинается с user_main, далее последовательно идут вызовы и видно, в каком месте и с какими параметрами происходит ошибка.
Чтобы корректно выйти из отладки, необходимо продолжить дальше, после чего можно сделать
Если по какой-то причине отладочные процессы зависли их можно убить с помощью команды
Наиболее востребованные команды gdb:
И как обычно,
Благодарю за внимание! Надеюсь, кому-нибудь пригодится
Unified Parallel C (UPC) — это расширение языка C, разработанное для высокопроизводительных вычислений на крупномасштабных параллельных машинах. Язык представляет единую программную модель для систем с общей и разделенной памятью. Количество параллелизма фиксируется на старте программы, обычно с одним потоком на ядро процессора.
» Официальный сайт UPC
» Официальный сайт Berkeley UPC
В прошлой статье Установка в среде Windows и Linux описано, как выполнить установку UPC, но остался не раскрытым важный вопрос использования отладки. Очень часто наступает крах программы, если где-то неправильно выделена память или происходит превышение размерности массива
*** Caught a fatal signal: SIGSEGV(11) on node 0/1
NOTICE: Before reporting bugs, run with GASNET_BACKTRACE=1 in the environment to generate a backtrace.
Ошибка сегментирования (слепок снят)
Что можно сделать в данной ситуации, чтобы бы сузить место поиска? Об этом в текущей статье.
Долгое время я избегал изучение отладки, т.к. уже нужно было заняться программированием. Вместо отладки я достаточно подробно логировал через printf действия каждого потока. Однако, дело омрачается тем, что программа UPC переводится на С и в общем случае оказывается не интерпретируемой. Если какая-то строчка была успешно выполнена (по логам), а следующего лога не произошло, то не факт, что ошибка между логируемыми строками! Очень часто ошибка «будущего» влияет на текущую ситуацию и вызывает крах программы совсем в другом месте.
Если в порядке с английским, полную информацию по отладке можно найти на официальной странице Debugging Berkeley UPC applications.
Если у вас есть почтовый ящик в домене университета, то вы можете запросить студенческую лицензию рекомендуемого TotalView, если нет, то можно воспользоваться штатным отладчиком С.
Нужно обратить внимание, что после перевода на С функция main() превратится в user_main().
Первое, чтобы воспользоваться специальным режимом отладки, необходимо запускать upcc c параметром
-g
. Это означает, что будет запускаться специальная конфигурация UPC из подпапки dbg. Чтобы была возможность увидеть конкретные строки кода, необходимо сохранить во время компиляции временные файлы с исходниками с помощью параметра -save-temps
:upcc ./Pack_Polycubes.upc -o Pack_Polycubes -pthreads <b>-save-temps -g</b>
Существует несколько точек входа в отладку. Можно остановить поток с определенным номером с помощью параметра
-freeze[=<thread_id>]
, а можно просто остановиться по ошибке с помощью -freeze-on-error
:upcrun -n 1 -freeze-on-error ./Pack_Polycubes
— WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
This application was built from a Berkeley UPC installation that
was configured and built with these optional features enabled:
debugging tracing statistical collection debugging malloc
This usually has a SERIOUS impact on performance, so you should NOT
trust any performance numbers reported in this program run!!!
To suppress this message, pass '-quiet' to the upcrun command or set
the UPC_NO_WARN or UPC_QUIET environment variables.
— UPCR: UPC thread 0 of 1 on Rosa-VB (pshm node 0 of 1, process 0 of 1, pid=31257)
Hello, I am 0 of 1.
…
*** Caught a fatal signal: SIGSEGV(11) on node 0/1
Process frozen for debugger: host=Rosa-VB pid=31257
To unfreeze, attach a debugger and set 'gasnet_frozen' to 0, or send a SIGCONT
Далее необходимо запустить gdb еще в одном сеансе консоли из папки с выходными файлами компиляции и указать PID потока
gdb Pack_Polycubes.o 31257
GNU gdb (Linaro GDB) 7.7.1_2014.06_1-10 ()
Copyright © 2014 Free Software Foundation, Inc.
…
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007f0afab16cd0 in __nanosleep_nocancel () from /lib64/libc.so.6
Чтобы продолжить выполнение программы, необходимо выполнить следующий код:
(gdb) set gasnet_frozen = 0
(gdb) continue
Программа услужливо сообщает строчку с ошибкой:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004289f8 in MultiplyMatrixPackSpace (Result=0x26274ac, Matrix=0x2696340, CurPackSpace=0x7ffd81634020)
at ./Pack_Polycubes.upc:1065
1065 Result[row][col] = 0;
Чтобы посмотреть подробнее текущую точку останова, можно воспользоваться командой:
(gdb) list
1060 // Умножение по правилу «строка на столбец»
1061 for(row = 0; row < Params.Demension; row++)
1062 {
1063 for(col = 0; col < Params.Demension; col++)
1064 {
1065 Result[row][col] = 0;
Кто бы мог подумать. Пойду разбираться с индексами и выделенной памятью )) Чтобы узнать стек вызова, можно воспользоваться командой bt
(gdb) bt
#0 0x00000000004289f8 in MultiplyMatrixPackSpace (Result=0x26274ac, Matrix=0x2696340, CurPackSpace=0x7ffd81634020)
#1 0x0000000000428680 in CheckIndependancePS (CurPackSpace=0x7ffd81634020) at ./Pack_Polycubes.upc:1032
#2 0x0000000000428430 in AddIndependentPackSpace (CurPackSpace=0x7ffd81634020) at ./Pack_Polycubes.upc:1011
…
#8 0x0000000000427e21 in ExplorePackSpaces () at ./Pack_Polycubes.upc:922
#9 0x00000000004244c5 in user_main (argc=4, argv=0x7ffd816344e8) at ./Pack_Polycubes.upc:214...
Стек вызова нужно рассматривать с низу. Пользовательская программа начинается с user_main, далее последовательно идут вызовы и видно, в каком месте и с какими параметрами происходит ошибка.
Чтобы корректно выйти из отладки, необходимо продолжить дальше, после чего можно сделать
quit
.(gdb) continue
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
Если по какой-то причине отладочные процессы зависли их можно убить с помощью команды
kill
из другого окна консоли, но в Росе получается проще с помощью Ctrl^C.Наиболее востребованные команды gdb:
break [file:]functiop
— установить точку остановки на функции
bt
— вызвать стек
print expr
— вывести значение выражения
с
— продолжить выполнение программы
next
— выполнить следующую строчку программы (перепрыгнуть)
step
— шагнуть внутрь строчки программы
list
— просмотр текущей строчки останова
help
— вызвать помощь
quit
— выход
И как обычно,
man gdb
Благодарю за внимание! Надеюсь, кому-нибудь пригодится
Поделиться с друзьями
Комментарии (2)
SuperVasek
14.12.2016 10:10-1Огромные благодарности! Мне очень помогло! Трудно найти нечто подобное в нете.
SuperVasek
Отличная статья!