In GDB, it cannot pass input file to fortran program - fortran

I can pass the input file to fortran program, like this:
./foo < inputfile
But in gdb, I tried this:
gdb ./foo
run < inputfile
It displays nothing and doesn't work.
Update:
My system is MACOS high sierra
GDB version: 8.0

Example of main program getting optionally an input data file from argument :
program test
character(256) :: cfile
integer :: unit,status,itest
call get_command_argument(1,cfile)
if(cfile /= "") then
unit=15
open(unit,file=cfile,iostat=status)
if(status /= 0) then
write(*,*) 'invalid file ',trim(cfile)
stop
endif
else
unit=5
endif
read(unit,*) itest
write(*,*) itest
! ...
end program
Input deck "d.dat" :
25
Test :
[coul#localhost ~]$ gfortran -g test.f90
[coul#localhost ~]$ ./a.out < d.dat
25
[coul#localhost ~]$ gdb a.out
GNU gdb (GDB) Fedora 7.10.1-31.fc23
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
(gdb) run d.dat
Starting program: /home/coul/a.out d.dat
25
(gdb)

Related

htobe64 function disables debugger's ability to list source code

I have compiled the very simple program
$ cat main.cpp
#include <iostream>
int main() {
uint64_t val=1;
// val = htobe64(val);
std::cout << val << std::endl;
}
$ g++ -g main.cpp -o a.out
When I debug it using cgdb I get the following:
$ cgdb a.out
But when I uncomment the line // val = htobe64(val) something strange happens:
$ cat main.cpp
#include <iostream>
int main() {
uint64_t val=1;
val = htobe64(val);
std::cout << val << std::endl;
}
$ g++ -g main.cpp -o a.out
$ cgdb a.out
Uncommenting this single line causes cgdb to start showing the splash screen and when I type start as in the screenshot it only gives me assembler code (before cgdb started directly showing the source code and not its splash screen). Furthermore somehow the file path /home/user/byteswap.h appears in the screenshot, but this file does not exist (In this example user is was my username and /home/user my working directory).
Can someone tell me what is happening here and what I can do to be able to debug a program that is calling htobe64, i.e. how to achieve that cgdb will show me the source code as in the first example at the top?
Here are the tool versions:
$ cgdb --version
CGDB 0.7.1
Copyright 2002-2019 Bob Rossi and Mike Mueller.
CGDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
There is absolutely no warranty for CGDB.
$ gdb --version
GNU gdb (Debian 8.2.1-2+b3) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ g++ --version
g++ (Debian 11.2.0-10) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
When posting this questions I became aware of the fact that my g++ version is very new compared to my gdb version (I recently updated it to have better C++20 support).
I turns out that updating the gdb version solved the problem: With gdb version GNU gdb (Debian 10.1-2) 10.1.90.20210103-git the problem is no longer present. I admit that I should have verified this before posting but I do not delete the question because it may help others having similar strange obervations.

Truncation of deferred-length string when passing as optional

I am passing optional deferred-length strings (character(len=:), allocatable, optional) between subroutines and getting unexpected behavior in GCC.
Here is my minimal example, where I pass an optional string through an interface routine to a routine that sets it:
$ cat main.f90
module deepest_call_m
implicit none
contains
subroutine deepest_call(str)
character(len=:), allocatable, intent(OUT), optional :: str
if (present(str)) str = '12345'
write(*,*) 'at bot of deepest_call, str is "'//trim(str)//'"'
end subroutine deepest_call
end module deepest_call_m
module interface_call_m
implicit none
contains
subroutine interface_call(str)
use deepest_call_m, only : deepest_call
character(len=:), allocatable, intent(OUT), optional :: str
call deepest_call(str=str)
write(*,*) 'at bot of interface_call, str is "'//trim(str)//'"'
end subroutine interface_call
end module interface_call_m
program main
use interface_call_m, only : interface_call
implicit none
character(len=:), allocatable :: str
call interface_call(str=str)
write(*,*) 'at bot of main, str is "'//trim(str)//'"'
end program main
(Note that, for simplicity, I'm not wrapping the write statements in if(present) and if(allocated), although that would be necessary for a real implementation.)
In Intel 16.0 and 2019_U4, and PGI 15.10, this routine gives the expected result: str is set in deepest_call and remains the same through interface_call and in main:
$ ifort --version
ifort (IFORT) 16.0.0 20150815
Copyright (C) 1985-2015 Intel Corporation. All rights reserved.
$ ifort main.f90 && ./a.out
at bot of deepest_call, str is "12345"
at bot of interface_call, str is "12345"
at bot of main, str is "12345"
However, with gfortran 4.8.5:
$ gfortran --version
GNU Fortran (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Copyright (C) 2015 Free Software Foundation, Inc.
GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING
$ gfortran main.f90 && ./a.out
at bot of deepest_call, str is "12345"
at bot of interface_call, str is ""
at bot of main, str is ""
The string has been truncated when returning from the deepest_call in interface_call. With gfortran 7.3.0 and 8.2.0, the code crashes at runtime when no compile-time options are provided:
[chaud106#epyc-login-1-0 Testing]$ gfortran --version && gfortran main.f90 && ./a.out
GNU Fortran (GCC) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
at bot of deepest_call, str is "12345"
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x2af39a82733f in ???
#1 0x400c68 in ???
#2 0x400d9c in ???
#3 0x400f0e in ???
#4 0x2af39a813494 in ???
#5 0x400878 in ???
#6 0xffffffffffffffff in ???
Segmentation fault
However, adding compile-time checking recovers the previous truncation behavior:
$ gfortran --version
GNU Fortran (GCC) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gfortran -g -fbacktrace -Wall -Wextra -std=f2008 -fcheck=all -Og main.f90 && ./a.out
at bot of deepest_call, str is "12345"
at bot of interface_call, str is ""
at bot of main, str is ""
This looks a lot like a compiler bug to me, so perhaps I just need to post on the bugzilla. But I would like some feedback here first, specifically:
Is my test case standard-conforming? I'm specifically curious about the str=str argument to deepest_call. I use this structure often to pass an argument as optional if and only if it's optional in the present scope, but I couldn't easily find this in the standard and I'm not sure if it's really valid. Passing just str seemed to give the same behavior, though.
Are there any simple workarounds? Given that this issue affects a wide range of versions (4.8.5 to 8.2.0) simply avoiding them is not feasible.
Is anybody aware of this behavior for other versions of gfortran, or other compilers? I only have easy access to GCC, Intel, and PGI.
Your code is standard compliant.
An optional dummy argument may be an actual dummy argument in a subsequent call without the keyword, and whether or not it is present. (Of course, it may only be not present in the case that the following dummy argument is optional.) That is:
call interface_call(str)
is just as correct as
call interface_call(str=str)
As to (suboptimal) workarounds (I see this fail with gfortran 9.1.0, but working with gfortran 10.0.0 20190625), you could consider having the arguments as not deferred-length. After all, you're using trim everywhere, so trailing whitespace would be chomped.
Your code is just one small change away from not being compliant: the write statements aren't protected by a presence check for the optional dummy. If the optional dummy is not present in the call chain then the program would be invalid.

"Fortran runtime error: End of file" while writing

I have written a piece of code, compiled with GNU Fortran (GCC) 7.2.1 20171128 on Arch Linux, that tries to write to a file. The unit is opened with the newunit=... Fortran 2008-feature
When trying to write to the file, the code crashes, raising the error Fortran runtime error: End of file.
Non working code
Here's a minimal non-working version of the code. If the file does not exist, the code crashes with gfortran 7.2.1
program foo
implicit none
character(len=80) :: filename
character(len=5) :: nchar
integer :: ilun=1
call title(1, nchar)
! nchar = '00001'
filename = trim(nchar)//'.txt'
write(*, '(a, "<", a, ">")') 'filename ', trim(filename)
open(newunit=ilun, file=trim(filename), form='formatted', status='replace')
write(ilun, '(a1,a12,a10)') '#', 'Family', 'Count'
close(ilun)
end program foo
subroutine title(n, nchar)
implicit none
integer, intent(in) :: n
character(len=5), intent(out) :: nchar
write(nchar, '(i0.5)') n
end subroutine title
Here the command I'm using rm -f 00001.txt; gfortran foo.f90 -o a.out && ./a.out.
Working code
By comparison, the following code compiles and works perfectly on the same machine
program foo
implicit none
character(len=80) :: filename
character(len=5) :: nchar
integer :: ilun=1
! call title(1, nchar)
nchar = '00001'
filename = trim(nchar)//'.txt'
write(*, '(a, "<", a, ">")') 'filename ', trim(filename)
open(newunit=ilun, file=trim(filename), form='formatted', status='replace')
write(ilun, '(a1,a12,a10)') '#', 'Family', 'Count'
close(ilun)
end program foo
Here's the command I'm using rm -f 00001.txt; gfortran foo.f90 -o a.out && ./a.out.
Important note
Both codes work well when compiled using ifort (any version tried between ifort15 and ifort18) as well as GNU Fortran (GCC) 6.4.1 20171003 and GNU Fortran (GCC) 7.2.0, so there seems to be an issue introduced in version 7.2.1 of gfortran or on the version bundled with Arch Linux.
A few comments
If you uncomment nchar = '00001' in the non-working example, it still doesn't work.
If you change newunit=ilun to unit=ilun, with e.g. ilun=10 before, it works in any case
System details
OS: GNU Linux
Distribution: Arch Linux (up-to-date as of 15-12-2017)
$ uname -a
Linux manchot 4.14.4-1-ARCH #1 SMP PREEMPT Tue Dec 5 19:10:06 UTC 2017 x86_64 GNU/Linux
$ gfortran --version
GNU Fortran (GCC) 7.2.1 20171128
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This issue is related to the Arch Linux distribution of Gfortran 7.2.1. It has now been fixed (see https://bugs.archlinux.org/task/56768).
If you encounter the issue, you should update your installation using
pacman -Syu gcc-fortran

objdump -W sees line numbers, objdump -drl and gdb don't? [duplicate]

I am trying to figure out a very strange issue. I have CentOS 6.5 system with gdb:
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6)
and gcc:
gcc (GCC) 4.8.2 20131212 (Red Hat 4.8.2-8)
I have this file:
#include<stdio.h>
int main()
{
printf("OK!");
return 0;
}
which I compile with:
gcc -o a a.c -g -O0
The file seems to be fine:
$ file a
a: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
But when I try to debug it, this happens:
$ gdb a
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from a...done.
(gdb) b main
Breakpoint 1 at 0x4004e4
(gdb) r
Starting program: a
Breakpoint 1, 0x00000000004004e4 in main ()
(gdb) l
1 /* Run time dynamic linker.
2 Copyright (C) 1995-2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
(gdb) l main
No line number known for main.
I.e., gdb refuses to see any debug information. Anybody has an idea what could be a problem here?
Your GDB is pretty old. Your GCC is fairly new.
I suspect that your GCC is emitting DWARF4 debug info (default as of gcc-4.8 according to release notes), which your GDB does not recognize.
Do you get better result with -gdwarf-2 instead of -g?
If so, upgrade your GDB or use -gdwarf-2 with this compiler.

File format not recognized with GNU gdb 6.4 on Solaris 10

Below details are from a session in a Sun machine running Solaris 10.
$ file devli
devli: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, stripped
$ file a
a: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, not stripped
$ gdb
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "sparc-sun-solaris2.10".
(gdb) file a
Reading symbols from /tmp/tnmy/a...(no debugging symbols found)...done.
(gdb) file devli
"/tmp/tnmy/devli": not in executable format: File format not recognized
(gdb) q
$ ls -l a devlisrvr
-rwxr-xr-x 1 test2 dba 1480 Dec 23 18:23 a
-rwxr-xr-x 1 test2 dba 633088 Dec 23 18:26 devli
$ uname -a ;
SunOS myhost 5.10 Generic_127111-11 sun4v sparc SUNW,SPARC-Enterprise-T5220
$ cat a.c
int main() {return 0;}
$ /opt/SUNONE8/SUNWspro/bin/CC -V
CC: Sun C++ 5.5 2003/03/12
$ file `which gdb`
/usr/local/bin/gdb: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, not stripped
$
Any details on why would not gdb recognize the file format for devli? I searched over the Internet but could not find anything related to this particular issue. Any pointers would be helpful.
a.c goes into a, built using gcc; devli using Sun ONE Studio 8.
Note that GDB 6.4 is 4 years old. You might get better luck with (current) GDB 7.0.
It is also possible that the devli executable is corrupt (file just looks at the first few bytes of the executable, but GDB requires much more of the file contents to be self-consistent). Does readelf --all > /dev/null report any warnings?