nemiver r770 - in trunk: . src/common src/dbgengine tests



Author: dodji
Date: Mon Mar 17 16:30:48 2008
New Revision: 770
URL: http://svn.gnome.org/viewvc/nemiver?rev=770&view=rev

Log:
fixed #476472 â Nemiver fails on libtool wrappers

	* src/common/nmv-proc-utils.cc,h:
	  added  is_libtool_executable_wrapper () entry point to detect whever
	  if a file is a litbool wrapper to an executable. If so, it returns
	  the path to the actual executable that is wrapped.
	* tests/test-libtool-wrapper-detection.cc: added a regression test.
	* src/dbgengine/nmv-gdb-engine.cc:
	  (GDBEngine::load_program): check if the program to load is a litbool
	  wrapper. If yes, load the actuall binary instead.


Added:
   trunk/tests/test-libtool-wrapper-detection.cc
Modified:
   trunk/ChangeLog
   trunk/src/common/nmv-proc-utils.cc
   trunk/src/common/nmv-proc-utils.h
   trunk/src/dbgengine/nmv-gdb-engine.cc
   trunk/tests/Makefile.am

Modified: trunk/src/common/nmv-proc-utils.cc
==============================================================================
--- trunk/src/common/nmv-proc-utils.cc	(original)
+++ trunk/src/common/nmv-proc-utils.cc	Mon Mar 17 16:30:48 2008
@@ -31,6 +31,7 @@
 #include <termios.h>
 #include <vector>
 #include <memory>
+#include <fstream>
 #include "nmv-proc-utils.h"
 #include "nmv-exception.h"
 #include "nmv-log-stream-utils.h"
@@ -201,6 +202,76 @@
     io_source->connect (a_slot) ;
     io_source->attach (a_ctxt) ;
 }
+
+/// open the file name a_path and test if it is a litbool
+/// wrapper shell script. If it is, its first line
+/// would ressembles:
+/// # bar - temporary wrapper script for .libs/bar
+/// In that case, the function extracts the string ".libs/bar",
+/// which is the path to the actual binary that is being wrapped
+/// and returns.
+/// \param a_path path to the possible libtool wrapper script.
+/// \a_path_to_real_exec out parameter. The path to the actual
+/// executable that has been wrapped by a_path. This out parameter
+/// is set if and only the function returns true.
+/// \return true if a_path is a libtool wrapper script, false otherwise.
+bool
+is_libtool_executable_wrapper (const UString &a_path,
+                               UString &a_path_to_real_exec)
+{
+    if (a_path.empty ()) {
+        return false;
+    }
+    string path = Glib::filename_from_utf8 (a_path);
+    if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
+        return FALSE;
+    }
+    ifstream file (path.c_str ());
+    if (!file.good ()) {
+        return false;
+    }
+    int c = 0;
+    c = file.get ();
+    if (file.eof () || !file.good ()) {
+        return false;
+    }
+    if (c != '#') {
+        return false;
+    }
+    //goto dash, skip the white space that comes after
+    while (file.good () && !file.eof () && c != '-') {c = file.get ();}
+    if (c != '-')
+        return false;
+    c = file.get ();
+    if (!isspace (c))
+        return false;
+    //now go get the string "temporary wrapper script for "
+    string str;
+    for (int i=0; i < 29/*length of the string we are looking for*/; ++i) {
+        c = file.get ();
+        if (file.eof () || !file.good ())
+            return false;
+        str += c;
+    }
+    if (str != "temporary wrapper script for ") {
+        LOG_ERROR ("got wrong magic string: " << str);
+        return false;
+    }
+    str.clear ();
+    //now go get the path that comes next.
+    //that path is terminated normally by an '\n'
+    while (true) {
+        c = file.get ();
+        if (file.eof () || c == '\n')
+            break;
+        else if (!file.good ())
+            return false;
+        str += c;
+    }
+    a_path_to_real_exec = Glib::filename_to_utf8 (str);
+    return true;
+}
+
 }//end namespace
 }//end namespace nemiver
 

Modified: trunk/src/common/nmv-proc-utils.h
==============================================================================
--- trunk/src/common/nmv-proc-utils.h	(original)
+++ trunk/src/common/nmv-proc-utils.h	Mon Mar 17 16:30:48 2008
@@ -43,6 +43,9 @@
                          const sigc::slot<bool, Glib::IOCondition> &a_slot,
                          const Glib::RefPtr<Glib::IOChannel> &a_chan,
                          const Glib::RefPtr<Glib::MainContext>&a_ctxt) ;
+
+bool NEMIVER_API is_libtool_executable_wrapper (const UString &a_path,
+                                                UString &a_path_to_real_exec);
 }//end namspace common
 }//end namespace nemiver
 #endif //__NMV_PROC_UTILS_H__

Modified: trunk/src/dbgengine/nmv-gdb-engine.cc
==============================================================================
--- trunk/src/dbgengine/nmv-gdb-engine.cc	(original)
+++ trunk/src/dbgengine/nmv-gdb-engine.cc	Mon Mar 17 16:30:48 2008
@@ -2016,12 +2016,27 @@
     LOG_FUNCTION_SCOPE_NORMAL_DD;
     THROW_IF_FAIL (m_priv);
     THROW_IF_FAIL (!a_argv.empty ());
+    vector<UString> argv (a_argv);
+
+    //first, check if the the inferior is a libtool wrapper or not.
+    //if yes, bet the real path of the actual binary and use that instead
+    UString real_path;
+    if (is_libtool_executable_wrapper (argv[0], real_path)
+        && !real_path.empty ()) {
+        LOG_DD ("handling libtool wrapper script ...");
+        string tmp_str = Glib::filename_from_utf8 (real_path);
+        string dir_name = Glib::path_get_dirname
+                                    (Glib::filename_to_utf8 (argv[0]));
+        string path = Glib::build_filename (dir_name, tmp_str);
+        argv[0] = Glib::filename_to_utf8 (path);
+        LOG_DD ("got path to real binary from libtool wrapper: " << path);
+    }
 
     if (!m_priv->is_gdb_running ()) {
         vector<UString> gdb_opts;
         THROW_IF_FAIL (m_priv->launch_gdb_and_set_args
                                     (working_dir, a_source_search_dirs, 
-                                     a_argv, gdb_opts));
+                                     argv, gdb_opts));
 
         Command command;
 
@@ -2041,13 +2056,13 @@
         }
     } else {
         UString args;
-        UString::size_type len (a_argv.size ());
+        UString::size_type len (argv.size ());
         for (UString::size_type i = 1; i < len; ++i) {
-            args += " " + a_argv[i];
+            args += " " + argv[i];
         }
 
         Command command ("load-program",
-                         UString ("-file-exec-and-symbols ") + a_argv[0]);
+                         UString ("-file-exec-and-symbols ") + argv[0]);
         queue_command (command);
 
         command.value ("set args " + args);

Modified: trunk/tests/Makefile.am
==============================================================================
--- trunk/tests/Makefile.am	(original)
+++ trunk/tests/Makefile.am	Mon Mar 17 16:30:48 2008
@@ -7,7 +7,8 @@
 runtestvarwalker runtestbreakpoint \
 runtestoverloads runtestderef \
 runtestlocalvarslist runtestcpplexer \
-runtestcppparser runtestglobalvariables
+runtestcppparser runtestglobalvariables \
+runtestlibtoolwrapperdetection
 
 
 else
@@ -94,6 +95,12 @@
 $(top_builddir)/src/langs/libnemivercparser.la \
 $(top_builddir)/src/common/libnemivercommon.la
 
+runtestlibtoolwrapperdetection_SOURCES=test-libtool-wrapper-detection.cc
+runtestlibtoolwrapperdetection_LDADD= NEMIVERCOMMON_LIBS@ \
+ BOOST_UNIT_TEST_FRAMEWORK_STATIC_LIB@ \
+$(top_builddir)/src/langs/libnemivercparser.la \
+$(top_builddir)/src/common/libnemivercommon.la
+
 docore_SOURCES=do-core.cc
 docore_LDADD= NEMIVERCOMMON_LIBS@ \
 $(top_builddir)/src/common/libnemivercommon.la

Added: trunk/tests/test-libtool-wrapper-detection.cc
==============================================================================
--- (empty file)
+++ trunk/tests/test-libtool-wrapper-detection.cc	Mon Mar 17 16:30:48 2008
@@ -0,0 +1,36 @@
+#include <iostream>
+#include <string>
+#include <boost/test/unit_test.hpp>
+#include "common/nmv-exception.h"
+#include "common/nmv-initializer.h"
+#include "common/nmv-proc-utils.h"
+
+using namespace nemiver::common;
+using boost::unit_test::test_suite ;
+
+void
+test0 ()
+{
+    UString real_path;
+    BOOST_REQUIRE (is_libtool_executable_wrapper ("./fooprog", real_path));
+    BOOST_REQUIRE (real_path == ".libs/fooprog");
+}
+
+test_suite*
+init_unit_test_suite (int argc, char** argv)
+{
+    if (argc || argv) {/*keep compiler happy*/}
+
+    NEMIVER_TRY
+
+    Initializer::do_init () ;
+
+    test_suite *suite = BOOST_TEST_SUITE ("libtool wrapper detect tests") ;
+    suite->add (BOOST_TEST_CASE (&test0)) ;
+    return suite;
+
+    NEMIVER_CATCH_NOX
+
+    return 0;
+}
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]