This is the mail archive of the gdb@sourceware.cygnus.com mailing list for the GDB project. See the GDB home page for more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Sorry, I do not intend to spend time on any F77 support fixes, as I am lacking the required Fortran expertise. I have a few objections to the proposed patches however: > In fact, the second part of his patch isn't needed and the first part > needs a little modification to avoid junk output. My suggested solution > (appended below) is to fix the length of these character strings to 1. This might work for Fortran, but it will break C and C++, where dynamic arrays are represented with a type length of zero. Perhaps the proper fix is to remove the arbitrary output of one element for Fortran assumed size arrays in f-valprint.c, which will get rid of the junk output when printing an assumed size array. > both strings. I modified the STREQ, STREQN, and STRCMP macros in gdb/defs.h > to catch such things in general (without too much tradeoff in speed, I hope). These macros are used in inner loops, so I think that we should not do the extra test, and the calling code in f-typeprint.c should get fixed. Perhaps g77 should output the type of __g77_length_* as `integer*4', to avoid an `Invalid type code' message from GDB, but I don't know. > + /* Fortran character strings were told by g77 to be character arrays */ > + /* which can be fixed here. */ > + if ( TYPE_NAME(element_type) != NULL && > + current_subfile->language == language_fortran ) > + if ( STRCMP(TYPE_NAME(element_type),"char") == 0 ) > + TYPE_CODE (result_type) = TYPE_CODE_STRING; If we really want to do this, then it should be done in the symbol reader. A cleaner solution might be to handle character arrays explicitly in f-valprint.c:f77_print_array_1. > Hello again, > > Peter Schauer kindly provided a fix to the gdb segmentation fault > which I reported recently (g77 compiled Fortran functions passing > character strings as CHARACTER*(*) arguments). > In fact, the second part of his patch isn't needed and the first part > needs a little modification to avoid junk output. My suggested solution > (appended below) is to fix the length of these character strings to 1. > By default then, only the first character is displayed but the '@' > modifier to the print command can of course be used to show more. > The actual length of the character string is passed in an additional > variable '__g77_length_something' for a string named 'something'. > > This variable caused another gdb segmentation fault with the same > example program: > > Program xyz > Character c*30 > c = 'This is only a test' > Call sub(c) > End > > Subroutine sub ( c ) > Character c*(*) > Write(*,*) 'C=''',c,'''' > Write(*,*) 'LEN(C)=',Len(c) > End > > Example session: > (gdb) break x.f:4 > Breakpoint 1 at 0x8048dcb: file x.f, line 4. > (gdb) run > Starting program: /home/users/bernlohr/x > > Breakpoint 1, MAIN__ () at x.f:4 > 4 Call sub(c) > Current language: auto; currently fortran > (gdb) print c > $1 = (84 'T', 104 'h', 105 'i', 115 's', 32 ' ', 105 'i', 115 's', 32 ' ', 111 'o', 110 'n', 108 'l', 121 'y', 32 ' ', 97 'a', 32 ' ', 116 't', 101 'e', 115 's', 116 't', 32 ' ', 32 ' ', 32 ' ', 32 ' ', 32 ' ', 32 ' ', 32 ' ', 32 ' ', 32 ' ', 32 ' ', 32 ' ') > (gdb) step > sub_ (c=0xbffff8c8, __g77_length_c=30) at x.f:9 > 9 Write(*,*) 'C=''',c,'''' > (gdb) print c > $2 = (PTR TO -> ( char (*))) 0xbffff8c8 > (gdb) print *c > $3 = (<assumed size array> 84 'T') > (gdb) whatis c > type = PTR TO -> ( char (*)) > (gdb) whatis __g77_length_c > Segmentation fault > > That's what gdb's core dump tells: > GNU gdb 4.17 > Copyright 1998 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 "i586-pc-linux-gnu"... > Core was generated by `gdb/gdb /home/users/bernlohr/t'. > Program terminated with signal 11, Segmentation fault. > find_solib: Can't read pathname for load map: Input/output error > > #0 0x80ee366 in f_type_print_base (type=0x81c9d64, stream=0x819da68, show=-1, > level=0) at f-typeprint.c:414 > 414 if (STREQ (TYPE_NAME (type), "char")) > (gdb) where > #0 0x80ee366 in f_type_print_base (type=0x81c9d64, stream=0x819da68, show=-1, > level=0) at f-typeprint.c:414 > #1 0x80edb7c in f_print_type (type=0x81c9d64, varstring=0x818626c "", > stream=0x819da68, show=-1, level=0) at f-typeprint.c:69 > #2 0x80eae00 in type_print (type=0x81c9d64, varstring=0x818626c "", > stream=0x819da68, show=-1) at typeprint.c:63 > #3 0x80eae90 in whatis_exp (exp=0x81b1ccf "__g77_length_c", show=-1) > at typeprint.c:88 > #4 0x80eaece in whatis_command (exp=0x81b1ccf "__g77_length_c", from_tty=1) > at typeprint.c:104 > #5 0x8100b23 in execute_command (p=0x81b1cdc "c", from_tty=1) at top.c:1259 > #6 0x8100d06 in command_loop () at top.c:1339 > #7 0x81099e5 in main (argc=2, argv=0xbffff910) at main.c:554 > > The fatal problem was that a NULL pointer was passed to the STREQ macro > which tries to optimize for speed and compares first the first character of > both strings. I modified the STREQ, STREQN, and STRCMP macros in gdb/defs.h > to catch such things in general (without too much tradeoff in speed, I hope). > Well, after that fix the 'whatis __g77_length_c' still shows a wrong type > (apparently due to incorrect debugging info from g77) but at least gdb > doesn't die anymore. > > Once being at it, I noticed that g77 declares character strings as > arrays of characters in the debugging info. That is the reason why > the first 'print c' above results in such an ugly output. Therefore, > I decided that (at least for the present g77) characters of arrays > should instead be declared as character strings (TYPE_CODE_STRING > instead of TYPE_CODE_ARRAY). See the patch below. > > With the final patched gdb the above gdb session again: > (gdb) break x.f:4 > Breakpoint 1 at 0x8048dcb: file x.f, line 4. > (gdb) run > Starting program: /home/users/bernlohr/x > > Breakpoint 1, MAIN__ () at x.f:4 > 4 Call sub(c) > Current language: auto; currently fortran > (gdb) print c > $1 = 'This is only a test', ' ' <repeats 11 times> > (gdb) step > sub_ (c=0xbffff8b0, __g77_length_c=30) at x.f:9 > 9 Write(*,*) 'C=''',c,'''' > (gdb) print c > $2 = (PTR TO -> ( character*(*) )) 0xbffff8b0 > (gdb) print *c > $3 = 'T' > (gdb) whatis c > type = PTR TO -> ( character*(*) ) > (gdb) whatis __g77_length_c > type = character > (gdb) print __g77_length_c > $4 = 30 > (gdb) print *c@30 > $5 = ('T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'o', 'n', 'l', 'y', ' ', 'a', ' ', 't', 'e', 's', 't', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ') > > By the way, I would also like to 'print' a substring as a Fortran expression, e.g. > 'print C(5:20)', but I can only 'print *(c+4)@16'. I will leave that as an > exercise. > > Kind regards, > Konrad Bernloehr > > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > Dr. Konrad Bernloehr, Institut fuer Kernphysik III > Forschungszentrum Karlsruhe, 76021 Karlsruhe, Germany > E-mail: bernlohr@ik3.fzk.de > > > *** gdb/gdbtypes.c.orig Mon Jun 29 12:05:04 1998 > --- gdb/gdbtypes.c Tue Jun 30 18:10:17 1998 > *************** > *** 31,36 **** > --- 31,37 ---- > #include "value.h" > #include "demangle.h" > #include "complaints.h" > + #include "buildsym.h" > > /* These variables point to the objects > representing the predefined C data types. */ > *************** > *** 436,447 **** > --- 437,465 ---- > result_type = alloc_type (TYPE_OBJFILE (range_type)); > } > TYPE_CODE (result_type) = TYPE_CODE_ARRAY; > + /* Fortran character strings were told by g77 to be character arrays */ > + /* which can be fixed here. */ > + if ( TYPE_NAME(element_type) != NULL && > + current_subfile->language == language_fortran ) > + if ( STRCMP(TYPE_NAME(element_type),"char") == 0 ) > + TYPE_CODE (result_type) = TYPE_CODE_STRING; > TYPE_TARGET_TYPE (result_type) = element_type; > if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) > low_bound = high_bound = 0; > CHECK_TYPEDEF (element_type); > TYPE_LENGTH (result_type) = > TYPE_LENGTH (element_type) * (high_bound - low_bound + 1); > + > + /* Fix to avoid segmentation faults when printing for example */ > + /* Fortran variables passed as CHARACTER*(*). */ > + if (low_bound > high_bound) > + { > + /* A minimum length of 1 is needed to avoid chunk output */ > + TYPE_LENGTH (result_type) = 1; > + if (high_bound == -1) > + TYPE_ARRAY_UPPER_BOUND_TYPE(result_type) = BOUND_CANNOT_BE_DETERMINED; > + } > + > TYPE_NFIELDS (result_type) = 1; > TYPE_FIELDS (result_type) = > (struct field *) TYPE_ALLOC (result_type, sizeof (struct field)); > *** gdb/defs.h.orig Tue Jun 30 13:16:27 1998 > --- gdb/defs.h Tue Jun 30 13:16:27 1998 > *************** > *** 77,85 **** > /* Gdb does *lots* of string compares. Use macros to speed them up by > avoiding function calls if the first characters are not the same. */ > > ! #define STRCMP(a,b) (*(a) == *(b) ? strcmp ((a), (b)) : (int)*(a) - (int)*(b)) > ! #define STREQ(a,b) (*(a) == *(b) ? !strcmp ((a), (b)) : 0) > ! #define STREQN(a,b,c) (*(a) == *(b) ? !strncmp ((a), (b), (c)) : 0) > > /* The character GNU C++ uses to build identifiers that must be unique from > the program's identifiers (such as $this and $$vptr). */ > --- 77,85 ---- > /* Gdb does *lots* of string compares. Use macros to speed them up by > avoiding function calls if the first characters are not the same. */ > > ! #define STRCMP(a,b) ((a)!=NULL && (b)!=NULL ? (*(a) == *(b) ? strcmp ((a), (b)) : (int)*(a) - (int)*(b)) : 999) > ! #define STREQ(a,b) ((a)!=NULL && (b)!=NULL ? (*(a) == *(b) ? !strcmp ((a), (b)) : 0) : 999) > ! #define STREQN(a,b,c) ((a)!=NULL && (b)!=NULL ? (*(a) == *(b) ? !strncmp ((a), (b), (c)) : 0) : 999) > > /* The character GNU C++ uses to build identifiers that must be unique from > the program's identifiers (such as $this and $$vptr). */ > > -- Peter Schauer pes@regent.e-technik.tu-muenchen.de