Fortran 77 debugger to check array bounds - fortran77

I am still green to debugging F77 and am having some problems with array bounds. I recently modified a lengthy code to have new array sizes. Everything 'seemed' okay until I noticed methods to alter one array, altered another. Somewhere in this code, I assume, an assignment is out of bounds and writing to the other arrays.
Is there a debugger/tool in the linux environment that will 'catch' the out of bounds exception?
I am currently using gfortran

There is a flag for gfortran to insert checks for out of bounds
-fbounds-check Enable generation of run-time checks for array
subscripts and against the declared
minimum and maximum values. It also
checks array indices for assumed and
deferred shape arrays against the
actual allocated bounds. In the future
this may also include other forms of
checking, eg. checking substring
references.
http://linux.die.net/man/1/gfortran
The output is as desired:
At line 2153 of file src/cdtm0402.f
Fortran runtime error: Array reference out of bounds for array 'wv1mp', upper bound of dimension 1 exceeded (78 > 77)
Backtrace for this error:
+ function coefdp (0x448BC3)
at line 2153 of file cdtm0402.f
+ in the main program
at line 371 of file cdtm0402.f
+ /lib64/libc.so.6(__libc_start_main+0xfd) [0x7ffff703da7d]

If this is at an employer, you may want to have them buy a license for "flint" - it's like "lint" for C, but for fortran.
Also, doesn't gdb/dbx/ddd do fortran debugging?
Oh, sometimes you need to turn on special flags in f77 in order to maintain the strings and debugging info in the executables and object files, much like "cc -g".

Related

Is Static Dynamic Array not allowed in RPGLE sub-procedure

SEQ is throwing a RNF3772 error if I try to declare a Static Dynamic array in a RPGLE sub-procedure. Is static dynamic array not allowed in sub-procedure?
Below is an example of what I entered in SEQ. The error that I got is "The keyword is not allowed following keyword STATIC; keyword is ignored."
P proc1 B
D pi
D myArray s 10 dim(1000) static based(myArray_p)
P E
static means the memory is kept (allocated) locally between calls
based means that no memory is allocated locally
So yeah, the two are mutually exclusive...
Unless you're %alloc() memory yourself, there's no dynamic arrays in RPG...I think even the new "dynamic arrays" in 7.4 actually just allocate the max memory. What's nice is they keep track of how many elements are used automatically.
edit2 As Barbara called out, if you are doing %Alloc()/%Realloc() yourself, then all you need is the basing pointer declared static I'd include a parm to indicate the memory should be cleaned up.
P proc1 B
D pi
d cleanUp n value
D myArray s 10 dim(1000) based(myArray_p)
d myArray_p s * static
if cleanUp;
dealloc(myArray_p);
return;
endif;
P E
Just use static. Same memory requirements as if you'd used a global variable, but hidden inside the procedure.
If you really want dynamic arrays, you could build your own routines in a *SRVPGM to use. Or you could make use of some open source.
RPG Next Gen - Vector
RPG Array List/Linked List
RPGMap
Dynamic Array using a user space
With an actual dynamic array, you'd likely end up with a pointer (or maybe an integer) variable in your procedure that you'd want defined as STATIC so that it remains between calls.
You'll also need to consider how to clean up the memory when you are done.
To define your array as based, but have it retain its values between calls, you have to define the basing pointer as static. It will probably be impossible to free the allocated storage except by reclaiming the activation group, unless your procedure has a way of knowing the array is no longer needed for future calls.

How to tell compiler to pad a specific amount of bytes on every C function?

I'm trying to practice some live instrumentation and I saw there was a linker option -call-nop=prefix-nop, but it has some restriction as it only works with GOT function (I don't know how to force compiler to generate GOT function, and not sure if it's good idea for performance reason.) Also, -call-nop=* cannot pad more than 1 byte.
Ideally, I'd like to see a compiler option to pad any specific amount of bytes, and compiler will still perform all the normal function alignment.
Once I have this pad area, I can at run time to reuse these padding area to store some values or redirect the control flow.
P.S. I believe Linux kernel use similar trick to dynamically enable some software tracepoint.
-pg is intended for profile-guided optimization. The correct option for this is -fpatchable-function-entry
-fpatchable-function-entry=N[,M]
Generate N NOPs right at the beginning of each function, with the function entry point before the Mth NOP. If M is omitted, it defaults to 0 so the function entry points to the address just at the first NOP. The NOP instructions reserve extra space which can be used to patch in any desired instrumentation at run time, provided that the code segment is writable. The amount of space is controllable indirectly via the number of NOPs; the NOP instruction used corresponds to the instruction emitted by the internal GCC back-end interface gen_nop. This behavior is target-specific and may also depend on the architecture variant and/or other compilation options.
It'll insert N single-byte 0x90 NOPs and doesn't make use of multi-byte NOPs thus performance isn't as good as it should, but you probably don't care about that in this case so the option should work fine
I achieved this goal by implement my own mcount function in an assembly file and compile the code with -pg.

How can I keep a stack variable from overwriting a static array in C++ with GCC?

I have a problem in which an array that is declared on the stack as an automatic variable overwrites an array that is declared statically. I cannot quote the exact code both for reasons of size and of intellectual property, but the outline follows.
I have the following struct:
struct mystruct_type {
const int list_size;
const int* list;
};
I have a global static array of these structs:
struct mystruct_type mystruct_ar[] = {
{3, (int[]){1, 2, 3}},
{2, (int[]){1, 3}},
{5, (int[]){4, 2, 3, 4, 5}}
};
This array is in a source file that's compiled into a library.
I have another source file that's compiled into another library that has an automatic array:
void my_func(void)
{
char my_string[1000];
// etc...
}
When this is all linked together, I see that the address of one of the lists in mystruct_ar, overlaps with my_string, and when I copy something into my_string it overrides elements in that list, causing a variety of problems.
My understanding of how the compiler and the linker work is that the static array and all of its subarrays belong in one region of memory, while the stack (on which my_string is declared) is in a separate non-overlapping region. What could be causing this overlap? What can I check?
I'm using GCC 4.3.2 on SuSE10 Linux (x86-64_linux26). Everything is linked statically.
EDIT: a few comments below said that this doesn't compile. They are right. In the process of sanitizing my snippet for presentation I neglected to cast the list array to int[]. This is fixed above.
I don't think this code would compile. Specifically, you can't pass a { list, of, ints } in mystruct_ar for the list pointer. You would have to declare each array of ints separately above.
You need to present a coherent sample that actually demonstrates the error, or failing that, actual code snippets.
The size of the stack is determined at runtime, not at compile-time. Run ulimit -s to find out the current maximum stack size, and pass an argument (like ulimit -s 16384) to increase it. Both of my Linux machines showed 8192 as the current stack size, try increasing it and see if your app works better.
What could be causing this overlap?
You didn't say whether you are using multiple threads. If you are, it is very likely that my_string overflows the (limited) stack, and thus un-intentionally overlaps global data.
The typical stack on Linux is 8MB, with a default guard region of 1 page (== 4K). This makes it unlikely that you are actually overflowing the stack (8MB is quite large) and that a 1000-element my_string can "step over" the guard region without touching it (touching the guard region results in SIGSEGV).
However, it is likely that you have not told us all the relevant details. If you create threads with non-default attributes, perhaps you are creating them with a small stack and disabling guard region?
Worse yet, you might be creating a thread with a fixed stack region (via pthread_attr_setstackaddr), and that fixed stack region might be a global array. If you (or some third-party code you call) do that, there is nothing that would separate globals from other globals (which are now used as a stack), and the collision (as well as lack of guard region) is entirely likely.
The overflow is also possible without threads, if you use coroutine style of programming (essentially user-level threads) via e.g. makecontext/swapcontext or a similar mechanism.

Memory leak in Ada.Strings.Unbounded ?

I have a curious memory leak, it seems that the library function to_unbounded_string is leaking!
Code snippets:
procedure Parse (Str : in String;
... do stuff...
declare
New_Element : constant Ada.Strings.Unbounded.Unbounded_String :=
Ada.Strings.Unbounded.To_Unbounded_String (Str); -- this leaks
begin
valgrind output:
==6009== 10,276 bytes in 1 blocks are possibly lost in loss record 153 of 153
==6009== at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==6009== by 0x42703B8: __gnat_malloc (in /usr/lib/libgnat-4.4.so.1)
==6009== by 0x4269480: system__secondary_stack__ss_allocate (in /usr/lib/libgnat-4.4.so.1)
==6009== by 0x414929B: ada__strings__unbounded__to_unbounded_string (in /usr/lib/libgnat-4.4.so.1)
==6009== by 0x80F8AD4: syntax__parser__dash_parser__parseXn (token_parser_g.adb:35)
Where token_parser_g.adb:35 is listed above as the "-- this leaks" line.
Other info: Gnatmake version 4.4.5. gcc version 4.4 valgrind version valgrind-3.6.0.SVN-Debian, valgrind options -v --leak-check=full --read-var-info=yes --show-reachable=no
Any help or insights appreciated,
NWS.
Valgrind clearly says that there is possibly a memory leak. It doesn't necessarily mean there is one. For example, if first call to that function allocates a pool of memory that is re-used during the life time of the program but is never freed, Valgrind will report it as a possible memory leak, even though it is not, as this is a common practice and memory will be returned to OS upon process termination.
Now, if you think that there is a memory leak for real, call this function in a loop, and see it memory continues to grow. If it does - file a bug report or even better, try to find and fix the leak and send a patch along with a bug report.
Hope it helps.
Was trying to keep this to comments, but what I was saying got too long and started to need formatting.
In Ada string objects are generally assumed to be perfectly-sized. The language provies functions to return the size and bounds of any string. Because of this, string handling in Ada is very different than C, and in fact more resembles how you'd do it in a functional language like Lisp.
But the basic principle is that, except in some very unusual situations, if you find yourself using Ada.Strings.Unbounded, you are going about things the wrong way.
The one case where you really can't get around using a variable-length string (or perhaps a buffer with a separate valid_length variable), is when reading strings as input from some external source. As you say, your parsing example is such a situation.
However, even here you should only have that situation on the initial buffer. Your call to your Parse routine should look something like this:
Ada.Text_IO.Get_Line (Buffer, Buffer_Len);
Parse (Buffer(Buffer'first..Buffer'first + Buffer_Len - 1));
Now inside the Parse routine you have a perfectly-sized constant Ada string to work with. If for some reason you need to pull out a subslice, you would do the following:
... --// Code to find start and end indices of my subslice
New_Element : constant String := Str(Element_Start...Element_End);
If you don't actually need to make a copy of that data for some reason though, you are better off just finding Element_Start and Element_End and working with a slice of the original string buffer. Eg:
if Str(Element_Start..Element_End) = "MyToken" then
I know this doesn't answer your question about Ada.Strings.Unbounded possibly leaking. But even if it doesn't leak, that code is relatively wasteful of machine resources (CPU and memory), and probably shouldn't be used for string manipulation unless you really need it.
Are bound[ed] strings scoped?
Expanding on #T.E.D.'s comments, Ada.Strings.Bounded "objects should not be implemented by implicit pointers and dynamic allocation." Instead, the maximum size is fixed when the generic in instantiated. As an implmentation detail, GNAT uses a discriminant to specify the maximum size of the string and a record to store the current size & contents.
In contrast, Ada.Strings.Unbounded requires that "No storage associated with an Unbounded_String object shall be lost upon assignment or scope exit." As an implmentation detail, GNAT uses a buffered implementation derived from Ada.Finalization.Controlled. As a result, the memory used by an Unbounded_String may appear to be a leak until the object is finalized, as for example when the code returns to an enclosing scope.

Visual C++ App crashes before main in Release, but runs fine in Debug

When in release it crashes with an unhandled exception: std::length error.
The call stack looks like this:
msvcr90.dll!__set_flsgetvalue() Line 256 + 0xc bytes C
msvcr90.dll!__set_flsgetvalue() Line 256 + 0xc bytes C
msvcr90.dll!_getptd_noexit() Line 616 + 0x7 bytes C
msvcr90.dll!_getptd() Line 641 + 0x5 bytes C
msvcr90.dll!rand() Line 68 C
NEM.exe!CGAL::Random::Random() + 0x34 bytes C++
msvcr90.dll!_initterm(void (void)* * pfbegin=0x00000003, void (void)* * pfend=0x00345560) Line 903 C
NEM.exe!__tmainCRTStartup() Line 582 + 0x17 bytes C
kernel32.dll!7c817067()
Has anyone got any clues?
Examining the stack dump:
InitTerm is simply a function that walks a list of other functions and executes each in step - this is used for, amongst other things, global constructors (on startup), global destructors (on shutdown) and atexit lists (also on shutdown).
You are linking with CGAL, since that CGAL::Random::Random in your stack dump is due to the fact that CGAL defines a global variable called default_random of the CGAL::Random::Random type. That's why your error is happening before main, the default_random is being constructed.
From the CGAL source, all it does it call the standard C srand(time(NULL)) followed by the local get_int which, in turn, calls the standard C rand() to get a random number.
However, you're not getting to the second stage since your stack dump is still within srand().
It looks like it's converting your thread into a fiber lazily, i.e., this is the first time you've tried to do something in the thread and it has to set up fiber-local storage before continuing.
So, a couple of things to try and investigate.
1/ Are you running this code on pre-XP? I believe fiber-local storage (__set_flsgetvalue) was introduced in XP. This is a long shot but we need to clear it up anyway.
2/ Do you need to link with CGAL? I'm assuming your application needs something in the CGAL libraries, otherwise don't link with it. It may be a hangover from another project file.
3/ If you do use CGAL, make sure you're using the latest version. As of 3.3, it supports a dynamic linking which should prevent the possibility of mixing different library versions (both static/dynamic and debug/nondebug).
4/ Can you try to compile with VC8? The CGAL supported platforms do NOT yet include VC9 (VS2008). You may need to follow this up with the CGAL team itself to see if they're working on that support.
5/ And, finally, do you have Boost installed? That's another long shot but worth a look anyway.
If none of those suggestions help, you'll have to wait for someone more knowledgable than I to come along, I'm afraid.
Best of luck.
Crashes before main() are usually caused by a bad constructor in a global or static variable.
Looks like the constructor for class Random.
Do you have a global or static variable of type Random? Is it possible that you're trying to construct it before the library it's in has been properly initialized?
Note that the order of construction of global and static variables is not fixed and might change going from debug to release.
Could you be more specific about the error you're receiving? (unhandled exception std::length sounds weird - i've never heard of it)
To my knowledge, FlsGetValue automatically falls back to TLS counterpart if FLS API is not available.
If you're still stuck, take .dmp of your process at the time of crash and post it (use any of the numerous free upload services - and give us a link) (Sounds like a missing feature in SO - source/data file exchange?)

Resources