static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels) { unsigned long addr; while (levels && stack & (THREAD_SIZE - 1)) { if (unlikely(_stp_read_address(addr, (unsigned long *)stack, KERNEL_DS))) { /* cannot access stack. give up. */ return; } _stp_print_addr(addr, verbose | _STP_SYM_INEXACT, NULL); levels--; stack++; } }
/** Return a printable text string. * * Takes a string, and any ASCII characters that are not printable are * replaced by the corresponding escape sequence in the returned * string. * * @param outstr Output string pointer * @param in Input string pointer * @param inlen Maximum length of string to read not including terminating 0. * @param outlen Maximum length of string to return not including terminating 0. * 0 means MAXSTRINGLEN. * @param quoted Put double quotes around the string. If input string is truncated * in will have "..." after the second quote. * @param user Set this to indicate the input string pointer is a userspace pointer. */ static int _stp_text_str(char *outstr, const char *in, int inlen, int outlen, int quoted, int user) { char c = '\0', *out = outstr; if (inlen <= 0 || inlen > MAXSTRINGLEN-1) inlen = MAXSTRINGLEN-1; if (outlen <= 0 || outlen > MAXSTRINGLEN-1) outlen = MAXSTRINGLEN-1; if (quoted) { outlen = max(outlen, 5) - 2; *out++ = '"'; } if (_stp_read_address(c, in, (user ? USER_DS : KERNEL_DS))) goto bad; while (c && inlen > 0 && outlen > 0) { int num = 1; if (isprint(c) && isascii(c) && c != '"' && c != '\\') /* quoteworthy characters */ *out++ = c; else { switch (c) { case '\a': case '\b': case '\f': case '\n': case '\r': case '\t': case '\v': case '"': case '\\': num = 2; break; default: num = 4; break; } if (outlen < num) break; *out++ = '\\'; switch (c) { case '\a': *out++ = 'a'; break; case '\b': *out++ = 'b'; break; case '\f': *out++ = 'f'; break; case '\n': *out++ = 'n'; break; case '\r': *out++ = 'r'; break; case '\t': *out++ = 't'; break; case '\v': *out++ = 'v'; break; case '"': *out++ = '"'; break; case '\\': *out++ = '\\'; break; default: /* output octal representation */ *out++ = to_oct_digit((c >> 6) & 03); *out++ = to_oct_digit((c >> 3) & 07); *out++ = to_oct_digit(c & 07); break; } } outlen -= num; inlen--; in++; if (_stp_read_address(c, in, (user ? USER_DS : KERNEL_DS))) goto bad; } if (quoted) { if (c && inlen > 0) { out = out - 3 + outlen; *out++ = '"'; *out++ = '.'; *out++ = '.'; *out++ = '.'; } else *out++ = '"'; } *out = '\0'; return 0; bad: strlcpy (outstr, "<unknown>", outlen); return -1; // PR15044 }