Breakpad: added symbol extraction to the build.

Add -DRELEASE_CRASH_REPORTING:BOOL=ON to enable symbol extraction
on build time. Viewer without this set won't sent crash
reports to the crash server
This commit is contained in:
Latif Khalifa
2013-10-02 18:23:19 +02:00
parent ba1b482025
commit a27dad4db0
5 changed files with 252 additions and 11 deletions

View File

@@ -12,11 +12,25 @@ include(Variables)
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1") set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
set(CMAKE_CXX_FLAGS_RELEASE set(CMAKE_CXX_FLAGS_RELEASE
"-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=1 -DNDEBUG") "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DNDEBUG")
set(CMAKE_C_FLAGS_RELEASE set(CMAKE_C_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE}") "${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"-DLL_RELEASE=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=1 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1") "-DLL_RELEASE=1 -D_SECURE_SCL=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
# Configure crash reporting
set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")
set(NON_RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in developer builds")
if(RELEASE_CRASH_REPORTING)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DLL_SEND_CRASH_REPORTS=1")
endif()
if(NON_RELEASE_CRASH_REPORTING)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DLL_SEND_CRASH_REPORTS=1")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLL_SEND_CRASH_REPORTS=1")
endif()
# Don't bother with a MinSizeRel build. # Don't bother with a MinSizeRel build.

View File

@@ -1734,6 +1734,64 @@ if (INSTALL)
include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake) include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
endif (INSTALL) endif (INSTALL)
if (PACKAGE)
set(SYMBOL_SEARCH_DIRS "")
if (WINDOWS)
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-windows.tar.bz2")
# slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
# set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}")
set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
endif (WINDOWS)
if (DARWIN)
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
# *TODO: Generate these search dirs in the cmake files related to each binary.
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/webkit/${CMAKE_CFG_INTDIR}")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2")
set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
set(VIEWER_LIB_GLOB "*.dylib")
endif (DARWIN)
if (LINUX)
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux.tar.bz2")
set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
endif (LINUX)
if(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
if(CMAKE_CFG_INTDIR STREQUAL ".")
set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
else(CMAKE_CFG_INTDIR STREQUAL ".")
# set LLBUILD_CONFIG to be a shell variable evaluated at build time
# reflecting the configuration we are currently building.
set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
endif(CMAKE_CFG_INTDIR STREQUAL ".")
add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
COMMAND "${PYTHON_EXECUTABLE}"
ARGS
"${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
"${LLBUILD_CONFIG}"
"${SYMBOL_SEARCH_DIRS}"
"${VIEWER_EXE_GLOBS}"
"${VIEWER_LIB_GLOB}"
"${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/bin/dump_syms"
"${VIEWER_SYMBOL_FILE}"
DEPENDS generate_breakpad_symbols.py
VERBATIM)
add_custom_target(generate_breakpad_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}")
add_dependencies(package generate_breakpad_symbols)
endif(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
endif (PACKAGE)
# Add tests # Add tests
if (LL_TESTS) if (LL_TESTS)
ADD_VIEWER_BUILD_TEST(llagentaccess viewer) ADD_VIEWER_BUILD_TEST(llagentaccess viewer)

View File

@@ -0,0 +1,167 @@
#!/usr/bin/env python
"""\
@file generate_breakpad_symbols.py
@author Brad Kittenbrink <brad@lindenlab.com>
@brief Simple tool for generating google_breakpad symbol information
for the crash reporter.
$LicenseInfo:firstyear=2010&license=viewerlgpl$
Second Life Viewer Source Code
Copyright (C) 2010-2011, Linden Research, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License only.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""
import collections
import fnmatch
import itertools
import operator
import os
import re
import sys
import shlex
import subprocess
import tarfile
import StringIO
import pprint
DEBUG=False
def usage():
print >>sys.stderr, "usage: %s search_dirs viewer_exes libs_suffix dump_syms_tool viewer_symbol_file" % sys.argv[0]
class MissingModuleError(Exception):
def __init__(self, modules):
Exception.__init__(self, "Failed to find required modules: %r" % modules)
self.modules = modules
def main(configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
print "generate_breakpad_symbols run with args: %s" % str((configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
if not re.match("release", configuration, re.IGNORECASE):
print "skipping breakpad symbol generation for non-release build."
return 0
# split up list of viewer_exes
# "'Second Life' SLPlugin" becomes ['Second Life', 'SLPlugin']
viewer_exes = shlex.split(viewer_exes)
found_required = dict([(module, False) for module in viewer_exes])
def matches(f):
if f in viewer_exes:
found_required[f] = True
return True
return fnmatch.fnmatch(f, libs_suffix)
search_dirs = search_dirs.split(";")
def list_files():
for search_dir in search_dirs:
for (dirname, subdirs, filenames) in os.walk(search_dir):
if DEBUG:
print "scanning '%s' for modules..." % dirname
for f in itertools.ifilter(matches, filenames):
yield os.path.join(dirname, f)
def dump_module(m):
print "dumping module '%s' with '%s'..." % (m, dump_syms_tool)
dsym_full_path = m
child = subprocess.Popen([dump_syms_tool, dsym_full_path] , stdout=subprocess.PIPE)
out, err = child.communicate()
return (m,child.returncode, out, err)
modules = {}
for m in list_files():
if DEBUG:
print "examining module '%s' ... " % m,
filename=os.path.basename(m)
if -1 != m.find("DWARF"):
# Just use this module; it has the symbols we want.
modules[filename] = m
if DEBUG:
print "found dSYM entry"
elif filename not in modules:
# Only use this if we don't already have a (possibly better) entry.
modules[filename] = m
if DEBUG:
print "found new entry"
elif DEBUG:
print "ignoring entry"
print "Found these following modules:"
pprint.pprint( modules )
out = tarfile.open(viewer_symbol_file, 'w:bz2')
for (filename,status,symbols,err) in itertools.imap(dump_module, modules.values()):
if status == 0:
module_line = symbols[:symbols.index('\n')]
module_line = module_line.split()
hash_id = module_line[3]
module = ' '.join(module_line[4:])
if sys.platform in ['win32', 'cygwin']:
mod_name = module[:module.rindex('.pdb')]
else:
mod_name = module
symbolfile = StringIO.StringIO(symbols)
info = tarfile.TarInfo("%(module)s/%(hash_id)s/%(mod_name)s.sym" % dict(module=module, hash_id=hash_id, mod_name=mod_name))
info.size = symbolfile.len
out.addfile(info, symbolfile)
else:
print >>sys.stderr, "warning: failed to dump symbols for '%s': %s" % (filename, err)
out.close()
missing_modules = [m for (m,_) in
itertools.ifilter(lambda (k,v): not v, found_required.iteritems())
]
if missing_modules:
print >> sys.stderr, "failed to generate %s" % viewer_symbol_file
os.remove(viewer_symbol_file)
raise MissingModuleError(missing_modules)
symbols = tarfile.open(viewer_symbol_file, 'r:bz2')
tarfile_members = symbols.getnames()
symbols.close()
for required_module in viewer_exes:
def match_module_basename(m):
return os.path.splitext(required_module)[0].lower() \
== os.path.splitext(os.path.basename(m))[0].lower()
# there must be at least one .sym file in tarfile_members that matches
# each required module (ignoring file extensions)
if not reduce(operator.or_, itertools.imap(match_module_basename, tarfile_members)):
print >> sys.stderr, "failed to find required %s in generated %s" \
% (required_module, viewer_symbol_file)
os.remove(viewer_symbol_file)
raise MissingModuleError([required_module])
print "successfully generated %s including required modules '%s'" % (viewer_symbol_file, viewer_exes)
return 0
if __name__ == "__main__":
if len(sys.argv) != 7:
usage()
sys.exit(1)
sys.exit(main(*sys.argv[1:]))

View File

@@ -248,7 +248,7 @@ void LLCrashLogger::gatherFiles()
std::ifstream f((*itr).second.c_str()); std::ifstream f((*itr).second.c_str());
if(!f.is_open()) if(!f.is_open())
{ {
std::cout << "Can't find file " << (*itr).second << std::endl; llinfos << "Can't find file " << (*itr).second << llendl;
continue; continue;
} }
std::stringstream s; std::stringstream s;
@@ -349,10 +349,12 @@ void LLCrashLogger::checkCrashDump()
std::string dumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug"; std::string dumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug";
if (gDirUtilp->fileExists(dumpDir)) if (gDirUtilp->fileExists(dumpDir))
{ {
#if LL_SEND_CRASH_REPORTS
if (!mCrashHost.empty() && gSavedSettings.getS32("CrashSubmitBehavior") != 2) if (!mCrashHost.empty() && gSavedSettings.getS32("CrashSubmitBehavior") != 2)
{ {
sendCrashLog(dumpDir); sendCrashLog(dumpDir);
} }
#endif
gDirUtilp->deleteDirAndContents(dumpDir); gDirUtilp->deleteDirAndContents(dumpDir);
} }
else else

View File

@@ -571,30 +571,30 @@
<key>darwin</key> <key>darwin</key>
<map> <map>
<key>md5sum</key> <key>md5sum</key>
<string>723cd70d5090e448319b485b88aea379</string> <string>5a5c90d28fd9bdc4244c56fef4216998</string>
<key>url</key> <key>url</key>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/google_breakpad-0.0.0-rev1099-darwin-20130329.tar.bz2</uri> <uri>https://bitbucket.org/SingularityViewer/libraries/downloads/google_breakpad-0.0.0-rev1099-darwin-20131002.tar.bz2</uri>
</map> </map>
<key>linux</key> <key>linux</key>
<map> <map>
<key>md5sum</key> <key>md5sum</key>
<string>849241f3b638ee90b553a2ef6346107c</string> <string>03852edfa946bdc365b5fbd1a373b17f</string>
<key>url</key> <key>url</key>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/google_breakpad-0.0.0-rev1099-linux-20130329.tar.bz2</uri> <uri>https://bitbucket.org/SingularityViewer/libraries/downloads/google_breakpad-0.0.0-rev1099-linux-20131002.tar.bz2</uri>
</map> </map>
<key>linux64</key> <key>linux64</key>
<map> <map>
<key>md5sum</key> <key>md5sum</key>
<string>cf5300008895efcfcfcfacef05f32bff</string> <string>e2e8d8068eceaad66758bb5f031d5246</string>
<key>url</key> <key>url</key>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/google_breakpad-0.0.0-rev1099-linux64-20130506.tar.bz2</uri> <uri>https://bitbucket.org/SingularityViewer/libraries/downloads/google_breakpad-0.0.0-rev1099-linux64-20131002.tar.bz2</uri>
</map> </map>
<key>windows</key> <key>windows</key>
<map> <map>
<key>md5sum</key> <key>md5sum</key>
<string>7c33a10f132864f8492fd9ef9b6a4ccc</string> <string>37d1f91f486e357c9a74e6b4af91fe13</string>
<key>url</key> <key>url</key>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/google_breakpad-0.0.0-rev1099-windows-20130813.tar.bz2</uri> <uri>https://bitbucket.org/SingularityViewer/libraries/downloads/google_breakpad-0.0.0-rev1099-windows-20131002.tar.bz2</uri>
</map> </map>
</map> </map>
</map> </map>