The purpose of this document is to explain in high level, some memory issues encountered in running standard business functions through the CallObject Kernel in EnterpriseOne. This document includes case studies and resolutions on certain memory issues. This document is not intended to cover specific definition on memory errors or how to detect memory problems.
This document is intended to help internal JDE developer on what to check when hitting memory errors in EnterpriseOne and how to apply possible fix for these errors while working on reported bug. But information in this document maybe helpful for developing custom business function.
The audience for this document is someone with expert 'C' Programming Language development knowledge. This document only contains examples. It is not meant to be all encompassing. Also see the second document in this series document 1554611 Case Study on Memory Violation, Memory Corruption, Memory Overwrite, ACCESS VIOLATION and Zombie Kernel Caused by Standard Business Functions Part 2.
This document does not cover any memory corruption issues caused by the Tools Foundation Layer which is usually fixed through tools release upgrade. This document mainly focuses on memory errors caused by standard business functions which results in CallObject Kernels to crash or runbatch application to fail.
Caution: This document may contain information, software, products or services which are not supported by Oracle Support Services and are being provided ‘as is’ without warranty. Please refer to the following site for My Oracle Support Terms of Use: https://support.oracle.com/CSP/ui/TermsOfUse.html. For custom business function, field services may need to be engaged.
In running EnterpriseOne applications, memory error may occur in 3 different locations,
In this document, we will be focusing on memory errors in the register memory on the logic server. We will concentrate on C programming or Business Functions in EnterpriseOne.
In EnterpriseOne, memory can be represented as data structure, cache, handles (or pointers), cursor, data pointer and so on. Additionally, this document explains some case studies based on ill-treatment of memory in EnterpriseOne Business Functions. Since C's pointers give great possibility on memory manipulation, in return which may cause some memory problem. Memory corruption in client machine may cause service or application getting terminated.
For easier reading, we shall categorize memory error into Memory Leak and Memory corruption,
Note:
Memory leak takes place when allocated memory is not released/terminated/killed/flushed/deleted. Reducing the available memory for other applications and eventually causing the system to page virtual memory to the hard drive slowing the application or crashing the application when the computer memory resource limits are reached. The system may stop working as these limits are reached. From Tools Release 8.97 onwards, Kernel Recycling will happen when it is not executing any BSFN for a certain amount of time.
This is implemented only for Call Object kernels. In EnterpriseOne (CallObject) Kernel Recycling can free leaked memory.
Un-paired API calling
For further detail, please refer to the "JD Edwards EnterpriseOne Tools 9.1 Development Tools: APIs and Business Functions Guide".
Database APIs (Understanding Database Communication Steps)
Several APIs called in succession can perform these steps for database communication:
This table lists some of the API levels and the communication handles and API names that are associated with them:
API Name | Communication Handles | API Level |
---|---|---|
JDB_InitEnv | Environment handle | Control level (application) |
JDB_InitUser | User handle (created) | Control level (application) |
JDB_InitBhvr | User handle (retrieved) | Request level (business function) |
JDB_OpenTable | Request handle | Request level (business function) |
JDB_FetchKeyed() | Request handle | Request level (business function) |
JDB_CloseTable | Request handle | Request level (business function) |
JDB_FreeBhvr | User handle | Request level (business function) |
JDB_FreeUser | User handle | Control level (application) |
JDB_FreeEnv | Environment handle | Control level (application) |
JDECACHE and JDECACHE APIs
JDECACHE Manipulation APIs
Calling JDECACHE APIs
API Calling | Explanation |
---|---|
1. Call JDB_InitBhvr | Each cache must be associated with a user, you must also pass the user handle obtained from the call to JDB_InitUser. This API returns an HCACHE handle to the cache that JDECACHE creates. This handle appears in every subsequent JDECACHE API to identify the cache.
|
2. Create index or indices | |
3. Call jdeCacheInit, jdeCacheInitEx, jdeCacheInitMultipleIndex, or jdeCacheInitMultipleIndexEx. | The jdeCacheInit and jdeCacheInitMultipleIndex APIs initialize the cache uniquely per user. Therefore, if a user logs in to the software and then runs two sessions of the same application simultaneously, the two application sessions will share the same cache. Consequently, if the first application deletes a record from the cache, the second application cannot access the record. Conversely, if two users log in to the software and then run the same application simultaneously, the two application sessions have different caches. Consequently, if the first application deletes a record from its cache, the second application will still be able to access the record in its own cache. The jdeCacheInitEx and jdeCacheInitMultipleIndexEx APIs function exactly the same, but they additionally enable you to define the maximum number of cursors that can be opened by the cache. The jdeCacheInitUser and jdeCacheInitMultipleIndexUser APIs initialize the cache uniquely per application. Therefore, if a user logs in to the software and then runs two sessions of the same application simultaneously, the two application sessions will have different caches. Consequently, if the first application deletes a record from its cache, the second application can still access the record in its own cache. |
4. Call jdeCacheAdd | |
5. Call jdeCacheOpenCursor | a JDECACHE cursor is a pointer to a record in a users cache |
6. Call JDECACHE Operations | JDECACHE operation APIs can be called any order |
Mainpulation of Cache: jdeCacheOpenCursor, jdeCacheResetCursor, jdeCacheAdd, jdeCacheFetch, jdeCacheFetchPosition, jdeCacheUpdate, jdeCacheDelete, jdeCacheDeleteAll, jdeCacheCloseCursor, jdeCacheFetchPositionByRef, jdeCacheSetIndex, jdeCacheGetIndex etc. | |
jdeCacheTerminate | For every jdeCacheInit, jdeCacheInitEx, jdeCacheInitMultipleIndex, or jdeCacheInitMultipleIndexEx, a corresponding jdeCacheTerminate must exist, except instances in which the same cache is used across business functions or forms. In this case, all unterminated jdeCacheInit, jdeCacheInitEx, jdeCacheInitMultipleIndex, or jdeCacheInitMultipleIndexEx calls must be terminated with a jdeCacheTerminateAll. A jdeCacheTerminate call terminates the most recent corresponding jdeCacheInit or jdeCacheInitEx. This means that the same cache can be used in nested business functions. In each function, perform a jdeCacheInit or jdeCacheInitEx or jdeCacheInitEx that passes the cache name. Before exiting that function, call jdeCacheTerminate. This does not destroy the cache. Instead, it destroys the association between the cache and the passed HCACHE handle. The cache is completely destroyed from memory only when the number of jdeCacheTerminate calls matches the number of jdeCacheInit or jdeCacheInitEx calls. In contrast, one call to jdeCacheTerminateAll destroys the cache from memory regardless of the number of jdeCacheInit, jdeCacheInitEx, jdeCacheInitMultipleIndex, or jdeCacheInitMultipleIndexEx calls or jdeCacheTerminate calls |
Memory Corruption can occur when :
For further detail, please refer to the "JD Edwards EnterpriseOne Tools 9.1 Development Tools: APIs and Business Functions Guide" (Link JD Edwards EnterpriseOne Documentation)
According to industry terms , memory corruption can be categorized as follows:
Cause | Explanation | Example | Resolution | Others |
---|---|---|---|---|
Memory is not initialized | Contents of uninitialized memory are treated as garbage values. Using such values can lead to unpredictable program behavior. | Refer to components for c Source file below. Initializations (of variables) |
Correct code. | |
Memory belongs to different process | It is common to use pointers to access and modify memory. If such a pointer is a null pointer, dangling pointer (pointing to memory that has already been freed), or to a memory location outside of current stack or heap bounds, it is referring to memory that is not then possessed by the program. Using such pointers is a serious programming flaw. Accessing such memory usually causes operating system exceptions, also termed page faults, which most commonly lead to a program crash. | Since EnterpriseOne CallObject Kernel is running in multi-thread so it is rare to have this type of issue. | Move global variables to parameter of calling/called business functions | This definition is more for C/C++ language in general rather than EnterpriseOne. In EnterpriseOne most of business function holds general information as parameters which minimize the usage of Globals. |
(Memory) Buffer Over flow (Using beyond allocated Memory) | If an array is used in a loop, with incorrect terminating condition, memory beyond the array bounds may be manipulated. Buffer overflow is one of the most common programming flaws exploited by computer viruses causing serious computer security issues (e.g. return-to-libc attack, stack-smashing protection) in widely used programs. One can also incorrectly access the memory before the beginning of a buffer. | This issue can come in a single string (which is character array) in stripping a certain character. Or in running R3483 the allocated memory is far smaller than cache to be created. | Allocate correct size of array. | Or buffer overrun |
Incorrect Heap Memory Management | Memory leaks and freeing non-heap or un-allocated memory are the most frequent errors caused by faulty heap memory management | Refer to heap and stack section. Usually resulted in ACCESS VIOLATION | N/A | Refer to http://msdn.microsoft.com/en-us/library/ms810603.aspx |
Typical Business Function components in EnterpriseOne
For example (B4200310.c),
JDEBFRTN(ID) JDEBFWINAPI F4211FSBeginDoc(LPBHVRCOM lpBhvrCom, LPVOID lpVoid, LPDSD4200310H lpDS)
{
:
:
}
Above statement can be understood F4211FSBeginDoc is Windows API which can be called directly from application and returns (ID - pointer) with 3 parameters. All business functions share the same return type and parameter data types. Only the function name and the data structure number vary between business functions.
Component | Where created (repository) |
Detail |
---|---|---|
Business Function Specification | OMW - Business Function Design (Central Object in Database Server) |
F98762 - JDEBLC - Behavior Information JDEBLC |
Data Structure Specifications | OMW - Data Structure Design (Central Object in Database Server) |
F98743 - Data Structure Templates DSTMPL |
.H File | Generated in Business Function Design Modified with the IDE (Deployment Server) |
Header File Comment Table Header Inclusions External Business Function Header Inclusions Global Definitions Structure Type Definition DS Template Type Definition Source Preprocessor Business Function Prototype Internal Function Prototype |
.C File | Generated in Business Function Design Modified with the IDE (Deployment Server) |
Refer below "Components for Source File" |
components | Usage | Example |
---|---|---|
Variable declarations | (via IDE) Declares variables that are local to the business function | ID idReturnValue = ER_SUCCESS; |
Declare structures (Optional) | (IDE) Declares local data structures to communicate between business functions, internal functions, and the database. | |
Declare Pointers | (IDE) declare pointers | |
Check for NULL pointers | (Business Function Standard) Verifies that all communication structures between an application and the business function are valid | (lpBhvrCom == (LPBHVRCOM) NULL) || (lpDS == (LPDSD4200310H) NULL)) |
Set Pointers | (IDE) Declares and assigns appropriate values to pointers | |
Initialize Behavior Routine | ||
Initializations (of variables) | ||
Initialize Data Structures | Allocate memory for declared structure above. | |
Initialize Behavior Routine | JDB_InitBhvr(lpBhvrCom, &hUser,(JCHAR *) NULL, JDEDB_COMMIT_AUTO); | |
Set Up Cache Index Keys | This routine can come after or before main | |
Main Processing | jdeCallObject(), CALLIBFRET(), CALLBF() (IDE) Provides main functionality for a business function In C standard main() is to be handled here |
|
Function Clean Up | (IDE) Frees any dynamically allocated memory |
Memory Initialization
In a certain compiler it may write Warning Message C6001: Using uninitialized memory <variable>
Global Variables (Memory belongs to other process)
Since EnterpriseOne CallObject Kernel can be running in multi-threaded CallObject Kernel Process. So it is very unlikely to have this type of issue in the EnterpriseOne release you are working on. For detail refer to <Document 748330.1> Multithreaded Kernels.
Currently business functions in EnterpriseOne are threadsafe (that is, can safely share a kernel with other business functions). In general, to make your business functions threadsafe, you must remove global and static variables, as
well as references to non-threadsafe APIs.
Buffer overflow
Buffer overrun or buffer overwrite can be used to explain this terms.
C6386: Buffer overrun accessing <buffer>, the writable size is <write-size>, but <write-index> bytes may be written
Incorrect Heap Manager
JDEdwards EnterprisneOne do not have control over Heap manager. Refer to your vendor for detail because this is very much operating system dependent. Some external reference:-
Heap Memory Error and Stack Memory Error:
Cause of Heap memory errors and Stack memory errors,
Refer to the following sections in the JD Edwards EnterpriseOne Tools Server and Workstation Administration Guide Release 9.1 (HTML Link: http://docs.oracle.com/cd/E24705_01/doc.91/e24259/toc.htm , PDF Link: http://docs.oracle.com/cd/E24705_01/doc.91/e24259.pdf)
The JD Edwards EnterpriseOne kernel architecture is divided into the C business function layer and the tools foundation layer. This architecture is susceptible to the intrinsic memory manipulation weaknesses in the C programming paradigm of memory leaks and corruption. This can lead to crashed CallObject kernels and runbatch processes which directly result in failed business transactions, loss of productivity and downtime usually requiring an excessive amount of time to troubleshoot and correct.
In addition, the kernel and batch processes utilize resources and place demands on memory and the CPU and execute in the context of other processes that also demand memory and CPU resources. Each process has its own level of impact on the system, and the cumulative effect of all processes currently running will impact performance. Appropriate data can be captured and used with measurement tools to evaluate overall performance as well as the impact of individual processes. When utilization or performance exceeds certain thresholds, it is critical to have tools that can diagnose which process is creating the resource overload in order to correct the problem and restore the performance to normal levels before the system crashes.
A new administration tool called Kernel Resource Management (KRM) has been added to Server Manager to enable you to increase system stability and simplify the troubleshooting process. Graphs allow you to quickly identify processes with high resource consumption and recycling allows the ability to reclaim system resources.
New tools allow the JD Edwards EnterpriseOne development and QE processes to identify and resolve resource consumption defects prior to RTM. KRM enables you to monitor kernel and batch processes and to diagnose CPU and memory usage issues.
Refer to part 2 of this document: <Document 1554611.1> E1: BSFN: Case Study on Memory Violation, Memory Corruption, Memory Overwrite, ACCESS VIOLATION and Zombie Kernel Troubleshooting.
Memory Violation message in PDF or JDEDEBUG.log shall not reflect actual offending business function. Because Memory Violation message in PDF is to be written by UBE Kernel, which reads and process line by line based on event rule as a result it only indicates the first level business function (which is called by report). So if a certain UBE is calling any business function through UBE Kernel, which is waiting for called business function to return. If it fails, then Memory Violation Message is to be written in PDF. For this reason if you turn on UBE log, same message can be retrieved. For this case, it is very important for you to capture both UBE kernel log and CallObject Kernel log by setting tracing (which records callobject process) and UBE Logging Level 6.
As we have describe above, Memory Violation can be understood as violating memory safety which in turn returns unexpected result. So you need to resolve this message to guarantee the result you are getting is correct and valid.
Unlike interactive application, transaction volume in a certain batch may affect result so verify that whether there is any memory leak. If so, resolve memory leak first to move on to memory corruption. Most of time, memory leak and memory corruption can be related in batch.
For detail, Refer to part 2 of this document: <Document 1554611.1> E1: BSFN: Case Study on Memory Violation, Memory Corruption, Memory Overwrite, ACCESS VIOLATION and Zombie Kernel Troubleshooting.
Most commonly un-faired JDB API can cause this issue which failed to disconnect from database. But if a certain application is closed properly (either through UBE Kernel for batch job or JAS for interactive application) jdeFreeEnvBSFN will detect and determine all the memory leak and open connection. If any, this same routine will handle this type of memory leak.
For further detail, refer to JDB_FreeEnv() section
This section is to show correct coding in "Function Clean Up" section of C Source Codes. Our case study shows that most commonly ACCESS VIOLATION is caused by below routines. But it is not madatory to check whether handle, pointer, data pointer and so on is NULL before calling Free(). So you may need to approach it case by case basis.
Source code | Actual Implemenation | Considerations |
---|---|---|
B4200310.c | Example 1: if (hRequestF4211 != (HREQUEST)NULL) { JDB_CloseTable(hRequestF4211); } |
|
Example 2: if (hUser != (HUSER)NULL) { JDB_FreeBhvr(hUser); hUser = (HUSER)NULL; } |
||
XT4314Z2 | Example 1 if ((dsGetPODetail.idPointerToF4311DataStructure != (ID) 0) && (lpdsF4311Detail != (LPF4311) NULL) ) { lpdsF4311Detail = jdeRemoveDataPtr(hUser, (unsigned long) dsGetPODetail.idPointerToF4311DataStructure ); if (lpdsF4311Detail != (LPF4311) NULL) { jdeFree( (void*) lpdsF4311Detail); } lpdsF4311Detail= (LPF4311) NULL; dsGetPODetail.idPointerToF4311DataStructure = (ID) 0; } |
|
Example 2: Free pointer to the F43121 Data Structure if ( dsGetPOReceipt.idPointerToF43121DataStructure != (ID) 0) { if (lpdsF43121 != (LPF43121) NULL) { jdeFree( (void*) lpdsF43121); } lpdsF43121= (LPF43121) NULL; dsGetPOReceipt.idPointerToF43121DataStructure =(ID) 0; } |
||
Examaple 3: Free pointer to the Item Branch record - i.e. F4102 if ((dsChkItemBr.idItemBranchRecord != (ID) 0) && (lpdsF4102 != (LPF4102)NULL)) { if (lpdsF4102 != (LPF4102) NULL) { jdeFree( (void*) lpdsF4102); } lpdsF4102= (LPF4102) NULL; dsChkItemBr.idItemBranchRecord =(ID) 0; } |
||
Example 4 if(hUser) /* or this can be written if (hUser != (HUSER) NULL) */ { JDB_FreeBhvr(hUser); } |
The API JDB_FreeEnv() is to release all memories, connections to DB, Library caches and so on. Through JDB_FreeEnv(), memory leak or open table are to be handled for specific user and environment.
Below APIs can be called in JDB_FreeEnv();
In JDEDEBUG message ""Entering JDB_FreeEnv (EnvHandle 999999)" (for this example, 999999 is handle for hExe),
API | For | Example in Log |
---|---|---|
jdeSpecTerminate(); | ||
JDB_FreeCriticalSections(); | ||
psthread_term_library(); | ||
JDERT_CleanRealTimeEvents((HENV)lpExe); | ||
JDB_DBWritePricingDetailData(); | Write transaction based pricing information from cache to table. | |
jdeSecFreeSecList((HENV)lpExe); | ||
CloseHhandlesForEXEINFO(lpExe); | Close all hRequests under lpExe | |
DLIST_Destroy(lpExe->lpF98BlobHandleList); | ||
JDB_FreeUser((HUSER) lpUserInfo); | Free ghUser if it has the same environment as the current one. | |
KillDBRequest(lpRequestInfo); | Remove all requests. | |
DLIST_Destroy(lpExe->lpRequestList); | Destroy request linked list | |
jdeCacheDestroyAllUserCaches((HENV) lpExe); | Destroy the user's cache list | |
jdeFree(lpExe->lpBhvrCom); | Free Memory | jdeFree( lpExe->lpBhvrCom->lpObj ); jdeListDestroy( lpExe->lpBhvrCom->lpObj->OpenTableList ); jdeFree( lpExe->lpBhvrCom->lpObj->lpGlobalApp ); jdeFree( lpExe->lpBhvrCom->lpObj->lpzAppVars ); jdeFree( lpExe->lpVoid ); |
FreeLibrary(hEMailLibrary); | This will logoff from MAPI and close the Mail Handle | |
FreeLibraryCache(lpLib); | ||
DLIST_Destroy(lpExe->hLib); | Destroy user linked list | |
jdeFreeRemoteEnvs(lpExe); | Free remote environments | |
DLIST_Delete(ghEnvList, NULL); | Remove from Env linked list and Free handle. | |
JDECM_CacheDestroy(lpExe->hWorkObjCache); | ||
psthread_mutex_destroy(lpExe->hWorkObjCacheMutex); | ||
set_ghEnv( (HENV) NULL); | ||
PRT_TerminateLib(); | ||
jdeSecFreeUserList(); | for KERNEL_NET Free user list maintained by the security server. This needs to be called before the freeing lpExe, FreeUserList needs lpExe parms for User, IPAddress, PID and it needs to write to F9312 History table |
|
jdeFree(lpVoid); | Remove all security info. | |
DLIST_Delete(lpExe->lpSecurityList, (void * *) &lpVoid); | ||
DLIST_Destroy(lpExe->lpSecurityList); | Destroy security info linked list | |
KillPOCache(lpExe); | ||
KillOMAPCache(lpExe); | ||
DLIST_Delete(lpExe->lpAuditInfoList, (void * *) &lpVoid); | Remove all Audit info. | |
DLIST_Destroy(lpExe->lpAuditInfoList); | Destroy audit info linked list | |
jdeListDestroyEmpty (&(lpExe->pEnv->pDBDSTransientCache)); | Destroy the Metadata database datasource cache. | |
jdeFree(lpExe->pDataPtr[nLoopCount]); | Refer below JDB4100006 | Loop through the data pointer array in the lpExe and log a debug message for each slot that has a non-null data pointer. This isn't necessarily a memory leak of some kind (because the pointer could have been freed without being removed from the array), but it's one of the slots used up which, over time, could cause the array to fill up. This code is just the early warning system. The information logged to the debug log should be enough to track back to see where the pointer was stored. If not, the user can turn on Data Pointer Tracing in the JDE.INI and watch for the problem again. |
jdeFree(lpExe); | ||
JDERT_CleanRealTimeLegacyGlobals(); | Clean the legacy real time event globals | |
FreeLibrary(ghLib); | ||
DestroyGlobalPricingData(); | ||
JDB_UnloadTriggerLibrariesPrv(lpEData); | Unload Table Trigger libraries | |
KillDBCache(lpEData, TRUE); | ||
DLIST_Delete(ghEnvData, (void * *) &lpEData); | ||
DLIST_Destroy(ghEnvList); | ||
KillDriverEnv(lpDriverEnv); | Remove all DriverEnv | |
DLIST_Delete(ghDriverEnvList, (void * *) &lpDriverEnv); | ||
DLIST_Destroy(ghDriverEnvList); | ||
jdeFree(lpConnectInfo); | Remove all connectinfo. | |
DLIST_Delete(ghConnectInfoList, (void * *) &lpConnectInfo); | ||
DLIST_Destroy(ghConnectInfoList); | Destroy connectinfo linked list | |
DLIST_Destroy(ghCacheList); | ||
DLIST_Destroy(ghUserList); | ||
DLIST_Destroy(ghRequestList); | ||
FreeBSFNLibraryList(); | Free all the BSFN libraries in BSFN library list and then delete the BSFN library list | |
JDENET_FreeKernel(); | ||
FreeOCMSharedMem(); | ||
RemoveKernelData (); | ||
jdelib_Terminate(); | ||
KillDRCache(); | ||
KillEnvironmentMapCache(); | ||
FreeLibrary((HINSTANCE)hJDEUSERLib); | ||
jdeGetOrSetSecondaryServer(NULL, NULL); | Free list of failed over servers | |
FreeKernelIPCs(); | ||
jdeSpecTerminate(); | destroy mutex | |
JDB_FreeCriticalSections(); | ||
psthread_term_library(); |
Note:
Example:
Below information can be modified directly in ...JDEdwards\E910\system\bin32\JDE.INI or can be modified through server manager by accessing Configuration>Logging and Diagnostics. This step is important because this can be means to track down the root cause of memory issue (both Memory Corruption and Memory Leak).
Section Name | Entry /Parameter |
Default Value | Available Values | Description | Others |
---|---|---|---|---|---|
BSFN MEMORY DIAGNOSTICS | bmdLevel | 0 | 0 - Disabled - No Memory Logging 1 - Level 1 - Sampled Memory Logging For All Processes 2 - Level 2 - BSFN Memory Logging (After MB Threshold) 3 - Level 3 - BSFN Memory Logging (After Specified BSFN) |
BMD Level: Level of diagnostics. Level 1 logs memory and CPU usage, at a samling frequency of allocations. Level 2 logs BSFN emory and CPU usage, for all BSFNs running at BSFN levels 1 and 2, after a trigger based on a memory usage. Level 3 logs BSFN memory and CPU usage, for all BSFNs and BSFN levels, after a trigger based on a memory usage combined with a specified BSFN name and BSFN level. |
|
allocFrequency | 15000 | Allocation Frequency: Number of memory allocations for memory sampling. Each samle logs memory and CPU usage. This value is only used for BMD level 1. |
|||
memThresholdMB | 100 | Memory Threshold (MB): Memory threshold (in megabytes) to begin logging detailed BSFN memory usage. For BMD level 2, this is the trigger when logging starts. For BMD level 3, this is combined with a specified BSFN name and level before logging starts. |
|||
bsfnName | BSFN Name: Business Function name. When combined with the BSFN level and memory threshold, triggers the logging of data. Used by BMD level 3 only. |
||||
bsfnLevel | 2 | BSFN Level: Business Function level. When combined with the BSFN name and memory threshold, triggers the logging of data. Used by BMD level 3 only. |
|||
enableDebug | 0 | 0 (False) - Do Not Change Debug Logging 1 (True) - Turn On Debug Logging With BMD Level 3 |
Enable Debug Logging: Option to turn on debug logging. If selected, debug logging will be dynamically turned on when trigger conditions for BMD level 3 are met. This does not change the debug logging settings of JDE.INI. Used by BMD level 3 only. |
||
DEBUG | Output | NONE | NONE - No Debug Logging FILE - Enable Debug Logging |
Enable Debug Logging: Defines whether debug (jdedebug) logging is enabled. The value configured in the JDE.INI will affect every new process that starts up. Changing this value will not affect already running process |
Do not set this value to FILE unless it is request by Oracle because there are many different ways to turn on logging for specific process dynamically |
DebugFile | jdedebug.log | JDEDEBUG.LOG Filename: Defines the complete path to use when creating the debug level logging file (jdedebug.log). The supplied filename will be replaced with 'jdedebug_###.log', where '###' is the operating system process identifier (PID) of the kernel process. |
|||
JobFile | jde.log | JDE.LOG Filename: Defined the complete path to use when creating the primary logging file (jde.log). The supplied filename will be replaced with 'jde_###.log', where '###' is the operating system process identifier (PID) of the kernel process. |
|||
JDETSFile | TS Log File: The complete path to the JDETS log file. @what's TS?? |
||||
LogErrors | 1 | 0 - Disabled 1 - Enabled |
Enable JDE.LOG: If enabled the jde.log logging file will be created. The value configured in the JDE.INI file will affect every new process that starts up. Changing this value will not affect already running processes. It is highly recommended to always enable this type of logging. |
It is important to check jde.log in hitting memory error. In latest tools release which contain detailed information on memory leak and memory corruption | |
ClientLog | 0 | 0 1 |
Enable Client Log: This setting controls whether logging messages generated by CallObject kernel shoul be set back to requesting fat client workstation for inclusion in it's tracing logging. |
||
KeepLogs | 1 | 0 - Remove logs Once Printed 1 - Keep Logs After Printed |
Keep UBE Logs: When enabled log files generated by a UBE process are kept after the UBE has been printed. If disabled the log files will be deleted. |
||
TamTraceLevel | 0 | 0 through 9 | TAM Trace Level: The settings configures the level of logging that should be written related to TAM file access. |
||
ThreadTraceLevel | 0 | 0 through 3 | Thread Trace Level: Configures the level of thread related debug information.Increasing the trace level may significantly negatively impact performance. |
||
QKLog | 0 | 0 - No Logging 1 - Execution Logging 2 - Debug Logging |
Queue Kernel Log: This entry configures the level of logging emitted by the queue kenrel processes. |
||
RepTrace | 0 | 0 - Disabled 1 - Enabled |
Trace Replication: If enabled replication activity performed by the replication kernel will be traced to the debug log file. |
||
CloseFiles | FLUSH | 0 - Flush To Disk Periodically 1 - Close After Each Write FLUSH - Flush To Disk After Each Write |
Close/Flush Debug Files: There are 3 allowed values for this setting. When set to '1', the trace (debug) log file will be closed (and effectively flushed to disk) after each message is written. When set to 'FLUSH', the trace (debug) log file will be flushed to disk (but not closed) after each message is written. When set to '0', the trace (debug) log file will be flushed to disk periodically. For th ebest performrance (with trace loggign turned on), this value should be set to '0'. To ensure all trace messges are written to the debug log (with trace logging turned on) - even when a process terminates abnormally - this value should be set to 'FLUSH' or '1'. there are 2 major differences between 'FLUSH' and '1'. The first is that 'FLUSH' will have better performance than '1'. The other difference is that '1' will make it easier to view or delete the trace (debug) log file while E1 processes are still runnning (as some editors and operating systems will not allow the viewing or deletion of files in use by other processes.) |
||
RunBatchDelay | 0 | RUNBATCH Delay: Specifies the time, in seconds, that the runbatch process shall wit prior to performing any actual work. While useful for setting a delay to allow time to connect a debugger to the process, it shluld be set to zero outside of debugging activity. |
|||
runprintDelay | 0 | RUNPRINT Delay: Specifies the time, in seconds, that the runprint process ahll wait prior to performing any actual work. While useful fo rsetting a delay to allow time to connect a debugger to the process, it should be set to zero outside of debugging activity. |
|||
TransactionLog | NONE | NONE - Disabled FILE - Enabled |
Transaction Log: This entry enables saving the SQL statements into the debug logs with the actual values used. If not enabled the actual values may be masked using a placeholder character such as '2'. Enabling this option may negatively impact performance. |
||
EVNDelay | 0 | EVN Kernel Delay: This entry defines a value, in seconds, that the event notification (EVN) kernel will wait after being created and prior to processing. This is typically set only wnen debugging the EVN kernel itself so should typically be left at zero. |
|||
DumpLPDS | 1 | 0 - Do Not Log 1 - Do Log Data Structures |
Log CallObject Data Structure: This setting enables or disables the logging of the data structures passed into and returned from a business function running within a CallObjectKernel. The data will be written to the trace (debug) if enabled. Enabling this logging may reduce the performance of the CallObject process but may also provide very useful information when developing or troubleshooting business functions. |
||
TraceRowSecurityFetch | FALSE | FALSE - Disabled TRUE - Enabled |
Trace Row Security Fetches: If enabled database fetches that violate row security will be logged to the trace (debug) log file. |
||
DataPointerTracing | false | FALSE - Disabled TRUE - Enabled |
Log Data Pointer Activity: If enabled activity related to caching data pointers within JDB will be captured and written to the trace (debug) log file. The need to utilize this tracing is very rare and should typically not be enabled. |
||
CMTrace | 0 | 0 - Disabled 1 - Enabled |
Cache Manager Trace: If enabled the cache manager (JDECM) activity will be written to the trace (debug) log file. |
With trace enabled, you will see similar to these in the log: JDECM_CacheFindPtrKeyed handle=087dda40 |
|
CacheInfoFrequency | 0 | Cache Manager Log Frequency: If non-zero this entry defines the frequency in which cache manager statistics should be written to the trace (debug) log files. If zero the information will never be written to the logs. Valid only if cache manager logging is enabled. This frequency is considered to be the number of cache manager related APIs/functions that are allowed between log statements. Enabling this tracing may negatively affect performance. |
|||
CMTraceFilter | ALL | Cache Manager Trace Filter: This entry defines the caches that should be logged to the trace file when cache manager logging is enabled. The value may be one or more cache names separated by either a comma or semicolon. If blank or the value 'ALL' then all caches will be logged. |
|||
maxDebugFileSize | 1GB | Max size of each debug log: This setting specifies the maximum file size for debug log files. This provides debug log rollover functionality, similar to that of the JAS server. Before each debug log file reaches the specified maimum size (specified by this setting), as new log file will be created. The preceding debug log file will be renamed using the suffix "_1". If there is already a proceding debug log with the "_1" suffix, that older file will be renamed to a suffix of "2". And so on, until maximum number of preceding debug log files is reached (specified by maxDebugBackupIndex). At that point, the earliest proceding debug log file will be deleted. The minimum size for a debug log file is two lines, regardless of this settings. When this setting is zero, there will be no maximum file size for debug logs. |
|||
maxDebugBackupIndex | 1 | Max number of prior debug logs: This setting specifies the maximum number of proceding debug log files to keep. This provides debug log rollover functionality, similar to that of the JAS server. Before each debug log file reaches the maximum size (specified by maxDebugFileSize), a new log file will be created. The proceding debug log file will be renamed using the suffix "_1". If ther eis already a proceding debug log with the "_1" suffix, that older file will be renamed to a suffix of "_2". And so on, until the maximum number of pecding debug log files (specified by this setting) is reached. At that point, the earliest proceding debug log file wil be deleted. When maxDebugFileSize is set to zro, this setting is ignored, since there is not maximum file size. |
|||
logMemDiagsAtSignOff | FALSE | TRUE FALSE |
Log memory diagnostics at signoff: This setting specifies whether or not memory diagnostics will be logged when a CallObject Kernel user session is ended or a UBE process ends. The memory diagnostics will be written to the jdedebug.log. |
||
logDPLeaksAtSignoff | FALSE | TRUE FALSE |
Log Data Pointer leaks at signoff: This setting specifies whether or not Data Pointer leaks will be logged when a user session is freed in an E1 Server process. Details about the leaked Data Pointers will be written to the jde.log. |
||
disableContextInfo | FALSE | TRUE FALSE |
Disable Contextual Information: This setting specifies whether or not Contextual Information for HUser, HRequest and DataPointer will be available in memory diagnostics or when these specific objects are reported as leaked resources in jde log or jdedebu log. |
||
JDEHEAP ADVANCED DIAGNOSTICS ENGINE (JADE) Configuration | trackMemUsage | 0 | 0 (False) - Do Not Begin JADE Memory Tracking 1 (True) - Begin JADE Memory Tracking At Process Start |
Track JdeHeap Memory Usage: Track jdeHeap memory usage by JADE. The tracking will start with the first jdeHeap usage of the process. It will terminate when the process shuts down and when any of the JADE buttons on the Server Manager process screen are used. |
|
logLevel | 2 | 1 - Summary of JdeHeap Memory Usage 2 - Summary plus BSFN-scoped Memory Detail 3 - Summary plus All JdeHeap Memory Details |
Logging Level: Level of logging the JADE diagnostics. Level 1 logs a summary of BSFN-scoped pointers and of all pointers. Level 2 logs the summary, plus, detail lines for each BSFN-scoped jdeHeap usage. Level 3 logs the summary, plus, detail lines for all jdeHeap usage. |
||
logInterval | 0 | Logging Intervals (in seconds): Logging interval (in seconds) between dumping of JADE data to the debug log file. This is a minimum interval, not an exact interval. No dumping will be done if there has been no jdeHeap activity since the last dumped data. This interval-based dumping will be termiated if any of the JADE buttons on the Server Manger process screen are used. |
|||
bsfnTriggerUseTrigger | 0 | 0 (False) - Do Not Use Specified Conditions To Begin JADE 1 (True) - Use specified Coonditions To Begin JADE |
Use BSFN Trigger to start JADE: Use BSFN Trigger to begin JADE memory tracking. The BSFN-related trigger conditions are given in this section of the INI file. When the trigger conditions are met, JADE memory tracking begins. The trigger does not cause any JADE data to be dumpted to log files. |
||
bsfnTriggerMemThresholdMB | 100 | Memory Threshold (MB): Memory threshold (in megabytes) to begin JADE tracking of jdeHeap memory usage. This can be combined with a specified BSFN name and level to trigger when tracking starts. |
|||
bsfnTriggerBsfnName | BSFN Name: Business Function name. When combined with the BSFN level and memory threshold, triggers the JADE tracking. |
||||
bsfnTriggerBsfnLevel | 0 | BSFN Level: Business Function level. When combined with the BSFN name and memory threshold, triggers the JADE tracking. Not used when set to zreo. |
|||
bsfnTriggerEnableDebug | 0 | 0 (False) - Do NOt Change Debug Logging 1 (True) - Turn on Debug Logging When JADE Is Triggered |
Enable Debug Logging: Option to turn on debug logging. If selected, debug logging will be dynamically turned on when trigger conditions for JADE are met. This does not change the debug logging settings of JDE.INI |
Rarely, in running EnterpriseOne application, memory leak can be causing unexpected result as written in <Document 1325310.1> E1: BSFN: Case Study - How to Interpret Error CAC0001017 in jde.log? The cause of this type of message is it has reached the maximum value which EnterpriseOne can hold.
A heap memory manager is responsible for the management of heap memory. The heap memory manager performs the following fundamental memory operations:
<Internal_Only>information below is added as suggested by Developer</Internal_Only>
Using the memory diagnostics at runtime to find out potential jdeCache, transaction, table and data pointer and database connection leak as well as using JDB Cache for a transaction table with lots of records.
In case you need to create your own business function, make it sure that below check points read and executed.
<Document 1237103.1> E1: 12: R12855 Ends In Memory Violation Error on Windows Server 2008 x64
<Document 632629.1> E1: 34: R3482 & R3483 Common Error Messages and Memory Violations
<Document 639397.1> E1: 30: R30601 EventRule: Business Function BillOfMaterialIntegrityCheckT1
<Document 1064662.1> E1: 43: Possible Causes of Memory Violation in P4314 - Voucher Match Application
<Document 1322258.1> E1: 47: R47011 Reads Memory Violation
<Document 1272974.1> E1: UBE: Case Study on "MEMORY ALLOCATION FAILURE" Errors in EnterpriseOne Batch Applications
<Document 1060818.1> E1: UBE: R98306X Ends in Error and Output is Showing Incomplete Data
<Document 1179493.1> E1: BSFN: Call Object Kernel Errors Clarification - COB0000*
See the second document in this series <Document 1554611.1> E1: BSFN: Case Study on Memory Violation, Memory Corruption, Memory Overwrite, Access Violation and Zombie Kernel Caused by Standard Business Functions Part 2.