summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorKarel Klic <kklic@redhat.com>2009-10-20 15:58:02 +0200
committerKarel Klic <kklic@redhat.com>2009-10-20 15:58:02 +0200
commit08b9971c3d1635ff1f6d17608e7e99d5ac4b5866 (patch)
tree1b7dc5c62858b8efdbc610431a21f3564e4d6f3b /lib
parent9e8a1ba0c9ddfa0108050f6fedc88de63b4b7c3f (diff)
parent4df20906ef57432edb505ce28179fd979729c975 (diff)
downloadabrt-08b9971c3d1635ff1f6d17608e7e99d5ac4b5866.tar.gz
abrt-08b9971c3d1635ff1f6d17608e7e99d5ac4b5866.tar.xz
abrt-08b9971c3d1635ff1f6d17608e7e99d5ac4b5866.zip
Merge branch 'master' of ssh://git.fedorahosted.org/git/abrt
Diffstat (limited to 'lib')
-rw-r--r--lib/Plugins/CCpp.cpp198
1 files changed, 195 insertions, 3 deletions
diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp
index 40aadd24..3fedd947 100644
--- a/lib/Plugins/CCpp.cpp
+++ b/lib/Plugins/CCpp.cpp
@@ -373,9 +373,200 @@ static std::string run_unstrip_n(const std::string& pDebugDumpDir)
static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& build_ids)
{
+ log("Getting module names, file names, build IDs from core file");
+ std::string unstrip_list = run_unstrip_n(pDebugDumpDir);
+
+ log("Builting list of missing debuginfos");
+ // lines look like this:
+ // 0x400000+0x209000 23c77451cf6adff77fc1f5ee2a01d75de6511dda@0x40024c - - [exe]
+ // 0x400000+0x209000 ab3c8286aac6c043fd1bb1cc2a0b88ec29517d3e@0x40024c /bin/sleep /usr/lib/debug/bin/sleep.debug [exe]
+ // 0x7fff313ff000+0x1000 389c7475e3d5401c55953a425a2042ef62c4c7df@0x7fff313ff2f8 . - linux-vdso.so.1
+ vector_string_t missing;
+ char *dup = xstrdup(unstrip_list.c_str());
+ char *p = dup;
+ char c;
+ do {
+ char* end = strchrnul(p, '\n');
+ c = *end;
+ *end = '\0';
+ char* word2 = strchr(p, ' ');
+ if (!word2)
+ continue;
+ word2++;
+ char* endsp = strchr(word2, ' ');
+ if (!endsp)
+ continue;
+ /* endsp points to 2nd space in the line now*/
+
+ /* This filters out linux-vdso.so, among others */
+ if (strstr(endsp, "[exe]") == NULL && endsp[1] != '/')
+ continue;
+ *endsp = '\0';
+ char* at = strchrnul(word2, '@');
+ *at = '\0';
+
+ bool file_exists = 1;
+ if (word2[0] && word2[1] && is_hexstr(word2))
+ {
+ struct stat sb;
+ char *fn = xasprintf("/usr/lib/debug/.build-id/%.2s/%s.debug", word2, word2 + 2);
+ /* Not lstat: this is a symlink and we want link's TARGET to exist */
+ file_exists = stat(fn, &sb) == 0 && S_ISREG(sb.st_mode);
+ free(fn);
+ build_ids += "build-id ";
+ build_ids += word2;
+ build_ids += file_exists ? " (debuginfo present)\n" : " (debuginfo absent)\n";
+ }
+ log("build_id:%s exists:%d", word2, (int)file_exists);
+ if (!file_exists)
+ missing.push_back(word2);
+
+ p = end + 1;
+ } while (c);
+ free(dup);
+
+ if (missing.size() == 0)
+ {
+ log("All debuginfos are present, not installing debuginfo packages");
+ return;
+ }
+ //missing vector is unused for now, but TODO: use it to install only needed debuginfos
+
+ std::string package;
+ {
+ CDebugDump dd;
+ dd.Open(pDebugDumpDir);
+ dd.LoadText(FILENAME_PACKAGE, package);
+ }
+
+ update_client(_("Searching for debug-info packages..."));
+
+ int pipein[2], pipeout[2];
+ xpipe(pipein);
+ xpipe(pipeout);
+
+ pid_t child = fork();
+ if (child < 0)
+ {
+ /*close(pipein[0]); close(pipeout[0]); - why bother */
+ /*close(pipein[1]); close(pipeout[1]); */
+ perror_msg_and_die("fork");
+ }
+ if (child == 0)
+ {
+ close(pipein[1]);
+ close(pipeout[0]);
+ xmove_fd(pipein[0], STDIN_FILENO);
+ xmove_fd(pipeout[1], STDOUT_FILENO);
+ /* Not a good idea, we won't see any error messages */
+ /*close(STDERR_FILENO);*/
+
+ setsid();
+/* Honestly, I do not know what is worse, pk-debuginfo-install or debuginfo-install:
+
+# pk-debuginfo-install -y -- coreutils-7.2-4.fc11
+1. Getting sources list...OK. Found 16 enabled and 23 disabled sources.
+2. Finding debugging sources...OK. Found 0 disabled debuginfo repos.
+3. Enabling debugging sources...OK. Enabled 0 debugging sources.
+4. Finding debugging packages...Failed to find the package : more than one package found for
+Failed to find the package : more than one package found for
+FAILED. Found no packages to install.
+5. Disabling sources previously enabled...OK. Disabled 0 debugging sources.
+
+:( FAIL!
+
+# debuginfo-install -y -- coreutils-7.2-4.fc11
+Loaded plugins: refresh-packagekit
+Another application is holding the yum lock, cannot continue
+
+:( FAIL!
+
+# debuginfo-install -y -- coreutils-7.2-4.fc11
+(second time in a row - it worked)
+
+*/
+ /* log() goes to stderr/syslog, it's ok to use it here */
+ VERB1 log("Executing: %s %s %s %s", "pk-debuginfo-install", "-y", "--", package.c_str());
+ execlp("pk-debuginfo-install", "pk-debuginfo-install", "-y", "--", package.c_str(), NULL);
+ /* fall back */
+ VERB1 log("Executing: %s %s %s %s", "debuginfo-install", "-y", "--", package.c_str());
+ execlp("debuginfo-install", "debuginfo-install", "-y", "--", package.c_str(), NULL);
+ exit(1);
+ }
+
+ close(pipein[0]);
+ close(pipeout[1]);
+
+ /* Should not be needed (we use -y option), but just in case: */
+ safe_write(pipein[1], "y\n", sizeof("y\n")-1);
+ close(pipein[1]);
+
+ update_client(_("Downloading and installing debug-info packages..."));
+
+ FILE *pipeout_fp = fdopen(pipeout[0], "r");
+ if (pipeout_fp == NULL) /* never happens */
+ {
+ close(pipeout[0]);
+ wait(NULL);
+ return;
+ }
+
+/* glx-utils, for example, do not have glx-utils-debuginfo package.
+ * Disabled code was causing failures in backtrace decoding.
+ * This does not seem to be useful.
+ */
+#ifdef COMPLAIN_IF_NO_DEBUGINFO
+ bool already_installed = false;
+#endif
+ char buff[1024];
+ std::string packageName = package.substr(0, package.rfind("-", package.rfind("-")-1));
+ while (fgets(buff, sizeof(buff), pipeout_fp))
+ {
+ int last = strlen(buff) - 1;
+ if (last >= 0 && buff[last] == '\n')
+ buff[last] = '\0';
+
+ /* log(buff); - update_client logs it too */
+ update_client(buff); /* maybe only if buff != ""? */
+
+#ifdef COMPLAIN_IF_NO_DEBUGINFO
+ if (already_installed == false)
+ {
+ /* "Package foo-debuginfo-1.2-5.ARCH already installed and latest version" */
+ char* pn = strstr(buff, packageName.c_str());
+ if (pn)
+ {
+ char* already_str = strstr(pn, "already installed and latest version");
+ if (already_str)
+ {
+ already_installed = true;
+ }
+ }
+ }
+
+ if (already_installed == false &&
+ (strstr(buff, "No debuginfo packages available to install") != NULL ||
+ strstr(buff, "Could not find debuginfo for main pkg") != NULL ||
+ strstr(buff, "Could not find debuginfo pkg for dependency package") != NULL))
+ {
+ fclose(pipeout_fp);
+ kill(child, SIGTERM);
+ wait(NULL);
+ throw CABRTException(EXCEP_PLUGIN, std::string(__func__) + ": cannot install debuginfos for " + pPackage);
+ }
+#endif
+ }
+
+ fclose(pipeout_fp);
+ wait(NULL);
+}
+#if 0
+/* Needs gdb feature from here: https://bugzilla.redhat.com/show_bug.cgi?id=528668 */
+static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& build_ids)
+{
update_client(_("Searching for debug-info packages..."));
- int pipein[2], pipeout[2]; //TODO: get rid of pipein
+ int pipein[2], pipeout[2]; //TODO: get rid of pipein. Can we use ExecVP?
xpipe(pipein);
xpipe(pipeout);
@@ -400,8 +591,8 @@ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& bui
char *coredump = xasprintf("%s/"FILENAME_COREDUMP, pDebugDumpDir.c_str());
char *tempdir = xasprintf("/tmp/abrt-%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, "/"); // "/var/cache/abrt-di"
- execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump, tempdir, "/", NULL);
+ VERB1 log("Executing: %s %s %s %s", "abrt-debuginfo-install", coredump, tempdir, "/var/cache/abrt-di");
+ execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump, tempdir, "/var/cache/abrt-di", NULL);
exit(1);
}
@@ -447,6 +638,7 @@ static void InstallDebugInfos(const std::string& pDebugDumpDir, std::string& bui
fclose(pipeout_fp);
wait(NULL);
}
+#endif
std::string CAnalyzerCCpp::GetLocalUUID(const std::string& pDebugDumpDir)
{