Embitude Infotech1

Kprobes in Linux Kernel – Practical Use Cases with Code (Part 2)

(Focus Keyphrase: Kprobes practical examples Linux kernel)


🔁 Quick Recap

In the previous blog, we explored:

  • What Kprobes are
  • How they help debug without modifying kernel code
  • Why they are powerful for runtime debugging

Now let’s move one step deeper.

👉 Instead of just understanding the concept,
👉 Let’s use Kprobes in real debugging scenarios with code.


The Real Question

Understanding Kprobes is one thing.

But the real question is:

💭 When should I actually use Kprobes in real projects?
💭 What kind of problems can I solve using them?

Let’s answer that with practical use cases.


Use Case 1: “Is This Function Even Getting Called?”

Scenario

You suspect that a kernel function is not getting executed.

Instead of modifying kernel code and rebuilding…

👉 Just probe it.


🧪 Code Example

#include <linux/module.h>
#include <linux/kprobes.h>

static struct kprobe kp;

static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
    pr_info("Function hit: %s\n", p->symbol_name);
    return 0;
}

static int __init kprobe_init(void)
{
    kp.symbol_name = "do_sys_open";
    kp.pre_handler = handler_pre;

    register_kprobe(&kp);
    pr_info("Kprobe registered\n");
    return 0;
}

static void __exit kprobe_exit(void)
{
    unregister_kprobe(&kp);
    pr_info("Kprobe unregistered\n");
}

module_init(kprobe_init);
module_exit(kprobe_exit);
MODULE_LICENSE("GPL");

What This Solves

✔ Confirms execution path
✔ Helps debug missing flows
✔ No kernel rebuild required


Use Case 2: Inspect Function Arguments

Scenario

You suspect incorrect data is reaching a kernel function.


🧪 Code Example (x86_64)

static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
    pr_info("First argument: %lx\n", regs->di);
    return 0;
}

⚠️ Important Note

  • Register mapping depends on architecture
  • On ARM, arguments are passed differently

What This Solves

✔ Debug incorrect inputs
✔ Trace runtime data flow
✔ Understand function behavior


Use Case 3: Tracking Frequency of Execution

Scenario

You want to know:

💭 Why is CPU usage high?
💭 Is this function being called too frequently?


🧪 Code Example

static int count = 0;

static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
    count++;
    pr_info("Called %d times\n", count);
    return 0;
}

What This Solves

✔ Detect hotspots
✔ Identify unexpected loops
✔ Analyze performance issues


Use Case 4: Conditional Debugging

Scenario

You only want logs when a specific condition occurs.


🧪 Code Example

static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
    if (regs->di == 0) {
        pr_info("Suspicious value detected!\n");
    }
    return 0;
}

What This Solves

✔ Reduces unnecessary logs
✔ Focuses on critical cases
✔ Makes debugging cleaner


⚠️ Best Practices

  • Keep probe handlers lightweight
  • Avoid probing high-frequency functions blindly
  • Always unregister probes
  • Use carefully in production environments

Key Takeaway

In the previous blog, we asked:

👉 Can we debug without modifying kernel code?

Now you’ve seen:

👉 Yes — and you can apply it in multiple real-world scenarios.

Kprobes are not just theoretical tools.
They are practical debugging instruments.


🔜 What’s Next?

So far, we’ve focused on:

✔ Function entry
✔ Arguments
✔ Execution flow

But what about:

💭 What does the function return?
💭 Did it succeed or fail?

👉 In the next blog, we will explore Kretprobes to capture return values.


Build Real Debugging Confidence

Knowing tools is useful.

But real debugging confidence comes from understanding the system deeply.

If you want to build that foundation:

👉 https://embitude.in/embedded-linux-bundle/


🎥 Deep dive into Embedded Linux:
👉 https://www.youtube.com/@PradeepTewani

🤝 Join the community of like-minded professionals:
👉 https://embitudeinfotech.graphy.com/s/community

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top