Index
Initialization
of insiderTools
Fatal errors API
Extended
callstack API
Extended
Memory Information
Xbase++ Inspector API
Initialization of insiderTools
InsiderTools
do not need any initialization. If you want to handle fatal errors,
insert this line somewhere in your program's start-up:
insider():installHandlers() |
This will
install extended handlers for fatal
errors.
Fatal
Errors API
This
API extend
Xbase++ fatal error handling to strong professional level. Unlike almost
uninformative native xppfatal.log,
we log all possible information. more>
::installHandlers()
initializes
extended fatal error handling.
::setErrorPath(pathName) ->
oldPath
set up
path for storing fatal errors. By default, directory
with main .exe file.
::setErrorName(fileName) ->
oldName
set up
name for fatal error file. By default, "xppCrash.log"
Extended
Callstack API
::procParamA(nCallStack,nThreadId)
-> paramsArr
get parameters
of an function on call stack as array
::procParam(nCallStack,nIndex,nThreadId)
-> paramValue
get individual
parameter of an function on call stack
::procParamCount(nCallStack,nThreadId)
-> numParams
get number
of parameters of an function on call stack
::procBlock(nCallStack,nThreadId)
-> codeblock|NIL
get codeblock
for an codeblock call on call
stack
::procObject(nCallStack,nThreadId)
-> object|NIL
get object
for of an method call on call stack
example
of dump
callstack |
Local
i
Local args
Local block
Local object
//this loop is part of original Alaska's ErrorSys.prg
i
:= nStackStart
DO WHILE ! Empty( ProcName(++i) )
? EHS_CALLED_FROM, Trim( ProcName(i) ) + "(" +
;
LTrim( Str( ProcLine(i) ) ) + ")"
//add this lines to show additional info
//about current callstack entry
args:=
insider():procParamA(i)
block:=
insider():procBlock(i)
object:=
insider():procObject(i)
If block!=NIL
?" block="+Var2Char(block)
End
If object!=NIL
?" object="+Var2Char(object)
End
If Len(args)>0
?" args="+Var2Char(args)
End
ENDDO
?
|
Extended
Memory Information (XppMemoryInfo class)
Xbase++
is object-oriented, non strongtyped, multithreaded language. This
complexity produced times more complexity on realization level. Xbase++
internally have a lot of tables and structures for different memory
usages.
We try to
sort all known for us undocumented structures and pointers and collect
most interesting info to special class XppMemoryInfo().
To
guarantee proper values in related variables of this class, all info
collected in atomic (snapshot) way.
To get current
memory information call insider():getMemorySnapshot(). This
call return XppMemoryInfo object.
All variables
grouped by level.
Xbase++ level ivars of XppMemoryInfo
::varStat
statistic
of used variables, grouped by types and access. This array holds
arrays of two elements represented statistic by an type. First element
is number of alloced variables of this type and second is number
of references to variables of this type.
|
example |
|
//print
usage of types
types:="ABCDLMNOU"
With insider():getMemorySnapshot()
a:=:::varStat
For i:=1 To Len(types)
?types[i]+"=",a[i,1],"
(+",a[i,2],"refs)"
Next
EndWith |
::objects
contains
list of all used objects with class names and counts.
|
example |
|
//print
used objects
With insider():getMemorySnapshot()
a:=:::objects
For i:=1 To Len(a)
?"name=",a[i,1],"
count=",a[i,2]
Next
EndWith |
::variables
contains
number of alloced Xbase++ variables. NOTE: references not counted.
::inArrays
inside
Xbase++, arrays holds its values away from garbage collector. This
ivar is sum of sizes of all used arrays.
::inObjects
like arrays,
objects holds values of its ivars away from garbage collector. This
ivar is sum of number of ivars of all used objects.
Core
level ivars of XppMemoryInfo
::allocedMemory
total
size (include free space) of momHandles table. This table holds all
values of all variables. To calculate size of used memory, substract
::freeMemory from this ivar.
::freeMemory
size of
free memory of momHandles table.
::totalMomObjs
total
count of momObjs, special structures handled by garbage collector.
In most cases, one momObj represent reference to one Xbase++ level
variable. Unlike momHandle structures, momObjs is not relocable.
When you call _con*() C-Api function, ContainerHandle points to an
momObj structure.
::freeMomObjs
number
of free momObjs, special structures handled by garbage
collector. In most cases, one momObj represent reference to one Xbase++
level variable.
Other,
non XppMemoryInfo functions
insider():getVarRefs(var) ->
nRefCount
Returns
number of references to checked
var. This call valid only for arrays or objects.
|
example |
|
//test
number of references of arr
arr:={1}
holdArr:={arr,arr,arr}
? insider():getVarRefs(arr)
//prints 4, i.e. arr self
//plus 3 refs in holdArr |
insider():getVarId(var) ->
nVarId
Returns
an ID, unique for checked array, object, codeblock or string. This info useful for logging or other cases when need to distinguish the objects of same class or arrays with similar values.
Xbase++ Inspector API
Xbase++
Inspector is powerful tool for inspecting Xbase++ application.
UI part of Inspector described here.
To initialize Xbase++ Inspector insert following somewhere at application start-up:
insider():installInspector() |
insider():setInspectorHotkey(shiftF,ctrlF,altF,key)
Set up hot-key used to pop-up Inspector window. ShiftF, ctrlF and altF are logical values and key is some Windows API VK_??? constant or char.
|
example |
|
//set up Ctrl-Alt-V for hotkey
insider():setInspectorHotkey(.F.,.T.,.T.,"V")
#define VK_TAB 0x09
//set up Ctrl-Shift-Tab for hotkey
insider():setInspectorHotkey(.T.,.F.,.T.,VK_TAB)
|
insider():threadEval(block|blocksA,threadId|threadO) ->
result|resultsA
This call allow to run code in any running Xbase++ thread. The first parameter can be codeblock or array of codeblocks. Second parameter can be numeric thread id or thread object of target thread.
The return value of ::threadEval() is array of result and elapsed time in seconds. If array of blocks is used, the return value is array of arrays for every block. If evaluated block raise an error, the result and time array will be replaced by error object.
|
example |
|
//eval single block in 3rd thread
insider():threadEval({|| dbCloseAll()},3)
//ret is: {NIL,0.045}
//eval two blocks in 1st thread
insider():threadEval({{|| 2+2},{|| 2*2},1)
//ret is: {{4,0.00},{4,0.00}}
//eval two blocks (with bug) in 1st thread
insider():threadEval({{|| 2+2},{|| 2/Time()},1)
//ret is: {{4,0.00},ErrorObject}
|
©2006
Eleus Software
|