Hi James & Sasha,
Have a look at the source for cputrack (usr/src/cmd/cpc/common/cputrack.c).
It does essentially what you are trying to do, though it uses the libpctx
interfaces to do it. See also __pctx_cpc() in libpctx.c
(usr/src/lib/pctx/common/libpctx.c).
When the controlled process crashes, what is the current instruction? What
is it doing at the time of the crash?
- Russ
jla40 at sfu.ca wrote:
> I have a tool that controls and monitors a hardware counter for a captured
> process. I have programmed the Instr_cnt counter so that when it overflows a
> SIGEMT signal is sent to the controlled process. The controlled process
> stops on the receipt of SIGEMT and allows me to do some measurements from
> the context of my monitoring process.
>
> The problem: I cannot find the proper way to restart the hardware counter
> once they have stopped after receipt of the SIGEMT. cpc_request_preset() and
> cpc_set_restart() seemed promising but they always return an error. I have
> been assuming the error is caused because cpc_request_preset() and
> cpc_set_restart() must be executed from the context of the controlled
> process, not my monitoring tool (please advise if I'm wrong on this
> assumption).
>
> Psyscall() seemed like a promising solution. It will "execute the private
> 'cpc' system call in the context of the controlled process." However my
> implementation of it using CPC_RESTART causes the controlled process to
> crash (see code below).
>
> Any pointers, suggestions or documentation would be hugely appreciated.
>
> Regards,
> James
>
> int
> my_pctx_restart(pctx_t *pctx, cpc_t *cpc)
> {
>
> /* Variables to support Psyscall(). */
> sysret_t rval;
> argdes_t argd[5];
> argdes_t *adp = &argd[0];
> int error;
>
> struct __pctx *pctx_int;
> pctx_int = (struct __pctx*)pctx;
>
> /* Keeping track... */
> if (pctx->cpc != NULL && pctx->cpc != cpc && pctx_cpc_callback !=
> NULL)
> (*pctx_cpc_callback)(pctx->cpc, pctx);
> pctx->cpc = cpc;
>
> /* cmd */
> adp->arg_value = CPC_RESTART;
> adp->arg_object = NULL;
> adp->arg_type = AT_BYVAL;
> adp->arg_inout = AI_INPUT;
> adp->arg_size = 0;
> adp++;
>
> /* lwpid */
> adp->arg_value = 1;
> adp->arg_object = NULL;
> adp->arg_type = AT_BYVAL;
> adp->arg_inout = AI_INPUT;
> adp->arg_size = 0;
> adp++;
>
> /* not used for CPC_RESTART */
> adp->arg_value = 0;
> adp->arg_object = 0;
> adp->arg_type = AT_BYVAL;
> adp->arg_inout = AI_INPUT;
> adp->arg_size = 0;
> adp++;
>
> /* not used for CPC_RESTART */
> adp->arg_value = 0;
> adp->arg_object = 0;
> adp->arg_type = AT_BYVAL;
> adp->arg_inout = AI_INPUT;
> adp->arg_size = 0;
> adp++;
>
> /* not used for CPC_RESTART */
> adp->arg_value = 0;
> adp->arg_object = 0;
> adp->arg_type = AT_BYVAL;
> adp->arg_inout = AI_INPUT;
> adp->arg_size = 0;
>
> error = Psyscall(pctx_int->Pr, &rval, SYS_cpc, 5, &argd[0]);
> if (error) {
> log_message(LOGFILE, "ERROR on Psyscall()");
> }
>
> return (rval.sys_rval1);
> }
> _______________________________________________
> observability-discuss mailing list
> observability-discuss at opensolaris.org
--
-----------------------------------------------------
Russ Blaine | Solaris Kernel | russell.blaine at sun.com