[PATCH-libreport] report-python: don't include executable
by Martin Milata
Doesn't really make sense, as it is always path to the python
executable. bz#741255
---
src/include/problem_data.h | 3 +++
src/lib/problem_data.c | 5 +++++
src/report-python/problem_data.c | 8 ++++++++
3 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/src/include/problem_data.h b/src/include/problem_data.h
index 14d1240..87037a2 100644
--- a/src/include/problem_data.h
+++ b/src/include/problem_data.h
@@ -74,6 +74,9 @@ void add_to_problem_data(problem_data_t *problem_data,
const char *name,
const char *content);
+/* Removes item from problem data */
+void remove_from_problem_data(problem_data_t *problem_data, const char *key);
+
static inline struct problem_item *get_problem_data_item_or_NULL(problem_data_t *problem_data, const char *key)
{
return (struct problem_item *)g_hash_table_lookup(problem_data, key);
diff --git a/src/lib/problem_data.c b/src/lib/problem_data.c
index 2ddff86..7d85709 100644
--- a/src/lib/problem_data.c
+++ b/src/lib/problem_data.c
@@ -155,6 +155,11 @@ void add_to_problem_data(problem_data_t *problem_data,
add_to_problem_data_ext(problem_data, name, content, CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE);
}
+void remove_from_problem_data(problem_data_t *problem_data, const char *key)
+{
+ g_hash_table_remove(problem_data, key);
+}
+
const char *get_problem_item_content_or_die(problem_data_t *problem_data, const char *key)
{
struct problem_item *item = get_problem_data_item_or_NULL(problem_data, key);
diff --git a/src/report-python/problem_data.c b/src/report-python/problem_data.c
index 9067dea..8b4088d 100644
--- a/src/report-python/problem_data.c
+++ b/src/report-python/problem_data.c
@@ -115,8 +115,16 @@ static PyObject *p_create_dump_dir_from_problem_data(PyObject *pself, PyObject *
static PyObject *p_add_basics_to_problem_data(PyObject *pself, PyObject *always_null)
{
p_problem_data *self = (p_problem_data*)pself;
+ int have_executable = (get_problem_data_item_or_NULL(self->cd, "executable") != NULL);
+
add_basics_to_problem_data(self->cd);
+ /* Workaround - the executable item will always be /usr/bin/python, which is useless. */
+ if (!have_executable)
+ {
+ remove_from_problem_data(self->cd, "executable");
+ }
+
Py_RETURN_NONE;
}
--
1.7.6.4
12 years, 1 month
[PATCH] query chrooted RPM db if non-chrooted one returns negative result
by Denys Vlasenko
This patch uses "rootdir" element in problem dir.
If executable can't be identified, we check whether
its name starts with rootdir prefix. If it does,
we retry RPM query after we do rpmtsSetRootDir(rootdir).
Run tested: now it does catch the example described in rhbz#691019
Please review.
--
vda
diff -x '*.po' -d -urpN abrt.4/src/daemon/abrt-action-save-package-data.c abrt.5/src/daemon/abrt-action-save-package-data.c
--- abrt.4/src/daemon/abrt-action-save-package-data.c 2011-10-27 19:11:55.000000000 +0200
+++ abrt.5/src/daemon/abrt-action-save-package-data.c 2011-12-20 11:15:00.608501636 +0100
@@ -189,6 +189,7 @@ static int SavePackageDescriptionToDebug
char *cmdline = NULL;
char *executable = NULL;
+ char *rootdir = NULL;
char *script_name = NULL; /* only if "interpreter /path/to/script" */
char *package_short_name = NULL;
char *package_full_name = NULL;
@@ -209,6 +210,8 @@ static int SavePackageDescriptionToDebug
{
cmdline = dd_load_text(dd, FILENAME_CMDLINE);
executable = dd_load_text(dd, FILENAME_EXECUTABLE);
+ rootdir = dd_load_text_ext(dd, FILENAME_ROOTDIR,
+ DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
/* Close dd while we query package database. It can take some time,
* don't want to keep dd locked longer than necessary */
@@ -220,7 +223,7 @@ static int SavePackageDescriptionToDebug
goto ret; /* return 1 (failure) */
}
- package_full_name = rpm_get_package_nvr(executable);
+ package_full_name = rpm_get_package_nvr(executable, rootdir);
if (!package_full_name)
{
if (settings_bProcessUnpackaged)
@@ -252,7 +255,7 @@ static int SavePackageDescriptionToDebug
char *script_name = get_argv1_if_full_path(cmdline);
if (script_name)
{
- script_pkg = rpm_get_package_nvr(script_name);
+ script_pkg = rpm_get_package_nvr(script_name, NULL);
if (script_pkg)
{
/* There is a well-formed script name in argv[1],
@@ -308,7 +311,7 @@ static int SavePackageDescriptionToDebug
*/
}
- component = rpm_get_component(executable);
+ component = rpm_get_component(executable, rootdir);
dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
if (!dd)
@@ -331,6 +334,7 @@ static int SavePackageDescriptionToDebug
ret:
free(cmdline);
free(executable);
+ free(rootdir);
free(script_name);
free(package_short_name);
free(package_full_name);
diff -x '*.po' -d -urpN abrt.4/src/daemon/rpm.c abrt.5/src/daemon/rpm.c
--- abrt.4/src/daemon/rpm.c 2011-12-20 11:29:39.303868072 +0100
+++ abrt.5/src/daemon/rpm.c 2011-12-20 11:34:08.512582379 +0100
@@ -166,18 +166,38 @@ error:
}
*/
-char* rpm_get_component(const char* filename)
+char* rpm_get_component(const char *filename, const char *rootdir_or_NULL)
{
char *ret = NULL;
char *srpm = NULL;
- const char *errmsg = NULL;
+ rpmts ts;
+ rpmdbMatchIterator iter;
+ Header header;
- rpmts ts = rpmtsCreate();
- rpmdbMatchIterator iter = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
- Header header = rpmdbNextIterator(iter);
+ ts = rpmtsCreate();
+ again:
+ iter = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
+ header = rpmdbNextIterator(iter);
+ //log("%s: header('%s'):%p", __func__, filename, header);
if (!header)
+ {
+ unsigned len = (rootdir_or_NULL ? strlen(rootdir_or_NULL) : 0);
+ if (len > 0 && strncmp(filename, rootdir_or_NULL, len) == 0 && filename[len] == '/')
+ {
+ //log("%s: skipping '%s' pfx", __func__, rootdir_or_NULL);
+ rpmdbFreeIterator(iter);
+ rpmtsFree(ts);
+ ts = rpmtsCreate();
+ if (rpmtsSetRootDir(ts, rootdir_or_NULL) != 0)
+ goto error1;
+ filename += len;
+ rootdir_or_NULL = NULL;
+ goto again;
+ }
goto error;
+ }
+ const char *errmsg = NULL;
srpm = headerFormat(header, "%{SOURCERPM}", &errmsg);
if (!srpm && errmsg)
{
@@ -188,31 +208,52 @@ char* rpm_get_component(const char* file
ret = get_package_name_from_NVR_or_NULL(srpm);
free(srpm);
-error:
+ error:
rpmdbFreeIterator(iter);
+ error1:
rpmtsFree(ts);
return ret;
}
// caller is responsible to free returned value
-char* rpm_get_package_nvr(const char* filename)
+char* rpm_get_package_nvr(const char *filename, const char *rootdir_or_NULL)
{
- char* nvr = NULL;
- const char *errmsg = NULL;
-
- rpmts ts = rpmtsCreate();
- rpmdbMatchIterator iter = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
- Header header = rpmdbNextIterator(iter);
+ char *nvr = NULL;
+ rpmts ts;
+ rpmdbMatchIterator iter;
+ Header header;
+ ts = rpmtsCreate();
+ again:
+ iter = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
+ header = rpmdbNextIterator(iter);
+ //log("%s: header('%s'):%p", __func__, filename, header);
if (!header)
+ {
+ unsigned len = (rootdir_or_NULL ? strlen(rootdir_or_NULL) : 0);
+ if (len > 0 && strncmp(filename, rootdir_or_NULL, len) == 0 && filename[len] == '/')
+ {
+ //log("%s: skipping '%s' pfx", __func__, rootdir_or_NULL);
+ rpmdbFreeIterator(iter);
+ rpmtsFree(ts);
+ ts = rpmtsCreate();
+ if (rpmtsSetRootDir(ts, rootdir_or_NULL) != 0)
+ goto error1;
+ filename += len;
+ rootdir_or_NULL = NULL;
+ goto again;
+ }
goto error;
+ }
+ const char *errmsg = NULL;
nvr = headerFormat(header, "%{NAME}-%{VERSION}-%{RELEASE}", &errmsg);
if (!nvr && errmsg)
error_msg("cannot get nvr. reason: %s", errmsg);
-error:
+ error:
rpmdbFreeIterator(iter);
+ error1:
rpmtsFree(ts);
return nvr;
}
diff -x '*.po' -d -urpN abrt.4/src/daemon/rpm.h abrt.5/src/daemon/rpm.h
--- abrt.4/src/daemon/rpm.h 2011-10-27 19:11:55.000000000 +0200
+++ abrt.5/src/daemon/rpm.h 2011-12-20 10:49:21.480817177 +0100
@@ -64,15 +64,15 @@ int rpm_chk_fingerprint(const char* pkg)
* @param filename A file name.
* @return A package name (malloc'ed string)
*/
-char* rpm_get_package_nvr(const char* filename);
+char* rpm_get_package_nvr(const char *filename, const char *rootdir_or_NULL);
/**
* Finds a main package for given file. This package contains particular
* file. If the file doesn't belong to any package, empty string is
* returned.
* @param filename A file name.
- * @return a malloc'ed package name. Need to be freed.
+ * @return Component name (malloc'ed string)
*/
-char* rpm_get_component(const char* filename);
+char* rpm_get_component(const char *filename, const char *rootdir_or_NULL);
char* get_package_name_from_NVR_or_NULL(const char* packageNVR);
12 years, 4 months
New template for report rhbz#747410
by Jiri Moskovcak
There is a bugzilla 747410 based on some complains from developers that
they are used to default bugzilla template for new bugs and some of the
already have some tools to parse it and they can't use it on ABRT
reports. Since ABRT was meant to help the developers, we should twek our
format to match the bugzilla template as much as possible. So here is my
proposals based on the bugzilla template:
1. Automatically create it, keeping the UI unchanged:
Description of problem:
<content of field comment>
Version-Release number of selected component (if applicable):
<content of field package>
Additional info:
<backtrace>
<and everything else we usually attach>
2. pre-fill the comment field with the template:
- the headers from the template will be non-editable/non-removable
Description of problem:
Version-Release number of selected component (if applicable):
<automatically added $package>
How reproducible:
Steps to Reproduce:
1.
2.
3.
Actual results:
Expected results:
Additional info:
12 years, 4 months
[PATCH] abrt-action-trim-files: delete up to 128 files between rescans, not one at a time
by Denys Vlasenko
This fixes a performance problem I noticed while
working on another problem:
we scan debuginfo cache directory, find the "worst" file,
and if we need to trim the directory, we delete this one file
and repeat the scan. But scan is a long operation on large dirs.
This patch makes abrt-action-trim-files to delete more than one file
between rescans.
Run tested.
--
vda
diff -x '*.po' -d -urpN abrt.0/src/plugins/abrt-action-trim-files.c abrt.1/src/plugins/abrt-action-trim-files.c
--- abrt.0/src/plugins/abrt-action-trim-files.c 2011-12-09 17:43:00.000000000 +0100
+++ abrt.1/src/plugins/abrt-action-trim-files.c 2011-12-13 15:17:19.794298614 +0100
@@ -18,15 +18,57 @@
*/
#include "libabrt.h"
-/* TODO: remember N worst files and their sizes, not just one:
- * if DIR is deep, scanning it takes *a few seconds*.
+/* We remember N worst files and their sizes, not just one:
+ * if DIR is deep, scanning it takes *a few seconds* even if it's in cache.
* If we rescan it after each single file deletion, it can be VERY slow.
* (I observed ~20 min long case).
*/
+#define MAX_VICTIM_LIST_SIZE 128
+
+struct name_and_size {
+ off_t size;
+ double weighted_size_and_age;
+ char name[1];
+};
+
+/* Updates a list of files sorted by increasing weighted_size_and_age.
+ */
+static GList *insert_name_and_sizes(GList *list, const char *name, double wsa, off_t sz)
+{
+ struct name_and_size *ns;
+ unsigned list_len = 0;
+ GList *cur = list;
+
+ while (cur)
+ {
+ ns = cur->data;
+ if (ns->weighted_size_and_age >= wsa)
+ break;
+ list_len++;
+ cur = cur->next;
+ }
+ list_len += g_list_length(cur);
+
+ if (cur != list || list_len < MAX_VICTIM_LIST_SIZE)
+ {
+ ns = xmalloc(sizeof(*ns) + strlen(name));
+ ns->weighted_size_and_age = wsa;
+ ns->size = sz;
+ strcpy(ns->name, name);
+ list = g_list_insert_before(list, cur, ns);
+ list_len++;
+ if (list_len > MAX_VICTIM_LIST_SIZE)
+ {
+ free(list->data);
+ list = g_list_delete_link(list, list);
+ }
+ }
+
+ return list;
+}
static double get_dir_size(const char *dirname,
- char **worst_file,
- double *worst_file_size,
+ GList **pp_worst_file_list,
char **preserve_list
) {
DIR *dp = opendir(dirname);
@@ -34,7 +76,7 @@ static double get_dir_size(const char *d
return 0;
/* "now" is used only if caller wants to know worst_file */
- time_t now = worst_file ? time(NULL) : 0;
+ time_t now = pp_worst_file_list ? time(NULL) : 0;
struct dirent *dent;
double size = 0;
while ((dent = readdir(dp)) != NULL)
@@ -49,19 +91,19 @@ static double get_dir_size(const char *d
if (S_ISDIR(stats.st_mode))
{
- double sz = get_dir_size(fullname, worst_file, worst_file_size, preserve_list);
+ double sz = get_dir_size(fullname, pp_worst_file_list, preserve_list);
size += sz;
}
else if (S_ISREG(stats.st_mode))
{
double sz = stats.st_size;
/* Account for filename and inode storage (approximately).
- * This also makes even zero-length files to have nonzero cost
+ * This also makes even zero-length files to have nonzero cost.
*/
sz += strlen(dent->d_name) + sizeof(stats);
size += sz;
- if (worst_file)
+ if (pp_worst_file_list)
{
if (preserve_list)
{
@@ -82,13 +124,7 @@ static double get_dir_size(const char *d
if (age > 1)
sz *= age;
- if (sz > *worst_file_size)
- {
- *worst_file_size = sz;
- free(*worst_file);
- *worst_file = fullname;
- fullname = NULL;
- }
+ *pp_worst_file_list = insert_name_and_sizes(*pp_worst_file_list, fullname, sz, stats.st_size);
}
}
next:
@@ -138,23 +174,34 @@ static void delete_files(gpointer data,
const char *dir = parse_size_pfx(&cap_size, data);
char **preserve_list = void_preserve_list;
- unsigned count = 1000;
+ unsigned count = 20;
while (--count != 0)
{
- char *worst_file = NULL;
- double worst_file_size = 0;
- double cur_size = get_dir_size(dir, &worst_file, &worst_file_size, preserve_list);
- if (cur_size <= cap_size || !worst_file)
+ GList *worst_file_list = NULL;
+ double cur_size = get_dir_size(dir, &worst_file_list, preserve_list);
+
+ if (cur_size <= cap_size || !worst_file_list)
{
+ list_free_with_free(worst_file_list);
VERB2 log("cur_size:%.0f cap_size:%.0f, no (more) trimming", cur_size, cap_size);
- free(worst_file);
break;
}
- log("%s is %.0f bytes (more than %.0f MB), deleting '%s'",
- dir, cur_size, cap_size / (1024*1024), worst_file);
- if (unlink(worst_file) != 0)
- perror_msg("Can't unlink '%s'", worst_file);
- free(worst_file);
+
+ /* Invert the list, so that largest/oldest file is first */
+ worst_file_list = g_list_reverse(worst_file_list);
+ /* And delete (some of) them */
+ while (worst_file_list && cur_size > cap_size)
+ {
+ struct name_and_size *ns = worst_file_list->data;
+ log("%s is %.0f bytes (more than %.0f MB), deleting '%s' (%llu bytes)",
+ dir, cur_size, cap_size / (1024*1024), ns->name, (long long)ns->size);
+ if (unlink(ns->name) != 0)
+ perror_msg("Can't unlink '%s'", ns->name);
+ else
+ cur_size -= ns->size;
+ free(ns);
+ worst_file_list = g_list_delete_link(worst_file_list, worst_file_list);
+ }
}
}
12 years, 4 months
[PATCH] abrt-action-trim-files: do not delete files preserved files point to
by Denys Vlasenko
Preserve not only files specified on command line, but,
if they are symlinks, preserve also the real files they point to.
While we are at it, also allow deletion of symlinks.
--
vda
diff -x '*.po' -d -urpN abrt.1/src/plugins/abrt-action-trim-files.c abrt.2/src/plugins/abrt-action-trim-files.c
--- abrt.1/src/plugins/abrt-action-trim-files.c 2011-12-13 15:17:19.794298614 +0100
+++ abrt.2/src/plugins/abrt-action-trim-files.c 2011-12-13 17:26:25.923648803 +0100
@@ -69,7 +69,7 @@ static GList *insert_name_and_sizes(GLis
static double get_dir_size(const char *dirname,
GList **pp_worst_file_list,
- char **preserve_list
+ GList *preserve_files_list
) {
DIR *dp = opendir(dirname);
if (!dp)
@@ -91,10 +91,10 @@ static double get_dir_size(const char *d
if (S_ISDIR(stats.st_mode))
{
- double sz = get_dir_size(fullname, pp_worst_file_list, preserve_list);
+ double sz = get_dir_size(fullname, pp_worst_file_list, preserve_files_list);
size += sz;
}
- else if (S_ISREG(stats.st_mode))
+ else if (S_ISREG(stats.st_mode) || S_ISLNK(stats.st_mode))
{
double sz = stats.st_size;
/* Account for filename and inode storage (approximately).
@@ -105,16 +105,13 @@ static double get_dir_size(const char *d
if (pp_worst_file_list)
{
- if (preserve_list)
+ GList *cur = preserve_files_list;
+ while (cur)
{
- char **pp = preserve_list;
- while (*pp)
- {
- //log("'%s' ? '%s'", fullname, *pp);
- if (strcmp(fullname, *pp) == 0)
- goto next;
- pp++;
- }
+ //log("'%s' ? '%s'", fullname, *pp);
+ if (strcmp(fullname, (char*)cur->data) == 0)
+ goto next;
+ cur = cur->next;
}
/* Calculate "weighted" size and age
@@ -172,13 +169,13 @@ static void delete_files(gpointer data,
{
double cap_size;
const char *dir = parse_size_pfx(&cap_size, data);
- char **preserve_list = void_preserve_list;
+ GList *preserve_files_list = void_preserve_list;
- unsigned count = 20;
+ unsigned count = 100;
while (--count != 0)
{
GList *worst_file_list = NULL;
- double cur_size = get_dir_size(dir, &worst_file_list, preserve_list);
+ double cur_size = get_dir_size(dir, &worst_file_list, preserve_files_list);
if (cur_size <= cap_size || !worst_file_list)
{
@@ -244,8 +241,33 @@ int main(int argc, char **argv)
/* We don't have children, so this is not needed: */
//export_abrt_envvars(/*set_pfx:*/ 0);
+ /* Preserve not only files specified on command line, but,
+ * if they are symlinks, preserve also the real files they point to:
+ */
+ GList *preserve_files_list = NULL;
+ while (*argv)
+ {
+ char *name = *argv++;
+ /* Since we don't bother freeing preserve_files_list on exit,
+ * we take a shortcut and insert name instead of xstrdup(name)
+ * in the next line:
+ */
+ preserve_files_list = g_list_prepend(preserve_files_list, name);
+
+ char *rp = realpath(name, NULL);
+ if (rp)
+ {
+ if (strcmp(rp, name) != 0)
+ preserve_files_list = g_list_prepend(preserve_files_list, rp);
+ else
+ free(rp);
+ }
+ }
+ /* Not really necessary, but helps to reduce confusion when debugging */
+ preserve_files_list = g_list_reverse(preserve_files_list);
+
g_list_foreach(dir_list, delete_dirs, preserve);
- g_list_foreach(file_list, delete_files, argv);
+ g_list_foreach(file_list, delete_files, preserve_files_list);
return 0;
}
12 years, 4 months
[PATCH] dumpoops: ignore "Oops" messages in syslog rhbz#726707
by Jiri Moskovcak
This patch makes abrt-dump-oops ignore the messages with "Oops" prefix,
it's not a standard warning and doesn't have any predefined format, so
it's hard to properly parse it and in some cases (when it's followed by
other kerneloops) it confuses the logic in abrt-dump-oops. After a
discussion with kernel devs I propose to not catch these messages.
Proposed patch and testing syslog attached. Run-tested, please review.
--Jirka
12 years, 4 months
Re: [PATCH 1/1] x86: Add process memory layout to coredump file
by Jan Kratochvil
On Sun, 11 Dec 2011 15:10:00 +0100, t cheney wrote:
> This patch just add memory layout(same as /proc/pid/maps) to
> coredump file. The layout is appended to corenote segment with
> flag NT_MAPS=7.
FYI this has been solved by ABRT - Automated Bug-Reporting Tool
https://fedorahosted.org/abrt/
(it is distro-neutral despite its homepage)
Core file is there a subdirectory where the core file is just one of the many
associated files:
/var/spool/abrt/ccpp-*:
abrt_version analyzer architecture cmdline component coredump count
dso_list environ executable hostname kernel maps os_release package
pid pwd reason time uid username uuid var_log_messages
More info files are being continually added, such as /proc/PID/fd{,info}/
mapping at the crash dump time etc. You would need to add many more core file
notes to make the core files useful for later analysis.
Regards,
Jan
12 years, 4 months
set of patches for abrt-server
by Vratislav Podzimek
These are patches that make abrt-server usable for passing more information to it. So we can patch e.g. pyhook to provide additional information.
At least two of them deserve additional comments:
10/12 -- this is the biggest patch and I really recommend to look at whole patched file attached to a reply to this mail
11/12 -- this one is closely related to the previous one and it contains two shell scripts and .txt files (input for the scripts)
libreport -- I know that the FILENAME_BASENAME is not an ideal name for this value, but it fits in the rest of
them and is related to filenames, so I see it as the least confusing name
Rationale for the whole patch set:
1.) We need to have abrt-server more versatile to be able to provide more information in bugreports. Some of them are Python/Ruby/whatever specific or at least can be obtained from the running interpret environment in an easier way then from abrtd's perspective.
2.) Using GLib adds no additional dependencies.
3.) Using regular expressions makes parsing (and thus whole abrt-server) more versatile, better readable and maintable.
4.) Values checking should be done in one function and easily maintable so that we would be able to add more restrictions easily. If you see the ".txt files -> scripts -> .c files" flow as unnecessary, try to think again about maintainability a security. I mean, this way we have these restrictions hardcoded from the user's point of view (so that he cannot accidentaly modify it), but still easily editable from the maintainer's point of view. But there is one thing missing -- add "parse_checks.sh check_rules.txt > rules.c" to the Makefile. This is something I don't know how to do with Autotools. Can somebody help?
5.) I've tried to preserve the behaviour of the abrt-server including restrictions, but I see length checks as unnecessary. What is the reason for checking length of e.g. ANALYZER? We check the length of the whole communication, so there shouldn't be any security issues after removing it. And if the length causes a system call failure (e.g. creating new file) there still will be an error reported. And we believe that clients won't provide nonsense information (there's no way to check this) so I see no difference in believing that the info is "reasonably short".
So I've tried to explain the reasons of my steps, but of course feel free to ask me to explain anything that's not clear.
--
Vratislav Podzimek
Anaconda Rider | Red Hat, Inc. | Brno -- Czech Republic
12 years, 4 months