[ABRT PATCH 1/2] make the upload-watcher testsuite friendly - related #657
by Jiri Moskovcak
Signed-off-by: Jiri Moskovcak <jmoskovc(a)redhat.com>
---
src/daemon/abrt-upload-watch.c | 39 +++++++++++++++++++++++++++++++++++----
1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/src/daemon/abrt-upload-watch.c b/src/daemon/abrt-upload-watch.c
index 3ed2854..41d2ba6 100644
--- a/src/daemon/abrt-upload-watch.c
+++ b/src/daemon/abrt-upload-watch.c
@@ -29,6 +29,7 @@
#define DEFAULT_CACHE_MIB_SIZE 4
static int g_signal_pipe[2];
+static sig_atomic_t got_sigusr;
struct queue
{
@@ -123,11 +124,29 @@ handle_new_path(struct process *proc, char *name)
}
}
-static void
-decrement_child_count(struct process *proc)
+static gboolean
+print_stats(struct process *proc)
{
- --proc->children;
+ /* there is a race, because we run this function from 2 different places
+ * 1st when a child dies
+ * 2nd as idle source from mainloop
+ * if it happens the stats will be printed twice, which I think
+ * is not a big deal, because it's only for debug and tests
+ */
+ if (got_sigusr == 1)
+ {
+ got_sigusr = 0;
+ /* this is meant only for debugging, so not marking it as translatable */
+ fprintf(stderr, "%i archives to process, %i active workers\n", g_queue_get_length(&proc->queue.q), proc->children);
+ }
+
+ /* don't remove this source from glib */
+ return true;
+}
+static void
+process_next_in_queue(struct process *proc)
+{
char *name = queue_pop(&proc->queue);
if (!name)
{
@@ -140,6 +159,13 @@ decrement_child_count(struct process *proc)
}
static void
+handle_sigusr(int signo)
+{
+ /* just set the flag and process it synchronously */
+ got_sigusr = 1;
+}
+
+static void
handle_signal(int signo)
{
int save_errno = errno;
@@ -185,7 +211,9 @@ handle_signal_pipe_cb(GIOChannel *gio, GIOCondition condition, gpointer user_dat
{
while (safe_waitpid(-1, NULL, WNOHANG) > 0)
{
- decrement_child_count(proc);
+ --proc->children;
+ process_next_in_queue(proc);
+ print_stats(proc);
}
}
}
@@ -338,6 +366,7 @@ main(int argc, char **argv)
close_on_exec_on(g_signal_pipe[1]);
ndelay_on(g_signal_pipe[0]);
ndelay_on(g_signal_pipe[1]);
+ signal(SIGUSR1, handle_sigusr);
signal(SIGTERM, handle_signal);
signal(SIGINT, handle_signal);
signal(SIGCHLD, handle_signal);
@@ -347,6 +376,7 @@ main(int argc, char **argv)
handle_signal_pipe_cb,
&proc);
+ int status_callback_source_id = g_idle_add((GSourceFunc)print_stats, &proc);
VERB2 log("Starting glib main loop");
g_main_loop_run(proc.main_loop);
@@ -354,6 +384,7 @@ main(int argc, char **argv)
VERB2 log("Glib main loop finished");
g_source_remove(channel_signal_source_id);
+ g_source_remove(status_callback_source_id);
GError *error = NULL;
g_io_channel_shutdown(channel_signal, FALSE, &error);
--
1.8.3.1
10 years, 8 months
[ABRT PATCH] adds a kdump.conf parser to get the correct dump dir location, closes #640
by Petr Kubat
Signed-off-by: Petr Kubat <pkubat(a)redhat.com>
---
src/hooks/abrt_harvest_vmcore.py.in | 93 +++++++++++++++++++++++++++++++++----
1 file changed, 83 insertions(+), 10 deletions(-)
diff --git a/src/hooks/abrt_harvest_vmcore.py.in b/src/hooks/abrt_harvest_vmcore.py.in
index 22dad07..4f2e1d0 100644
--- a/src/hooks/abrt_harvest_vmcore.py.in
+++ b/src/hooks/abrt_harvest_vmcore.py.in
@@ -1,22 +1,92 @@
#!/usr/bin/python
"""
This script is meant to be run once at system startup after abrtd is up
- and running. It moves all vmcore directories in /var/crash
+ and running. It moves all vmcore directories in kdump's dump directory
(which are presumably created by kdump) to abrtd spool directory.
The goal is to let abrtd notice and process them as new problem data dirs.
"""
import os
+import sys
import ConfigParser
import StringIO
import shutil
import time
import hashlib
+import re
+
import problem
-# Path to the vmcore directories
-CORE_DIR = '/var/crash'
+
+def get_mount_point(part_id, filesystem):
+ """
+ A function used to look up a mount point in mtab using
+ the provided identifier.
+
+ part_id - device node, label or uuid
+ filesystem - filesystem type of the mounted partition
+ """
+
+ # look up the identifier in /etc/fstab
+ with open('/etc/mtab') as fs_table_file:
+ fs_table = fs_table_file.read()
+ regexp = re.compile(part_id + r'\s+(.*)\s+' + filesystem)
+ result = regexp.search(fs_table)
+ if result:
+ return result.group(1).strip()
+ else:
+ # identifier not in the table
+ sys.stderr.write("Error: Cannot access partition '" + part_id +
+ "', mount point not found! \n")
+ sys.exit(1)
+
+
+def parse_kdump():
+ """
+ This function parses /etc/kdump.conf to get a path to kdump's
+ dump directory.
+ """
+
+ # filesystem types that can be used by kdump for dumping
+ fs_types = ['ext4', 'ext3', 'ext2', 'minix', 'btrfs', 'xfs']
+
+ with open('/etc/kdump.conf') as conf_file:
+ kdump_conf = conf_file.read()
+
+ # first uncommented path instruction
+ regexp = re.compile('^(?<!#)path (.*)$', flags=8) # MULTILINE
+ result = regexp.search(kdump_conf)
+ if result:
+ dump_path = result.group(1).strip()
+ else:
+ # default
+ dump_path = '/var/crash'
+
+ # default
+ partition = None
+ # first uncommented fs_type partition instruction
+ for fs_type in fs_types:
+ regexp = re.compile('^(?<!#)' + fs_type + ' (.*)$', flags=8)
+ result = regexp.search(kdump_conf)
+ if result:
+ partition = result.group(1)
+ filesystem = fs_type
+ break
+
+ if partition:
+ if os.path.isabs(dump_path):
+ # path is absolute
+ sys.stderr.write("Path '" + dump_path + "' cannot be an absolute"
+ " path when mounting a dump partition.\n")
+ sys.exit(1)
+ mount_point = get_mount_point(partition, filesystem)
+ path = os.path.join(mount_point, dump_path)
+ else:
+ path = dump_path
+
+ # full path to the dump directory
+ return path
def write_to_file(path, content):
@@ -102,20 +172,23 @@ def create_abrtd_info(dest):
def harvest_vmcore():
"""
- This function moves vmcore directories from /var/crash to a dump dir.
+ This function moves vmcore directories from kdump's dump dir
+ to abrt's dump dir and notifies abrt.
The script also creates additional files used to tell abrt what kind of
problem it is and creates an uuid from the vmcore using a sha1 hash
function.
"""
- if not os.path.exists('/etc/os-release'):
- exit(0)
+ dump_dir = parse_kdump()
+
+ if not os.path.exists(dump_dir):
+ sys.exit(0)
# Wait for abrtd to start. Give it at least 1 second to initialize.
for i in xrange(10):
if i is 9:
- exit(1)
+ sys.exit(1)
elif os.system('pidof abrtd >/dev/null'):
time.sleep(1)
else:
@@ -142,9 +215,9 @@ def harvest_vmcore():
except ConfigParser.NoOptionError:
abrtdumpdir = '@DEFAULT_DUMP_LOCATION@'
- # Go through all directories in /var/crash
- for cfile in os.listdir(CORE_DIR):
- f_full = os.path.join(CORE_DIR, cfile)
+ # Go through all directories in core dump directory
+ for cfile in os.listdir(dump_dir):
+ f_full = os.path.join(dump_dir, cfile)
if not os.path.isdir(f_full):
continue
files = [ff for ff in os.listdir(f_full)
--
1.8.3.1
10 years, 8 months
[ABRT PATCH] xorg_event.conf: use abrt-action-list-dsos to create dso_list
by Denys Vlasenko
We used to use a shell script for this, but its format lists just
a package name:
mesa-dri-drivers-8.0.4-1.fc17.x86_64
instead of the more informative format used by ccpp:
/usr/lib64/libssl3.so nss-3.14.3-2.fc18.x86_64 (Fedora Project) 1370297473
An added benefit is that by using abrt-action-list-dsos, we reuse code and use
the same format of list of DSOs for ccpp and xorg problems.
Signed-off-by: Denys Vlasenko <dvlasenk(a)redhat.com>
---
src/plugins/xorg_event.conf | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/plugins/xorg_event.conf b/src/plugins/xorg_event.conf
index 1bd7617..e6d0a3a 100644
--- a/src/plugins/xorg_event.conf
+++ b/src/plugins/xorg_event.conf
@@ -2,9 +2,9 @@ EVENT=post-create analyzer=xorg
# Blacklist known binary-only modules.
# Generate duplicate detection hashes.
abrt-action-analyze-xorg
-
+ #
# Get versions of binaries listed in Xorg backtrace
- cat backtrace | cut -f2 -d" " | xargs rpm -qf | sort -u >> backtrace_binaries_versions
+ abrt-action-list-dsos -m backtrace -o dso_list
#
test -f /var/log/Xorg.0.log && cp /var/log/Xorg.0.log .
test -f /etc/X11/xorg.conf && cp /etc/X11/xorg.conf .
--
1.8.1.4
10 years, 8 months
[ABRT PATCH] abrt-action-list-dsos: extend it to be able to parse Xorg backtrace.
by Denys Vlasenko
It also fixes a latent bug: x.strip()[x.find('/'):] does NOT cut everything
up to first slash. If there is some leading whitespace, the position
of find() will be wrong. This didn't bite us because the lines we parse
had no leading whitespace so far.
Preparation for rhbz#880694.
Signed-off-by: Denys Vlasenko <dvlasenk(a)redhat.com>
---
src/plugins/abrt-action-list-dsos | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/plugins/abrt-action-list-dsos b/src/plugins/abrt-action-list-dsos
index 81a9927..6f2bd5b 100644
--- a/src/plugins/abrt-action-list-dsos
+++ b/src/plugins/abrt-action-list-dsos
@@ -28,8 +28,15 @@ def xopen(name, mode):
def parse_maps(maps_path):
try:
f = xopen(maps_path, "r")
- # set() -> uniqifies the list of filenames
- return set([x.strip()[x.find('/'):] for x in f.readlines() if x.find('/') > -1])
+ # We want to handle both /proc/PID/maps format:
+ # 4f200000-4f215000 r-xp 00000000 08:03 1835520 /usr/lib64/libz.so.1.2.7
+ # and Xorg backtrace format:
+ # [ 86985.880] 9: /usr/lib64/libdrm.so.2 (drmHandleEvent+0xa3) [0x376b407513]
+ # To do that, we take only lines which have a / character,
+ # then for each line we start at first /, then remove everyting after first whitespace
+ files = [x[x.find('/'):].split()[0] for x in f.readlines() if x.find('/') > -1]
+ # set() uniqifies the list of filenames
+ return set(files)
except IOError, e:
error_msg_and_die("Can't read '%s': %s" % (maps_path, e))
--
1.8.1.4
10 years, 8 months
[LIBREPORT PATCH] print warning when there is not engough free space for debuginfos, closes #170
by Petr Kubat
Signed-off-by: Petr Kubat <pkubat(a)redhat.com>
---
src/client-python/debuginfo.py | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/src/client-python/debuginfo.py b/src/client-python/debuginfo.py
index 035d697..68fe6e0 100644
--- a/src/client-python/debuginfo.py
+++ b/src/client-python/debuginfo.py
@@ -324,6 +324,29 @@ class DebugInfoDownload(YumBase):
if self.noninteractive == False and not ask_yes_no(question):
print _("Download cancelled by user")
return RETURN_CANCEL_BY_USER
+ # set up tmp and cache dirs so that we can check free space in both
+ retval = self.setup_tmp_dirs()
+ if retval != RETURN_OK:
+ return retval
+ # check if there is enough free space in both tmp and cache
+ res = os.statvfs(self.tmpdir)
+ tmp_space = float(res.f_bsize * res.f_bavail) / (1024*1024)
+ if (todownload_size / (1024*1024)) > tmp_space:
+ question = _("Warning: Not enough free space in tmp dir '{0}'"
+ " ({1:.2f}Mb left). Continue?").format(
+ self.tmpdir, tmp_space)
+ if not self.noninteractive and not ask_yes_no(question):
+ print _("Download cancelled by user")
+ return RETURN_CANCEL_BY_USER
+ res = os.statvfs(self.cachedir)
+ cache_space = float(res.f_bsize * res.f_bavail) / (1024*1024)
+ if (installed_size / (1024*1024)) > cache_space:
+ question = _("Warning: Not enough free space in cache dir "
+ "'{0}' ({1:.2f}Mb left). Continue?").format(
+ self.cachedir, cache_space)
+ if not self.noninteractive and not ask_yes_no(question):
+ print _("Download cancelled by user")
+ return RETURN_CANCEL_BY_USER
for pkg, files in package_files_dict.iteritems():
dnlcb.downloaded_pkgs = downloaded_pkgs
--
1.8.3.1
10 years, 8 months
[ABRT PATCH] don't require debuginfo for vmcore analysis rhbz#768389
by Jiri Moskovcak
Signed-off-by: Jiri Moskovcak <jmoskovc(a)redhat.com>
---
doc/abrt-action-analyze-vmcore.txt | 6 --
src/plugins/abrt-action-analyze-vmcore.in | 93 ++++++-------------------------
2 files changed, 16 insertions(+), 83 deletions(-)
diff --git a/doc/abrt-action-analyze-vmcore.txt b/doc/abrt-action-analyze-vmcore.txt
index 3e016f5..20a28c2 100644
--- a/doc/abrt-action-analyze-vmcore.txt
+++ b/doc/abrt-action-analyze-vmcore.txt
@@ -38,15 +38,9 @@ OPTIONS
-v::
Be more verbose. Can be given multiple times.
---cache=DIR1[:DIR2]::
- Additional debuginfo directories (Default: /var/cache/abrt-di)
-
--core=VMCORE::
Path to vmcore to analyze (Default: ./vmcore)
---tmpdir=TMPDIR::
- Where to store temporary files (Default: /tmp/abrt-tmp-debuginfo-<time>-<pid>)
-
AUTHORS
-------
* ABRT team
diff --git a/src/plugins/abrt-action-analyze-vmcore.in b/src/plugins/abrt-action-analyze-vmcore.in
index 6c27e9a..78a7b19 100644
--- a/src/plugins/abrt-action-analyze-vmcore.in
+++ b/src/plugins/abrt-action-analyze-vmcore.in
@@ -7,8 +7,6 @@ from subprocess import Popen, PIPE
import os
import sys
from reportclient import _, verbose, set_verbosity, error_msg_and_die, error_msg
-import time
-from reportclient.debuginfo import DebugInfoDownload
import getopt
PROGNAME = "abrt-action-analyze-vmcore"
@@ -20,15 +18,16 @@ RETURN_FAILURE = 2
ver = ""
if __name__ == "__main__":
+ dmesg_log = "dmesg_log"
cachedirs = []
vmlinux_di_cachedir = ""
vmlinux_di_path = ""
tmpdir = ""
vmcore = ""
- help_text = _("Usage: {0} [-v[v]] [--core=VMCORE] [--tmpdir=TMPDIR] [--cache=CACHEDIR]").format(PROGNAME)
+ help_text = _("Usage: {0} [-v[v]] [--core=VMCORE]").format(PROGNAME)
try:
- opts, args = getopt.getopt(sys.argv[1:], "hvd", ["help", "tmpdir=", "cache=", "core="])
+ opts, args = getopt.getopt(sys.argv[1:], "hvd", ["help", "core="])
except getopt.GetoptError, err:
error_msg(str(err)) # prints something like "option -a not recognized"
error_msg_and_die(help_text)
@@ -38,15 +37,8 @@ if __name__ == "__main__":
if opt in ("-h", "--help"):
print help_text
exit(0)
- if opt == "--cache":
- cachedirs = arg.split(':')
- usercache = True
elif opt == "-v":
verbose += 1
- elif opt == "--core":
- vmcore = arg
- elif opt == "--tmpdir":
- tmpdir = arg
elif opt in ("-d"):
try:
os.chdir(arg)
@@ -63,74 +55,21 @@ if __name__ == "__main__":
print _("File {0} doesn't exist").format(vmcore)
sys.exit(RETURN_FAILURE)
- if not cachedirs:
- try:
- fp = open("@sysconfdir@/@PACKAGE_NAME(a)/plugins/CCpp.conf", "r")
- for line in fp:
- stripped = line.lstrip()
- if len(stripped) == 0:
- continue
- if stripped[0] == "#":
- continue
- if stripped[:len("DebuginfoLocation")] != "DebuginfoLocation":
- continue
+ print _("Extracting the oops text from core")
+ crash = Popen(["makedumpfile", "--dump-dmesg", "-f", vmcore, dmesg_log], stdout=PIPE, stderr=PIPE, bufsize = -1)
+ out, err = crash.communicate()
- cachedirs = stripped[len("DebuginfoLocation"):].strip(" =\n").split(":")
- fp.close()
- except IOError as (errno, strerror):
- print "I/O error({0}): {1}".format(errno, strerror)
+ if crash.returncode != 0:
+ error_msg_and_die(_("Can't process {0}:\n{1}").format(vmcore, err))
- if not cachedirs:
- cachedirs = ["/var/cache/abrt-di"]
-
- if not tmpdir:
- # security people prefer temp subdirs in app's private dir, like /var/run/abrt
- # and we switched to /tmp but Fedora feature tmp-on-tmpfs appeared, hence we must
- # not use /tmp for potential big data anymore
- tmpdir = "@LARGE_DATA_TMP_DIR(a)/abrt-tmp-debuginfo-%s.%u" % (time.strftime("%Y-%m-%d-%H:%M:%S"), os.getpid())
-
- crash = Popen(["crash", "--osrelease", vmcore], stdout=PIPE, bufsize = -1)
- ver, err = crash.communicate()
- ver = ver.strip() #remove '\n'
- if not ver or crash.returncode != 0:
- error_msg_and_die(_("{0} is not a valid vmcore").format(vmcore))
-
- for cachedir in cachedirs:
- path = "{0}/usr/lib/debug/lib/modules/{1}/vmlinux".format(cachedir, ver)
- if os.path.exists(path):
- vmlinux_di_cachedir = cachedir
- print _("Required vmlinux debuginfo is installed in {0}".format(vmlinux_di_cachedir))
- vmlinux_di_path = path
- break
-
- if not vmlinux_di_path: #didn't find the vmlinux in any cachedir
- vmlinux_di_cachedir = cachedirs[0] # let's hope it has always at least 1 item
- print _("Installing kernel debuginfo(s)")
- # replace with abrt-action-install-debuginfo
- vmlinux_di_path = "/usr/lib/debug/lib/modules/%s/vmlinux" % ver
- if usercache: # if user set the cache, we assume it's writeable for him
- downloader = DebugInfoDownload(cache=vmlinux_di_cachedir, tmp=tmpdir, keep_rpms=True)
- res = downloader.download([vmlinux_di_path], download_exact_files=True)
- if res != RETURN_OK:
- error_msg_and_die(_("Can't download required debuginfo"))
- vmlinux_di_path = "{0}/usr/lib/debug/lib/modules/{1}/vmlinux".format(vmlinux_di_cachedir, ver)
- else: # we need to use the suid wrapper, if we use the default cache
- downloader_args = ["/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache", "--size_mb=4096", "--exact={0}".format(vmlinux_di_path)]
- if verbose > 0:
- downloader_args.append("-{0}".format("v"*verbose))
- downloader = Popen(downloader_args, bufsize = -1)
- res = downloader.wait()
- if res != 0:
- error_msg_and_die(_("Can't download required debuginfo"))
- vmlinux_di_path = "{0}/usr/lib/debug/lib/modules/{1}/vmlinux".format(vmlinux_di_cachedir, ver)
-
- print _("Generating backtrace")
- log_file = open("kernel_log","w")
- crash = Popen(["crash", "-s", "vmcore", vmlinux_di_path], stdin=PIPE, stderr=PIPE, stdout=log_file, bufsize = -1)
- out, err = crash.communicate(input="log")
- log_file.close()
backtrace_file = open("backtrace", "w")
- dump_oops = Popen(["abrt-dump-oops", "-u", ".", "kernel_log"], stdout=backtrace_file, bufsize=-1)
+ dump_oops = Popen(["abrt-dump-oops", "-u", ".", dmesg_log], stdout=backtrace_file, stderr=PIPE, bufsize=-1)
+ out, err = dump_oops.communicate()
backtrace_file.close()
- ret = dump_oops.wait()
+ ret = dump_oops.returncode
+ if dump_oops.returncode != 0:
+ print _("Can't extract the oops message: '{0}'").format(err)
+ sys.exit(ret)
+
+ print _("Oops text extracted successfully")
sys.exit(ret)
--
1.8.3.1
10 years, 8 months
[SATYR PATCH] python: fix reference counts for crash_thread
by Martin Milata
Fixes #101.
Signed-off-by: Martin Milata <mmilata(a)redhat.com>
---
python/py_base_stacktrace.c | 3 ++-
tests/python/core.py | 8 ++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/python/py_base_stacktrace.c b/python/py_base_stacktrace.c
index e9bf484..8a8c6f0 100644
--- a/python/py_base_stacktrace.c
+++ b/python/py_base_stacktrace.c
@@ -356,6 +356,7 @@ sr_py_multi_stacktrace_get_bthash(PyObject *self, PyObject *args)
PyObject *
sr_py_single_stacktrace_get_crash(PyObject *self, void *unused)
{
+ Py_INCREF(self);
return self;
}
@@ -403,7 +404,7 @@ sr_py_multi_stacktrace_get_crash(PyObject *self, void *unused)
struct sr_py_base_thread *thread = (struct sr_py_base_thread *)item;
if (thread->thread == crash_thread)
{
- /* TODO incref? */
+ Py_INCREF(item);
return item;
}
}
diff --git a/tests/python/core.py b/tests/python/core.py
index cb880ae..96f4ffd 100755
--- a/tests/python/core.py
+++ b/tests/python/core.py
@@ -55,6 +55,14 @@ class TestCoreStacktrace(BindingsTestCase):
def test_crash_thread(self):
self.assertTrue(self.trace.crash_thread is self.trace.threads[1])
+ def test_crash_thread_refcount(self):
+ c = self.trace.crash_thread
+ del c
+ c = self.trace.crash_thread
+ del c
+ # segfault in revision 6f91aba95397e56c665c420f574d73adb64df832
+ f = self.trace.crash_thread.frames[0]
+
def test_from_json(self):
trace = satyr.CoreStacktrace.from_json('{}')
self.assertEqual(trace.threads, [])
--
1.8.3.1
10 years, 8 months
[SATYR PATCH 0/8] Python bindings for the report structure
by Martin Milata
Please note that this patchset depends on following, as of yet unreviewed
patches:
[SATYR PATCHv3 1/7] Add sr_java_frame_append
[SATYR PATCHv3 2/7] Helper functions for json deserialization
[SATYR PATCHv3 3/7] Implement JSON deserialization for reports
[SATYR PATCHv3 4/7] Type-agnostic JSON deserialization
[SATYR PATCHv3 5/7] python: add version attribute to Kerneloops object
[SATYR PATCHv3 6/7] python: expose from_json for stacktraces
[SATYR PATCHv3 7/7] tests for json deserialization of stacktraces
[SATYR PATCHv3] python: treat UINT64_MAX as None
* * *
Martin Milata (8):
python: bindings for struct sr_operating_system
python: bindings for struct sr_rpm_package
Minor json parsing refactorization
report: function for parsing json text
Helpers for converting report type to/from string
report: use generic stacktrace type
python: factor out stacktrace object creation
python: bindings for struct sr_report
include/json.h | 2 +-
include/report.h | 14 +-
include/report_type.h | 8 +
lib/Makefile.am | 2 +-
lib/abrt.c | 34 +--
lib/core_stacktrace.c | 19 +-
lib/generic_stacktrace.c | 15 +-
lib/json.c | 10 +-
lib/report.c | 129 +++++------
python/Makefile.am | 6 +
python/py_common.c | 7 +
python/py_common.h | 4 +
python/py_core_stacktrace.c | 64 +++---
python/py_core_stacktrace.h | 3 +
python/py_java_stacktrace.c | 65 +++---
python/py_java_stacktrace.h | 3 +
python/py_koops_stacktrace.c | 59 +++--
python/py_koops_stacktrace.h | 3 +
python/py_module.c | 35 +++
python/py_operating_system.c | 167 ++++++++++++++
python/py_operating_system.h | 63 ++++++
python/py_python_stacktrace.c | 59 +++--
python/py_python_stacktrace.h | 3 +
python/py_report.c | 491 ++++++++++++++++++++++++++++++++++++++++++
python/py_report.h | 79 +++++++
python/py_rpm_package.c | 225 +++++++++++++++++++
python/py_rpm_package.h | 67 ++++++
tests/Makefile.am | 1 +
tests/json_files/ureport-1 | 107 +++++++++
tests/python/report.py | 88 ++++++++
tests/python_bindings.at | 1 +
tests/report.at | 59 +++++
tests/testsuite.at | 1 +
33 files changed, 1625 insertions(+), 268 deletions(-)
create mode 100644 python/py_operating_system.c
create mode 100644 python/py_operating_system.h
create mode 100644 python/py_report.c
create mode 100644 python/py_report.h
create mode 100644 python/py_rpm_package.c
create mode 100644 python/py_rpm_package.h
create mode 100644 tests/json_files/ureport-1
create mode 100755 tests/python/report.py
create mode 100644 tests/report.at
--
1.8.3.1
10 years, 8 months
[SATYR PATCH] python: treat UINT64_MAX as None
by Martin Milata
Note: this patch depends on "[SATYR PATCH 7/7] tests for json
deserialization of stacktraces" as it modifies one of the tests.
-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8--
Some structures (namely struct sr_core_frame) use (uint64_t)-1 to denote
unknown value. This is difficult to compare with in python, so this
patch introduces translation to None in uint64 accessor function.
Signed-off-by: Martin Milata <mmilata(a)redhat.com>
---
python/py_common.c | 20 ++++++++++++++++----
tests/python/core.py | 6 +++---
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/python/py_common.c b/python/py_common.c
index 90a0ccb..c1366dd 100644
--- a/python/py_common.c
+++ b/python/py_common.c
@@ -162,6 +162,10 @@ sr_py_getter_uint64(PyObject *self, void *data)
uint64_t num
= MEMB_T(uint64_t, MEMB(self, gsoff->c_struct_offset), gsoff->member_offset);
+
+ if (num == -1)
+ Py_RETURN_NONE;
+
return PyLong_FromUnsignedLongLong(num);
}
@@ -174,12 +178,20 @@ sr_py_setter_uint64(PyObject *self, PyObject *rhs, void *data)
return -1;
}
- struct getset_offsets *gsoff = data;
+ uint64_t newvalue;
- unsigned long long newvalue = PyInt_AsUnsignedLongLongMask(rhs);
- if (PyErr_Occurred())
- return -1;
+ if (rhs == Py_None)
+ {
+ newvalue = -1;
+ }
+ else
+ {
+ newvalue = (uint64_t)PyInt_AsUnsignedLongLongMask(rhs);
+ if (PyErr_Occurred())
+ return -1;
+ }
+ struct getset_offsets *gsoff = data;
MEMB_T(uint64_t, MEMB(self, gsoff->c_struct_offset), gsoff->member_offset) = newvalue;
return 0;
}
diff --git a/tests/python/core.py b/tests/python/core.py
index e4593b4..cb880ae 100755
--- a/tests/python/core.py
+++ b/tests/python/core.py
@@ -113,9 +113,9 @@ class TestCoreStacktrace(BindingsTestCase):
self.assertEqual(trace.threads[0].frames[0].fingerprint, '1234123412341234123412341234')
self.assertTrue(trace.threads[0].frames[0].fingerprint_hashed)
- self.assertEqual(trace.threads[0].frames[1].address, 18446744073709551615L) # !!! FIXME
+ self.assertEqual(trace.threads[0].frames[1].address, None)
self.assertEqual(trace.threads[0].frames[1].build_id, None)
- self.assertEqual(trace.threads[0].frames[1].build_id_offset, 18446744073709551615L) # !!!
+ self.assertEqual(trace.threads[0].frames[1].build_id_offset, None)
self.assertEqual(trace.threads[0].frames[1].function_name, None)
self.assertEqual(trace.threads[0].frames[1].file_name, None)
self.assertEqual(trace.threads[0].frames[1].fingerprint, None)
@@ -123,7 +123,7 @@ class TestCoreStacktrace(BindingsTestCase):
self.assertEqual(trace.threads[0].frames[2].address, 2)
self.assertEqual(trace.threads[0].frames[2].build_id, None)
- self.assertEqual(trace.threads[0].frames[2].build_id_offset, 18446744073709551615L) # !!!
+ self.assertEqual(trace.threads[0].frames[2].build_id_offset, None)
self.assertEqual(trace.threads[0].frames[2].function_name, None)
self.assertEqual(trace.threads[0].frames[2].file_name, None)
self.assertEqual(trace.threads[0].frames[2].fingerprint, 'a b c d')
--
1.8.3.1
10 years, 8 months
[SATYR PATCH 1/7] Add sr_java_frame_append
by Martin Milata
Signed-off-by: Martin Milata <mmilata(a)redhat.com>
---
include/java/frame.h | 9 +++++++++
lib/java_frame.c | 15 +++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/include/java/frame.h b/include/java/frame.h
index 57eb96e..903fde2 100644
--- a/include/java/frame.h
+++ b/include/java/frame.h
@@ -135,6 +135,15 @@ void
sr_java_frame_free_full(struct sr_java_frame *frame);
/**
+ * Appends 'item' at the end of the list 'dest'.
+ * @returns
+ * This function returns the 'dest' frame.
+ */
+struct sr_java_frame *
+sr_java_frame_append(struct sr_java_frame *dest,
+ struct sr_java_frame *item);
+
+/**
* Gets a number of frame in list.
* @param frame
* If the frame is NULL, no operation is performed.
diff --git a/lib/java_frame.c b/lib/java_frame.c
index 2bea373..a9f906c 100644
--- a/lib/java_frame.c
+++ b/lib/java_frame.c
@@ -194,6 +194,21 @@ sr_java_frame_cmp_distance(struct sr_java_frame *frame1,
return 0;
}
+struct sr_java_frame *
+sr_java_frame_append(struct sr_java_frame *dest,
+ struct sr_java_frame *item)
+{
+ if (!dest)
+ return item;
+
+ struct sr_java_frame *dest_loop = dest;
+ while (dest_loop->next)
+ dest_loop = dest_loop->next;
+
+ dest_loop->next = item;
+ return dest;
+}
+
void
sr_java_frame_append_to_str(struct sr_java_frame *frame,
struct sr_strbuf *dest)
--
1.8.3.1
10 years, 8 months