관리-도구
편집 파일: errno.stp
// errno tapset // Copyright (C) 2006-2018 Red Hat Inc. // // This file is part of SystemTap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General // Public License (GPL); either version 2, or (at your option) any // later version. %{ #define N(a) [a]=#a static const char * const errlist[] = { /* from asm-generic/errno-base.h */ [1] = "EPERM", [2] = "ENOENT", [3] = "ESRCH", [4] = "EINTR", [5] = "EIO", [6] = "ENXIO", [7] = "E2BIG", [8] = "ENOEXEC", [9] = "EBADF", [10]= "ECHILD", [11]= "EAGAIN", [12]= "ENOMEM", [13]= "EACCES", [14]= "EFAULT", [15]= "ENOTBLK", [16]= "EBUSY", [17]= "EEXIST", [18]= "EXDEV", [19]= "ENODEV", [20]= "ENOTDIR", [21]= "EISDIR", [22]= "EINVAL", [23]= "ENFILE", [24]= "EMFILE", [25]= "ENOTTY", [26]= "ETXTBSY", [27]= "EFBIG", [28]= "ENOSPC", [29]= "ESPIPE", [30]= "EROFS", [31]= "EMLINK", [32]= "EPIPE", [33]= "EDOM", [34]= "ERANGE", /* end of errno-base.h */ /* The rest of this is arch-dependent */ #ifdef EDEADLK N(EDEADLK), #endif #ifdef ENAMETOOLONG N(ENAMETOOLONG), #endif #ifdef ENOLCK N(ENOLCK), #endif #ifdef ENOSYS N(ENOSYS), #endif #ifdef ENOTEMPTY N(ENOTEMPTY), #endif #ifdef ELOOP N(ELOOP), #endif #ifdef ENOMSG N(ENOMSG), #endif #ifdef EIDRM N(EIDRM), #endif #ifdef ECHRNG N(ECHRNG), #endif #ifdef EL2NSYNC N(EL2NSYNC), #endif #ifdef EL3HLT N(EL3HLT), #endif #ifdef EL3RST N(EL3RST), #endif #ifdef ELNRNG N(ELNRNG), #endif #ifdef EUNATCH N(EUNATCH), #endif #ifdef ENOCSI N(ENOCSI), #endif #ifdef EL2HLT N(EL2HLT), #endif #ifdef EBADE N(EBADE), #endif #ifdef EBADR N(EBADR), #endif #ifdef EXFULL N(EXFULL), #endif #ifdef ENOANO N(ENOANO), #endif #ifdef EBADRQC N(EBADRQC), #endif #ifdef EBADSLT N(EBADSLT), #endif #ifdef EBFONT N(EBFONT), #endif #ifdef ENOSTR N(ENOSTR), #endif #ifdef ENODATA N(ENODATA), #endif #ifdef ETIME N(ETIME), #endif #ifdef ENOSR N(ENOSR), #endif #ifdef ENONET N(ENONET), #endif #ifdef ENOPKG N(ENOPKG), #endif #ifdef EREMOTE N(EREMOTE), #endif #ifdef ENOLINK N(ENOLINK), #endif #ifdef EADV N(EADV), #endif #ifdef ESRMNT N(ESRMNT), #endif #ifdef ECOMM N(ECOMM), #endif #ifdef EPROTO N(EPROTO), #endif #ifdef EMULTIHOP N(EMULTIHOP), #endif #ifdef EDOTDOT N(EDOTDOT), #endif #ifdef EBADMSG N(EBADMSG), #endif #ifdef EOVERFLOW N(EOVERFLOW), #endif #ifdef ENOTUNIQ N(ENOTUNIQ), #endif #ifdef EBADFD N(EBADFD), #endif #ifdef EREMCHG N(EREMCHG), #endif #ifdef ELIBACC N(ELIBACC), #endif #ifdef ELIBBAD N(ELIBBAD), #endif #ifdef ELIBSCN N(ELIBSCN), #endif #ifdef ELIBMAX N(ELIBMAX), #endif #ifdef ELIBEXEC N(ELIBEXEC), #endif #ifdef EILSEQ N(EILSEQ), #endif #ifdef ERESTART N(ERESTART), #endif #ifdef ESTRPIPE N(ESTRPIPE), #endif #ifdef EUSERS N(EUSERS), #endif #ifdef ENOTSOCK N(ENOTSOCK), #endif #ifdef EDESTADDRREQ N(EDESTADDRREQ), #endif #ifdef EMSGSIZE N(EMSGSIZE), #endif #ifdef EPROTOTYPE N(EPROTOTYPE), #endif #ifdef ENOPROTOOPT N(ENOPROTOOPT), #endif #ifdef EPROTONOSUPPORT N(EPROTONOSUPPORT), #endif #ifdef ESOCKTNOSUPPORT N(ESOCKTNOSUPPORT), #endif #ifdef EOPNOTSUPP N(EOPNOTSUPP), #endif #ifdef EPFNOSUPPORT N(EPFNOSUPPORT), #endif #ifdef EAFNOSUPPORT N(EAFNOSUPPORT), #endif #ifdef EADDRINUSE N(EADDRINUSE), #endif #ifdef EADDRNOTAVAIL N(EADDRNOTAVAIL), #endif #ifdef ENETDOWN N(ENETDOWN), #endif #ifdef ENETUNREACH N(ENETUNREACH), #endif #ifdef ENETRESET N(ENETRESET), #endif #ifdef ECONNABORTED N(ECONNABORTED), #endif #ifdef ECONNRESET N(ECONNRESET), #endif #ifdef ENOBUFS N(ENOBUFS), #endif #ifdef EISCONN N(EISCONN), #endif #ifdef ENOTCONN N(ENOTCONN), #endif #ifdef ESHUTDOWN N(ESHUTDOWN), #endif #ifdef ETOOMANYREFS N(ETOOMANYREFS), #endif #ifdef ETIMEDOUT N(ETIMEDOUT), #endif #ifdef ECONNREFUSED N(ECONNREFUSED), #endif #ifdef EHOSTDOWN N(EHOSTDOWN), #endif #ifdef EHOSTUNREACH N(EHOSTUNREACH), #endif #ifdef EALREADY N(EALREADY), #endif #ifdef EINPROGRESS N(EINPROGRESS), #endif #ifdef ESTALE N(ESTALE), #endif #ifdef EUCLEAN N(EUCLEAN), #endif #ifdef ENOTNAM N(ENOTNAM), #endif #ifdef ENAVAIL N(ENAVAIL), #endif #ifdef EISNAM N(EISNAM), #endif #ifdef EREMOTEIO N(EREMOTEIO), #endif #ifdef EDQUOT N(EDQUOT), #endif #ifdef ENOMEDIUM N(ENOMEDIUM), #endif #ifdef EMEDIUMTYPE N(EMEDIUMTYPE), #endif #ifdef ECANCELED N(ECANCELED), #endif #ifdef ENOKEY N(ENOKEY), #endif #ifdef EKEYEXPIRED N(EKEYEXPIRED), #endif #ifdef EKEYREVOKED N(EKEYREVOKED), #endif #ifdef EKEYREJECTED N(EKEYREJECTED), #endif #ifdef EOWNERDEAD N(EOWNERDEAD), #endif #ifdef ENOTRECOVERABLE N(ENOTRECOVERABLE), #endif #if defined (EDEADLOCK) && EDEADLOCK != EDEADLK N(EDEADLOCK), #endif #ifdef E N(EADV), #endif }; #undef N static const int Maxerrno = sizeof(errlist)/sizeof(char *); %} /** * sfunction errno_str - Symbolic string associated with error code * * @err: The error number received * * Description: This function returns the symbolic string associated * with the giver error code, such as ENOENT for the number 2, or * E#3333 for an out-of-range value such as 3333. */ function errno_str:string (err:long) %{ /* pure */ long e = STAP_ARG_err; e = (e > 0 ? e : -e); if (e > 0 && e < Maxerrno && errlist[e]) strlcpy (STAP_RETVALUE, errlist[e], MAXSTRINGLEN); %} function errno_p:long (err:long) %{ /* pure */ long e = STAP_ARG_err; e = (e > 0 ? e : -e); if (e > 0 && e < Maxerrno && errlist[e]) STAP_RETVALUE = e; else STAP_RETVALUE = 0; %} %{ static long _stp_returnval(struct pt_regs *regs) { if (regs) { #if defined (STAPCONF_X86_UNIREGS) && (defined (__x86_64__) || defined (__i386__)) return regs->ax; #elif defined (__i386__) return regs->eax; #elif defined (__x86_64__) // TODO: Handle -m32 apps. return regs->rax; #elif defined (__powerpc__) return regs->gpr[3]; #elif defined (__ia64__) return regs->r8; #elif defined (__sparc64__) return regs->u_regs[UREG_RETPC]; #elif defined (__s390x__) return regs->gprs[2]; #elif defined (__aarch64__) return regs->regs[0]; #elif defined (__arm__) return regs->ARM_r0; #elif defined (__mips__) return regs->regs[2]; #else _stp_error("returnval() not defined for this architecture"); return 0; #endif } _stp_error("_stp_returnval called with 0"); /* non-crashy assert */ return 0;} %} %( systemtap_v <= "4.0" %? %{ #define STAP_NEED_CONTEXT_RETURNVAL 1 %} function set_returnval(val:long) %{ CONTEXT->returnval_override = STAP_ARG_val; CONTEXT->returnval_override_p = 1; %} %) /* compatible <= 4.0 */ /* NB: The following function is not STABLE because it depends on varying state in the context. */ /** * sfunction returnval - Possible return value of probed function * * Description: Return the value of the register in which function values * are typically returned. Can be used in probes where $return isn't * available. This is only a guess of the actual return value and can be * totally wrong. Normally only used in dwarfless probes. */ function returnval:long () %{ /* pure */ struct pt_regs *regs; #if STAP_COMPAT_VERSION <= STAP_VERSION(4,0) if (CONTEXT->returnval_override_p) STAP_RETURN(CONTEXT->returnval_override); #endif regs = (CONTEXT->user_mode_p ? CONTEXT->uregs : CONTEXT->kregs); if (regs) STAP_RETURN(_stp_returnval(regs)); else STAP_ERROR("returnval() not defined in this context %s", CONTEXT->probe_point); %} /** * sfunction returnstr - Formats the return value as a string * * @format: Variable to determine return type base value * * Description: This function is used by the nd_syscall tapset, and * returns a string. Set format equal to 1 for a decimal, * 2 for hex, 3 for octal. * * Note that this function should only be used in dwarfless probes * (i.e. 'kprobe.function("foo")'). Other probes should use * return_str(). */ function returnstr:string (format:long) %{ /* pure */ struct pt_regs *regs; regs = (CONTEXT->user_mode_p ? CONTEXT->uregs : CONTEXT->kregs); if (regs) { long ret = _stp_returnval(regs); if (ret < 0 && ret > -Maxerrno && errlist[-ret]) snprintf (STAP_RETVALUE, MAXSTRINGLEN, "%ld (%s)", ret, errlist[-ret]); else if (STAP_ARG_format == 2) snprintf (STAP_RETVALUE, MAXSTRINGLEN, "0x%lx", ret); else if (STAP_ARG_format == 3) snprintf (STAP_RETVALUE, MAXSTRINGLEN, "%#lo", ret); else snprintf (STAP_RETVALUE, MAXSTRINGLEN, "%ld", ret); } else { no_ret: strlcpy(STAP_RETVALUE, "N/A", MAXSTRINGLEN); // XXX: empty string better } %} /** * sfunction return_str - Formats the return value as a string * * @format: Variable to determine return type base value * @ret: Return value (typically $return) * * Description: This function is used by the syscall tapset, and * returns a string. Set format equal to 1 for a decimal, * 2 for hex, 3 for octal. * * Note that this function is preferred over returnstr(). */ function return_str:string(format:long, ret:long) { if (ret < 0 && errno_p(ret)) return sprintf("%d (%s)", ret, errno_str(ret)) if (format == 2) return sprintf("0x%x", ret) else if (format == 3) return sprintf("%#o", ret) else return sprintf("%d", ret) }