[LTP] [PATCH v5] Rewrite ftrace_regression tests with new C API
Li Wang
wangli.ahau@gmail.com
Mon Apr 27 10:40:03 CEST 2026
Hi Lufei,
Thanks for the refactoring, see comment inline below:
On Fri, Apr 24, 2026 at 10:09 AM lufei <lufei@uniontech.com> wrote:
>
> Rewritten from old shell scripts.
>
> ftrace_regression01: regression test for panic bug while using
> userstacktrace, set userstacktrace in loop and check if success.
>
> ftrace_regression02: for checking signal:signal_generate gives
> 2 more fields: grp res.
>
> Signed-off-by: lufei <lufei@uniontech.com>
> ---
> runtest/tracing | 4 +-
> .../kernel/tracing/ftrace_test/.gitignore | 2 +
> .../tracing/ftrace_test/ftrace_regression.h | 62 ++++++++++++++
> .../tracing/ftrace_test/ftrace_regression01.c | 82 ++++++++++++++++++
> .../ftrace_test/ftrace_regression01.sh | 83 -------------------
> .../tracing/ftrace_test/ftrace_regression02.c | 56 +++++++++++++
> .../ftrace_test/ftrace_regression02.sh | 63 --------------
> 7 files changed, 204 insertions(+), 148 deletions(-)
> create mode 100644 testcases/kernel/tracing/ftrace_test/.gitignore
> create mode 100644 testcases/kernel/tracing/ftrace_test/ftrace_regression.h
> create mode 100644 testcases/kernel/tracing/ftrace_test/ftrace_regression01.c
> delete mode 100755 testcases/kernel/tracing/ftrace_test/ftrace_regression01.sh
> create mode 100644 testcases/kernel/tracing/ftrace_test/ftrace_regression02.c
> delete mode 100755 testcases/kernel/tracing/ftrace_test/ftrace_regression02.sh
>
> diff --git a/runtest/tracing b/runtest/tracing
> index 674e2ad97..2a4a92c5f 100644
> --- a/runtest/tracing
> +++ b/runtest/tracing
> @@ -1,6 +1,6 @@
> #DESCRIPTION:Tracing testing
> -ftrace_regression01 ftrace_regression01.sh
> -ftrace_regression02 ftrace_regression02.sh
> +ftrace_regression01 ftrace_regression01
> +ftrace_regression02 ftrace_regression02
> ftrace-stress-test ftrace_stress_test.sh 90
> dynamic_debug01 dynamic_debug01.sh
> fanotify25 fanotify25
> diff --git a/testcases/kernel/tracing/ftrace_test/.gitignore b/testcases/kernel/tracing/ftrace_test/.gitignore
> new file mode 100644
> index 000000000..b0153e9fa
> --- /dev/null
> +++ b/testcases/kernel/tracing/ftrace_test/.gitignore
> @@ -0,0 +1,2 @@
> +ftrace_regression01
> +ftrace_regression02
> diff --git a/testcases/kernel/tracing/ftrace_test/ftrace_regression.h b/testcases/kernel/tracing/ftrace_test/ftrace_regression.h
> new file mode 100644
> index 000000000..ab18e3768
> --- /dev/null
> +++ b/testcases/kernel/tracing/ftrace_test/ftrace_regression.h
> @@ -0,0 +1,62 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * Copyright (c) 2026 lufei <lufei@uniontech.com>
> + *
> + * Shared header for ftrace regression tests.
> + */
> +
> +#ifndef FTRACE_REGRESSION_H
> +#define FTRACE_REGRESSION_H
> +
> +#include "tst_test.h"
> +#include "tst_safe_file_ops.h"
> +#include "tst_safe_stdio.h"
> +
> +#include <regex.h>
> +#include <stdio.h>
> +
> +#define FTRACE_LINE_BUF_SIZE 1024
> +#define DEBUGFS_DIR "debugfs"
> +
> +/**
> + * file_contains - Check if a file contains specific regex pattern.
> + */
> +static inline int file_contains(const char *path, const char *pattern)
> +{
> + FILE *fp = SAFE_FOPEN(path, "r");
> + char *buf = SAFE_MALLOC(FTRACE_LINE_BUF_SIZE);
> + bool found = false;
> +
> + regex_t re;
> +
> + if (regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0) {
> + SAFE_FCLOSE(fp);
> + free(buf);
> + return found;
> + }
> +
> + while (fgets(buf, FTRACE_LINE_BUF_SIZE, fp)) {
> + if (regexec(&re, buf, 0, NULL, 0) == 0) {
> + found = true;
> + break;
> + }
> + }
> +
> + regfree(&re);
> + SAFE_FCLOSE(fp);
> + free(buf);
> + return found;
> +}
> +
> +static inline void mount_debugfs(void)
> +{
> + SAFE_MKDIR(DEBUGFS_DIR, 0755);
> + SAFE_MOUNT(NULL, DEBUGFS_DIR, "debugfs", 0, NULL);
> +}
> +
> +static inline void umount_debugfs(void)
> +{
> + SAFE_UMOUNT(DEBUGFS_DIR);
> +}
> +
> +#endif /* FTRACE_REGRESSION_H */
> diff --git a/testcases/kernel/tracing/ftrace_test/ftrace_regression01.c b/testcases/kernel/tracing/ftrace_test/ftrace_regression01.c
> new file mode 100644
> index 000000000..be2327582
> --- /dev/null
> +++ b/testcases/kernel/tracing/ftrace_test/ftrace_regression01.c
> @@ -0,0 +1,82 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2015 Red Hat Inc.
> + * Copyright (c) 2026 lufei <lufei@uniontech.com>
> + */
> +
> +/*\
> + * Regression test for panic while using userstacktrace.
> + *
> + * BUG: unable to handle kernel paging request at 00000000417683c0
> + * IP: [<ffffffff8105c834>] update_curr+0x124/0x1e0
> + * Thread overran stack, or stack corrupted
> + * Oops: 0000 [#1] SMP
> + * last sysfs file: ../system/cpu/cpu15/cache/index2/shared_cpu_map
> + *
> + * The bug was fixed by:
> + * 1dbd195 (tracing: Fix preempt count leak)
> + */
> +
> +#include <unistd.h>
> +#include "ftrace_regression.h"
> +
> +#define STACK_TRACER_PATH "/proc/sys/kernel/stack_tracer_enabled"
> +#define TRACE_OPTIONS DEBUGFS_DIR "/tracing/trace_options"
> +#define EXC_PAGE_FAULT DEBUGFS_DIR "/tracing/events/exceptions/page_fault_kernel/enable"
> +#define MM_PAGE_FAULT DEBUGFS_DIR "/tracing/events/kmem/mm_kernel_pagefault/enable"
> +
> +#define LOOP 10
> +
> +static const char *page_fault_path;
> +static int page_fault_origin;
> +
> +static void setup(void)
> +{
> + mount_debugfs();
> +
> + if (access(EXC_PAGE_FAULT, F_OK) == 0)
> + page_fault_path = EXC_PAGE_FAULT;
> + else if (access(MM_PAGE_FAULT, F_OK) == 0)
> + page_fault_path = MM_PAGE_FAULT;
> + else
> + tst_brk(TCONF, "Page fault event not available");
> +
> + SAFE_FILE_SCANF(page_fault_path, "%d", &page_fault_origin);
> +}
> +
> +static void run(void)
> +{
> + int i;
> +
> + for (i = 0; i < LOOP; i++) {
> + SAFE_FILE_PRINTF(STACK_TRACER_PATH, "1");
> + SAFE_FILE_PRINTF(TRACE_OPTIONS, "userstacktrace");
> +
> + if (!file_contains(TRACE_OPTIONS, "^userstacktrace"))
> + tst_brk(TBROK, "Failed to set userstacktrace");
> +
> + SAFE_FILE_PRINTF(page_fault_path, "1");
> + }
> +
> + SAFE_FILE_PRINTF(page_fault_path, "%d", page_fault_origin);
> +
> + tst_res(TPASS, "Test passed for setting userstacktrace "
> + "bug(preempt count leak) not reproduced"
> + );
No need put the ")" in a new line.
tst_res(TPASS, "Test passed for setting userstacktrace "
- "bug(preempt count leak) not reproduced"
- );
+ "bug(preempt count leak) not reproduced");
> +}
> +
> +static struct tst_test test = {
> + .needs_root = 1,
> + .needs_tmpdir = 1,
> + .setup = setup,
> + .test_all = run,
> + .cleanup = umount_debugfs,
> + .save_restore = (const struct tst_path_val[]) {
> + {STACK_TRACER_PATH, NULL, TST_SR_TCONF},
> + {}
> + },
> + .tags = (const struct tst_tag[]) {
> + {"linux-git", "1dbd1951f39e"},
> + {}
> + },
> +};
> diff --git a/testcases/kernel/tracing/ftrace_test/ftrace_regression01.sh b/testcases/kernel/tracing/ftrace_test/ftrace_regression01.sh
> deleted file mode 100755
> index d6969cfc6..000000000
> --- a/testcases/kernel/tracing/ftrace_test/ftrace_regression01.sh
> +++ /dev/null
> @@ -1,83 +0,0 @@
> -#! /bin/sh
> -
> -###########################################################################
> -## ##
> -## Copyright (c) 2015, Red Hat Inc. ##
> -## ##
> -## This program is free software: you can redistribute it and/or modify ##
> -## it under the terms of the GNU General Public License as published by ##
> -## the Free Software Foundation, either version 3 of the License, or ##
> -## (at your option) any later version. ##
> -## ##
> -## This program is distributed in the hope that it will be useful, ##
> -## but WITHOUT ANY WARRANTY; without even the implied warranty of ##
> -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ##
> -## GNU General Public License for more details. ##
> -## ##
> -## You should have received a copy of the GNU General Public License ##
> -## along with this program. If not, see <http://www.gnu.org/licenses/>. ##
> -## ##
> -## Author: Li Wang <liwang@redhat.com> ##
> -## ##
> -###########################################################################
> -## ##
> -## Summary: panic while using userstacktrace ##
> -## ##
> -## BUG: unable to handle kernel paging request at 00000000417683c0 ##
> -## IP: [<ffffffff8105c834>] update_curr+0x124/0x1e0 ##
> -## PGD 41a796067 PUD 0 ##
> -## Thread overran stack, or stack corrupted ##
> -## Oops: 0000 [#1] SMP ##
> -## last sysfs file: ../system/cpu/cpu15/cache/index2/shared_cpu_map ##
> -## ##
> -## The bug was fixed by: ##
> -## 1dbd195 (tracing: Fix preempt count leak) ##
> -## ##
> -###########################################################################
> -
> -export TCID="ftrace_regression01"
> -export TST_TOTAL=1
> -
> -. ftrace_lib.sh
> -
> -LOOP=10
> -
> -TSTACK_TRACE_PATH="/proc/sys/kernel/stack_tracer_enabled"
> -EXC_PAGE_FAULT_ENABLE="$TRACING_PATH/events/exceptions/page_fault_kernel/enable"
> -MM_PAGE_FAULT_ENABLE="$TRACING_PATH/events/kmem/mm_kernel_pagefault/enable"
> -
> -ftrace_userstacktrace_test()
> -{
> - if [ ! -e "$TSTACK_TRACE_PATH" ]; then
> - tst_brkm TCONF "Stack Tracer is not cofigured in This kernel"
> - fi
> -
> - for i in $(seq $LOOP); do
> - echo 1 > $TSTACK_TRACE_PATH
> - echo userstacktrace > $TRACING_PATH/trace_options
> - grep -q "^userstacktrace" $TRACING_PATH/trace_options
> - if [ $? -ne 0 ]; then
> - tst_brkm TBROK "Failed to set userstacktrace"
> - fi
> -
> - if [ -f "$EXC_PAGE_FAULT_ENABLE" ]; then
> - exc_page_fault_enable=`cat $EXC_PAGE_FAULT_ENABLE`
> - echo 1 > $EXC_PAGE_FAULT_ENABLE
> - else
> - mm_page_fault_enable=`cat $MM_PAGE_FAULT_ENABLE`
> - echo 1 > $MM_PAGE_FAULT_ENABLE
> - fi
> - done
> -
> - if [ -f "$EXC_PAGE_FAULT_ENABLE" ]; then
> - echo "$exc_page_fault_enable" > $EXC_PAGE_FAULT_ENABLE
> - else
> - echo "$mm_page_fault_enable" > $MM_PAGE_FAULT_ENABLE
> - fi
> -
> - tst_resm TPASS "Finished running the test"
> -}
> -
> -ftrace_userstacktrace_test
> -
> -tst_exit
> diff --git a/testcases/kernel/tracing/ftrace_test/ftrace_regression02.c b/testcases/kernel/tracing/ftrace_test/ftrace_regression02.c
> new file mode 100644
> index 000000000..b4aac7ad0
> --- /dev/null
> +++ b/testcases/kernel/tracing/ftrace_test/ftrace_regression02.c
> @@ -0,0 +1,56 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2015 Red Hat Inc.
> + * Copyright (c) 2026 lufei <lufei@uniontech.com>
> + */
> +
> +/*\
> + * Check signal:signal_generate gives 2 more fields: grp=[0-9] res=[0-9]
> + */
> +
> +#include "ftrace_regression.h"
> +
> +#define SET_EVENT DEBUGFS_DIR "/tracing/set_event"
> +#define TRACING_ON DEBUGFS_DIR "/tracing/tracing_on"
> +#define TRACE_FILE DEBUGFS_DIR "/tracing/trace"
> +
> +#define LOOP 100
> +
> +static void run(void)
> +{
> + int i;
> + const char *const cmd_ls[] = {"ls", "-l", "/proc", NULL};
Here I'd suggest using a stable directory for listing, since in /proc there are
many pid DIRs that temporarily exist, so it easy to hit race condition
in testing.
const char *const cmd_ls[] = {"ls", "-l", "/sys/kernel/tracing/", NULL};
In my strace output:
[pid 4696] 1777276263.339591 (+ 0.000048) statx(AT_FDCWD,
"/proc/4677", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT,
STATX_MODE|STATX_NLINK|STATX_UID|STATX_GID|STATX_MTIME|STATX_SIZE,
0x7ffc8cdef8f0) = -1 ENOENT (No such file or directory) <0.000016>
...
ftrace_regression02.c:30: TBROK: ls failed (1)
> +
> + SAFE_FILE_PRINTF(SET_EVENT, "signal:signal_generate");
> + SAFE_FILE_PRINTF(TRACING_ON, "1");
> + SAFE_FILE_PRINTF(TRACE_FILE, "\n");
> +
> + // to generate trace
Please use /* */ in LTP code comments.
Otherwise looks good to me:
Reviewed-by: Li Wang <li.wang@linux.dev>
--
Regards,
Li Wang
More information about the ltp
mailing list