如何调试Fortran代码

时间:2018-01-04 04:57:53

标签: debugging fortran gdb gfortran dr-memory

我在ODE求解器套件中实现事件检测。以下是我正在调试的实现中的一段代码,并注意到一个奇怪的行为。一旦根查找例程成功返回根,则执行第一个if块(ROOTFINDING_ERR == 0) - 第1到14行 - 这是预期的行为。但是,一旦块完成执行,执行意外跳转到对应于(ROOTFINDING_ERR == 0) - 第20行的ELSE块的最后一个语句,并且语句EVENT_OUT(j)= .FALSE。在第21行执行ENDIF之前执行。

               1  IF (ROOTFINDING_ERR == 0) THEN
               2     IF ((ABS(EVENT_TIMES(1, j) - T_STAR) > &
               3          NEARBY_ROOTS_ABSTOL)  &
               4          .AND. (EVENT_ITER < EVENT_ITER_MAX)) THEN
               5        EVENT_TIMES(1, j) = T_STAR
               6        EVENT_TIMES(2, j) = DBLE(j)
               7        EVENT_TEST(j)     = .TRUE.
               8        EVENT_OUT(j)      = .TRUE.
               9     ELSE
              10        EVENT_TIMES(1, j) = T_STAR
              11        EVENT_TIMES(2, j) = DBLE(j)
              12        EVENT_TEST(j) = .FALSE.
              13        EVENT_OUT(j)  = .TRUE.
              14     ENDIF
              15  ELSE
              16     EVENT_TIMES(1, j) = T_STAR
              17     EVENT_TIMES(2, j) = DBLE(j)
              18     ! Dont test this event further
              19     EVENT_TEST(j)     = .FALSE.
              20     EVENT_OUT(j)      = .FALSE.
              21  ENDIF

我认为这与一些内存访问/分配问题有关,并在可执行文件上运行DrMemory(Valgrind之类的工具)。 DrMemory确实指出一些读取是未初始化的,我将进一步研究。

我想知道从哪里开始。我使用gdb逐步完成了代码,并且难以隔离DrMemory抱怨的“未初始化的读取”。我打开-Wall, -Wextra, -fbounds-check等来确定编译器是否能够捕获它。我也尝试用x32dbg反汇编exe,但是由于x32dbg不支持DWARF符号,因此不会读取调试符号。

1 个答案:

答案 0 :(得分:1)

从显示的代码中我看不出任何错误的原因。因此我猜测错误是由我们看不到的东西引起的。

现在,接下来的内容并没有解决这个难题,而是试图绕过它......

...显示的代码可以简化为

EVENT_TIMES(1, j) = T_STAR
EVENT_TIMES(2, j) = DBLE(j)
IF (ROOTFINDING_ERR == 0) THEN
   EVENT_OUT(j)      = .TRUE.
   IF ((ABS(EVENT_TIMES(1, j) - T_STAR) > &
        NEARBY_ROOTS_ABSTOL)  &
        .AND. (EVENT_ITER < EVENT_ITER_MAX)) THEN
      EVENT_TEST(j)     = .TRUE.
   ELSE
      EVENT_TEST(j) = .FALSE.
   ENDIF
ELSE
   ! Dont test this event further
   EVENT_TEST(j)     = .FALSE.
   EVENT_OUT(j)      = .FALSE.
ENDIF

......甚至更进一步......

EVENT_TIMES(1, j) = T_STAR
EVENT_TIMES(2, j) = DBLE(j)
EVENT_OUT(j) = ROOTFINDING_ERR == 0
EVENT_TEST(j)     = ((ROOTFINDING_ERR == 0) .AND. &
                    (ABS(EVENT_TIMES(1, j) - T_STAR) > &
                    NEARBY_ROOTS_ABSTOL)  &
                    .AND. (EVENT_ITER < EVENT_ITER_MAX))