How to really trap all errors with $etrap in Intersystems Caché? - error-handling

I've been banging my head a lot because of this. In the way that $etrap (error handling special variable) was conceived you must be careful to really trap all errors. I've been partially successful in doing this. But I'm still missing something, because when run in user mode (application mode) there are internal Cache library errors that are still halting the application.
What I did was:
ProcessX(var)
set sc=$$ProcessXProtected(var)
w !,"after routine call"
quit sc
ProcessXProtected(var)
new $etrap
;This stops Cache from processing the error before this context. Code
; will resume at the line [w !,"after routine call"] above
set $etrap="set $ECODE = """" quit:$quit 0 quit"
set sc=1
set sc=$$ProcessHelper(var)
quit sc
ProcessHelper(var)
new $etrap
; this code tells Cache to keep unwindind error handling context up
; to the previous error handling.
set $etrap="quit:$quit 0 quit"
do AnyStuff^Anyplace(var)
quit 1
AnyStuffFoo(var)
; Call anything, which might in turn call many sub routines
; The important point is that we don't know how many contexts
; will be created from now on. So we must trap all errors, in any
; case.
;Call internal Cache library
quit
After all this, I can see that when I call the program from a prompt it works! But when I call from Cache Terminal Script (application mode, I was told) it fails and aborts the program (the error trapping mechanism doesn't work as expected).

Is is possible that an old-style error trap ($ZTRAP) is being set only in Usermode?
The documentation on this is pretty good, so I won't repeat it all here, but a key point is that $ZTRAP isn't New-ed in the same way as $ETRAP. In a way, it is "implicitly new-ed", in that its value only applies to the current stack level and subsequent calls. It reverts to any previous value once you Quit up past the level it was set in.
Also, I'm not sure if there's a defined order of precedence between $ETRAP and $ZTRAP handlers, but if $ZTRAP is of higher precedence, that would override your $ETRAPs.
You could try setting $ZTRAP yourself right before you call the library function. Set it to something different than $ETRAP so you can be sure which one was triggered.
Even that might not help though. If $ZTRAP is being set within the library function, the new value will be in effect, so this won't make a difference. This would only help you if the value of $ZTRAP came from somewhere further up the stack.
You didn't mention what library function caused this. My company has source code for some library functions, so if you can tell me the function name I'll see what I can find. Please give me the value of $ZVersion too so I can be sure we're talking about the same version of Cache.

Related

How does an interpreter resolve function calls or branch(jump) statement?

I know the question seems a bit broad. I tried searching for answers, couldn't find much.If anyone could describe or point me to the right source.
Assuming a bytecode-based interpreter, the usual way to do this would be as follows:
You have a variable, the program counter, which tells you the index of the instruction to execute. Usually you increase that counter by 1, but when executing a branch, you instead set it to the target location of the jump.
For function calls you do the same thing, but you also push the old value of the counter plus one onto the call stack. Then when you execute the return instruction, you pop the value of the stack and set the counter to that.

Time breaks between methods vb .net

I have written a process in vb.net, that writes multiple text files based on SQL queries. I would like to put a "time break" after or before each method to slow down the process. Maybe just like a minute or two. I feel as this might be the solution for the problem I'm having with the last method(text file). Ever once and awhile I will get an exception that says: "EXCEPTION CAPTURED: The process cannot access the file 'D:\ORG.TXT' because it is being used by another process.". My thinking is that the other methods might somehow be blocking this one from running. If anyone feels there might be a better solution let me know.
System.Threading.Thread.Sleep()
However, you could also build a recursive method that tries to access the file, and if it can't, sleeps then tries again. You would need to stop it at some point so it doesn't go on and on forever.
(Psuedocode)
If trythefile()
do stuff with the file
Else
fail
End If
function trythefile()
try
attempts + 1
access the file
return true
catch
sleep for a bit
If attempts < 10
trythefile()
Else
return false
End if
end function

Creating robust real-time monitors for variables

We can create a real-time monitor for a variable like this:
CreatePalette#Panel#Row[{"x = ", Dynamic[x]}]
(This is more interesting and useful if x happens to be something like $Assumptions. It's so easy to set a value and then forget about it.)
Unfortunately this stops working if the kernel is re-launched (Quit[], then evaluate something). The palette won't show changes in the value of x any more.
Is there a way to do this so it keeps working even across kernel sessions? I find myself restarting the kernel quite often. (If the resulting palette causes the kernel to be automatically started after Quit that's fine.)
Update: As mentioned in the comments, it turns out that the palette ceases working only if we quit by evaluating Quit[]. When using Evaluation -> Quit Kernel -> Local, it will keep working.
Link to same question on MathGroup.
I can only guess, because on my Ubuntu here the situations seems buggy. The trick with the Quit from the menu like Leonid suggested did not work here. Another one is: on a fresh Mathematica session with only one notebook open:
Dynamic[x]
x = 1
Dynamic[x]
x = 2
gives as expected
2
1
2
2
Typing in the next line Quit, evaluating and typing then x=3 updates only the first of the Dynamic[x].
Nevertheless, have you checked the command
Internal`GetTrackedSymbols[]
This gives not only the tracked symbols but additionally some kind of ID where the dynamic content belongs. If you can find out, what exactly these numbers are and investigate in the other functions you find in the Internal context, you may be able to add your palette Dynamic-content manually after restarting the kernel.
I thought I had something like that with
Internal`SetValueTrackExtra
but I'm currently not able to reproduce the behavior.
#halirutan's answer jarred my memory...
Have you ever come across: Experimental/ref/ValueFunction? (documentation address)
Although the documentation contains no examples, the 'more information' section provides the following tidbit:
The assignment ValueFunction[symb] = f specifies that whenever
symb gets a new value val, the expression f[symb,val] should be
evaluated.

set a breakpoint, when called: return and continue

I know how to do this in gdb. I'd attach, and follow with:
break myfunction
commands
return
cont
end
cont
I'm wondering if there's a way of doing this in c? I already have my code working for reading memory addresses and writing to memory addresses. And it automatically finds the pid and does related stuff. I'm stuck with implementing that use of breakpoints.
If you are talking about some sort of hand-written debugger, you can use IP value to set a breakpoint; Literally, when IP hits some certain value, you stop the program being debugged and perform some routine (for example, heading away to debugger process). To use function names, you should use symbol tables like it is done in GDB.
It's not quite clear what you are trying to achieve.
The GDB sequence you've show will simply make myfunction immediately return.
Assuming you want your mini-debugger to have the same effect, simply write the opcode for ret (0xC3 on x86) to the address of myfunction; no need to do the breakpoint at all.

Is using fflush(stdout) as fprintf() argument safe?

To I came upon this line of code:
fprintf(stdout, "message", fflush(stdout));
Note that the message does not contain any %-tag.
Is that safe in visual c++? fflush() returns 0 on success and EOF on failure. What will fprintf() do with this extra parameter?
I first thought that this was a strange hack to add a fflush() call without needing an extra line. But written like this, the fflush() call will be executed before the fprintf() call so it does not flush the message being printed right now but the ones waiting to be flushed, if any... am I right?
It's safe. Here's what C (C99 atleast, paragraph
7.19.6.1) says about it
If the format is exhausted while
arguments remain, the excess arguments
shall be evaluated but are otherwise
ignored.
If the goal was to avoid a line, i'd rather do
fflush(stdout); fprintf(stdout, "message");
if for nothing else than to prevent the person later reading that code to hunt me down with a bat.
fprintf doesn't know the exact number of parameters, it only tries to load one argument per '%'. If you provide less arguments than '%', it results in undefined behavior, if you provide more arguments, they are ignored.
Ad second question, yes, this would only flush messages in queue, the new message won't be flushed.
I think fprintf is using varargs to process parameters, so any extra parameters should be safely ignored (not that it's a good practice or anything). And you are right that fflush will be called before fprintf, so this is kind of a pointless hack.
With enough warning flags enabled (like -Wall for gcc) you will get a warning