I'm trying to find a way to initiate the stack trace window that you can access of a message-box when you have the debugging enabled. Is this feasible? Also is there a good way to grab the stack trace aside from traversing the executing programs tree?
Yes if you use structured error handling.
The Progress.Lang.Error interface has a CallStack property that returns the stack trace contents. You need to set the -errorstack session startup parameter (or SESSION:ERROR-STACK-TRACE).
AFAIK, the only way is to set SESSION:DEBUG-ALERT = true (or -debugalert) and MESSAGE VIEW-AS .
You can get a stack track using structured error handling (enable via SESSION:ERROR-STACK-TRACE or -errorstack). You would have to throw something in order to query the CallStack property on a P.L.Error.
-- peter
AFAIK there's only the travering of the PROGRAM-NAME function and throwing an error that you catch yourself for this sole purpose.
I assume you don't need the stack too often, so that should be acceptable - even though far from perfect.
I actually need a snapshot of the stack-trace at any given time. The MESSAGE ... VIEW-AS can access the stack-trace anytime and not just when there is an error or exception, so I am wondering if that information is accessible from somewhere.
I'm trying to display an on-demand stack-trace infromation not just when there is an error or exception.
I'm trying to display an on-demand stack-trace infromation not just when there is an error or exception.
Understood - but why don't you throw an error just to catch it yourself?
You'd need to add code to trigger the event, right? So whether it was a MESSAGE statement or a THROW doesn't really matter. You could do a small, localised error with the express purpose of getting the call stack. Yes, this is a horrible abuse of an error/exception, but I'm not sure there are alternatives. I don't believe that the stack trace is accessible otherwise, except via something like:
iLoop = 1.
DO WHILE PROGRAM-NAME(iLoop) NE ?:
/* whatever */ PUT UNFORMATTED PROGRAM-NAME(iLoop) SKIP.
iLoop = iLoop + 1.
END.
Is this missing something (data-wise) that the MESSAGE dialog's stack has?
-- peter
Put this pseudo-property in a class, e.g. Consultingwerk.Util.SessionHelper.
/*------------------------------------------------------------------------------
Purpose: Returns the current ABL stack trace
Notes:
------------------------------------------------------------------------------*/
DEFINE PUBLIC STATIC PROPERTY CurrentStacktrace AS CHARACTER NO-UNDO
GET():
DEFINE VARIABLE cStacktrace AS CHARACTER NO-UNDO.
DEFINE VARIABLE lCurrentErrorStack AS LOGICAL NO-UNDO.
DEFINE VARIABLE iIndex AS INTEGER NO-UNDO.
ASSIGN lCurrentErrorStack = SESSION:ERROR-STACK-TRACE
SESSION:ERROR-STACK-TRACE = TRUE .
DO ON ERROR UNDO, THROW:
UNDO, THROW NEW AppError () .
CATCH err AS Progress.Lang.Error:
ASSIGN cStacktrace = err:CallStack .
END CATCH.
END.
ASSIGN iIndex = R-INDEX (cStacktrace, CHR (10)) .
IF iIndex > 1 THEN
ASSIGN cStacktrace = SUBSTRING (cStacktrace, 1, iIndex - 1) .
RETURN cStacktrace .
FINALLY:
ASSIGN SESSION:ERROR-STACK-TRACE = lCurrentErrorStack .
END FINALLY.
END GET.
And then try this anywhere you need to:
MESSAGE "You are here:" SKIP Consultingwerk.Util.SessionHelper:CurrentStacktrace VIEW-AS ALERT-BOX.
That's fine I guess. How about displaying the stak-trace window that you can view from the message-box, can you call it as standalone window?
That's fine I guess. How about displaying the stak-trace window that you can view from the message-box, can you call it as standalone window?
No.