Virtual Pascal RunTime Error (or no output) if including Printer unit? - pascal

I'm using Virtual Pascal on Windows and have a weird problem whereby if an attempt to Reset() any file that doesn't exist causes the WriteLn() to CRT fail. Example:
{$I+}
program TestIt;
uses Printer; { attempts to open LPT1 as Lst but LPT1 doesn't exist on system }
begin
{ Generates a RunTime Error with $I+ and no output with $I- }
writeln('Test It');
end.
This also fails:
program TestIt;
var
SomeFile : text;
begin
{$I-}
Assign(SomeFile, 'a:\filepath_not_exist');
{ Without $I- the Reset generates a RunTime Error as expected }
Reset(SomeFile);
{$I+}
{ Generates a RunTime Error with $I+ and no output with $I- }
writeln('Test It');
end.
This works as expected:
{$I+}
program TestIt;
begin
writeln('Test It');
end.
Any ideas why this may be happening and how to fix it? Is the source available for WriteLn() or Assign() ? I'm able to change the Printer unit to not Reset() to work around it until needing to get printing working but I don't think failure to open a file should cause the screen output to stop working.

Probably the error state is kept in some variable (which is queried by ioresult) and might cause an error to be raised in the next I/O function. If you don't do automatic error checking ($I+) you must call ioresult after every operation.
Such implementation is not ideal (if errors from the opening using "somefile" spill into a writeln to a second(output) file as happens in the second example), but it happens, specially in older compilers, and specially on targets that are less dos-like.
Also, not existing drive errors are much harder to cache than non existing files. Keep those cases fundamentally apart.
You can test this theory by trying to reset state by querying ioresult just before the action in the hope it resets the state.
Afaik VP is dead for almost a decade now. What you see (read: download) is what you get.

Related

OpenEdge Progress-4GL development: how to know from an error message the procedure I'm running?

As stated in previous questions, I'm quite new at Progress-4GL development.
I've just created a windows (*.w file), together with a procedure file (*.p file), which are based on an include file (*.i file).
I've done something wrong and I get an error message, copy-paste reveals the following:
---------------------------
Fout
---------------------------
** Begin positie voor SUBSTRING, OVERLAY, enz. moet 1 of groter zijn. (82)
---------------------------
OK
---------------------------
As you can see, this is the Dutch translation of error 82:
** Starting position for SUBSTRING, OVERLAY, etc. must be 1 or greater. (82)
The SUBSTRING, OVERLAY, etc, functions require that the start position (second argument) be greater than or equal to 1.
P
I'd like to know which procedure/function is launching this error message. I'm working with the AppBuilder release 11.6 and the corresponding procedure editor, so the debugging possibilities are very limited. One thing I'm thinking of, is taking a dump of the Windows process, in order to determine the call stack, but I'm not sure how to do this. I also tried using Process Explorer and check the stack of the individual stacks of the threads inside the "procwin32.exe" process, but I'm not sure how to proceed.
By the way, I'm regularly adding message boxes to my code, which look as follows (just an example):
MESSAGE "begin procedure combobox-value-changed" VIEW-AS ALERT-BOX.
As you see, the name of the procedure is hardcoded, while in other programming languages (like C++) the procedure/function name can be shown as follows:
OUTPUT("begin procedure %s", __FUNCTION__);
Next to __FUNCTION__, C++ also knows __FILE__ (for filename) and __LINE__ (for line number).
Do such predefined values also exist in Progress 4GL, preferably release 11.6 or previous?
As ABL code is not compiled into Windows byte-code a windows debugger will not be really helpful.
You should start by adding the -debugalert startup parameter to prowin/prowin32.exe. Or add this
ASSIGN SESSION:DEBUG-ALERT = TRUE .
That will add a HELP button to all (error) messages which will open a dialog with the ABL stack trace.
As you'Re using include files, be aware that the line numbers referenced in the stack-trace are based on the debug listing, not the actual source code. So execute
COMPILE myfile.w DEBUG-LIST c:\temp\myfile.debuglist .
to receive the debug-listing file with the correct line numbers.
Are you aware of the visual debugger that's available for the AVM? https://docs.progress.com/de-DE/bundle/openedge-abl-troubleshoot-applications-117/page/Introduction.html
%DLC%\bin\proDebugger.bat
Or the Compile -> Debug menu in the AppBuilder.
It looks a bit antique, but usually does it's job.
Debugging needs to be enabled as an Administrator in proenv:
prodebugenable -enable-all
Of course the grass is greener when you switch to Progress Developer Studio as your IDE.
Regarding the second part of your question. See the PROGRAM-NAME function.
message
program-name(1) skip
program-name(2)
.
Additionally see the {} preprocessor name reference.
message 'file: {&file-name} line: {&line-number}'.

Deallocate Statement Causes Crash

I am working on a code that is crashing. I realized that the compiled program crashes when it is deallocating the variables, but I don't know how to fix it.
When I run the code, a pop-up from Windows appears saying:
main.exe has stopped working.
Windows can check for a solution to the problem.
and the compiler shows the message Process returned -1073740940 (0xC0000374) execution time : 1.171 s
Bellow there is a sample of the code:
Subroutine PoissonCode()
Use Mesh
Implicit none
Real(8), Allocatable :: u(:,:),v(:,:),p(:,:)
Character(50) :: Nome
Allocate(u(0:Imax,0:jmax),v(0:Imax,0:jmax),p(0:Imax,0:jmax),fx(0:Imax,0:jmax),fy(0:Imax,0:jmax))
Allocate(xd(0:Imax),yd(0:Jmax))
........Code Here...............
Deallocate(u,v,p,fx,fy,xd,yd)
Deallocate(xd,yd)
End Subroutine PoissonCode
I put the complete code here for further investigation.
I also tried to run the code with different versions of GFortran in Windows 7 x64 and Windows XP x86 with no success.
Edit:
The correct end of the code is:
...
Deallocate(u,v,p,fx,fy)
Deallocate(xd,yd)
End Subroutine PoissonCode
Up date:
I tested the code with a different compiler (Intel Visual Fortran) and still no success.
D'uhhhh (to all of us)
Deallocate(u,v,p,fx,fy,xd,yd)
Deallocate(xd,yd)
In the second line your program (attempts to) deallocate variables already deallocated in the first line. I suppose that sometimes it pays to read code posted.
deallocate has optional arguments stat and errmsg which can be used to catch this sort of mistake and provide an alternative to the default behaviour which is for the program to crash.

Pascal WriteLn failing

I'm working on small project in Pascal for school.
I'm using Lazaruz 1.0.2
I have problem with wirteLn function when writing to file.
After some time it just stops writing to file.
Take for example this program:
var oFile: Text;
i: LongWord;
begin
Assign(oFile, 'test.txt');
ReWrite(oFile);
for i:=1 to 4096 do
WriteLn(oFile, 'ThisIsTest');
CloseFile(oFile);//Added as suggested
end.
This is output:
...
4072 ThisIsTest
4073 ThisIsTest
4074 ThisIsTest
4075 ThisIsTe
As you can see it just stops at the middle of sentence and it is not writing all.
All depends on how long is one WriteLn insturction and how many times it is called.
How to fix it?
I tried to use WinApi function from "Windows" module called WriteFile but I failed to pass last 3 arguments to it.
BIG UPDATE
Thanks. That works (Closing file) in that example. But I have little bit more complex program where I'm passing opened file handle to functions that are writing to it via "var". And even after closing that file at the and does nothing. It is strange.
You should Close(oFile) at the end of your program to be sure the output is flushed.
It's also possible to update a file without closing it by adding (in this example)
Flush(oFile);
after a Writeln
This is useful where you might have a long file and want to make sure it's updated regularly. Of course, you should still close the file when finished.

Is it possible to install custom unhandled exception handler while debugging in VS 2008/2010?

I'm working on an utility that processes very large data sets. Since there are lots of code it uses to operate, some totally unexpected errors appear while running. So I run it inside Visual Studio debugging session. In most cases I can skip an error or recover from it using immediate window and some manipulation with "Set next statement". But this error can reoccur in future. Is it possible to automatize recovering process without restarting debugging session?
Depending on the structure of your code and the language you are using you may be able to do something similar with Conditional Breakpoint abuse.
The idea is to use the Breakpoint condition to do an evaluation, basically an automated way of doing what you do in the immediate window.
int c = a + b; // some type of calculation
if (c == 5) // your test
{
// ERROR
return;
}
E.g. If you know the test c==5 is what is going wrong you can place a Conditional Breakpoint at that line:
if (c == 5) // your test
With the expression of some correct value:
c = 1
And then you won't go down the error condition path. Of course this doesn't always work, but can be useful in come circumstances.

Problem with .release behavior in file_operations

I'm dealing with a problem in a kernel module that get data from userspace using a /proc entry.
I set open/write/release entries for my own defined /proc entry, and manage well to use it to get data from userspace.
I handle errors in open/write functions well, and they are visible to user as open/fopen or write/fwrite/fprintf errors.
But some of the errors can only be checked at close (because it's the time all the data is available). In these cases I return something different than 0, which I supposed to be in some way the value 'close' or 'fclose' will return to user.
But whatever the value I return my close behave like if all is fine.
To be sure I replaced all the release() code by a simple 'return(-1);' and wrote a program that open/write/close the /proc entry, and prints the close return value (and the errno). It always return '0' whatever the value I give.
Behavior is the same with 'fclose', or by using shell mechanism (echo "..." >/proc/my/entry).
Any clue about this strange behavior that is not the one claimed in many tutorials I found?
BTW I'm using RHEL5 kernel (2.6.18, redhat modified), on a 64bit system.
Thanks.
Regards,
Yannick
The release() isn't allowed to cause the close() to fail.
You could require your userspace programs to call fsync() on the file descriptor before close(), if they want to find out about all possible errors; then implement your final error checking in the fsync() handler.

Resources