Currently, the log command will display human readable Rust
symbol name by default if any, but, sometimes still want to
print the original messages from the log buffer(do not demangle).
In addition, if the log buffer has lines like "_R ... +" which
are not Rust symbols unexpectedly, probably the output will be
missed, that is unexpected.
To fix above cases, add "log -R" to display human readable Rust
symbol name, otherwise still print the original messages.
With the patch:
crash> log -R
...
[ 2174.289360] Tainted: [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[ 2174.297322] Hardware name: Intel Corporation S2600CWR/S2600CWR, BIOS
SE5C610.86B.01.01.0018.072020161249 07/20/2016
[ 2174.308966] Call Trace:
[ 2174.311693] <TASK>
[ 2174.314033] dump_stack_lvl+0x5d/0x80
[ 2174.318125] panic+0x156/0x32a
[ 2174.321539] rust_panic::area_in_hp+0xf7/0x120 [rust_panic]
[ 2174.329700] ? console_unlock+0x9c/0x140
[ 2174.334080] ? irq_work_queue+0x2d/0x50
[ 2174.338352] ? __pfx_init_module+0x10/0x10 [rust_panic]
[ 2174.344183] <rust_panic::HelloPanic>::step_two+0x20/0xe0 [rust_panic]
[ 2174.353698] ? _printk+0x6b/0x90
[ 2174.357303] init_module+0x57/0xff0 [rust_panic]
[ 2174.362456] ? __pfx_init_module+0x10/0x10 [rust_panic]
...
Suggested-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
defs.h | 1 +
help.c | 24 ++++++++++++++++++-
kernel.c | 5 +++-
printk.c | 71 ++++++++++++++++++++++++++++++++++----------------------
4 files changed, 71 insertions(+), 30 deletions(-)
diff --git a/defs.h b/defs.h
index 3fd7d897c781..c434a5cae702 100644
--- a/defs.h
+++ b/defs.h
@@ -6229,6 +6229,7 @@ void parse_kernel_version(char *);
#define SHOW_LOG_CTIME (0x10)
#define SHOW_LOG_SAFE (0x20)
#define SHOW_LOG_CALLER (0x40)
+#define SHOW_LOG_RUST (0x80)
void set_cpu(int);
void clear_machdep_cache(void);
struct stack_hook *gather_text_list(struct bt_info *);
diff --git a/help.c b/help.c
index 4f071e0bd0a0..78d7a5c70e30 100644
--- a/help.c
+++ b/help.c
@@ -4026,7 +4026,7 @@ NULL
char *help_log[] = {
"log",
"dump system message buffer",
-"[-Ttdmasc]",
+"[-TtdmascR]",
" This command dumps the kernel log_buf contents in chronological order.
The",
" command supports the older log_buf formats, which may or may not contain
a",
" timestamp inserted prior to each message, as well as the newer
variable-length",
@@ -4053,6 +4053,8 @@ char *help_log[] = {
" the CPU id (if in CPU context) that called printk(), if available.",
" Generally available on Linux 5.1 to 5.9 kernels configured with",
" CONFIG_PRINTK_CALLER or Linux 5.10 and later kernels.",
+" -R Display the message text with human readable Rust symbol name if
any,",
+" otherwise still print the original message text.",
" ",
"\nEXAMPLES",
" Dump the kernel message buffer:\n",
@@ -4231,6 +4233,26 @@ char *help_log[] = {
" [ 0.014179] [ T29] RAMDISK: [mem 0x3cf4f000-0x437bbfff]",
" [ 0.198789] [ C0] DMAR: DRHD: handling fault status reg 3",
" ...",
+" ",
+" Display the message text with human readable Rust symbol name if any,",
+" otherwise still print the original message text.\n",
+" %s> log -R",
+" ...",
+" [ 2174.289360] Tainted: [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE,
[E]=UNSIGNED_MODULE",
+" [ 2174.297322] Hardware name: Intel Corporation S2600CWR/S2600CWR, BIOS
SE5C610.86B.01.01.0018.072020161249 07/20/2016",
+" [ 2174.308966] Call Trace:",
+" [ 2174.311693] <TASK>",
+" [ 2174.314033] dump_stack_lvl+0x5d/0x80",
+" [ 2174.318125] panic+0x156/0x32a",
+" [ 2174.321539] rust_panic::area_in_hp+0xf7/0x120 [rust_panic]",
+" [ 2174.329700] ? console_unlock+0x9c/0x140",
+" [ 2174.334080] ? irq_work_queue+0x2d/0x50",
+" [ 2174.338352] ? __pfx_init_module+0x10/0x10 [rust_panic]",
+" [ 2174.344183] <rust_panic::HelloPanic>::step_two+0x20/0xe0
[rust_panic]",
+" [ 2174.353698] ? _printk+0x6b/0x90",
+" [ 2174.357303] init_module+0x57/0xff0 [rust_panic]",
+" [ 2174.362456] ? __pfx_init_module+0x10/0x10 [rust_panic]",
+" ...",
NULL
};
diff --git a/kernel.c b/kernel.c
index e4213d7a663e..e077275d7ed6 100644
--- a/kernel.c
+++ b/kernel.c
@@ -5136,7 +5136,7 @@ cmd_log(void)
msg_flags = 0;
- while ((c = getopt(argcnt, args, "Ttdmasc")) != EOF) {
+ while ((c = getopt(argcnt, args, "TtdmascR")) != EOF) {
switch(c)
{
case 'T':
@@ -5160,6 +5160,9 @@ cmd_log(void)
case 'c':
msg_flags |= SHOW_LOG_CALLER;
break;
+ case 'R':
+ msg_flags |= SHOW_LOG_RUST;
+ break;
default:
argerrs++;
break;
diff --git a/printk.c b/printk.c
index 51b618e2a434..f7346f4c1c1d 100644
--- a/printk.c
+++ b/printk.c
@@ -116,7 +116,7 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
uint64_t ts_nsec;
ulonglong nanos;
ulonglong seq;
- int ilen = 0, i;
+ int ilen = 0, i, nlines;
char *desc, *info, *text, *p;
ulong rem;
@@ -202,44 +202,59 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
text = m->text_data + begin;
- if (text_len > BUFSIZE) {
+ if ((msg_flags & SHOW_LOG_RUST) && (text_len > BUFSIZE)) {
error(WARNING, "\nThe messages could be truncated!\n");
text_len = BUFSIZE;
}
- for (i = 0, p = text; i < text_len; i++, p++) {
- if (*p == '\n')
+ for (i = 0, nlines = 0, p = text; i < text_len; i++, p++) {
+ if (*p == '\n') {
+ if ((msg_flags & SHOW_LOG_RUST) && (i != text_len - 1)) {
+ nlines++;
+ if (strlen(buf)) {
+ fprintf(fp, "%s", buf);
+ memset(buf, 0, strlen(buf));
+ }
+ }
fprintf(fp, "\n%s", space(ilen));
- else if (isprint(*p) || isspace(*p))
- sprintf(&buf[i], "%c", *p);
+ } else if ((msg_flags & SHOW_LOG_RUST) && (isprint(*p) || isspace(*p))) {
+ if (nlines >= 1)
+ fputc(*p, fp);
+ else
+ sprintf(&buf[i], "%c", *p);
+ } else if (isprint(*p) || isspace(*p))
+ fputc(*p, fp);
else
fputc('.', fp);
}
/*
* Try to demangle a mangled Rust symbol(calltrace) from log buffer
*/
- char *p1 = strstr(buf, "_R");
- if (!p1)
- p1 = strstr(buf, "_ZN");
- char *p2 = strrchr(buf, '+');
- if (p1 && p2) {
- char mangled[BUFSIZE] = {0};
- char demangled[BUFSIZE] = {0};
- char *res;
- size_t slen = p1 - buf;
-
- if (slen)
- memcpy(demangled, buf, slen);
-
- memcpy(mangled, p1, p2-p1);
- res = rust_demangle(mangled, DMGL_RUST);
- if (res) {
- snprintf(demangled+slen, BUFSIZE-slen, "%s%s", res, p2);
- fprintf(fp, "%s",demangled);
- free(res);
- }
- } else
- fprintf(fp, "%s", buf);
+ if (msg_flags & SHOW_LOG_RUST) {
+ char *p1 = strstr(buf, "_R");
+ if (!p1)
+ p1 = strstr(buf, "_ZN");
+ char *p2 = strrchr(buf, '+');
+ if (p1 && p2) {
+ char mangled[BUFSIZE] = {0};
+ char demangled[BUFSIZE] = {0};
+ char *res;
+ size_t slen = p1 - buf;
+
+ if (slen)
+ memcpy(demangled, buf, slen);
+
+ memcpy(mangled, p1, p2-p1);
+ res = rust_demangle(mangled, DMGL_RUST);
+ if (res) {
+ snprintf(demangled+slen, BUFSIZE-slen, "%s%s", res, p2);
+ fprintf(fp, "%s",demangled);
+ free(res);
+ } else
+ fprintf(fp, "%s", buf);
+ } else
+ fprintf(fp, "%s", buf);
+ }
if (msg_flags & SHOW_LOG_DICT) {
text = info + OFFSET(printk_info_dev_info) +
--
2.50.1