NUIST HPC使用讲座 ——代码调试 刘建宇 2015-04-28.

Slides:



Advertisements
Similar presentations
Linux 环境及 Shell 程序 操作系统实验 1. 二、 Shell 编程与进程通信 常用 shell 命令 文件及文件属性操作 ls 、 cp 、 mv 、 rm ln 、 ln –s 、 chmod 、 groupadd 、 useradd 输入输出操作 echo 、 cat >> 、
Advertisements

第三单元明清帝国的繁荣与近代前夜的危机 第19课明清抗击外国侵略的英勇斗争.
河內塔(Hanoi)問題.
第八章 组织文化的整合 ——并购中的文化整合(二) 小组成员:浦若蓉、朱谷一、贾彦彦.
Unix 指令4.
上課教材 Database Slide Windows筆電 (32 bit)
2013—2014(二)职业发展教育课件 第十讲 就业准备 学生发展教育中心 职业发展教研室 二〇一四年三月.
病毒及防范.
培养目标 1.建立基本的程序设计概念体系,掌握基础程序设计方法。
第 2 章 初探 C++.
程序设计基础 贺辉 图书馆三楼办公室(进馆左侧上楼)
轻扣诗歌的大门.
Fortran — 世界上推出的第一种高级程序设计语言 谢建勤(电子与信息工程学院)
研 究 背 景 現在若談到木屐時,世界上最知名國家就屬 日本,是日本服飾文化的一個標誌。據記載,日
第七章 异常控制流 CPU控制流的概念 进程上下文切换 异常和中断的基本概念 异常和中断的响应和处理
阅读领航 春天景致类诗歌 徐扬 小组 组员:徐成 周闻欣 洪骋宇 胡浦欣 (排名不分先后).
補充: Input from a text file
Chapter 4 流程控制.
基于操作系统的编程复习 张玉宏
System Administration Practice Homework 2: Shell Programming
第6章 電腦軟體 應用軟體 多元程式處理 系統軟體 記憶體配置 作業系統簡介 虛擬記憶體 作業系統的演進與發展 行程管理
第五章 数 组 Fortran 90数组的特点: *** 可以逐个元素对数组进行操作,也可以对数组整体、数组段直接进行操作;
第三讲 shell 程序设计.
南京天石软件技术有限公司 陈锺 (QQ: Solaris 10 C编程 南京天石软件技术有限公司 陈锺 (QQ:
複習 struct score_Type{ int chinese,english; }; struct my_Type{
Python入门培训演示 系统测试部 叶华 文件级别:公开
講師:戴志華 國立台灣大學電機工程研究所 Visual Basic 程式設計 講師:戴志華 國立台灣大學電機工程研究所.
Shell Script 程式設計.
Shell程序设计 曙光信息产业股份有限公司.
第五章 shell 编程 shell 编程的基本过程分为三步: 1. 建立 shell 文件 包含任意多行操作系统命令或shell命令的文本
實作輔導 日期: 3/11 09:10~16:00 地點:臺北市立大學 臺北市中正區愛國西路一號 (中正紀念堂站7號出口)
第1章 Fortran概述 作为一门诞生于上个世纪50年代后半期的高级计算机语言,Fortran在这个C/C++、Java等新兴语言大行其道的时代仍然活跃在人们的视野之中。Fortran语言的长项在于数值计算,在科学研究和工程设计领域有着广泛的用途。在描述数学语言的自然性方面,Fortran同现存的其他高级语言相比有着明显的优势。对于科研工作者和工程技术人员而言,Fortran语言的易学性和易用性是公认的。
編譯環境介紹.
Linux 基础与常用命令简介 生物信息学培训班 杭州,2018年1月18日 周银聪.
Matlab M檔案 方煒 台大生機系.
1 Introduction Prof. Lin-Shan Lee TA: Chun-Hsuan Wang.
培训内容安排 APDL基础 模态分析技术 非线性分析技术 热-结构耦合分析 练习 APDL练习 模态分析 接触分析.
講師:戴志華 國立台灣大學電機工程研究所 Visual Basic 程式設計 講師:戴志華 國立台灣大學電機工程研究所.
前處理指令可以要求前處理器 (preprocessor) 在程式編譯之前,先進行加入其它檔案的內容、文字取代以及選擇性編譯等工作。
曙光集群简明使用手册 技术支持中心.
第4章 程序控制结构与算法基础.
流程控制、陣列 台南市聖功女子高級中學 毛全良.
Introduction to Multimedia Coding
Introduction to the C Programming Language
进程操作.
重點 資料結構之選定會影響演算法 選擇對的資料結構讓您上天堂 程式.
第12章 shell编程基础 本章主要介绍shell编程的基础知识。shell脚本的执行类似于Linux下的任何其他命令,脚本可以包含复杂的逻辑,也可以包含一系列Linux命令行指令。在一个shell程序内可以运行其他shell脚本。通过本章的学习,读者可以学到如何使用bash(最流行的Linux.
簡易 Visual Studio 2005 C++ 使用手冊
計數式重複敘述 for 迴圈 P
第六章 shell 程序调试 一. 程序执行状态跟踪 程序: -n 读取命令, 但不执行. 主要用于跟踪程序流程是
海報評比 班級:系統四甲 學號: 姓名:蔡飛宏 授課老師:唐蔚.
Chapter 指標.
软件工程 第四章 软件设计 软件过程设计技术与工具.
第二章 流编辑器sed 一. 什么是流编辑器? 流编辑器是一种流水线型的、非交互式
五十年前英国伦敦的情况与我国当前 何其相似乃尔
Intel Compiler 安裝.
第二章、第三章错题分析.
杨振伟 清华大学 第一讲:Linux环境下编程(1)
Compute System Administration Homework 2: Shell Script
本节内容 Lua基本语法.
1.3操作系统提供的服务和用户接口 操作系统提供的用户接口 程序接口与系统调用 操作接口与系统程序
問題解決與流程圖 高慧君 台北市立南港高中 2006年12月22日.
 隐式欧拉法 /* implicit Euler method */
粒子物理与核物理实验中的数据分析 杨振伟 清华大学 第1讲:Linux环境下的编程.
Arguments to the main Function and Final Project
「Love症候群」身心靈無痛治療法.
杨振伟 清华大学 第一讲:Linux环境下编程(1)
第6章 PHP基本語法介紹.
第二单元 第3课 Matlab命令执行方式 1.Matlab命令执行方式 2.程序调试.
劉庠宏、林合治編著 國立高雄大學應用數學系 2005年3月1日
Presentation transcript:

NUIST HPC使用讲座 ——代码调试 刘建宇 2015-04-28

!!!声明!!! ftp://202.195.238.13/Public/debugging.pdf 仅校内可访问 这里讨论的用户环境设置是基于目前(2014年)的NUIST HPC的配置上进行的 相关的用法、设置方式等有一定的普遍性,也有本地局限性 这里讨论的用法、设置方式,在不同的系统及配置下可能不适用 这里讨论的用法、设置方式,可能有不全面或不足之处 仅供参考,谨慎使用 ftp://202.195.238.13/Public/debugging.pdf 仅校内可访问

脚本调试 使用shell的执行选项 在shell中输出调试信息 使用“调试钩子” 脚本调试器bashdb http://bashdb.sourceforge.net/

脚本调试 ——使用shell的执行选项(-n) 读取脚本但不执行 测试脚本是否存在语法错误 bash -n script.sh ksh -n script.sh csh/tcsh -n script.sh #!/bin/bash if [ "$#" != "1" ]; then echo "usage : $0 filename" elif [ ! -f $1 ] then echo "$1 not exists" else tail $1 fi bash -n ./exp01.bash exp02.bash: line 8: syntax error near unexpected token `else' exp02.bash: line 8: `else'

脚本调试 ——使用shell的执行选项(-x) 进入跟踪方式,显示所执行的每一条命令 全局调试 bash -x script.sh ksh -x script.sh csh/tcsh -x script.sh 局部调试(仅bash/ksh) set -x 打开调试信息 set +x 关闭调试信息

脚本调试 ——使用shell的执行选项(-x) #!/bin/bash echo "Hello $USER," echo Today is `date +"%Y-%m-%d"` echo bye-bye bash -x ./exp02.bash + echo 'Hello jliu' Hello jliu + echo Today is `date +%Y-%m-%d` Today is 2015-04-26 + echo bye-bye bye-bye #!/bin/bash echo "Hello $USER," set -x echo Today is `date +"%Y-%m-%d"` set +x echo bye ./exp03.bash Hello jliu + echo Today is `date +%Y-%m-%d` Today is 2015-04-26 + set +x bye-bye

脚本调试 ——对“-x”的增强选项 BASH KSH PS4='+${BASH_SOURCE}:${LINENO}:${FUNCNAME[0]}:' KSH PS4='+${LINENO}:'

脚本调试 ——对“-x”的增强选项 #!/bin/bash isRoot () { if [ $UID -ne 0 ]; then return 1 else return 0 fi } isRoot if ["$?" -ne 0 ]; then echo "Must be root to run this script" exit 1 echo "welcome root user"

脚本调试 ——对“-x”的增强选项 bash -n ./exp04.bash ./exp04.bash exp04.bash: line 10: [1: command not found welcome root user export PS4='+${BASH_SOURCE}:${LINENO}:${FUNCNAME[0]}:' bash -x ./exp04.bash +exp04.bash:9::isRoot +exp04.bash:3:isRoot:'[' 502 -ne 0 ']' +exp04.bash:4:isRoot:return 1 +exp04.bash:10::'[1' -ne 0 ']' exp04.bash: line 10: [1: command not found +exp04.bash:14::echo 'welcome root user' welcome root user

脚本调试 ——使用shell的执行选项(-e) 如果产生错误立即退出 全局影响 bash -e script.sh ksh -e script.sh csh/tcsh -e script.sh 局部影响(仅bash/ksh) set -e 打开退出陷阱 set +e 关闭退出陷阱

脚本调试 ——使用shell的执行选项(-e) #!/bin/bash ls dummy_$$ echo "Hello $USER" echo Today is `date +"%Y-%m-%d"` echo bye-bye bash ./exp05.bash ls: cannot access dummy_25097: No such file or directory Hello jliu Today is 2015-04-26 bye-bye bash -e ./exp05.bash ls: cannot access dummy_25107: No such file or directory

脚本调试 ——在shell中输出调试信息 使用echo输出调试信息 使用 trap命令 echo '|var='$var'|' 其基本的语法是: trap 'command' signal shell伪信号 EXIT 从一个函数中退出或整个脚本执行完毕 ERR 当一条命令返回非零状态时(代表命令执行不成功) DEBUG 脚本中每一条命令执行之前

脚本调试 ——使用 trap命令 #!/bin/bash ERRTRAP() { echo "[LINE:$1] Error: Command or function exited with status $?" } foo() { return 1 trap 'ERRTRAP $LINENO' ERR abc foo echo "End" bash ./exp07.bash exp07.bash: line 11: abc: command not found [LINE:11] Error: Command or function exited with status 127 [LINE:8] Error: Command or function exited with status 1 End

脚本调试 ——使用 trap命令 #!/bin/bash trap 'echo "before execute line:$LINENO, a=$a,b=$b,c=$c"' DEBUG a=1 if [ "$a" -eq 1 ]; then b=2 else b=1 fi c=3 bash ./exp08.bash before execute line:3, a=,b=,c= before execute line:4, a=1,b=,c= before execute line:5, a=1,b=,c= before execute line:9, a=1,b=2,c= before execute line:10, a=1,b=2,c=3 end

脚本调试 ——使用“调试钩子” 使用if块 使用命令序列 if [ “$DEBUG” = “true” ]; then #此处可以输出调试信息 fi 使用命令序列 namelist=`ls -l namelist.input` || { echo Error; exit 1; } 使用DEBUG函数 _DEBUG=“on" DEBUG() { [ "$_DEBUG" == "on" ] && $@ } DEBUG echo "hello"

脚本调试 ——使用“调试钩子” #!/bin/bash _DEBUG="on" function DEBUG () { } fun01 () { echo "BUT HERE I am inside the function fun01() body" echo "HERE I am outside the function fun01() body!" sleep 2 debug fun01 echo "End" bash ./exp09.bash HERE I am outside the function fun01() body! BUT HERE I am inside the function fun01() body End

程序调试 程序出错了!!!

程序调试 ——系统的相关文件 标准输入/标准输出/标准错误 stdin/stdout/stderr 文件描述符 stdin stdout 程序调试 ——系统的相关文件 标准输入/标准输出/标准错误 stdin/stdout/stderr 文件描述符 stdin stdout stderr Unix 1 2 Fortran 通常约定 5 6 F2003 ISO_FORTRAN_ENV INPUT_UNIT OUPUT_UNIT ERROR_UNIT C

程序调试 ——输出重定向 PROGRAM TEST WRITE(0,*) "Error" WRITE(6,*) "Good" WRITE(*,*) "Error Good" END PROGRAM TEST #include <stdio.h> int main() { fprintf(stderr,"Error\n"); fprintf(stdout,"Good\n"); printf("Error Good\n"); return 0; }

程序调试 ——输出重定向 ./a.out bash & ksh Error ./a.out 1>out.log Good Error Error Good a.out > out.log ./a.out >& out.log bash & ksh ./a.out 1>out.log Error ./a.out 2>error.log Good Error Good ./a.out > out.log 2>&1 ./a.out >out.log 2>err.log csh/tcsh (a.out > out.log) >& err.log sh -c 'a.out > out' 2>& err.log

程序调试 ——错误信息的查找 应用程序自己输出的日志文件 运行时重定向输出的日志文件 作业调度系统的标准输出和标准错误文件 WRF :rsl 文件 运行时重定向输出的日志文件 >& out.log 作业调度系统的标准输出和标准错误文件 PBS O 文件(标准输出)和E文件(标准错误) 或由 #PBS -j,#PBS -o, #PBS -e 指定的文件 错误的诊断需要综合查看所有的日志文件

程序调试 ——错误信息的查找(示例) PBS O 文件 任务脚本中没有重定向的标准输出的内容 并行环境的标准输出的内容 作业调度系统自己的标准输出的内容 =================================================================================== = BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES = EXIT CODE: 9 = CLEANING UP REMAINING PROCESSES = YOU CAN IGNORE THE BELOW CLEANUP MESSAGES

程序调试 ——错误信息的查找(示例) PBS E文件 任务脚本中没有重定向的标准错误的内容 并行环境的标准错误的内容 作业调度系统自己的标准错误的内容 [proxy:0:0@c01n10] HYD_pmcd_pmip_control_cmd_cb (pm/pmiserv/pmip_cb.c:902): assert (!closed) failed [proxy:0:0@c01n10] HYDT_dmxu_poll_wait_for_event (tools/demux/demux_poll.c:76): callback returned error status [proxy:0:0@c01n10] main (pm/pmiserv/pmip.c:206): demux engine error waiting for event [mpiexec@c01n10] HYDT_bscu_wait_for_completion (tools/bootstrap/utils/bscu_wait.c:75): one of the processes terminated badly; aborting … … …

程序调试 ——错误信息的查找(示例) 应用程序自己的输出文件 WRF RSL文件 rsl.out :WRF输出到标准输出的内容 rsl.err :WRF输出到标准错误的内容 Timing for main: time 2010-06-09_11:48:00 on domain   1:  110.25500 elapsed …             1  points exceeded cfl=2 in domain d01 at time 2010-06-09_11:48:00 hours   MAX AT i,j,k:           39          16           2  vert_cfl,w,d(eta)=   2.0284483     … … …             6  points exceeded cfl=2 in domain d01 at time 2010-06-09_11:48:00 hours   MAX AT i,j,k:           39          16           3  vert_cfl,w,d(eta)=   3.4704070      … … … Timing for main: time 2010-06-09_11:49:00 on domain   2:   31.64400 elapsed …

程序调试 ——异常终止常见错误信息 Signal 11 or Signal 9 Signal 10 Singal 15 通常都是内存访问问题,例如数组下标越界、非法使用指针 或非正常结束并行程序 Singal 11(segmentation fault),多数访问了程序空间以外的地址 Singal 9 ,多数访问了程序内部不该访问的地址 Signal 10 ‘bus error’,不常见,通常由糟糕的代码编写引起或用不正确的方式进行的编译 Singal 15 Killed,进程被强制终止

程序调试 ——编译器的调试选项 PGI INTEL GFORTRAN -g -O0 -traceback -Mbounds -Mchkfpstk  -Mchkstk  -Mchkptr  -Ktrap=fp -Minfo=all INTEL -check all -check bounds -check pointers -check uninit -ftrapuv -warn all GFORTRAN -g -O0 -fbacktrace -ffpe-trap=list -fbounds-check -fcheck-array-temporaries -Wall

程序调试 ——定位错误 异常终止运行 去掉所有优化选项 加入调试编译选项进行编译 打开程序编译时的调试代码宏开关 打开程序运行时的调试开关 根据程序输出信息,在代码中添加相应调试输出信息 测试时使相同错误能在3-5分钟内就能触发 如果是并行程序,仅可能先测试串行运行的情况

程序调试 ——定位错误 运行异常/结果有问题 去掉所有优化选项,仅使用 加上浮点运算约束编译选项 PGI : -Kieee -g -O0 加上浮点运算约束编译选项 PGI : -Kieee Intel : -fp-model precise -no-fma GNU : -ffloat-store -fno-fast-math 根据程序输出信息,在代码中添加相应调试输出信息 如果是并行程序,尽可能先测试串行运行的情况

程序调试 ——定位错误(示例一) program loop 不加边界检查编译选项 implicit none real, allocatable :: u(:) integer i allocate(u(10)) do i=1,11 ! off-by-one error u(i)= i * 1.0 enddo print *,"i=",i, "u=",u(i) deallocate(u) end 不加边界检查编译选项 PGI无运行时错误,给出不正确结果 i= 12 u= 0.000000 Intel、Gfotran产生运行时错误 *** glibc detected *** ./a.out: free(): invalid next size (fast): 0x0000000001ec5b40 *** 添加边界检查编译选项后的运行情况 At line 6 of file loop.f90 Fortran runtime error: Array reference out of bounds for array 'u', upper bound of dimension 1 exceeded (11 > 10)

程序调试 ——定位错误(示例二) 添加-traceback选项编译运行情况 无-traceback选项编译运行情况 [jliu@log01 interpolation_grib_api]$ ./test.sh Interpolate product number 1 forrtl: severe (174): SIGSEGV, segmentation fault occurred 添加-traceback选项编译运行情况 [jliu@log01 interpolation_grib_api]$ ./test.sh Interpolate product number 1 forrtl: severe (174): SIGSEGV, segmentation fault occurred Image PC Routine Line Source interpolation_exa 0000000000497AE6 hntfauh_ 161 hntfauh.F interpolation_exa 00000000004979C6 hntfau_ 124 hntfau.F interpolation_exa 0000000000417711 intf_ 380 intf.F interpolation_exa 0000000000413BD0 Unknown Unknown Unknown interpolation_exa 00000000004106D8 Unknown Unknown Unknown interpolation_exa 0000000000406B37 MAIN__ 123 interpolation_example.F interpolation_exa 00000000004063FC Unknown Unknown Unknown libc.so.6 00000030AE61ECDD Unknown Unknown Unknown interpolation_exa 00000000004062F9 Unknown Unknown Unknown

程序调试 ——定位错误(示例二) interpolation_example.F 122 INLEN = IREC 123 IRET = INTF2(INGRIB,INLEN,NEWFLD,NEWLEN) intf.F 379 IF( LUSEHIR ) THEN 380 IRET = HNTFAU(FLDIN,INLEN) 381 ELSE 382 IRET = INTFAU(FLDIN,INLEN) hntfau.F 124 IRET = HNTFAUH(INGRIB,INLEN) hntfauh.F 160 DO LOOP = 1, INLEN 161 ZNFELDI( LOOP ) = FLDIN( LOOP ) 162 ENDDO

程序调试 ——定位错误(示例三) 我已经设置了debug_level=0,为什么生成的rsl.out文件还是这么大,这样我的程序跑不完就断掉了!有没有方法可以继续接着跑么

程序调试 ——定位错误(示例三) 使用head/tail查看rsl.out的头/尾信息 包含大量的‘Error in mapping flagsoap to start_ind’ 信息 使用grep在chem中查找包含“mapping flagsoap”的代码 grep -i "mapping flagsoap" chem/*.F 5081 ! 20130807 acd_alma_bugfix start 5082 do iv = start_ind, ngas_ioa + ngas_soa 5083 if (flagsoap(iv-start_ind+1).eq.2) then 5084 xsumfresh(ibin)= xsumfresh(ibin)+aer(iv,jtotal,ibin) 5085 elseif (flagsoap(iv-start_ind+1).eq.1) then 5086 xsumaged(ibin)= xsumaged(ibin)+aer(iv,jtotal,ibin) 5087 elseif (flagsoap(iv-start_ind+1).eq.0) then <--------------- 5088 print *, 'Error in mapping flagsoap to start_ind' 5089 endif 5090 enddo

程序调试 ——错误的修正 不要简单的在‘代码层面’做修正 在没有确切弄清楚相关代码的‘实际意义’时 修改前先备份原来的代码 向代码开发人员寻求帮助 或尽量做一些安全、保守的修改 修改前先备份原来的代码 注释掉原来的代码而不是直接修改或删除 修改后做相应注释

程序调试 ——错误的修正(示例) 示例三中,假设数据就是会有这种情况,能不能简单注释掉行5088的print语句? 不能 一种安全、保守的修改方式为 elseif (flagsoap(iv-start_ind+1).eq.0) then if ( err_sum .lt. 10 ) & print * ' Error in mapping flagsoap to start_ind ' err_sum = err_sum +1 endif endo if ( err_sum .gt. 10 ) & print * ' Too many errors in mapping flagsoap to start_ind '

程序调试 ——其他调试工具 TotalView idb pgdbg gdb 使用版本控制管理 IBM Graphical Symbolic Debugger idb Intel Debugger for Linux pgdbg PGI Graphical Symbolic Debugger gdb GNU Debugger 使用版本控制管理 SVN,CVS等

问题或建议 hpc@nuist.edu.cn