summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-11-18 18:30:08 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2009-11-18 18:30:08 +0100
commite55e12659f0dce36224c48d4c86f33cfb4b527b5 (patch)
treee9cdbe29bb18ba04e934d4a952cb0708b37170b0 /lib
parentb6a34a21048ca7edfa913e8c5ee094f4cb85503f (diff)
downloadabrt-e55e12659f0dce36224c48d4c86f33cfb4b527b5.tar.gz
abrt-e55e12659f0dce36224c48d4c86f33cfb4b527b5.tar.xz
abrt-e55e12659f0dce36224c48d4c86f33cfb4b527b5.zip
ccpp hook: implemented ReadonlyLocalDebugInfoDirs directive
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/Plugins/CCpp.conf5
-rw-r--r--lib/Plugins/CCpp.cpp147
-rw-r--r--lib/Plugins/CCpp.h1
3 files changed, 93 insertions, 60 deletions
diff --git a/lib/Plugins/CCpp.conf b/lib/Plugins/CCpp.conf
index 988ddf32..459dff8c 100644
--- a/lib/Plugins/CCpp.conf
+++ b/lib/Plugins/CCpp.conf
@@ -12,6 +12,11 @@ DebugInfo = install
# debuginfos will be installed to @@LOCALSTATEDIR@@/cache/abrt-di
InstallDebugInfo = yes
+# Additional directories to search for debuginfos.
+# For example, you can list a network-mounted shared store
+# of all debuginfos here.
+# ReadonlyLocalDebugInfoDirs = /path1:/path2:...
+
# Keep @@LOCALSTATEDIR@@/cache/abrt-di
# from growing out-of-bounds.
DebugInfoCacheMB = 4000
diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp
index 49a9e4a2..93156a22 100644
--- a/lib/Plugins/CCpp.cpp
+++ b/lib/Plugins/CCpp.cpp
@@ -33,6 +33,8 @@
#include "CommLayerInner.h"
#include "Polkit.h"
+using namespace std;
+
#define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern"
#define CORE_PATTERN "|"CCPP_HOOK_PATH" "DEBUG_DUMPS_DIR" %p %s %u"
@@ -48,9 +50,9 @@ CAnalyzerCCpp::CAnalyzerCCpp() :
m_nDebugInfoCacheMB(4000)
{}
-static std::string CreateHash(const std::string& pInput)
+static string CreateHash(const string& pInput)
{
- std::string ret = "";
+ string ret;
HASHContext* hc;
unsigned char hash[SHA1_LENGTH];
unsigned int len;
@@ -80,9 +82,9 @@ static std::string CreateHash(const std::string& pInput)
return hash_str;
}
-static std::string concat_str_vector(char **strings)
+static string concat_str_vector(char **strings)
{
- std::string result;
+ string result;
while (*strings)
{
result += *strings++;
@@ -92,7 +94,7 @@ static std::string concat_str_vector(char **strings)
return result;
}
-static pid_t ExecVP(char** pArgs, uid_t uid, std::string& pOutput)
+static pid_t ExecVP(char** pArgs, uid_t uid, string& pOutput)
{
int pipeout[2];
pid_t child;
@@ -100,7 +102,7 @@ static pid_t ExecVP(char** pArgs, uid_t uid, std::string& pOutput)
struct passwd* pw = getpwuid(uid);
if (!pw)
{
- throw CABRTException(EXCEP_PLUGIN, std::string(__func__) + ": cannot get GID for UID.");
+ throw CABRTException(EXCEP_PLUGIN, string(__func__) + ": cannot get GID for UID.");
}
xpipe(pipeout);
@@ -217,7 +219,7 @@ static int rate_backtrace(const char *backtrace)
{
if (backtrace[i] == '#') /* this separates frames from each other */
{
- std::string s(backtrace + i + 1, len);
+ string s(backtrace + i + 1, len);
for (j=0; j<len; j++) /* replace tabs with spaces */
if (s[j] == '\t')
s[j] = ' ';
@@ -249,12 +251,12 @@ static int rate_backtrace(const char *backtrace)
return 0;
}
-static void GetBacktrace(const char *pDebugDumpDir, std::string& pBacktrace)
+static void GetBacktrace(const char *pDebugDumpDir, string& pBacktrace)
{
update_client(_("Getting backtrace..."));
- std::string UID;
- std::string executable;
+ string UID;
+ string executable;
{
CDebugDump dd;
dd.Open(pDebugDumpDir);
@@ -270,10 +272,24 @@ static void GetBacktrace(const char *pDebugDumpDir, std::string& pBacktrace)
char* args[11];
args[0] = (char*)"gdb";
args[1] = (char*)"-batch";
+
// when/if gdb supports it:
// (https://bugzilla.redhat.com/show_bug.cgi?id=528668):
args[2] = (char*)"-ex";
- args[3] = (char*)"set debug-file-directory /usr/lib/debug:" DEBUGINFO_CACHE_DIR"/usr/lib/debug";
+ string dfd = "set debug-file-directory /usr/lib/debug";
+ const char *p = m_sDebugInfoDirs.c_str();
+ while (1)
+ {
+ const char *colon_or_nul = strchrnul(p, ':');
+ dfd += ':';
+ dfd.append(p, colon_or_nul - p);
+ dfd += "/usr/lib/debug";
+ if (*colon_or_nul != ':')
+ break;
+ p = colon + 1;
+ }
+ args[3] = (char*)dfd.c_str()
+
/*
* Unfortunately, "file BINARY_FILE" doesn't work well if BINARY_FILE
* was deleted (as often happens during system updates):
@@ -282,22 +298,23 @@ static void GetBacktrace(const char *pDebugDumpDir, std::string& pBacktrace)
* See https://bugzilla.redhat.com/show_bug.cgi?id=525721
*/
args[4] = (char*)"-ex";
- args[5] = xasprintf("file %s", executable.c_str());
+ string file = ssprintf("file %s", executable.c_str());
+ args[5] = (char*)file.c_str();
+
args[6] = (char*)"-ex";
- args[7] = xasprintf("core-file %s/"FILENAME_COREDUMP, pDebugDumpDir);
+ string corefile = ssprintf("core-file %s/"FILENAME_COREDUMP, pDebugDumpDir);
+ args[7] = (char*)corefile.c_str();
+
args[8] = (char*)"-ex";
args[9] = (char*)"thread apply all backtrace full";
args[10] = NULL;
ExecVP(args, atoi(UID.c_str()), pBacktrace);
-
- free(args[5]);
- free(args[7]);
}
-static std::string GetIndependentBacktrace(const std::string& pBacktrace)
+static string GetIndependentBacktrace(const string& pBacktrace)
{
- std::string header;
+ string header;
bool in_bracket = false;
bool in_quote = false;
bool in_header = false;
@@ -305,7 +322,7 @@ static std::string GetIndependentBacktrace(const std::string& pBacktrace)
bool has_at = false;
bool has_filename = false;
bool has_bracket = false;
- std::set<std::string> set_headers;
+ set<string> set_headers;
/* Backtrace example:
#0 0x00007f047e21af70 in __nanosleep_nocancel () from /lib64/libc-2.10.1.so
@@ -348,11 +365,11 @@ static std::string GetIndependentBacktrace(const std::string& pBacktrace)
{
in_digit = true;
}
- else if (bk[0] == '\\' && bk[1] == '\"')
+ else if (bk[0] == '\\' && bk[1] == '"')
{
bk++;
}
- else if (*bk == '\"')
+ else if (*bk == '"')
{
in_quote = in_quote == true ? false : true;
}
@@ -406,8 +423,8 @@ static std::string GetIndependentBacktrace(const std::string& pBacktrace)
bk++;
}
- std::string pIndependentBacktrace;
- std::set<std::string>::iterator it = set_headers.begin();
+ string pIndependentBacktrace;
+ set<string>::iterator it = set_headers.begin();
for (; it != set_headers.end(); it++)
{
pIndependentBacktrace += *it;
@@ -416,12 +433,12 @@ static std::string GetIndependentBacktrace(const std::string& pBacktrace)
return pIndependentBacktrace;
}
-static void GetIndependentBuildIdPC(const std::string& pBuildIdPC, std::string& pIndependentBuildIdPC)
+static void GetIndependentBuildIdPC(const string& pBuildIdPC, string& pIndependentBuildIdPC)
{
int ii = 0;
while (ii < pBuildIdPC.length())
{
- std::string line;
+ string line;
int jj = 0;
while (pBuildIdPC[ii] != '\n' && ii < pBuildIdPC.length())
@@ -446,9 +463,9 @@ static void GetIndependentBuildIdPC(const std::string& pBuildIdPC, std::string&
}
}
-static std::string run_unstrip_n(const char *pDebugDumpDir)
+static string run_unstrip_n(const char *pDebugDumpDir)
{
- std::string UID;
+ string UID;
{
CDebugDump dd;
dd.Open(pDebugDumpDir);
@@ -461,7 +478,7 @@ static std::string run_unstrip_n(const char *pDebugDumpDir)
args[2] = (char*)"-n";
args[3] = NULL;
- std::string output;
+ string output;
ExecVP(args, atoi(UID.c_str()), output);
free(args[1]);
@@ -481,10 +498,10 @@ static bool is_hexstr(const char* str)
}
return true;
}
-static void InstallDebugInfos(const char *pDebugDumpDir, std::string& build_ids)
+static void InstallDebugInfos(const char *pDebugDumpDir, const char *debuginfo_dirs, string& build_ids)
{
log("Getting module names, file names, build IDs from core file");
- std::string unstrip_list = run_unstrip_n(pDebugDumpDir);
+ string unstrip_list = run_unstrip_n(pDebugDumpDir);
log("Builting list of missing debuginfos");
// lines look like this:
@@ -542,7 +559,7 @@ static void InstallDebugInfos(const char *pDebugDumpDir, std::string& build_ids)
}
//missing vector is unused for now, but TODO: use it to install only needed debuginfos
- std::string package;
+ string package;
{
CDebugDump dd;
dd.Open(pDebugDumpDir);
@@ -629,7 +646,7 @@ Another application is holding the yum lock, cannot continue
bool already_installed = false;
#endif
char buff[1024];
- std::string packageName = package.substr(0, package.rfind("-", package.rfind("-")-1));
+ string packageName = package.substr(0, package.rfind("-", package.rfind("-")-1));
while (fgets(buff, sizeof(buff), pipeout_fp))
{
int last = strlen(buff) - 1;
@@ -662,7 +679,7 @@ Another application is holding the yum lock, cannot continue
fclose(pipeout_fp);
kill(child, SIGTERM);
wait(NULL);
- throw CABRTException(EXCEP_PLUGIN, std::string(__func__) + ": cannot install debuginfos for " + pPackage);
+ throw CABRTException(EXCEP_PLUGIN, string(__func__) + ": cannot install debuginfos for " + pPackage);
}
#endif
}
@@ -674,7 +691,7 @@ Another application is holding the yum lock, cannot continue
/* Needs gdb feature from here: https://bugzilla.redhat.com/show_bug.cgi?id=528668
* It is slated to be in F12/RHEL6.
*/
-static void InstallDebugInfos(const char *pDebugDumpDir, std::string& build_ids)
+static void InstallDebugInfos(const char *pDebugDumpDir, const char *debuginfo_dirs, string& build_ids)
{
update_client(_("Searching for debug-info packages..."));
@@ -703,8 +720,8 @@ static void InstallDebugInfos(const char *pDebugDumpDir, std::string& build_ids)
/* SELinux guys are not happy with /tmp, using /var/run/abrt */
char *tempdir = xasprintf(LOCALSTATEDIR"/run/abrt/tmp-%u-%lu", (int)getpid(), (long)time(NULL));
/* log() goes to stderr/syslog, it's ok to use it here */
- VERB1 log("Executing: %s %s %s %s", "abrt-debuginfo-install", coredump, tempdir, DEBUGINFO_CACHE_DIR);
- execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump, tempdir, DEBUGINFO_CACHE_DIR, NULL);
+ VERB1 log("Executing: %s %s %s %s", "abrt-debuginfo-install", coredump, tempdir, debuginfo_dirs);
+ execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump, tempdir, debuginfo_dirs, NULL);
exit(1);
}
@@ -750,7 +767,7 @@ static void InstallDebugInfos(const char *pDebugDumpDir, std::string& build_ids)
wait(NULL);
}
-static double get_dir_size(const char *dirname, std::string *worst_file, double *maxsz)
+static double get_dir_size(const char *dirname, string *worst_file, double *maxsz)
{
DIR *dp = opendir(dirname);
if (dp == NULL)
@@ -763,7 +780,7 @@ static double get_dir_size(const char *dirname, std::string *worst_file, double
{
if (dot_or_dotdot(ep->d_name))
continue;
- std::string dname = concat_path_file(dirname, ep->d_name);
+ string dname = concat_path_file(dirname, ep->d_name);
if (lstat(dname.c_str(), &stats) != 0)
continue;
if (S_ISDIR(stats.st_mode))
@@ -801,7 +818,7 @@ static void trim_debuginfo_cache(unsigned max_mb)
{
while (1)
{
- std::string worst_file;
+ string worst_file;
double maxsz = 0;
double cache_sz = get_dir_size(DEBUGINFO_CACHE_DIR, &worst_file, &maxsz);
if (cache_sz / (1024 * 1024) < max_mb)
@@ -813,12 +830,12 @@ static void trim_debuginfo_cache(unsigned max_mb)
}
}
-std::string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir)
+string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir)
{
log(_("Getting local universal unique identification..."));
- std::string executable;
- std::string package;
+ string executable;
+ string package;
{
CDebugDump dd;
dd.Open(pDebugDumpDir);
@@ -826,19 +843,19 @@ std::string CAnalyzerCCpp::GetLocalUUID(const char *pDebugDumpDir)
dd.LoadText(FILENAME_PACKAGE, package);
}
- std::string buildIdPC = run_unstrip_n(pDebugDumpDir);
- std::string independentBuildIdPC;
+ string buildIdPC = run_unstrip_n(pDebugDumpDir);
+ string independentBuildIdPC;
GetIndependentBuildIdPC(buildIdPC, independentBuildIdPC);
return CreateHash(package + executable + independentBuildIdPC);
}
-std::string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir)
+string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir)
{
log(_("Getting global universal unique identification..."));
- std::string backtrace;
- std::string executable;
- std::string package;
+ string backtrace;
+ string executable;
+ string package;
{
CDebugDump dd;
dd.Open(pDebugDumpDir);
@@ -846,7 +863,7 @@ std::string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir)
dd.LoadText(FILENAME_EXECUTABLE, executable);
dd.LoadText(FILENAME_PACKAGE, package);
}
- std::string independentBacktrace = GetIndependentBacktrace(backtrace);
+ string independentBacktrace = GetIndependentBacktrace(backtrace);
return CreateHash(package + executable + independentBacktrace);
}
@@ -881,9 +898,9 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force)
{
update_client(_("Starting report creation..."));
- std::string package;
- std::string backtrace;
- std::string UID;
+ string package;
+ string backtrace;
+ string UID;
CDebugDump dd;
dd.Open(pDebugDumpDir);
@@ -901,11 +918,14 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force)
dd.LoadText(FILENAME_UID, UID);
dd.Close(); /* do not keep dir locked longer than needed */
- std::string build_ids;
- if (m_bInstallDebugInfo && DebuginfoCheckPolkit(atoi(UID.c_str()))) {
+ string build_ids;
+ if (m_bInstallDebugInfo && DebuginfoCheckPolkit(atoi(UID.c_str())))
+ {
if (m_nDebugInfoCacheMB > 0)
+ {
trim_debuginfo_cache(m_nDebugInfoCacheMB);
- InstallDebugInfos(pDebugDumpDir, build_ids);
+ }
+ InstallDebugInfos(pDebugDumpDir, m_sDebugInfoDirs.c_str(), build_ids);
}
else
{
@@ -926,7 +946,7 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force)
void CAnalyzerCCpp::Init()
{
- std::ifstream fInCorePattern;
+ ifstream fInCorePattern;
fInCorePattern.open(CORE_PATTERN_IFACE);
if (fInCorePattern.is_open())
{
@@ -951,22 +971,22 @@ void CAnalyzerCCpp::Init()
}
}
- std::ofstream fOutCorePattern;
+ ofstream fOutCorePattern;
fOutCorePattern.open(CORE_PATTERN_IFACE);
if (fOutCorePattern.is_open())
{
- fOutCorePattern << CORE_PATTERN << std::endl;
+ fOutCorePattern << CORE_PATTERN << endl;
fOutCorePattern.close();
}
}
void CAnalyzerCCpp::DeInit()
{
- std::ofstream fOutCorePattern;
+ ofstream fOutCorePattern;
fOutCorePattern.open(CORE_PATTERN_IFACE);
if (fOutCorePattern.is_open())
{
- fOutCorePattern << m_sOldCorePattern << std::endl;
+ fOutCorePattern << m_sOldCorePattern << endl;
fOutCorePattern.close();
}
}
@@ -999,6 +1019,13 @@ void CAnalyzerCCpp::SetSettings(const map_plugin_settings_t& pSettings)
{
m_bInstallDebugInfo = string_to_bool(it->second.c_str());
}
+ m_sDebugInfoDirs = DEBUGINFO_CACHE_DIR;
+ it = pSettings.find("ReadonlyLocalDebugInfoDirs");
+ if (it != end)
+ {
+ m_sDebugInfoDirs += ':';
+ m_sDebugInfoDirs += it->second;
+ }
}
//ok to delete?
diff --git a/lib/Plugins/CCpp.h b/lib/Plugins/CCpp.h
index 3fa0d99a..26dedead 100644
--- a/lib/Plugins/CCpp.h
+++ b/lib/Plugins/CCpp.h
@@ -35,6 +35,7 @@ class CAnalyzerCCpp : public CAnalyzer
unsigned m_nDebugInfoCacheMB;
std::string m_sOldCorePattern;
std::string m_sDebugInfo;
+ std::string m_sDebugInfoDirs;
public:
CAnalyzerCCpp();