summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarel Klic <kklic@redhat.com>2009-11-12 16:58:07 +0100
committerKarel Klic <kklic@redhat.com>2009-11-12 16:58:07 +0100
commit32cee84a34c005fe0d2863f439007ec633687fa8 (patch)
tree149ca7014e4295de3788f28ae88e9d9d7003da46 /src
parent5a8a8a6c99c9067e0dfcce839c32826a2badff0b (diff)
parent3938e6e075867ae3a349ba307ee672aa458d2662 (diff)
downloadabrt-32cee84a34c005fe0d2863f439007ec633687fa8.tar.gz
abrt-32cee84a34c005fe0d2863f439007ec633687fa8.tar.xz
abrt-32cee84a34c005fe0d2863f439007ec633687fa8.zip
Merge branch 'master' of ssh://git.fedorahosted.org/git/abrt
Diffstat (limited to 'src')
-rw-r--r--src/Daemon/Daemon.cpp60
-rw-r--r--src/Daemon/MiddleWare.cpp51
-rw-r--r--src/Daemon/MiddleWare.h7
-rw-r--r--src/Daemon/Settings.cpp2
-rwxr-xr-xsrc/Daemon/abrt-debuginfo-install249
-rw-r--r--src/Gui/CCMainWindow.py2
-rw-r--r--src/Gui/CCReporterDialog.py29
-rw-r--r--src/Gui/report.glade45
-rw-r--r--src/Hooks/CCpp.cpp10
-rw-r--r--src/Hooks/Makefile.am4
-rw-r--r--src/Hooks/abrt-pyhook-helper.cpp14
-rw-r--r--src/Hooks/abrt_exception_handler.py.in1
12 files changed, 279 insertions, 195 deletions
diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp
index 67e72cca..53c44d3f 100644
--- a/src/Daemon/Daemon.cpp
+++ b/src/Daemon/Daemon.cpp
@@ -165,18 +165,6 @@ static double GetDirSize(const std::string &pPath, std::string *worst_dir = NULL
return size;
}
-static bool analyzer_has_InformAllUsers(const char *analyzer_name)
-{
- CAnalyzer* analyzer = g_pPluginManager->GetAnalyzer(analyzer_name);
- if (!analyzer)
- return false;
- map_plugin_settings_t settings = analyzer->GetSettings();
- map_plugin_settings_t::const_iterator it = settings.find("InformAllUsers");
- if (it == settings.end())
- return false;
- return string_to_bool(it->second.c_str());
-}
-
static void cron_delete_callback_data_cb(gpointer data)
{
cron_callback_data_t* cronDeleteCallbackData = static_cast<cron_callback_data_t*>(data);
@@ -388,23 +376,24 @@ static void FindNewDumps(const char* pPath)
switch (res)
{
case MW_OK:
- VERB1 log("Saving into database (%s)", itt->c_str());
+ VERB1 log("Saving %s into database", itt->c_str());
RunActionsAndReporters(crashinfo[CD_MWDDD][CD_CONTENT].c_str());
break;
case MW_IN_DB:
- VERB1 log("Already saved in database (%s)", itt->c_str());
+ VERB1 log("%s is already saved in database", itt->c_str());
break;
case MW_REPORTED:
case MW_OCCURED:
+ VERB1 log("Already saved crash %s, deleting", itt->c_str());
+ DeleteDebugDumpDir(itt->c_str());
+ break;
case MW_BLACKLISTED:
case MW_CORRUPTED:
case MW_PACKAGE_ERROR:
case MW_GPG_ERROR:
case MW_FILE_ERROR:
default:
-//Perhaps corrupted & bad needs to be logged unconditionally,
-//already saved one - only on VERB1
- VERB1 log("Corrupted, bad or already saved crash, deleting");
+ log("Corrupted or bad crash %s (res:%d), deleting", itt->c_str(), (int)res);
DeleteDebugDumpDir(itt->c_str());
break;
}
@@ -556,7 +545,6 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin
: crashinfo[CD_UID][CD_CONTENT].c_str();
g_pCommLayer->Crash(crashinfo[CD_PACKAGE][CD_CONTENT].c_str(), uid_str);
}
- //DeleteDebugDumpDir(fullname.c_str());
break;
case MW_BLACKLISTED:
case MW_CORRUPTED:
@@ -670,29 +658,36 @@ static void start_syslog_logging()
logmode = LOGMODE_SYSLOG;
}
-static void ensure_root_writable_dir(const char *dir)
+static void ensure_writable_dir(const char *dir, mode_t mode, const char *group)
{
struct stat sb;
- if (mkdir(dir, 0755) != 0 && errno != EEXIST)
+ if (mkdir(dir, mode) != 0 && errno != EEXIST)
perror_msg_and_die("Can't create '%s'", dir);
if (stat(dir, &sb) != 0 || !S_ISDIR(sb.st_mode))
error_msg_and_die("'%s' is not a directory", dir);
- if ((sb.st_uid != 0 || sb.st_gid != 0) && chown(dir, 0, 0) != 0)
+
+ struct group *gr = getgrnam(group);
+ if (!gr)
+ perror_msg_and_die("Can't find group '%s'", group);
+
+ if ((sb.st_uid != 0 || sb.st_gid != gr->gr_gid) && chown(dir, 0, gr->gr_gid) != 0)
perror_msg_and_die("Can't set owner 0:0 on '%s'", dir);
- /* We can't allow anyone to create dumps: otherwise users can flood
- * us with thousands of bogus or malicious dumps */
- /* 07000 bits are setuid, setgit, and sticky, and they must be unset */
- /* 00777 bits are usual "rwxrwxrwx" access rights */
- if ((sb.st_mode & 07777) != 0755 && chmod(dir, 0755) != 0)
- perror_msg_and_die("Can't set mode rwxr-xr-x on '%s'", dir);
+ if ((sb.st_mode & 07777) != mode && chmod(dir, mode) != 0)
+ perror_msg_and_die("Can't set mode %o on '%s'", mode, dir);
}
static void sanitize_dump_dir_rights()
{
- ensure_root_writable_dir(DEBUG_DUMPS_DIR);
- ensure_root_writable_dir(DEBUG_DUMPS_DIR"-di"); /* debuginfo cache */
- ensure_root_writable_dir(VAR_RUN"/abrt"); /* temp dir */
+ /* We can't allow anyone to create dumps: otherwise users can flood
+ * us with thousands of bogus or malicious dumps */
+ /* 07000 bits are setuid, setgit, and sticky, and they must be unset */
+ /* 00777 bits are usual "rwxrwxrwx" access rights */
+ ensure_writable_dir(DEBUG_DUMPS_DIR, 0775, "abrt");
+ /* debuginfo cache */
+ ensure_writable_dir(DEBUG_DUMPS_DIR"-di", 0755, "root");
+ /* temp dir */
+ ensure_writable_dir(VAR_RUN"/abrt", 0755, "root");
}
int main(int argc, char** argv)
@@ -806,11 +801,6 @@ int main(int argc, char** argv)
pMainloop = g_main_loop_new(NULL, FALSE);
/* Watching DEBUG_DUMPS_DIR for new files... */
VERB1 log("Initializing inotify");
-// Enabled again since we have new abrt-pyhook-helper, remove comment when verified to work
- /* FIXME: python hook runs with ordinary user privileges,
- * so it fails if everyone doesn't have write acces
- * to DEBUG_DUMPS_DIR
- */
sanitize_dump_dir_rights();
errno = 0;
int inotify_fd = inotify_init();
diff --git a/src/Daemon/MiddleWare.cpp b/src/Daemon/MiddleWare.cpp
index 6a635642..0bc358e1 100644
--- a/src/Daemon/MiddleWare.cpp
+++ b/src/Daemon/MiddleWare.cpp
@@ -456,10 +456,9 @@ void DeleteDebugDumpDir(const char *pDebugDumpDir)
std::string DeleteCrashInfo(const char *pUUID,
const char *pUID)
{
- database_row_t row;
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
database->Connect();
- row = database->GetUUIDData(pUUID, pUID);
+ database_row_t row = database->GetUUIDData(pUUID, pUID);
database->Delete(pUUID, pUID);
database->DisConnect();
@@ -573,6 +572,21 @@ static mw_result_t SavePackageDescriptionToDebugDump(const char *pExecutable,
return MW_OK;
}
+bool analyzer_has_InformAllUsers(const char *analyzer_name)
+{
+ CAnalyzer* analyzer = g_pPluginManager->GetAnalyzer(analyzer_name);
+ if (!analyzer)
+ {
+ VERB1 log("Strange, asked for analyzer %s but it doesn't exist?", analyzer_name);
+ return false;
+ }
+ map_plugin_settings_t settings = analyzer->GetSettings();
+ map_plugin_settings_t::const_iterator it = settings.find("InformAllUsers");
+ if (it == settings.end())
+ return false;
+ return string_to_bool(it->second.c_str());
+}
+
/**
* Execute all action plugins, which are associated to
* particular analyzer plugin.
@@ -621,14 +635,12 @@ static mw_result_t SaveDebugDumpToDatabase(const char *pUUID,
const char *pDebugDumpDir,
map_crash_info_t& pCrashInfo)
{
- mw_result_t res;
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
- database_row_t row;
database->Connect();
database->Insert(pUUID, pUID, pDebugDumpDir, pTime);
- row = database->GetUUIDData(pUUID, pUID);
+ database_row_t row = database->GetUUIDData(pUUID, pUID);
database->DisConnect();
- res = GetCrashInfo(pUUID, pUID, pCrashInfo);
+ mw_result_t res = GetCrashInfo(pUUID, pUID, pCrashInfo);
if (row.m_sReported == "1")
{
log("Crash is already reported");
@@ -646,29 +658,19 @@ std::string getDebugDumpDir(const char *pUUID,
const char *pUID)
{
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
- database_row_t row;
database->Connect();
- row = database->GetUUIDData(pUUID, pUID);
+ database_row_t row = database->GetUUIDData(pUUID, pUID);
database->DisConnect();
return row.m_sDebugDumpDir;
}
-mw_result_t SaveDebugDump(const char *pDebugDumpDir)
-{
- map_crash_info_t info;
- return SaveDebugDump(pDebugDumpDir, info);
-}
-
mw_result_t SaveDebugDump(const char *pDebugDumpDir,
map_crash_info_t& pCrashInfo)
{
- std::string lUUID;
std::string UID;
std::string time;
std::string analyzer;
std::string executable;
- mw_result_t res;
-
try
{
CDebugDump dd;
@@ -692,15 +694,17 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir,
{
return MW_IN_DB;
}
- res = SavePackageDescriptionToDebugDump(executable.c_str(), pDebugDumpDir);
+ mw_result_t res = SavePackageDescriptionToDebugDump(executable.c_str(), pDebugDumpDir);
if (res != MW_OK)
{
return res;
}
- lUUID = GetLocalUUID(analyzer.c_str(), pDebugDumpDir);
-
- return SaveDebugDumpToDatabase(lUUID.c_str(), UID.c_str(), time.c_str(), pDebugDumpDir, pCrashInfo);
+ std::string lUUID = GetLocalUUID(analyzer.c_str(), pDebugDumpDir);
+ const char *uid_str = analyzer_has_InformAllUsers(analyzer.c_str())
+ ? "-1"
+ : UID.c_str();
+ return SaveDebugDumpToDatabase(lUUID.c_str(), uid_str, time.c_str(), pDebugDumpDir, pCrashInfo);
}
mw_result_t GetCrashInfo(const char *pUUID,
@@ -709,16 +713,14 @@ mw_result_t GetCrashInfo(const char *pUUID,
{
pCrashInfo.clear();
CDatabase* database = g_pPluginManager->GetDatabase(g_settings_sDatabase);
- database_row_t row;
database->Connect();
- row = database->GetUUIDData(pUUID, pUID);
+ database_row_t row = database->GetUUIDData(pUUID, pUID);
database->DisConnect();
std::string package;
std::string executable;
std::string description;
std::string analyzer;
-
try
{
CDebugDump dd;
@@ -737,6 +739,7 @@ mw_result_t GetCrashInfo(const char *pUUID,
}
return MW_ERROR;
}
+
add_crash_data_to_crash_info(pCrashInfo, CD_EXECUTABLE, executable);
add_crash_data_to_crash_info(pCrashInfo, CD_PACKAGE, package);
add_crash_data_to_crash_info(pCrashInfo, CD_DESCRIPTION, description);
diff --git a/src/Daemon/MiddleWare.h b/src/Daemon/MiddleWare.h
index 0671dd02..ac042def 100644
--- a/src/Daemon/MiddleWare.h
+++ b/src/Daemon/MiddleWare.h
@@ -120,12 +120,6 @@ void DeleteDebugDumpDir(const char *pDebugDumpDir);
std::string DeleteCrashInfo(const char *pUUID,
const char *pUID);
/**
- * Saves debugdump into database.
- * @param pDebugDumpDir A debugdump directory.
- * @return It return results of operation. See mw_result_t.
- */
-mw_result_t SaveDebugDump(const char *pDebugDumpDir);
-/**
* Saves debugdump into database. If saving is successful,
* it fills crash info.
* @param pDebugDumpDir A debugdump directory.
@@ -171,5 +165,6 @@ void AddAnalyzerActionOrReporter(const char *pAnalyzer,
void AddActionOrReporter(const char *pActionOrReporter,
const char *pArgs);
+bool analyzer_has_InformAllUsers(const char *analyzer_name);
#endif /*MIDDLEWARE_H_*/
diff --git a/src/Daemon/Settings.cpp b/src/Daemon/Settings.cpp
index d9c9a98b..cefd35a4 100644
--- a/src/Daemon/Settings.cpp
+++ b/src/Daemon/Settings.cpp
@@ -132,7 +132,7 @@ static void ParseCommon()
map_string_t::const_iterator end = s_mapSectionCommon.end();
if (it != end)
{
- g_settings_bOpenGPGCheck = it->second == "yes";
+ g_settings_bOpenGPGCheck = string_to_bool(it->second.c_str());
}
it = s_mapSectionCommon.find("OpenGPGPublicKeys");
if (it != end)
diff --git a/src/Daemon/abrt-debuginfo-install b/src/Daemon/abrt-debuginfo-install
index 6070b74d..b3d72922 100755
--- a/src/Daemon/abrt-debuginfo-install
+++ b/src/Daemon/abrt-debuginfo-install
@@ -80,22 +80,39 @@ count_words() {
echo $#
}
-cleanup_and_report_missing() {
-# Which debuginfo files are still missing, including those we just unpacked?
- missing_build_ids=`for build_id in $build_ids; do
+print_missing_build_ids() {
+ for build_id in $build_ids; do
build_id1=${build_id:0:2}
build_id2=${build_id:2}
file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
test -f "/$file" && continue
test -f "$cachedir/$file" && continue
echo -n "$build_id "
- done`
+ done
+}
+
+print_missing_debuginfos() {
+ for build_id in $build_ids; do
+ build_id1=${build_id:0:2}
+ build_id2=${build_id:2}
+ file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
+ if test x"$cachedir" != x"" && test x"$cachedir" != x"/" ; then
+ test -f "$cachedir/$file" && continue
+ fi
+ test -f "/$file" && continue
+ echo -n "/$file "
+ done
+}
+
+cleanup_and_report_missing() {
+# Which debuginfo files are still missing, including those we just unpacked?
+ missing_build_ids=`print_missing_build_ids`
$debug && echo "missing_build_ids:$missing_build_ids"
# If cachedir is specified, tempdir is just a staging area. Delete it
if test x"$cachedir" != x""; then
$debug && echo "Removing $tempdir"
- rm -rf "$tempdir"
+ $debug || rm -rf "$tempdir"
fi
for missing in $missing_build_ids; do
@@ -105,6 +122,98 @@ cleanup_and_report_missing() {
test x"$missing_build_ids" != x"" && echo "`count_words $missing_build_ids` debuginfos can't be found"
}
+# $1: iteration (1,2...)
+print_package_names() {
+ # We'll run something like:
+ # yum --enablerepo='*debuginfo*' --quiet provides \
+ # /usr/lib/debug/.build-id/bb/11528d59940983f495e9cb099cafb0cb206051.debug \
+ # /usr/lib/debug/.build-id/c5/b84c0ad3676509dc30bfa7d42191574dac5b06.debug ...
+ local yumopts=""
+ if test x"$1" = x"1"; then
+ yumopts="-C"
+ echo "`count_words $missing_debuginfo_files` missing debuginfos, getting package list from cache" >&2
+ else
+ echo "`count_words $missing_debuginfo_files` missing debuginfos, getting package list" >&2
+ fi
+ local cmd="yum $yumopts --enablerepo='*debuginfo*' --quiet provides $missing_debuginfo_files"
+ echo "$cmd" >"yum_provides.$1.OUT"
+ local yum_provides_OUT=`$cmd 2>&1`
+ local err=$?
+ printf "%s\nexitcode:%s\n" "$yum_provides_OUT" $err >>"yum_provides.$1.OUT"
+ test $err = 0 || exit 2
+
+ # The output is pretty machine-unfriendly:
+ # glibc-debuginfo-2.10.90-24.x86_64 : Debug information for package glibc
+ # Repo : rawhide-debuginfo
+ # Matched from:
+ # Filename : /usr/lib/debug/.build-id/5b/c784c8d63f87dbdeb747a773940956a18ecd2f.debug
+ #
+ # 1:dbus-debuginfo-1.2.12-2.fc11.x86_64 : Debug information for package dbus
+ # Repo : updates-debuginfo
+ # Matched from:
+ # Filename : /usr/lib/debug/.build-id/bc/da7d09eb6c9ee380dae0ed3d591d4311decc31.debug
+ # Need to massage it a lot.
+ # There can be duplicates (one package may provide many debuginfos).
+ printf "%s\n" "$yum_provides_OUT" \
+ | grep -- -debuginfo- \
+ | sed 's/^[0-9]*://' \
+ | sed -e 's/ .*//' -e 's/:.*//' \
+ | sort | uniq | xargs
+}
+
+download_packages() {
+ ## Download with one command (too silent):
+ ## Redirecting, since progress bar stuff only messes up our output
+ ##yumdownloader --enablerepo='*debuginfo*' --quiet $packages >yumdownloader.OUT 2>&1
+ ##err=$?
+ ##echo "exitcode:$err" >>yumdownloader.OUT
+ ##test $err = 0 || exit 2
+ >yumdownloader.OUT
+ i=1
+ for pkg in $packages; do
+ echo "Download $i/$num_packages: $pkg"
+ echo "Download $i/$num_packages: $pkg" >>yumdownloader.OUT
+ yumdownloader --enablerepo='*debuginfo*' --quiet $pkg >>yumdownloader.OUT 2>&1
+ err=$?
+ echo "exitcode:$err" >>yumdownloader.OUT
+ echo >>yumdownloader.OUT
+ test $err = 0 || { echo "Download of $pkg failed!"; sleep 1; }
+ : $((i++))
+ done
+
+ for f in *.rpm; do
+ # Happens if no .rpm's were downloaded (yumdownloader problem)
+ # In this case, $f is the literal "*.rpm" string
+ test -f "$f" || exit 2
+ echo "Unpacking: $f"
+ echo "Processing: $f" >>unpack.OUT
+ rpm2cpio <"$f" 2>>unpack.OUT | cpio -id >>unpack.OUT 2>&1
+ done
+
+ # Copy debuginfo files to cachedir
+ if test x"$cachedir" != x"" && test -d "$cachedir"; then
+ for build_id in $build_ids; do
+ build_id1=${build_id:0:2}
+ build_id2=${build_id:2}
+
+ file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
+
+ test -f "/$file" && continue
+ test x"$cachedir" != x"/" && test -f "$cachedir/$file" && continue
+
+ if test -f "$file"; then
+ # file is one of those we just installed.
+ # Cache it if cachedir is specified.
+ mkdir -p "$cachedir/usr/lib/debug/.build-id/$build_id1"
+ # Note: this does not preserve symlinks. This is intentional
+ $debug && echo Copying2 "$file" to "$cachedir/$file" >&2
+ cp --remove-destination "$file" "$cachedir/$file"
+ continue
+ fi
+ done
+ fi
+}
+
# eu-unstrip output example:
# 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe]
@@ -138,113 +247,39 @@ build_ids=`printf "%s\n" "$eu_unstrip_OUT" \
done | sort | uniq | xargs`
$debug && echo "build_ids:$build_ids"
-# Which debuginfo files are missing?
-missing_debuginfo_files=`for build_id in $build_ids; do
- build_id1=${build_id:0:2}
- build_id2=${build_id:2}
- file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
- if test x"$cachedir" != x"" && test x"$cachedir" != x"/" ; then
- test -f "$cachedir/$file" && continue
- fi
- test -f "/$file" && continue
- echo -n "/$file "
-done`
-$debug && echo "missing_debuginfo_files:$missing_debuginfo_files"
-
-if test x"$missing_debuginfo_files" = x""; then
- cleanup_and_report_missing
- exit 0
-fi
-
-# We'll run something like:
-# yum --enablerepo='*debuginfo*' --quiet provides \
-# /usr/lib/debug/.build-id/bb/11528d59940983f495e9cb099cafb0cb206051.debug \
-# /usr/lib/debug/.build-id/c5/b84c0ad3676509dc30bfa7d42191574dac5b06.debug ...
-echo "Determining list of packages for `count_words $missing_debuginfo_files` missing debuginfos"
-yum_provides_OUT=`yum --enablerepo='*debuginfo*' --quiet provides $missing_debuginfo_files 2>&1`
-err=$?
-printf "%s\nexitcode:%s\n" "$yum_provides_OUT" $err >yum_provides.OUT
-test $err = 0 || exit 2
+# We try to not run yum without -C unless absolutely necessary.
+# Therefore we loop. yum is run by print_package_names function,
+# on first iteration it is run with -C, on second - without,
+# which usually causes yum to download updated filelists,
+# which in turn takes several minutes and annoys users.
+iter=0
+while true; do
+ : $((iter++))
+ test $iter -gt 2 && break
-# The output is pretty machine-unfriendly:
-# glibc-debuginfo-2.10.90-24.x86_64 : Debug information for package glibc
-# Repo : rawhide-debuginfo
-# Matched from:
-# Filename : /usr/lib/debug/.build-id/5b/c784c8d63f87dbdeb747a773940956a18ecd2f.debug
-#
-# 1:dbus-debuginfo-1.2.12-2.fc11.x86_64 : Debug information for package dbus
-# Repo : updates-debuginfo
-# Matched from:
-# Filename : /usr/lib/debug/.build-id/bc/da7d09eb6c9ee380dae0ed3d591d4311decc31.debug
-# Need to massage it a lot.
-# There can be duplicates (one package may provide many debuginfos).
-packages=`printf "%s\n" "$yum_provides_OUT" \
-| grep -- -debuginfo- \
-| sed 's/^[0-9]*://' \
-| sed -e 's/ .*//' -e 's/:.*//' \
-| sort | uniq | xargs`
-$debug && echo "packages:$packages"
-
-# yum may return "" here if it found no packages (say, if coredump is from a new,
-# unreleased package fresh from koji).
-if test x"$packages" = x""; then
- cleanup_and_report_missing
- exit 1
-fi
-
-num_packages=`count_words $packages`
-echo "Downloading $num_packages packages"
-## Download with one command (too silent):
-## Redirecting, since progress bar stuff only messes up our output
-##yumdownloader --enablerepo='*debuginfo*' --quiet $packages >yumdownloader.OUT 2>&1
-##err=$?
-##echo "exitcode:$err" >>yumdownloader.OUT
-##test $err = 0 || exit 2
->yumdownloader.OUT
-i=1
-for pkg in $packages; do
- echo "Download $i/$num_packages: $pkg"
- echo "Download $i/$num_packages: $pkg" >>yumdownloader.OUT
- yumdownloader --enablerepo='*debuginfo*' --quiet $pkg >>yumdownloader.OUT 2>&1
- err=$?
- echo "exitcode:$err" >>yumdownloader.OUT
- echo >>yumdownloader.OUT
- test $err = 0 || { echo "Download of $pkg failed!"; sleep 1; }
- : $((i++))
-done
+ # Analyze $build_ids and check which debuginfos are present
+ missing_debuginfo_files=`print_missing_debuginfos`
+ $debug && echo "missing_debuginfo_files:$missing_debuginfo_files"
-for f in *.rpm; do
- # Happens if no .rpm's were downloaded (yumdownloader problem)
- # In this case, $f is the literal "*.rpm" string
- test -f "$f" || exit 2
- echo "Unpacking: $f"
- echo "Processing: $f" >>unpack.OUT
- rpm2cpio <"$f" 2>>unpack.OUT | cpio -id >>unpack.OUT 2>&1
-done
+ if test x"$missing_debuginfo_files" = x""; then
+ break
+ fi
-# Copy debuginfo files to cachedir
-if test x"$cachedir" != x"" && test -d "$cachedir"; then
- for build_id in $build_ids; do
- build_id1=${build_id:0:2}
- build_id2=${build_id:2}
+ # Map $missing_debuginfo_files to package names.
+ # yum is run here.
+ packages=`print_package_names $iter`
+ $debug && echo "packages ($iter):$packages"
- file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug"
+ # yum may return "" here if it found no packages (say, if coredump
+ # is from a new, unreleased package fresh from koji).
+ if test x"$packages" = x""; then
+ continue
+ fi
- test -f "/$file" && continue
- test x"$cachedir" != x"/" && test -f "$cachedir/$file" && continue
-
- if test -f "$file"; then
- # file is one of those we just installed.
- # Cache it if cachedir is specified.
- mkdir -p "$cachedir/usr/lib/debug/.build-id/$build_id1"
- # Note: this does not preserve symlinks. This is intentional
- $debug && echo Copying2 "$file" to "$cachedir/$file" >&2
- cp --remove-destination "$file" "$cachedir/$file"
- continue
- fi
- done
-fi
-$debug && echo "missing_build_ids:$missing_build_ids"
+ num_packages=`count_words $packages`
+ echo "Downloading $num_packages packages"
+ download_packages
+done
cleanup_and_report_missing
diff --git a/src/Gui/CCMainWindow.py b/src/Gui/CCMainWindow.py
index d3a3abd0..31ebb410 100644
--- a/src/Gui/CCMainWindow.py
+++ b/src/Gui/CCMainWindow.py
@@ -88,7 +88,7 @@ class MainWindow():
columns[0] = gtk.TreeViewColumn(_("Package"))
columns[1] = gtk.TreeViewColumn(_("Application"))
columns[2] = gtk.TreeViewColumn(_("Date"))
- columns[3] = gtk.TreeViewColumn(_("Crash Rate"))
+ columns[3] = gtk.TreeViewColumn(_("Crash count"))
if os.getuid() == 0:
column = gtk.TreeViewColumn(_("User"))
columns.append(column)
diff --git a/src/Gui/CCReporterDialog.py b/src/Gui/CCReporterDialog.py
index e1d1c1bb..61e65526 100644
--- a/src/Gui/CCReporterDialog.py
+++ b/src/Gui/CCReporterDialog.py
@@ -43,6 +43,10 @@ class ReporterDialog():
self.tvComment = self.wTree.get_widget("tvComment")
self.tvComment.connect("focus-in-event", self.on_comment_focus_cb)
self.comment_changed = False
+
+ # "how to reproduce" textview
+ self.tevHowToReproduce = self.wTree.get_widget("tevHowToReproduce")
+ self.how_to_changed = False
self.tvReport = self.wTree.get_widget("tvReport")
@@ -76,7 +80,7 @@ class ReporterDialog():
# connect the signals
self.tvReport.connect_after("size-allocate", self.on_window_resize)
self.wTree.get_widget("bSend").connect("clicked", self.on_send_clicked)
- # start whit the warning hidden, so it's not visible when there is no rating
+ # start with the warning hidden, so it's not visible when there is no rating
self.wTree.get_widget("ebErrors").hide()
self.hydrate()
@@ -182,6 +186,20 @@ class ReporterDialog():
self.tvComment.set_buffer(buff)
continue
+ if item == "How to reproduce":
+ buff = gtk.TextBuffer()
+ how_to_reproduce = _("")
+ try:
+ if self.report[item][CONTENT]:
+ how_to_reproduce = self.report[item][CONTENT]
+ self.how_to_changed = True
+ except Exception, e:
+ pass
+
+ buff.set_text(how_to_reproduce)
+
+ self.tevHowToReproduce.set_buffer(buff)
+ continue
# if an backtrace has rating use it
if item == "rating":
try:
@@ -198,7 +216,7 @@ class ReporterDialog():
ebErrors.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red"))
if package:
lErrors.set_markup(
- "<span color=\"white\">%s</span>" % _("Reporting disabled because the backtrace is unusable!\nPlease try to install debuginfo manually using command:<span color=\"blue\"> debuginfo-install %s </span>\nthen use Refresh button to regenerate the backtrace." % package[0:package.rfind('-',0,package.rfind('-'))]))
+ "<span color=\"white\">%s</span>" % _("Reporting disabled because the backtrace is unusable.\nPlease try to install debuginfo manually using command:<span color=\"blue\"> debuginfo-install %s </span>\nthen use Refresh button to regenerate the backtrace." % package[0:package.rfind('-',0,package.rfind('-'))]))
else:
lErrors.set_markup("<span color=\"white\">%s</span>" % _("The bactrace is unusable, you can't report this!"))
bSend.set_sensitive(False)
@@ -232,11 +250,18 @@ class ReporterDialog():
self.report[rowe["item"]][CONTENT] = rowe["content"]
else:
del self.report[rowe["item"]]
+ # handle comment
if self.comment_changed:
buff = self.tvComment.get_buffer()
self.report["Comment"] = ['t', 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())]
else:
del self.report["Comment"]
+ # handle how to reproduce
+ if self.how_to_changed:
+ buff = self.tevHowToReproduce.get_buffer()
+ self.report["How to reproduce"] = ['t', 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())]
+ else:
+ del self.report["How to reproduce"]
def on_send_clicked(self, button):
#def on_apply_clicked(self, button, treeview):
diff --git a/src/Gui/report.glade b/src/Gui/report.glade
index 2ccf1690..ce21acb1 100644
--- a/src/Gui/report.glade
+++ b/src/Gui/report.glade
@@ -69,7 +69,50 @@
</packing>
</child>
<child>
- <placeholder/>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkEventBox" id="eventbox2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="lHowToReproduce">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="ypad">2</property>
+ <property name="label" translatable="yes">How to reproduce (in a few simple steps)</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <widget class="GtkTextView" id="tevHowToReproduce">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="wrap_mode">word</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
diff --git a/src/Hooks/CCpp.cpp b/src/Hooks/CCpp.cpp
index 0f95d05b..3ab8f406 100644
--- a/src/Hooks/CCpp.cpp
+++ b/src/Hooks/CCpp.cpp
@@ -205,19 +205,19 @@ int main(int argc, char** argv)
dd.Close();
perror_msg_and_die("can't open '%s'", path);
}
- if (copyfd_eof(STDIN_FILENO, fd) < 0)
+ off_t size = copyfd_eof(STDIN_FILENO, fd);
+ if (size < 0 || close(fd) != 0)
{
- /* close(fd); - why bother? */
+ unlink(path);
dd.Delete();
dd.Close();
/* copyfd_eof logs the error including errno string,
* but it does not log file name */
error_msg_and_die("error saving coredump to %s", path);
}
- /* close(fd); - why bother? */
- /* free(executable); */
+ /* free(executable); - why bother? */
/* free(cmdline); */
- log("saved core dump of pid %u to %s", (int)pid, path);
+ log("saved core dump of pid %u to %s (%llu bytes)", (int)pid, path, (long long)size);
}
catch (CABRTException& e)
{
diff --git a/src/Hooks/Makefile.am b/src/Hooks/Makefile.am
index 4eb25e2d..e581c25b 100644
--- a/src/Hooks/Makefile.am
+++ b/src/Hooks/Makefile.am
@@ -57,7 +57,3 @@ 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
index 8a5a1914..08ccc125 100644
--- a/src/Hooks/abrt-pyhook-helper.cpp
+++ b/src/Hooks/abrt-pyhook-helper.cpp
@@ -20,6 +20,7 @@
*/
#include <getopt.h>
+#include <unistd.h>
/* We can easily get rid of abrtlib (libABRTUtils.so) usage in this file,
* but DebugDump will pull it in anyway */
#include "abrtlib.h"
@@ -34,7 +35,6 @@ static char *pid;
static char *executable;
static char *uuid;
static char *cmdline;
-static char *loginuid;
int main(int argc, char** argv)
{
@@ -45,7 +45,6 @@ int main(int argc, char** argv)
{ "executable", required_argument, NULL, 'e' },
{ "uuid" , required_argument, NULL, 'u' },
{ "cmdline" , required_argument, NULL, 'c' },
- { "loginuid" , required_argument, NULL, 'l' },
{ 0 },
};
int opt;
@@ -65,9 +64,6 @@ int main(int argc, char** argv)
case 'c':
cmdline = optarg;
break;
- case 'l':
- loginuid = optarg;
- break;
default:
usage:
error_msg_and_die(
@@ -77,7 +73,6 @@ int main(int argc, char** argv)
" -p,--executable PATH absolute path to the program that crashed\n"
" -u,--uuid UUID hash generated from the backtrace\n"
" -c,--cmdline TEXT command line of the crashed program\n"
- " -l,--loginuid UID login UID\n"
);
}
}
@@ -112,8 +107,11 @@ int main(int argc, char** argv)
dd.SaveText("cmdline", cmdline);
if (uuid)
dd.SaveText("uuid", uuid);
- if (loginuid)
- dd.SaveText("uid", loginuid);
+
+ char uid[sizeof(int) * 3 + 2];
+ sprintf(uid, "%d", (int)getuid());
+ dd.SaveText("uid", uid);
+
dd.SaveText("backtrace", bt);
free(bt);
dd.Close();
diff --git a/src/Hooks/abrt_exception_handler.py.in b/src/Hooks/abrt_exception_handler.py.in
index 010bf12d..5514f1a4 100644
--- a/src/Hooks/abrt_exception_handler.py.in
+++ b/src/Hooks/abrt_exception_handler.py.in
@@ -114,7 +114,6 @@ def write_dump(pid, tb_uuid, tb):
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)