patch-1.3.26 linux/scripts/ksymoops.cc
Next file: linux/Documentation/devices.tex
Previous file: linux/net/unix/af_unix.c
Back to the patch index
Back to the overall index
- Lines: 184
- Date:
Mon Sep 11 07:47:01 1995
- Orig file:
v1.3.25/linux/scripts/ksymoops.cc
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v1.3.25/linux/scripts/ksymoops.cc linux/scripts/ksymoops.cc
@@ -0,0 +1,182 @@
+/* ksymoops.c -- simple Linux Oops-log symbol resolver
+ Copyright (C) 1995 Greg McGary
+
+ 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 2, 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; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* This is a simple filter to resolve EIP and call-trace symbols from
+ a Linux kernel "Oops" log. Supply the symbol-map file name as a
+ command-line argument, and redirect the oops-log into stdin.
+ Out will come the EIP and call-trace in symbolic form. */
+
+#include <fstream.h>
+#include <string.h>
+#include <stdlib.h>
+
+inline int strequ(char const* x, char const* y) { return (::strcmp(x, y) == 0); }
+
+//////////////////////////////////////////////////////////////////////////////
+
+class KSym
+{
+ friend class NameList;
+
+ private:
+ long address_;
+ char type_;
+ char* name_;
+ long offset_;
+ long extent_;
+
+ public:
+ void set_extent(KSym const& next_ksym) { extent_ = next_ksym.address_ - address_; }
+ friend istream& operator >> (istream&, KSym&);
+ friend ostream& operator << (ostream&, const KSym&);
+};
+
+istream&
+operator >> (istream& is, KSym& n)
+{
+ is >> hex >> n.address_;
+ is >> n.type_;
+ char name[128];
+ is >> name;
+ n.name_ = new char [strlen(name)+1];
+ strcpy(n.name_, name);
+ n.offset_ = 0;
+ return is;
+}
+
+ostream&
+operator << (ostream& os, const KSym& n)
+{
+ os << hex << n.address_ + n.offset_ << ' ' << n.type_ << ' ' << n.name_;
+ if (n.offset_)
+ os << '+' << hex << n.offset_ << '/' << hex << n.extent_;
+ return os;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+class NameList
+{
+ private:
+ // Caution: Fixed Allocation!
+ // This should suffice for awhile since 1.1.86 has only 2482 symbols.
+ KSym ksyms_0_[4096];
+ int cardinality_;
+
+ public:
+ NameList() : cardinality_(0) { }
+
+ public:
+ KSym* find(long address);
+
+ public:
+ friend istream& operator >> (istream&, NameList&);
+};
+
+KSym*
+NameList::find(long address)
+{
+ KSym* start = ksyms_0_;
+ KSym* end = &ksyms_0_[cardinality_];
+ KSym* mid;
+
+ while (start <= end) {
+ mid = &start[(end - start) / 2];
+ if (mid->address_ < address)
+ start = mid + 1;
+ else if (mid->address_ > address)
+ end = mid - 1;
+ else
+ return mid;
+ }
+ while (mid->address_ > address)
+ --mid;
+ mid->offset_ = address - mid->address_;
+ if (mid->offset_ > mid->extent_)
+ clog << "Oops! " << *mid << endl;
+ return mid;
+}
+
+istream&
+operator >> (istream& is, NameList& n)
+{
+ KSym* ksyms = n.ksyms_0_;
+ int cardinality = 0;
+ while (!is.eof()) {
+ is >> *ksyms;
+ ksyms[-1].set_extent(*ksyms);
+ ksyms++;
+ cardinality++;
+ }
+ n.cardinality_ = --cardinality;
+ return is;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+char const* program_name;
+
+void
+usage()
+{
+ clog << "Usage: " << program_name << " system-map-file < oops-log" << endl;
+ exit(1);
+}
+
+int
+main(int argc, char** argv)
+{
+ program_name = (argc--, *argv++);
+ if (argc != 1)
+ usage();
+
+ char const* map_file_name = (argc--, *argv++);
+ ifstream map(map_file_name);
+ if (map.bad()) {
+ clog << program_name << ": Can't open `" << map_file_name << "'" << endl;
+ return 1;
+ }
+
+ NameList names;
+ map >> names;
+
+ char buffer[1024];
+ while (!cin.eof())
+ {
+ long address;
+ cin >> buffer;
+ if (strequ(buffer, "EIP:")) {
+ cin >> hex >> address;
+ cin >> buffer[0];
+ cin >> hex >> address;
+ KSym* ksym = names.find(address);
+ if (ksym)
+ cout << "EIP: " << *ksym << endl;
+ } else if (strequ(buffer, "Trace:")) {
+ while ((cin >> address) && address > 0xc) {
+ KSym* ksym = names.find(address);
+ if (ksym)
+ cout << "Trace: " << *ksym << endl;
+ }
+ cout << endl;
+ }
+ }
+ cout << flush;
+
+ return 0;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this