summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/Hooks/Makefile.am18
-rw-r--r--src/Hooks/abrt-pyhook-helper.cpp138
-rw-r--r--src/Hooks/abrt_exception_handler.py.in53
-rw-r--r--src/Hooks/sitecustomize.py12
5 files changed, 179 insertions, 43 deletions
diff --git a/.gitignore b/.gitignore
index f92001af..ce402b3a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,4 +45,5 @@ src/Daemon/abrtd
src/Hooks/abrt_exception_handler.py
src/Hooks/dumpoops
src/Hooks/hookCCpp
+src/Hooks/abrt-pyhook-helper
stamp-h1
diff --git a/src/Hooks/Makefile.am b/src/Hooks/Makefile.am
index be1b1a2f..4eb25e2d 100644
--- a/src/Hooks/Makefile.am
+++ b/src/Hooks/Makefile.am
@@ -1,5 +1,5 @@
libexec_PROGRAMS = hookCCpp
-bin_PROGRAMS = dumpoops
+bin_PROGRAMS = dumpoops abrt-pyhook-helper
# CCpp
hookCCpp_SOURCES = \
@@ -29,6 +29,18 @@ dumpoops_CPPFLAGS = \
dumpoops_LDADD = \
../../lib/Utils/libABRTUtils.la
+# abrt-pyhook-helper
+abrt_pyhook_helper_SOURCES = \
+ abrt-pyhook-helper.cpp
+abrt_pyhook_helper_CPPFLAGS = \
+ -I$(srcdir)/../../inc \
+ -I$(srcdir)/../../lib/Utils \
+ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \
+ -DVAR_RUN=\"$(VAR_RUN)\" \
+ -D_GNU_SOURCE
+abrt_pyhook_helper_LDADD = \
+ ../../lib/Utils/libABRTUtils.la
+
man_MANS = pyhook.conf.5
python_PYTHON = sitecustomize.py abrt_exception_handler.py
@@ -45,3 +57,7 @@ abrt_exception_handler.py:
# RPM fix: we need to regenerate abrt_exception_handler.py, because it has the default ddir
install-data-local:
sed s,@DEBUG_DUMP_DIR@,$(DEBUG_DUMPS_DIR),g abrt_exception_handler.py.in > abrt_exception_handler.py
+
+install-data-hook:
+ chmod u+s,g+s $(DESTDIR)$(bindir)/abrt-pyhook-helper
+
diff --git a/src/Hooks/abrt-pyhook-helper.cpp b/src/Hooks/abrt-pyhook-helper.cpp
new file mode 100644
index 00000000..4ac6ada6
--- /dev/null
+++ b/src/Hooks/abrt-pyhook-helper.cpp
@@ -0,0 +1,138 @@
+/*
+ python-hook-writer.cpp - writes data to the /var/cache/abrt directory
+ with SUID bit
+
+ Copyright (C) 2009 RedHat 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 2 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <argp.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "DebugDump.h"
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+const char *argp_program_version = "abrt-pyhook-helper " VERSION;
+const char *argp_program_bug_address = "<crash-catcher@lists.fedorahosted.org>";
+
+static char doc[] = "abrt-pyhook-helper -- stores crash data to abrt shared directory";
+
+static struct argp_option options[] = {
+ {"pid" , 'p', "PID" , 0, "PID of process that caused the crash" },
+ {"executable", 'e', "PATH" , 0, "absolute path to the program that crashed" },
+ {"uuid" , 'u', "UUID" , 0, "hash generated from the backtrace"},
+ {"cmdline" , 'c', "TEXT" , 0, "command line of the crashed program"},
+ {"loginuid" , 'l', "UID" , 0, "login UID"},
+ { 0 }
+};
+
+struct arguments
+{
+ char *pid;
+ char *executable;
+ char *uuid;
+ char *cmdline;
+ char *loginuid;
+};
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ /* Get the input argument from argp_parse, which we
+ know is a pointer to our arguments structure. */
+ struct arguments *arguments = (struct arguments*)state->input;
+
+ switch (key)
+ {
+ case 'p': arguments->pid = arg; break;
+ case 'e': arguments->executable = arg; break;
+ case 'u': arguments->uuid = arg; break;
+ case 'c': arguments->cmdline = arg; break;
+ case 'l': arguments->loginuid = arg; break;
+
+ case ARGP_KEY_ARG:
+ argp_usage(state);
+ exit(1);
+ break;
+
+ case ARGP_KEY_END:
+ if (!arguments->pid)
+ {
+ argp_usage(state);
+ exit(1);
+ }
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+/* Our argp parser. */
+static struct argp argp = { options, parse_opt, 0, doc };
+
+int main(int argc, char** argv)
+{
+ struct arguments arguments;
+ argp_parse (&argp, argc, argv, 0, 0, &arguments);
+
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "%s/pyhook-%ld-%s", DEBUG_DUMPS_DIR,
+ (long)time(NULL), arguments.pid);
+
+ CDebugDump dd;
+ dd.Create(path, geteuid());
+ dd.SaveText(FILENAME_ANALYZER, "Python");
+ if (arguments.executable)
+ dd.SaveText(FILENAME_EXECUTABLE, arguments.executable);
+ if (arguments.cmdline)
+ dd.SaveText("cmdline", arguments.cmdline);
+ if (arguments.uuid)
+ dd.SaveText("uuid", arguments.uuid);
+ if (arguments.loginuid)
+ dd.SaveText("uid", arguments.loginuid);
+
+ // Read the backtrace from stdin.
+ int c;
+ int capacity = 1024;
+ char *bt = (char*)malloc(capacity);
+ char *btptr = bt;
+ while ((c = getchar()) != EOF)
+ {
+ if (c >= 0 && c <= 255)
+ *btptr++ = (char)c;
+ if (btptr - bt >= capacity - 1)
+ {
+ capacity *= 2;
+ bt = (char*)realloc(bt, capacity);
+ if (!bt)
+ {
+ printf("Error while allocating memory for backtrace.");
+ return 1;
+ }
+ }
+ }
+ *btptr = '\0';
+
+ dd.SaveText("backtrace", bt);
+ free(bt);
+ dd.Close();
+
+ return 0;
+}
diff --git a/src/Hooks/abrt_exception_handler.py.in b/src/Hooks/abrt_exception_handler.py.in
index 8ac7aa23..362aaf24 100644
--- a/src/Hooks/abrt_exception_handler.py.in
+++ b/src/Hooks/abrt_exception_handler.py.in
@@ -45,10 +45,10 @@ def exception_function():
import sys
import os
import syslog
+import subprocess
# abrt lib for saving debugdumps
import ABRTUtils
-
__DUMPHASH = {}
# FIXME: do length limits on obj dumps.
def __dump_class(instance, fd, level=0):
@@ -105,45 +105,20 @@ def __dump_class(instance, fd, level=0):
fd.write("%s%s: %s\n" % (pad, key, value))
def write_dump(pid, tb_uuid, tb):
- import time
- ttime = int(time.time())
- # localstatedir
- dir_name = "@DEBUG_DUMP_DIR@/pyhook-%s-%s" % (ttime, pid)
- dd = ABRTUtils.CDebugDump()
- try:
- #os.mkdir(dir_name)
- dd.Create(dir_name, os.getuid())
- except Exception, e:
- syslog.syslog("abrt: Cannot create dir %s %s" % (dir_name, e))
- return
- # save executable
- fexecutable = open("%s/executable" % dir_name, "w")
+ executable = "Exception raised from python shell"
if sys.argv[0]:
- fexecutable.write(os.path.abspath(sys.argv[0]))
- else:
- fexecutable.write("Exception raised from python shell")
- fexecutable.close()
- # save coredump
- coredump = open("%s/backtrace" % dir_name, "w")
- coredump.write(tb)
- coredump.close()
- # save uuid
- uuid = open("%s/uuid" % dir_name, "w")
- uuid.write(tb_uuid)
- uuid.close()
- # save cmdline
- cmdline = open("%s/cmdline" % dir_name, "w")
- cmdline.write(open("/proc/%s/cmdline" % pid).read().replace('\x00',' '))
- cmdline.close()
- # save uid
- uid = open("%s/uid" % dir_name, "w")
- uid.write(open("/proc/%s/loginuid" % pid).readlines()[0])
- uid.close()
- # save analyzer
- analyzer = open("%s/analyzer" % dir_name, "w")
- analyzer.write("Python")
- analyzer.close()
- dd.Close()
+ executable = os.path.abspath(sys.argv[0])
+
+ command = ["abrt-pyhook-helper"]
+ command.append("--pid=%s" % pid)
+ command.append("--executable=%s" % executable)
+ command.append("--uuid=%s" % tb_uuid)
+ command.append("--cmdline=%s" % open("/proc/%s/cmdline" % pid).read().replace('\x00',' '))
+ command.append("--loginuid=%s" % open("/proc/%s/loginuid" % pid).readlines()[0])
+
+ helper = subprocess.Popen(command, stdin=subprocess.PIPE)
+ helper.communicate(tb)
+ helper.wait()
def __dump_exception(out, text, tracebk):
'write a traceback to "out"'
diff --git a/src/Hooks/sitecustomize.py b/src/Hooks/sitecustomize.py
index 56c6669b..32a3747b 100644
--- a/src/Hooks/sitecustomize.py
+++ b/src/Hooks/sitecustomize.py
@@ -1,14 +1,16 @@
+# ABRT crash hook
+#
# This special script is placed in
# /usr/local/lib/pythonNNN/site-packages/sitecustomize.py
# and python interpreter runs it automatically everytime
-# some python script is executed
+# some python script is executed.
config = None
conf = {}
try:
config = open("/etc/abrt/pyhook.conf","r")
except:
- #silently ignore if file doesn't exist
+ # Silently ignore if file doesn't exist.
pass
try:
@@ -20,10 +22,14 @@ try:
line = config.readline().lower().replace(' ','').strip('\n').split('=')
conf[line[0]] = line[1]
except:
- # ignore silently everything, because we don't want to bother user if this hook doesn't work
+ # Ignore silently everything, because we don't want to bother user
+ # if this hook doesn't work.
pass
if conf.has_key("enabled"):
+ # Prevent abrt exception handler from running when the abrtd daemon is
+ # not active.
+ # abrtd sets the value to "no" when deactivated and vice versa.
if conf["enabled"] == "yes":
try:
from abrt_exception_handler import *