add support for scanning of build logs for common issues #111436
authorMike Frysinger <vapier@gentoo.org>
Wed, 3 Jan 2007 02:32:09 +0000 (02:32 -0000)
committerMike Frysinger <vapier@gentoo.org>
Wed, 3 Jan 2007 02:32:09 +0000 (02:32 -0000)
svn path=/main/trunk/; revision=5449

bin/check-implicit-pointer-usage.py [new file with mode: 0755]
bin/misc-functions.sh
pym/portage.py

diff --git a/bin/check-implicit-pointer-usage.py b/bin/check-implicit-pointer-usage.py
new file mode 100755 (executable)
index 0000000..4afa8f2
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+# Ripped from HP and updated from Debian
+
+#
+# Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
+#      David Mosberger <davidm@hpl.hp.com>
+#
+# Scan standard input for GCC warning messages that are likely to
+# source of real 64-bit problems.  In particular, see whether there
+# are any implicitly declared functions whose return values are later
+# interpreted as pointers.  Those are almost guaranteed to cause
+# crashes.
+#
+import re
+import sys
+
+implicit_pattern = re.compile("([^:]*):(\d+): warning: implicit declaration "
+                              + "of function [`']([^']*)'")
+pointer_pattern = re.compile(
+    "([^:]*):(\d+): warning: "
+    + "("
+    +  "(assignment"
+    +  "|initialization"
+    +  "|return"
+    +  "|passing arg \d+ of `[^']*'"
+    +  "|passing arg \d+ of pointer to function"
+    +  ") makes pointer from integer without a cast"
+    + "|"
+    + "cast to pointer from integer of different size)")
+last_implicit_filename = ""
+last_implicit_linenum = -1
+last_implicit_func = ""
+
+while True:
+    line = sys.stdin.readline()
+    if line == '':
+        break
+    m = implicit_pattern.match(line)
+    if m:
+        last_implicit_filename = m.group(1)
+        last_implicit_linenum = int(m.group(2))
+        last_implicit_func = m.group(3)
+    else:
+        m = pointer_pattern.match(line)
+        if m:
+            pointer_filename = m.group(1)
+            pointer_linenum = int(m.group(2))
+            if (last_implicit_filename == pointer_filename
+                and last_implicit_linenum == pointer_linenum):
+                print "Function `%s' implicitly converted to pointer at " \
+                      "%s:%d" % (last_implicit_func, last_implicit_filename,
+                                 last_implicit_linenum)
index 8a42a2f7771b11e12fd730f5bf548ba450a06cd1..75b95ba0931dd95483285162f0e471930fc93d4e 100755 (executable)
@@ -216,7 +216,7 @@ install_qa_check() {
                        if [[ -L ${j} ]] ; then
                                linkdest=$(readlink "${j}")
                                if [[ ${linkdest} == /* ]] ; then
-                                       vecho -e "\a\n"
+                                       vecho -ne '\a\n'
                                        vecho "QA Notice: Found an absolute symlink in a library directory:"
                                        vecho "           ${j#${D}} -> ${linkdest}"
                                        vecho "           It should be a relative symlink if in the same directory"
@@ -248,7 +248,7 @@ install_qa_check() {
                if [[ ! -e ${s} ]] ; then
                        s=${s%usr/*}${s##*/usr/}
                        if [[ -e ${s} ]] ; then
-                               vecho -e "\a\n"
+                               vecho -ne '\a\n'
                                vecho "QA Notice: missing gen_usr_ldscript for ${s##*/}\a"
                                abort="yes"
                        fi
@@ -259,10 +259,10 @@ install_qa_check() {
        # Make sure people don't store libtool files or static libs in /lib
        f=$(ls "${D}"lib*/*.{a,la} 2>/dev/null)
        if [[ -n ${f} ]] ; then
-               vecho -e "\a\n"
+               vecho -ne '\a\n'
                vecho "QA Notice: excessive files found in the / partition\a"
                vecho "${f}"
-               vecho -e "\a\n"
+               vecho -ne '\a\n'
                die "static archives (*.a) and libtool library files (*.la) do not belong in /"
        fi
 
@@ -271,16 +271,52 @@ install_qa_check() {
        for a in "${D}"usr/lib*/*.la ; do
                s=${a##*/}
                if grep -qs "${D}" "${a}" ; then
-                       vecho -e "\a\n"
+                       vecho -ne '\a\n'
                        vecho "QA Notice: ${s} appears to contain PORTAGE_TMPDIR paths"
                        abort="yes"
                fi
        done
        [[ ${abort} == "yes" ]] && die "soiled libtool library files found"
 
+       # Evaluate misc gcc warnings
+       if [[ -n ${PORTAGE_LOG_FILE} && -r ${PORTAGE_LOG_FILE} ]] ; then
+               local m msgs=(
+                       ": warning: dereferencing type-punned pointer will break strict-aliasing rules$"
+                       ": warning: implicit declaration of function "
+                       ": warning: incompatible implicit declaration of built-in function "
+                       ": warning: is used uninitialized in this function$" # we'll ignore "may" and "might"
+                       ": warning: comparisons like X<=Y<=Z do not have their mathematical meaning$"
+                       ": warning: null argument where non-null required "
+               )
+               abort="no"
+               i=0
+               while [[ -n ${msgs[${i}]} ]] ; do
+                       m=${msgs[$((i++))]}
+                       f=$(grep "${m}" "${PORTAGE_LOG_FILE}")
+                       if [[ -n ${f} ]] ; then
+                               vecho -ne '\a\n'
+                               vecho "QA Notice: Package has poor programming practices which may compile"
+                               vecho "           fine but exhibit random runtime failures."
+                               vecho "${f}"
+                               vecho -ne '\a\n'
+                               abort="yes"
+                       fi
+               done
+               f=$(cat "${PORTAGE_LOG_FILE}" | check-implicit-pointer-usage.py)
+               if [[ -n ${f} ]] ; then
+                       vecho -ne '\a\n'
+                       vecho "QA Notice: Package has poor programming practices which may compile"
+                       vecho "           but will almost certainly crash on 64bit architectures."
+                       vecho "${f}"
+                       vecho -ne '\a\n'
+                       abort="yes"
+               fi
+               [[ ${abort} == "yes" ]] && hasq stricter ${FEATURES} && die "poor code kills airplanes"
+       fi
+
        # Portage regenerates this on the installed system.
-       if [ -f "${D}/usr/share/info/dir.gz" ]; then
-               rm -f "${D}/usr/share/info/dir.gz"
+       if [[ -f ${D}/usr/share/info/dir.gz ]] ; then
+               rm -f "${D}"/usr/share/info/dir.gz
        fi
 
        if hasq multilib-strict ${FEATURES} && \
index 054cf537d29a7a55318fc3141370963cbf21a5c5..f260f283703846fa784bb722468c37bbd4a6258a 100644 (file)
@@ -3122,6 +3122,8 @@ def prepare_build_dirs(myroot, mysettings, cleanup):
                        mysettings["PORT_LOGDIR"], "%s:%s:%s.log" % \
                        (mysettings["CATEGORY"], mysettings["PF"], logid_time))
                del logid_path, logid_time
+       else:
+               mysettings["PORTAGE_LOG_FILE"] = os.path.join(mysettings["T"], "build.log")
 
 _doebuild_manifest_exempt_depend = 0
 _doebuild_manifest_checked = None