From: Arjan on
Hi!

My question has already been put on this forum quite a few times in
the past years. Still I feel an urge to ask it once more:

--> What is the easiest way to get a complete diagram of all the
relations caller/callee of all the subroutines (including the main
program) and functions in a program?

I am analyzing a program written by a third party. They provided the
sources (F90), but the style of the code is ... different than I would
have used ... (=irreadable). I would hope that there is a compiler
(pgf90? ifort? g95? gfortran?) that generates such a tree with just
one extra switch, but I didn't find any. I tried ftnchek, but wasn't
satisfied with the result. I read about some nice utility named
"pyramid", but that utility requires another utility (graphviz?
vizgraph?) that does not seem to be available for my platform in
binary form and I am too lazy to compile it myself (I fear more
dependencies and I have no root-privileges to install it). What is my
best option?

Arjan
From: David Duffy on
Arjan <arjan.van.dijk(a)rivm.nl> wrote:
> I read about some nice utility named
> "pyramid", but that utility requires another utility (graphviz?
> vizgraph?) that does not seem to be available for my platform in
> binary form and I am too lazy to compile it myself (I fear more
> dependencies and I have no root-privileges to install it).

Everyone should have a copy of graphviz on their computer anyway ;) eg

http://www.graphviz.org/pub/graphviz/development/doxygen/html/structAgedge__t.htm

IIRC, you only need additional libraries to support particular output formats
eg libpng etc. I have compiled from source to make a personal version
of dot without any hassles.


Just 2c, David Duffy.

--
| David Duffy (MBBS PhD) ,-_|\
| email: davidD(a)qimr.edu.au ph: INT+61+7+3362-0217 fax: -0101 / *
| Epidemiology Unit, Queensland Institute of Medical Research \_,-._/
| 300 Herston Rd, Brisbane, Queensland 4029, Australia GPG 4D0B994A v
From: James Van Buskirk on
"Arjan" <arjan.van.dijk(a)rivm.nl> wrote in message
news:88efd67c-0bf5-4402-98bc-5d704bfa5a7a(a)r27g2000yqb.googlegroups.com...

> My question has already been put on this forum quite a few times in
> the past years. Still I feel an urge to ask it once more:

> --> What is the easiest way to get a complete diagram of all the
> relations caller/callee of all the subroutines (including the main
> program) and functions in a program?

In the general case this is impossible. For one thing, the call
graph need not be a tree, as RECURSIVE procedures are in the language
since F90. Since F03, a program unit could pass around arrays of
C_FUNPTRs around and then create procedure pointers from elements
indexed out of such arrays and then invoke the procedures. Since
F08 IIRC one can create procedure pointers to internal procedures
corresponding to different instances of their host procedure. How
do you express that in a call graph?

For that matter, a program may at runtime write code for a function,
link to a compiler in *.dll form, invoke the compiler to create a
*.dll file containing the compiled function, link to that *.dll file,
and then invoke the function that the program composed. This is a
real threat: FASM comes in also a *.dll format, although only in
32-bit form. I think that a program that attempts to generate a
call graph will miss such a function, not to mention all the
functions it may indirectly invoke.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: glen herrmannsfeldt on
James Van Buskirk <not_valid(a)comcast.net> wrote:
(snip, someone wrote)

>> --> What is the easiest way to get a complete diagram of all the
>> relations caller/callee of all the subroutines (including the main
>> program) and functions in a program?

> In the general case this is impossible. For one thing, the call
> graph need not be a tree, as RECURSIVE procedures are in the language
> since F90.

If I have it right, then it is a graph and not a tree.
Then I think a tree would be a directed acyclic graph.

> Since F03, a program unit could pass around arrays of
> C_FUNPTRs around and then create procedure pointers from elements
> indexed out of such arrays and then invoke the procedures. Since
> F08 IIRC one can create procedure pointers to internal procedures
> corresponding to different instances of their host procedure. How
> do you express that in a call graph?

Well, one that you usually want to know is where to look in
the program when something changes. So a link (I believe it is
edge in graph theory) would point the source of the C_FUNPTR.
Though I thought Fortran 2003 had its own procedure pointers,
in addition to C_FUNPTRs. (Mixing Fortran and C is likely
to complicate the generation of the graphical version.)

> For that matter, a program may at runtime write code for a function,
> link to a compiler in *.dll form, invoke the compiler to create a
> *.dll file containing the compiled function, link to that *.dll file,
> and then invoke the function that the program composed. This is a
> real threat: FASM comes in also a *.dll format, although only in
> 32-bit form. I think that a program that attempts to generate a
> call graph will miss such a function, not to mention all the
> functions it may indirectly invoke.

That is certainly possible. There are a lot of older programs,
though, likely back to Fortran 77 or even 66, which one might
try to understand. Having a graphical (printed) tree (or graph)
might help in visualizing the flow.

In most cases using C_FUNPTR or Fortran procedure pointers,
only a small fraction of the calls will use those, especially
in older code.

I believe that there are programs to do it for C and Fortran 77,
though I don't remember them by name.

-- glen
From: Florian Buerzle on

Hi!

Arjan wrote:

> Hi!
>
> My question has already been put on this forum quite a few times in
> the past years. Still I feel an urge to ask it once more:
>
> --> What is the easiest way to get a complete diagram of all the
> relations caller/callee of all the subroutines (including the main
> program) and functions in a program?
>

Have you tried any of the call graph generators mentioned here?

http://en.wikipedia.org/wiki/Call_graph

I must confess that I've never used it on Fortran code, but on C the egypt
script gave very good results (but it uses Graphviz, though). It works with
the intermediate RTL files generated by gcc, so maybe it will also work with
gfortran generated output (honestly, I've never tried). Since quite some
time has passed since I used it the last time, I don't remember all
details... but if you'd like to try it, you need the compiler option -fdump-
rtl-expand (the -dr option mentioned in the egypt documentation doesn't work
anymore in recent compilers).

Another possibility would be using gprof and the GProf2Dot script

http://code.google.com/p/jrfonseca/wiki/Gprof2Dot

which also uses Graphviz. This one has the advantage to generate even
dynamic call graphs which are pretty sophisticated (color coding of "hot
spots" etc.)

Hope that helps!

Florian