Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print values out of a Fortran polymorphic derived data type in GDB

Tags:

gdb

fortran

I am trying to debug the following code using gdb (GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) and gfortran (gcc-Version 4.6.3). If I start gdb and step through the subroutine fun, I want to print the variables of the derived type "mytype" within the module class_test. It is easy to print the variable "int" that is also within the module "class_test" using the command: print class_test::int . My question is how to print the variable int1, int2 ... int4 if the gdb steps through the subroutine fun?

!! class definition

  module class_test


 integer :: int = 1


 type, public :: mytype

    private

    integer :: int1  = 2

    integer :: int2  = 3

    integer :: int3  = 4

    integer :: int4  = 5

  contains


  procedure, pass(this) :: fun

  end type mytype

  contains

  subroutine fun ( this )

  class(mytype) :: this

  write (*,*) "subroutine" 

  end subroutine fun

  end module class_test


  !! Program
  program test 

 use class_test

 type(mytype) :: struct

 write (*,*) "whateveryouwant"

 call struct%fun()


  end program
like image 420
user3669991 Avatar asked May 23 '14 19:05

user3669991


2 Answers

This might only apply to newer versions of GDB, but according to Pretty print Fortran dynamic type in gdb?, it seems like you could use a hidden _data component to access the structure components. Something like

print this%_data%int1

(This answer might be useful for people like me who found this post easily from a Google search but couldn't find the linked post easily. The linked post primarily discusses a topic that is mostly unrelated, but he provides an example of using GDB to print out member variables of class instances in Fortran. I haven't been able to find any other example like this on the Internet.)

I also just tried it for my own Fortran code, and it seems to work.

Using your sample code above (I had to change the dummy variable "this" to "temp" because I kept getting a seg. fault in GDB for some reason when I tried to print this), here's what I get from GDB (version 7.11.1 on Ubuntu):

(gdb) print temp
$1 = ( 0x601070 <struct>, 0x4009c0 <__class_test_MOD___vtab_class_test_Mytype> )
(gdb) print temp%_data
$2 = (PTR TO -> ( Type mytype
integer(kind=4) :: int1
integer(kind=4) :: int2
integer(kind=4) :: int3
integer(kind=4) :: int4
End Type mytype )) 0x601070 <struct>
(gdb) print temp%_data%int1
$3 = 2
(gdb) print temp%_data%int2
$4 = 3
like image 148
nukeguy Avatar answered Nov 18 '22 05:11

nukeguy


It is possible, but I don't think you can avoid inspecting the memory manually. I took the following steps:

(gdb) break class_test::fun
(gdb) run
(gdb) info args

This reveals the name and address of the argument struct that is associated with the dummy this:

this = ( 0x601080 <struct>, 0x400ae0 <__class_test_MOD___vtab_class_test_Mytype> )

Trying to print or even tab-complete struct causes gdb to segfault for me. So I use the (Fortran 2008) function storage_size to find that this requires 128 bits of memory. Print the contents of four 4-byte blocks starting at address 0x601080, formatted as unsigned integer:

(gdb) x/4u 0x601080

For which the output is

0x601080 <struct.1905>: 2       3       4       5

showing that struct contains the integers 2, 3, 4 and 5 as expected.

Of course, this may not be so easy if your derived type includes various data types or even other derived types.

like image 20
sigma Avatar answered Nov 18 '22 05:11

sigma