Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  stackhandler.py   Sprache: Python

 

#!/usr/bin/python
#####################################################################
#             DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#                    Version 2, December 2004
#
# Copyright (C) 2011-2012 Ludovic Fauvet <etix@videolan.org>
#                         Jean-Baptiste Kempf <jb@videolan.org>
#
# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.
#
#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
#  0. You just DO WHAT THE FUCK YOU WANT TO.
#####################################################################
#
# This script can be started in two ways:
# - Without any arguments:
#   The script will search for stacktrace in the WORKDIR, process
#   them and dispatch them in their respective subdirectories.
# - With a stacktrace as only argument:
#   The script will write the output on stdout and exit immediately
#   after the stacktrace has been processed.
#   The input file will stay in place, untouched.
#
# NOTE: Due to a bug in the mingw32-binutils > 2.19 the section
#       .gnu_debuglink in the binary file is trimmed thus preventing
#       gdb to find the associated symbols. This script will
#       work around this issue and rerun gdb for each dbg file.
#
#####################################################################

VLC_VERSION         = "2.0.3"
VLC_BIN             = "/home/videolan/vlc/" + VLC_VERSION + "/vlc-" VLC_VERSION + "/vlc.exe"
VLC_BASE_DIR        = "/home/videolan/vlc/" + VLC_VERSION + "/vlc-" + VLC_VERSION + "/"
VLC_SYMBOLS_DIR     = "/home/videolan/vlc/" + VLC_VERSION + "/symbols-" + VLC_VERSION + "/"
WORKDIR             = "/srv/ftp/crashes-win32"
FILE_MATCH          = r"^\d{14}$"
FILE_MAX_SIZE       = 10000
GDB_CMD             = "gdb --exec=%(VLC_BIN)s --symbols=%(VLC_SYMBOLS_DIR)s%(DBG_FILE)s.dbg --batch -x %(BATCH_FILE)s"

EMAIL_TO            = "bugreporter -- videolan.org"
EMAIL_FROM          = "crashes@crash.videolan.org"
EMAIL_SUBJECT       = "[CRASH] New Win32 crash report"
EMAIL_BODY          = \
"""
Dear Bug Squasher,

This crash has been reported automatically and might be incomplete and/or broken.
Windows version: %(WIN32_VERSION)s

%(STACKTRACE)s

Truly yours,
a python script.
"""

import os, sys, re, tempfile
import string, shlex, subprocess
import smtplib, datetime, shutil
import traceback
from email.mime.text import MIMEText


def processFile(filename):
    print "Processing " + filename
    global win32_version

    f = open(filename, 'r')
    # Read (and repair) the input file
    content = "".join(filter(lambda x: x in string.printable, f.read()))
    f.close()

    if os.path.getsize(filename) < 10:
        print("File empty")
        os.remove(filename)
        return

    # Check if VLC version match
    if not isValidVersion(content):
        print("Invalid VLC version")
        moveFile(filename, outdated = True)
        return

    # Get Windows version
    win32_version = getWinVersion(content) or 'unknown'

    # Map eip <--> library
    mapping = mapLibraries(content)
    if not mapping:
        print("Stacktrace not found")
        os.remove(filename)
        return

    # Associate all eip to their respective lib
    # lib1
    #     `- 0x6904f020
    #      - 0x6927d37c
    # lib2
    #     `- 0x7e418734
    #      - 0x7e418816
    #      - 0x7e42bf15
    sortedEIP,delta_libs = sortEIP(content,mapping)
    # Compute the stacktrace using GDB
    eipmap = findSymbols(sortedEIP)
    # Generate the body of the email
    body = genEmailBody(mapping, eipmap, delta_libs)
    # Send the email
    sendEmail(body)
    # Print the output
    print(body)

    # Finally archive the stacktrace
    moveFile(filename, outdated = False)

def isValidVersion(content):
    pattern = re.compile(r"^VLC=%s " % VLC_VERSION, re.MULTILINE)
    res = pattern.search(content)
    return True if res else False

def getWinVersion(content):
    pattern = re.compile(r"^OS=(.*)$", re.MULTILINE)
    res = pattern.search(content)
    if res is not None:
        return res.group(1)
    return None

def getDiffAddress(content, name):
    plugin_name_section = content.find(name)
    if plugin_name_section < 0:
        return None

    begin_index = content.rfind("\n", 0, plugin_name_section) + 1
    end_index = content.find("|", begin_index)

    tmp_index = name.rfind('plugins\\')
    libname = name[tmp_index :].replace("\\", "/")
    full_path = VLC_BASE_DIR + libname

    if not os.path.isfile(full_path):
        return None

    cmd = "objdump -p " + full_path + " |grep ImageBase -|cut -f2-"
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout.read().strip()

    diff = int(content[begin_index:end_index], 16) - int(p, 16)
    return diff

def mapLibraries(content):
    stacktrace_section = content.find("[stacktrace]")
    if stacktrace_section < 0:
        return None

    stacklines = content[stacktrace_section:]
    stacklines = stacklines.splitlines()
    pattern = re.compile(r"^([0-9a-fA-F]+)\|(.+)$")

    mapping = []
    for line in stacklines:
        m = pattern.match(line)
        print(line)
        if m is not None:
            mapping.append(m.group(1, 2))

    if len(mapping) == 0:
        return None
    return mapping


def sortEIP(content, mapping):
    # Merge all EIP mapping to the same library
    libs = {}
    libs_address = {}
    for item in mapping:
        # Extract the library name (without the full path)
        index = item[1].rfind('\\')
        libname = item[1][index + 1:]

        # Append the eip to its respective lib
        if libname not in libs:
            libs[libname] = []
            diff = getDiffAddress(content, item[1])
            if diff is not None:
                libs_address[libname] = diff
            else:
                libs_address[libname] = 0

        libs[libname].append(int(item[0],16) - libs_address[libname])

    return libs,libs_address


def findSymbols(sortedEIP):
    eipmap = {}

    for k, v in sortedEIP.items():
        # Create the gdb batchfile
        batchfile = tempfile.NamedTemporaryFile(mode="w")
        batchfile.write("set print symbol-filename on\n")

        # Append all eip for this lib
        for eip in v:
            batchfile.write('p/a %s\n' % hex(eip))
        batchfile.flush()

        # Generate the command line
        cmd = GDB_CMD % {"VLC_BIN": VLC_BIN, "VLC_SYMBOLS_DIR": VLC_SYMBOLS_DIR, "DBG_FILE": k, "BATCH_FILE": batchfile.name}
        args = shlex.split(cmd)

        # Start GDB and get result
        p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        # Parse result
        gdb_pattern = re.compile(r"^\$\d+ = (.+)$")
        cnt = 0
        while p.poll() == None:
            o = p.stdout.readline()
            if o != b'':
                o = bytes.decode(o)
                m = gdb_pattern.match(o)
                if m is not None:
                    #print("LINE: [%s]" % m.group(1))
                    eipmap[v[cnt]] = m.group(1)
                    cnt += 1
        batchfile.close()
    return eipmap


def genEmailBody(mapping, eipmap, delta_libs):
    stacktrace = ""
    cnt = 0
    for item in mapping:
        index = item[1].rfind('\\')
        libname = item[1][index + 1:]
        print(int(item[0],16), delta_libs[libname])
        #print(eipmap)
        #print(mapping)
        stacktrace += "%d. %s [in %s]\n" % (cnt, eipmap[int(item[0],16)-delta_libs[libname]], item[1])
        cnt += 1
    stacktrace = stacktrace.rstrip('\n')
    return EMAIL_BODY % {"STACKTRACE": stacktrace, "WIN32_VERSION": win32_version}


def sendEmail(body):
    msg = MIMEText(body)
    msg['Subject'] = EMAIL_SUBJECT
    msg['From'] = EMAIL_FROM
    msg['To'] = EMAIL_TO

    # Send the email
    s = smtplib.SMTP()
    s.connect("127.0.0.1")
    s.sendmail(EMAIL_FROM, [EMAIL_TO], msg.as_string())
    s.quit()

def moveFile(filename, outdated = False):
    today = datetime.datetime.now().strftime("%Y%m%d")
    today_path = "%s/%s" % (WORKDIR, today)
    if not os.path.isdir(today_path):
        os.mkdir(today_path)
    if not outdated:
        shutil.move(filename, "%s/%s" % (today_path, os.path.basename(filename)))
    else:
        outdated_path = "%s/outdated/" % today_path
        if not os.path.isdir(outdated_path):
            os.mkdir(outdated_path)
        shutil.move(filename, "%s/%s" % (outdated_path, os.path.basename(filename)))


### ENTRY POINT ###

batch = len(sys.argv) != 2
if batch:
    print("Running in batch mode")

input_files = []
if not batch:
    if not os.path.isfile(sys.argv[1]):
        exit("file does not exists")
    input_files.append(sys.argv[1])
else:
    file_pattern = re.compile(FILE_MATCH)
    entries = os.listdir(WORKDIR)
    for entry in entries:
        path_entry = WORKDIR + "/" + entry
        if not os.path.isfile(path_entry):
            continue
        if not file_pattern.match(entry):
            print(entry)
            os.remove(path_entry)
            continue
        if os.path.getsize(path_entry) > FILE_MAX_SIZE:
            print("%s is too big" % entry)
            os.remove(path_entry)
            continue
        input_files.append(path_entry)

if not len(input_files):
    exit("Nothing to process")

# Start processing each file
for input_file in input_files:
    try:
        processFile(input_file)
    except Exception as ex:
        print(traceback.format_exc())

Messung
CHZG
848910091

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104842
#Domains=499162