Initial commit: Linux kernel 4.19 for Unplugged OS

This commit is contained in:
ziv committed 2025-10-06 13:52:42 +00:00
commit d30235b04c
80519 files changed
+35800681

No files matched your search

+129
View File
@@ -0,0 +1,129 @@
#!/usr/bin/python
"""
Copyright 2008 (c) Frederic Weisbecker <fweisbec@gmail.com>
Licensed under the terms of the GNU GPL License version 2
This script parses a trace provided by the function tracer in
kernel/trace/trace_functions.c
The resulted trace is processed into a tree to produce a more human
view of the call stack by drawing textual but hierarchical tree of
calls. Only the functions's names and the the call time are provided.
Usage:
Be sure that you have CONFIG_FUNCTION_TRACER
# mount -t debugfs nodev /sys/kernel/debug
# echo function > /sys/kernel/debug/tracing/current_tracer
$ cat /sys/kernel/debug/tracing/trace_pipe > ~/raw_trace_func
Wait some times but not too much, the script is a bit slow.
Break the pipe (Ctrl + Z)
$ scripts/draw_functrace.py < raw_trace_func > draw_functrace
Then you have your drawn trace in draw_functrace
"""
import sys, re
class CallTree:
""" This class provides a tree representation of the functions
call stack. If a function has no parent in the kernel (interrupt,
syscall, kernel thread...) then it is attached to a virtual parent
called ROOT.
"""
ROOT = None
def __init__(self, func, time = None, parent = None):
self._func = func
self._time = time
if parent is None:
self._parent = CallTree.ROOT
else:
self._parent = parent
self._children = []
def calls(self, func, calltime):
""" If a function calls another one, call this method to insert it
into the tree at the appropriate place.
@return: A reference to the newly created child node.
"""
child = CallTree(func, calltime, self)
self._children.append(child)
return child
def getParent(self, func):
""" Retrieve the last parent of the current node that
has the name given by func. If this function is not
on a parent, then create it as new child of root
@return: A reference to the parent.
"""
tree = self
while tree != CallTree.ROOT and tree._func != func:
tree = tree._parent
if tree == CallTree.ROOT:
child = CallTree.ROOT.calls(func, None)
return child
return tree
def __repr__(self):
return self.__toString("", True)
def __toString(self, branch, lastChild):
if self._time is not None:
s = "%s----%s (%s)\n" % (branch, self._func, self._time)
else:
s = "%s----%s\n" % (branch, self._func)
i = 0
if lastChild:
branch = branch[:-1] + " "
while i < len(self._children):
if i != len(self._children) - 1:
s += "%s" % self._children[i].__toString(branch +\
" |", False)
else:
s += "%s" % self._children[i].__toString(branch +\
" |", True)
i += 1
return s
class BrokenLineException(Exception):
"""If the last line is not complete because of the pipe breakage,
we want to stop the processing and ignore this line.
"""
pass
class CommentLineException(Exception):
""" If the line is a comment (as in the beginning of the trace file),
just ignore it.
"""
pass
def parseLine(line):
line = line.strip()
if line.startswith("#"):
raise CommentLineException
m = re.match("[^]]+?\\] +([0-9.]+): (\\w+) <-(\\w+)", line)
if m is None:
raise BrokenLineException
return (m.group(1), m.group(2), m.group(3))
def main():
CallTree.ROOT = CallTree("Root (Nowhere)", None, None)
tree = CallTree.ROOT
for line in sys.stdin:
try:
calltime, callee, caller = parseLine(line)
except BrokenLineException:
break
except CommentLineException:
continue
tree = tree.getParent(caller)
tree = tree.calls(callee, calltime)
print(CallTree.ROOT)
if __name__ == "__main__":
main()
+116
View File
@@ -0,0 +1,116 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Here's how to use this:
#
# This script is used to help find functions that are being traced by function
# tracer or function graph tracing that causes the machine to reboot, hang, or
# crash. Here's the steps to take.
#
# First, determine if function tracing is working with a single function:
#
# (note, if this is a problem with function_graph tracing, then simply
# replace "function" with "function_graph" in the following steps).
#
# # cd /sys/kernel/debug/tracing
# # echo schedule > set_ftrace_filter
# # echo function > current_tracer
#
# If this works, then we know that something is being traced that shouldn't be.
#
# # echo nop > current_tracer
#
# # cat available_filter_functions > ~/full-file
# # ftrace-bisect ~/full-file ~/test-file ~/non-test-file
# # cat ~/test-file > set_ftrace_filter
#
# *** Note *** this will take several minutes. Setting multiple functions is
# an O(n^2) operation, and we are dealing with thousands of functions. So go
# have coffee, talk with your coworkers, read facebook. And eventually, this
# operation will end.
#
# # echo function > current_tracer
#
# If it crashes, we know that ~/test-file has a bad function.
#
# Reboot back to test kernel.
#
# # cd /sys/kernel/debug/tracing
# # mv ~/test-file ~/full-file
#
# If it didn't crash.
#
# # echo nop > current_tracer
# # mv ~/non-test-file ~/full-file
#
# Get rid of the other test file from previous run (or save them off somewhere).
# # rm -f ~/test-file ~/non-test-file
#
# And start again:
#
# # ftrace-bisect ~/full-file ~/test-file ~/non-test-file
#
# The good thing is, because this cuts the number of functions in ~/test-file
# by half, the cat of it into set_ftrace_filter takes half as long each
# iteration, so don't talk so much at the water cooler the second time.
#
# Eventually, if you did this correctly, you will get down to the problem
# function, and all we need to do is to notrace it.
#
# The way to figure out if the problem function is bad, just do:
#
# # echo <problem-function> > set_ftrace_notrace
# # echo > set_ftrace_filter
# # echo function > current_tracer
#
# And if it doesn't crash, we are done.
#
# If it does crash, do this again (there's more than one problem function)
# but you need to echo the problem function(s) into set_ftrace_notrace before
# enabling function tracing in the above steps. Or if you can compile the
# kernel, annotate the problem functions with "notrace" and start again.
#
if [ $# -ne 3 ]; then
echo 'usage: ftrace-bisect full-file test-file non-test-file'
exit
fi
full=$1
test=$2
nontest=$3
x=`cat $full | wc -l`
if [ $x -eq 1 ]; then
echo "There's only one function left, must be the bad one"
cat $full
exit 0
fi
let x=$x/2
let y=$x+1
if [ ! -f $full ]; then
echo "$full does not exist"
exit 1
fi
if [ -f $test ]; then
echo -n "$test exists, delete it? [y/N]"
read a
if [ "$a" != "y" -a "$a" != "Y" ]; then
exit 1
fi
fi
if [ -f $nontest ]; then
echo -n "$nontest exists, delete it? [y/N]"
read a
if [ "$a" != "y" -a "$a" != "Y" ]; then
exit 1
fi
fi
sed -ne "1,${x}p" $full > $test
sed -ne "$y,\$p" $full > $nontest