📄 dtrace_impl.h
字号:
* restart it; if a DTrace consumer wishes to restart tracing, it must reopen * the DTrace pseudodevice. */typedef enum dtrace_activity { DTRACE_ACTIVITY_INACTIVE = 0, /* not yet running */ DTRACE_ACTIVITY_WARMUP, /* while starting */ DTRACE_ACTIVITY_ACTIVE, /* running */ DTRACE_ACTIVITY_DRAINING, /* before stopping */ DTRACE_ACTIVITY_COOLDOWN, /* while stopping */ DTRACE_ACTIVITY_STOPPED, /* after stopping */ DTRACE_ACTIVITY_KILLED /* killed due to deadman */} dtrace_activity_t;/* * DTrace Helper Implementation * * A description of the helper architecture may be found in <sys/dtrace.h>. * Each process contains a pointer to its helpers in its p_dtrace_helpers * member. This is a pointer to a dtrace_helpers structure, which contains an * array of pointers to dtrace_helper structures, helper variable state (shared * among a process's helpers) and a generation count. (The generation count is * used to provide an identifier when a helper is added so that it may be * subsequently removed.) The dtrace_helper structure is self-explanatory, * containing pointers to the objects needed to execute the helper. Note that * helpers are _duplicated_ across fork(2), and destroyed on exec(2). No more * than dtrace_helpers_max are allowed per-process. */#define DTRACE_HELPER_ACTION_USTACK 0#define DTRACE_NHELPER_ACTIONS 1typedef struct dtrace_helper_action { dtrace_difo_t *dthp_predicate; /* helper action predicate */ int dthp_nactions; /* number of actions */ dtrace_difo_t **dthp_actions; /* array of actions */ int dthp_generation; /* helper action generation */ struct dtrace_helper_action *dthp_next; /* next helper action */} dtrace_helper_action_t;typedef struct dtrace_helper_provider { dof_helper_t dthp_prov; /* DOF w/ provider and probes */ uint32_t dthp_ref; /* reference count */} dtrace_helper_provider_t;typedef struct dtrace_helpers { dtrace_helper_action_t **dthps_actions; /* array of helper actions */ dtrace_vstate_t dthps_vstate; /* helper action var. state */ dtrace_helper_provider_t **dthps_provs; /* array of providers */ uint_t dthps_nprovs; /* count of providers */ int dthps_generation; /* current generation */ pid_t dthps_pid; /* pid of associated proc */ struct dtrace_helpers *dthps_next; /* next pointer */ struct dtrace_helpers *dthps_prev; /* prev pointer */} dtrace_helpers_t;/* * DTrace Helper Action Tracing * * Debugging helper actions can be arduous. To ease the development and * debugging of helpers, DTrace contains a tracing-framework-within-a-tracing- * framework: helper tracing. If dtrace_helptrace_enabled is non-zero (which * it is by default on DEBUG kernels), all helper activity will be traced to a * global, in-kernel ring buffer. Each entry includes a pointer to the specific * helper, the location within the helper, and a trace of all local variables. * The ring buffer may be displayed in a human-readable format with the * ::dtrace_helptrace mdb(1) dcmd. */#define DTRACE_HELPTRACE_NEXT (-1)#define DTRACE_HELPTRACE_DONE (-2)#define DTRACE_HELPTRACE_ERR (-3)typedef struct dtrace_helptrace { dtrace_helper_action_t *dtht_helper; /* helper action */ int dtht_where; /* where in helper action */ int dtht_nlocals; /* number of locals */ uint64_t dtht_locals[1]; /* local variables */} dtrace_helptrace_t;/* * DTrace Credentials * * In probe context, we don't have the flexibility to examine the credentials * of the DTrace consumer that created a particular enabling. Instead, we use * the Least Privilege interfaces to cache the consumer's credentials in a * dtrace_cred_t structure. That structure contains two important sets of * credentials that limit the consumer's breadth of visibility and what * actions the consumer may take. */#define DTRACE_CRV_ALLPROC 0x01#define DTRACE_CRV_KERNEL 0x02#define DTRACE_CRV_ALL (DTRACE_CRV_ALLPROC | DTRACE_CRV_KERNEL)#define DTRACE_CRA_PROC 0x0001#define DTRACE_CRA_PROC_DESTRUCTIVE 0x0002#define DTRACE_CRA_PROC_CONTROL 0x0004#define DTRACE_CRA_KERNEL 0x0008#define DTRACE_CRA_KERNEL_DESTRUCTIVE 0x0010#define DTRACE_CRA_ALL (DTRACE_CRA_PROC | \ DTRACE_CRA_PROC_DESTRUCTIVE | DTRACE_CRA_PROC_CONTROL | \ DTRACE_CRA_KERNEL | DTRACE_CRA_KERNEL_DESTRUCTIVE)typedef struct dtrace_cred { uid_t dcr_uid; gid_t dcr_gid; uint8_t dcr_destructive; uint8_t dcr_visible; uint16_t dcr_action;} dtrace_cred_t;/* * DTrace Consumer State * * Each DTrace consumer has an associated dtrace_state structure that contains * its in-kernel DTrace state -- including options, credentials, statistics and * pointers to ECBs, buffers, speculations and formats. A dtrace_state * structure is also allocated for anonymous enablings. When anonymous state * is grabbed, the grabbing consumers dts_anon pointer is set to the grabbed * dtrace_state structure. */struct dtrace_state { dev_t dts_dev; /* device */ int dts_necbs; /* total number of ECBs */ dtrace_ecb_t **dts_ecbs; /* array of ECBs */ dtrace_epid_t dts_epid; /* next EPID to allocate */ size_t dts_needed; /* greatest needed space */ struct dtrace_state *dts_anon; /* anon. state, if grabbed */ dtrace_activity_t dts_activity; /* current activity */ dtrace_vstate_t dts_vstate; /* variable state */ dtrace_buffer_t *dts_buffer; /* principal buffer */ dtrace_buffer_t *dts_aggbuffer; /* aggregation buffer */ dtrace_speculation_t *dts_speculations; /* speculation array */ int dts_nspeculations; /* number of speculations */ int dts_naggregations; /* number of aggregations */ dtrace_aggregation_t **dts_aggregations; /* aggregation array */ vmem_t *dts_aggid_arena; /* arena for aggregation IDs */ uint32_t dts_speculations_busy; /* number of spec. busy */ uint32_t dts_speculations_unavail; /* number of spec unavail */ uint64_t dts_errors; /* total number of errors */ uint32_t dts_reserve; /* space reserved for END */ hrtime_t dts_laststatus; /* time of last status */ cyclic_id_t dts_cleaner; /* cleaning cyclic */ cyclic_id_t dts_deadman; /* deadman cyclic */ hrtime_t dts_alive; /* time last alive */ char dts_speculates; /* boolean: has speculations */ char dts_destructive; /* boolean: has dest. actions */ int dts_nformats; /* number of formats */ char **dts_formats; /* format string array */ dtrace_optval_t dts_options[DTRACEOPT_MAX]; /* options */ dtrace_cred_t dts_cred; /* credentials */};struct dtrace_provider { dtrace_pattr_t dtpv_attr; /* provider attributes */ dtrace_ppriv_t dtpv_priv; /* provider privileges */ dtrace_pops_t dtpv_pops; /* provider operations */ char *dtpv_name; /* provider name */ void *dtpv_arg; /* provider argument */ uint_t dtpv_defunct; /* boolean: defunct provider */ uint_t dtpv_anonmatched; /* boolean: anonymous matched */ struct dtrace_provider *dtpv_next; /* next provider */};struct dtrace_meta { dtrace_mops_t dtm_mops; /* meta provider operations */ char *dtm_name; /* meta provider name */ void *dtm_arg; /* meta provider user arg */ uint64_t dtm_count; /* no. of associated provs. */};/* * DTrace Enablings * * An dtrace_enabling structure is used to track a collection of ECB * descriptions -- before they have been turned into actual ECBs. This is * created as a result of DOF processing, and is generally used to generate * ECBs immediately thereafter. When enablings are used in this way, they are * destroyed immediately after they have been used to generate ECBs. Anonymous * enablings, however, may be created before the probes they wish to enable are * created. For anonymous enablings then, the enabling is retained; as each * new module or provider registers with the framework, the anonymous enabling * is reevaluated, with any new match resulting in new ECBs. */typedef struct dtrace_enabling { dtrace_ecbdesc_t **dten_desc; /* ECB descriptions */ int dten_ndesc; /* number of ECB descriptions */ int dten_maxdesc; /* size of ECB array */ dtrace_vstate_t *dten_vstate; /* associated variable state */} dtrace_enabling_t;/* * DTrace Anonymous Enablings * * Anonymous enablings are DTrace enablings that are not associated with a * controlling process, but rather derive their enabling from DOF stored as * properties in the dtrace.conf file. If there is an anonymous enabling, a * DTrace consumer state and enabling are created on attach. The state may be * subsequently grabbed by the first consumer specifying the "grabanon" * option. As long as an anonymous DTrace enabling exists, dtrace(7D) will * refuse to unload. */typedef struct dtrace_anon { dtrace_state_t *dta_state; /* DTrace consumer state */ dtrace_enabling_t *dta_enabling; /* pointer to enabling */ processorid_t dta_beganon; /* which CPU BEGIN ran on */} dtrace_anon_t;/* * DTrace Error Debugging */#ifdef DEBUG#define DTRACE_ERRDEBUG#endif#ifdef DTRACE_ERRDEBUGtypedef struct dtrace_errhash { const char *dter_msg; /* error message */ int dter_count; /* number of times seen */} dtrace_errhash_t;#define DTRACE_ERRHASHSZ 256 /* must be > number of err msgs */#endif /* DTRACE_ERRDEBUG *//* * DTrace Toxic Ranges * * DTrace supports safe loads from probe context; if the address turns out to * be invalid, a bit will be set by the kernel indicating that DTrace * encountered a memory error, and DTrace will propagate the error to the user * accordingly. However, there may exist some regions of memory in which an * arbitrary load can change system state, and from which it is impossible to * recover from such a load after it has been attempted. Examples of this may * include memory in which programmable I/O registers are mapped (for which a * read may have some implications for the device) or (in the specific case of * UltraSPARC-I and -II) the virtual address hole. The platform is required * to make DTrace aware of these toxic ranges; DTrace will then check that * target addresses are not in a toxic range before attempting to issue a * safe load. */typedef struct dtrace_toxrange { uintptr_t dtt_base; /* base of toxic range */ uintptr_t dtt_limit; /* limit of toxic range */} dtrace_toxrange_t;extern uint64_t dtrace_getarg(int, int);extern greg_t dtrace_getfp(void);extern int dtrace_getipl(void);extern uintptr_t dtrace_caller(int);extern uint32_t dtrace_cas32(uint32_t *, uint32_t, uint32_t);extern void *dtrace_casptr(void *, void *, void *);extern void dtrace_copyin(uintptr_t, uintptr_t, size_t);extern void dtrace_copyinstr(uintptr_t, uintptr_t, size_t);extern void dtrace_copyout(uintptr_t, uintptr_t, size_t);extern void dtrace_copyoutstr(uintptr_t, uintptr_t, size_t);extern void dtrace_getpcstack(pc_t *, int, int, uint32_t *);extern ulong_t dtrace_getreg(struct regs *, uint_t);extern int dtrace_getstackdepth(int);extern void dtrace_getupcstack(uint64_t *, int);extern void dtrace_getufpstack(uint64_t *, uint64_t *, int);extern uintptr_t dtrace_fulword(void *);extern uint8_t dtrace_fuword8(void *);extern uint16_t dtrace_fuword16(void *);extern uint32_t dtrace_fuword32(void *);extern uint64_t dtrace_fuword64(void *);extern void dtrace_probe_error(dtrace_state_t *, dtrace_epid_t, int, int, int, uintptr_t);extern int dtrace_assfail(const char *, const char *, int);extern int dtrace_attached(void);extern hrtime_t dtrace_gethrestime();#ifdef __sparcextern void dtrace_flush_windows(void);extern void dtrace_flush_user_windows(void);extern uint_t dtrace_getotherwin(void);extern uint_t dtrace_getfprs(void);#elseextern void dtrace_copy(uintptr_t, uintptr_t, size_t);extern void dtrace_copystr(uintptr_t, uintptr_t, size_t);#endif/* * DTrace Assertions * * DTrace calls ASSERT from probe context. To assure that a failed ASSERT * does not induce a markedly more catastrophic failure (e.g., one from which * a dump cannot be gleaned), DTrace must define its own ASSERT to be one that * may safely be called from probe context. This header file must thus be * included by any DTrace component that calls ASSERT from probe context, and * _only_ by those components. (The only exception to this is kernel * debugging infrastructure at user-level that doesn't depend on calling * ASSERT.) */#undef ASSERT#ifdef DEBUG#define ASSERT(EX) ((void)((EX) || \ dtrace_assfail(#EX, __FILE__, __LINE__)))#else#define ASSERT(X) ((void)0)#endif#ifdef __cplusplus}#endif#endif /* _SYS_DTRACE_IMPL_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -