__le_traceback() — Call chain traceback service
Standards
Standards / Extensions | C or C++ | Dependencies |
---|---|---|
Language Environment |
both | z/OS® V1.9 AMODE 64 |
Format
#include <__le_api.h>
void __le_traceback(int cmd, void* cmd_parms, _FEEDBACK *fc);
General description
- Parameter
- Description
- cmd
- The __le_traceback() command to be used. The following commands
can be used:
- __TRACEBACK_FIELDS
- Information that can be used to create a traceback message is returned in individual fields.
- cmd_parms
- A pointer to a structure that contains additional command specific parameters. For the command __TRACEBACK_FIELDS, this parameter must point to a __tf_parms_t.
- fc
- A 16-byte feedback code indicating the results of this function.
Table 1. Feedback Codes for __le_traceback() Code Severity Message number Message text CEE000 0 - - The service completed successfully. CEE310 3 3104S Information could not be successfully extracted for this DSA. It is likely that the dsaptr parameter does not point to an actual DSA or save area. CEE316 2 3110E The cmd parameter is not a valid command for __le_traceback(). CEE3NS 1 3836W A statement number is not available for this DSA. DWARF data in the load module is corrupted. CEE3NT 1 3837W Statement numbers are not available. The explicit DLL load of DLL CDAEQED failed with feedback code fc. CEE3NU 1 3838W Statement numbers are not available. The explicit DLL load of DLL CDAEQDPI failed with feedback code fc. CEE3NV 1 3839W Statement numbers are not available. The explicit DLL load of DLL CELQDSNF failed with feedback code fc. CEE3O0 1 3840 Statement numbers are not available. dllqueryfn() failed for a function in the DLL CELQDSNF. CEE3O1 1 3841 A statement number is not available for this DSA. An internal routine failed with return code return-code and reason code reason-code.
The __tf_parms_s structure is defined as follows:
typedef struct __tf_string_s {
size_t __tf_bufflen;
char* __tf_buff;
} __tf_string_t;
typedef struct __tf_parms_s {
/****************************************************************/
/* Input */
/****************************************************************/
void* __tf_dsa_addr;
void* __tf_caa_addr;
void* __tf_call_instruction;
/****************************************************************/
/* Output related to input DSA */
/****************************************************************/
void* __tf_ pu_addr;
void* __tf_ entry_addr;
struct __cib* __tf_cib_addr;
uint8_t __tf_member_id;
int __tf_is_main:1;
int :23;
int :32;
__tf_string_t __tf_pu_name;
__tf_string_t __tf_entry_name;
__tf_string_t __tf_statement_id;
/****************************************************************/
/* Output related to caller's DSA */
/****************************************************************/
void* __tf_caller_dsa_addr;
void* __tf_caller_call_instruction;
} __tf_parms_t;
- Member
- Description
- void* __tf_dsa_addr
- The address of the DSA for the current routine in the traceback. When this field is zero on input, the address of the DSA for the caller of __le_traceback() will be used and the address will be returned. No attempt is made to verify that the input is a DSA. Incorrect input can lead to unpredictable results.
- void* __tf_caa_addr
- The address of the CAA associated with the DSA. When this field is zero on input, the address of the CAA for the current thread will be used and the address will be returned. No attempt is made to verify that the input is a CAA. Incorrect input can lead to unpredictable results.
- void* __tf_call_instruction
- The address of the instruction that caused transfer out of the routine. This is either the address of a BASR, BRAS or BRASL instruction if transfer was made by subroutine call, or the address of the interrupted statement if transfer was caused by an exception. When multiple calls are made to __le_traceback() to scan the call chain, the callers_call_instruction (described below) returned from the previous call can be used here. If the address is not known, this field should be set to zero. When this field is zero on input and the address can be determined, it will be returned.
- void* __tf_pu_addr
- The address of the start of the program unit for the routine associated with the DSA is returned in this field. If the program unit address cannot be determined, this field is set to zero.
- void* __tf_entry_addr
- The address of the entry point into the routine associated with the DSA is returned in this field. If the entry point address cannot be determined, this parameter is set to zero.
- struct __cib* __tf_cib_addr
- The address of the CIB (struct __cib) associated with the DSA, if an exception occurred, is returned in this field. If no exception occurred, this field is set to zero. Note that if an exception caused transfer out of the routine, the state of the registers after the last instruction ran in the routine is saved in the CIB, rather than in the DSA.
- uint8_t __tf_member_id
- The member identifier for the routine associated with the DSA will be returned in this field. If the member ID cannot be determined, this field is set to negative one.
- int __tf_is_main:1
- One of two values is returned in this field: 0 (the routine associated with the DSA is not the main program) or 1 (the routine associated with the DSA is the main program).
- __tf_string_t __tf_pu_name
- A structure that will be used to return the name of the program
unit containing the routine associated with the DSA. The structure
has the following fields:
- char* __tf_buff
- The address of a buffer in which the program unit name will be returned. The name will be returned in the buffer as a null terminated string.
- size_t __tf_bufflen
- The size of the buffer
If the program unit name cannot be determined, the buffer is set to a null string. If the program unit name cannot fit within the supplied string, it is truncated. (Truncation of DBCS preserves even byte count and SI/SO pairing.) If __tf_buff is NULL or __tf_bufflen is zero, the program unit name is not returned.
- __tf_string_t __tf_entry_name
- A structure that will be used to return the name of the entry
point into the routine associated with the DSA. The structure has
the following fields:
- char* __tf_buff
- The address of a buffer in which the entry point name will be returned. The name will be returned in the buffer as a null terminated string.
- size_t __tf_bufflen
- The size of the buffer
If the entry point name cannot be determined, the buffer is set to a null string. If the entry point name cannot fit within the supplied string, it is truncated. (Truncation of DBCS preserves even byte count and SI/SO pairing.) If __tf_buff is NULL or __tf_bufflen is zero, the entry point name is not returned
- __tf_string_t __tf_statement_id
- A structure that will be used to return the identifier of the
statement containing the instruction which caused transfer out of
the routine associated with the DSA. The structure has the following
fields:
- char* __tf_buff
- The address of a buffer in which the statement id will be returned. The statement id will be returned in the buffer as a null terminated string.
- size_t __tf_bufflen
- The size of the buffer
If the statement id cannot be determined, the buffer is set to a null string. If the statement id cannot fit within the supplied string, it is truncated. (Truncation of DBCS preserves even byte count and SI/SO pairing.) If __tf_buff is NULL or __tf_bufflen is zero, the statement id is not returned
- void* __tf_callers_dsa_addr
- The address of the DSA for the caller is returned in this field. If the address of the caller's DSA cannot be determined or is not valid (points to inaccessible storage), then this field is set to zero.
- void* __tf_callers_call_instruction
- The address of the instruction that caused transfer out of the caller is returned in this field. This is either the address of a BASR, BRAS or BRASL instruction if transfer was made by subroutine call, or the address of the interrupted statement if transfer was caused by an exception. If the address cannot be determined, this parameter is set to zero.
Example
#include <__le_api.h>
#include <stdlib.h>
int main() {
__tf_parms_t tbck_parms;
char pu_name[256];
char entry_name[256];
char statement_id[256];
_FEEDBACK fc;
int rc;
tbck_parms.__tf_pu_name. __tf_bufflen = sizeof(pu_name);
tbck_parms.__tf_entry_name. __tf_bufflen = sizeof(entry_name);
tbck_parms.__tf_statement_id. __tf_bufflen = sizeof(statement_id);
tbck_parms.__tf_pu_name. __tf_buff = pu_name;
tbck_parms.__tf_entry_name. __tf_buff = entry_name;
tbck_parms.__tf_statement_id. __tf_buff = statement_id;
tbck_parms.__tf_dsa_addr = 0;
tbck_parms.__tf_caa_addr = 0;
tbck_parms.__tf_call_instruction = 0;
do {
_le_traceback(__TRACEBACK_FIELDS, &tbck_parms, &fc);
if ( fc.tok_sev >= 2 ) {
printf("Error: __le_traceback() failed.\n");
break;
}
printf("Entry=%s Offset=%c%x Line=%s\n",
tbck_parms.__tf_entry_name.__tf_buff,
tbck_parms.__tf_call_instruction
< tbck_parms.__tf_entry_addr ? '-' : '+',
abs((int)((long)tbck_parms.__tf_call_instruction
- (long)tbck_parms.__tf_entry_addr)),
tbck_parms.__tf_statement_id.__tf_buff
);
tbck_parms.__tf_dsa_addr = tbck_parms.__tf_caller_dsa_addr;
tbck_parms.__tf_call_instruction =
tbck_parms.__tf_caller_call_instruction;
} while (!tbck_parms.__tf_is_main);
return 0;
}
Entry=main Offset=+da Line=28
Entry=CELQINIT Offset=+134c Line=