Merge pull request #1210 from manongjohn/add_macos_dsym_files

Symbolicate macOS and Linux crash logs for debugging
This commit is contained in:
manongjohn 2023-09-14 16:30:25 -04:00 committed by GitHub
commit e146e4d800
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 120 additions and 96 deletions

View file

@ -15,6 +15,7 @@ source /opt/qt515/bin/qt515-env.sh
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
cmake ../sources \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DWITH_GPHOTO2:BOOL=ON \
-DWITH_SYSTEM_SUPERLU=ON

View file

@ -78,7 +78,7 @@ then
fi
export LD_LIBRARY_PATH=appdir/usr/lib/tahoma2d
./linuxdeployqt*.AppImage appdir/usr/bin/Tahoma2D -bundle-non-qt-libs -verbose=0 -always-overwrite \
./linuxdeployqt*.AppImage appdir/usr/bin/Tahoma2D -bundle-non-qt-libs -verbose=0 -always-overwrite -no-strip \
-executable=appdir/usr/bin/lzocompress \
-executable=appdir/usr/bin/lzodecompress \
-executable=appdir/usr/bin/tcleanup \
@ -91,7 +91,7 @@ rm appdir/AppRun
cp ../sources/scripts/AppRun appdir
chmod 775 appdir/AppRun
./linuxdeployqt*.AppImage appdir/usr/bin/Tahoma2D -appimage
./linuxdeployqt*.AppImage appdir/usr/bin/Tahoma2D -appimage -no-strip
mv Tahoma2D*.AppImage Tahoma2D/Tahoma2D.AppImage

View file

@ -13,7 +13,7 @@ then
export TOONZDIR=$TOONZDIR/Release
fi
echo ">>> Copying stuff to $TOONZDIR/Tahoma2D.app/tahomastuff"
echo ">>> Copying stuff to Tahoma2D.app/tahomastuff"
if [ -d $TOONZDIR/Tahoma2D.app/tahomastuff ]
then
# In case of prior builds, replace stuff folder
@ -26,7 +26,7 @@ find $TOONZDIR/Tahoma2D.app/tahomastuff -name .gitkeep -exec rm -f {} \;
if [ -d thirdparty/apps/ffmpeg/bin ]
then
echo ">>> Copying FFmpeg to $TOONZDIR/Tahoma2D.app/ffmpeg"
echo ">>> Copying FFmpeg to Tahoma2D.app/ffmpeg"
if [ -d $TOONZDIR/Tahoma2D.app/ffmpeg ]
then
# In case of prior builds, replace ffmpeg folder
@ -39,7 +39,7 @@ fi
if [ -d thirdparty/apps/rhubarb ]
then
echo ">>> Copying Rhubarb Lip Sync to $TOONZDIR/Tahoma2D.app/rhubarb"
echo ">>> Copying Rhubarb Lip Sync to Tahoma2D.app/rhubarb"
if [ -d $TOONZDIR/Tahoma2D.app/rhubarb ]
then
# In case of prior builds, replace rhubarb folder
@ -57,21 +57,44 @@ fi
if [ -d thirdparty/canon/Framework ]
then
echo ">>> Copying canon framework to $TOONZDIR/Tahoma2D.app/Contents/Frameworks/EDSDK.Framework"
cp -R thirdparty/canon/Framework/ $TOONZDIR/Tahoma2D.app/Contents/Frameworks
chmod -R 755 $TOONZDIR/Tahoma2D.app/Contents/Frameworks/EDSDK.framework
if [ ! -d $TOONZDIR/Tahoma2D.app/Contents/Frameworks/EDSDK.framework ]
then
echo ">>> Copying canon framework to Tahoma2D.app/Contents/Frameworks/EDSDK.Framework"
cp -R thirdparty/canon/Framework/ $TOONZDIR/Tahoma2D.app/Contents/Frameworks
chmod -R 755 $TOONZDIR/Tahoma2D.app/Contents/Frameworks/EDSDK.framework
fi
fi
echo ">>> Copying libghoto2 supporting directories"
cp -R /usr/local/lib/libgphoto2 $TOONZDIR/Tahoma2D.app/Contents/Frameworks
cp -R /usr/local/lib/libgphoto2_port $TOONZDIR/Tahoma2D.app/Contents/Frameworks
if [ ! -d $TOONZDIR/Tahoma2D.app/Contents/Frameworks/libgphoto2 ]
then
echo ">>> Copying libghoto2 supporting directories to Tahoma2D.app/Contents/Frameworks"
cp -R /usr/local/lib/libgphoto2 $TOONZDIR/Tahoma2D.app/Contents/Frameworks
cp -R /usr/local/lib/libgphoto2_port $TOONZDIR/Tahoma2D.app/Contents/Frameworks
rm $TOONZDIR/Tahoma2D.app/Contents/Frameworks/libgphoto2/print-camera-list
find $TOONZDIR/Tahoma2D.app/Contents/Frameworks/libgphoto2* -name *.la -exec rm -f {} \;
rm $TOONZDIR/Tahoma2D.app/Contents/Frameworks/libgphoto2/print-camera-list
find $TOONZDIR/Tahoma2D.app/Contents/Frameworks/libgphoto2* -name *.la -exec rm -f {} \;
fi
echo ">>> Creating DSYM files"
if [ -d $TOONZDIR/DSYM ]
then
rm -rf $TOONZDIR/DSYM
fi
for X in `find $TOONZDIR/Tahoma2D.app/Contents/MacOS -type f`
do
dsymutil -o $TOONZDIR/DSYM $X
strip -S $X
done
if [ -d $TOONZDIR/Tahoma2D.app/DSYM ]
then
rm -rf $TOONZDIR/Tahoma2D.app/DSYM
fi
echo ">>> Configuring Tahoma2D.app for deployment"
$QTDIR/bin/macdeployqt $TOONZDIR/Tahoma2D.app -verbose=0 -always-overwrite -no-strip \
$QTDIR/bin/macdeployqt $TOONZDIR/Tahoma2D.app -verbose=0 -always-overwrite \
-executable=$TOONZDIR/Tahoma2D.app/Contents/MacOS/lzocompress \
-executable=$TOONZDIR/Tahoma2D.app/Contents/MacOS/lzodecompress \
-executable=$TOONZDIR/Tahoma2D.app/Contents/MacOS/tcleanup \
@ -84,14 +107,14 @@ for FW in `echo "QtDBus QtPdf QtQml QtQmlModels QtQuick QtVirtualKeyboard"`
do
if [ ! -d $TOONZDIR/Tahoma2D.app/Contents/Frameworks/$FW.framework ]
then
echo ">>> Copying missing $FW.framework to Contents/Frameworks"
echo ">>> Copying missing $FW.framework to Tahoma2D.app/Contents/Frameworks"
cp -r $QTDIR/Frameworks/$FW.framework $TOONZDIR/Tahoma2D.app/Contents/Frameworks
fi
done
if [ ! -d $TOONZDIR/Tahoma2D.app/Contents/lib ]
then
echo ">>> Adding Contents/lib symbolic link to Contents/Frameworks"
echo ">>> Adding Contents/lib symbolic link to Tahoma2D.app/Contents/Frameworks"
ln -s Frameworks $TOONZDIR/Tahoma2D.app/Contents/lib
fi
@ -151,10 +174,13 @@ for FILE in `find $TOONZDIR/Tahoma2D.app/Contents -type f | grep -v -e"\.h" -e"\
do
checkLibFile $FILE
done
echo ">>> Moving DYSM to Tahoma2D.app"
mv $TOONZDIR/DSYM $TOONZDIR/Tahoma2D.app
echo ">>> Creating Tahoma2D-osx.dmg"
$QTDIR/bin/macdeployqt $TOONZDIR/Tahoma2D.app -dmg -verbose=0 -no-strip
$QTDIR/bin/macdeployqt $TOONZDIR/Tahoma2D.app -dmg -verbose=0
mv $TOONZDIR/Tahoma2D.dmg $TOONZDIR/../Tahoma2D-osx.dmg

View file

@ -549,7 +549,7 @@ elseif(BUILD_ENV_UNIXLIKE)
Tahoma2D Qt5::Core Qt5::Gui Qt5::Network Qt5::OpenGL Qt5::Svg Qt5::Xml
Qt5::Script Qt5::Widgets Qt5::PrintSupport Qt5::Multimedia Qt5::SerialPort Qt5::UiTools
${GL_LIB} ${GLUT_LIB} ${GLU_LIB} ${TURBOJPEG_LIB} ${OpenCV_LIBS}
${EXTRA_LIBS}
${EXTRA_LIBS} dl
)
endif()

View file

@ -11,12 +11,14 @@
#else
#ifdef MACOSX
#include <mach-o/dyld.h>
#else
#include <link.h>
#endif
#include <execinfo.h>
#include <signal.h>
#include <unistd.h>
#include <err.h>
#include <regex>
#include <dlfcn.h>
#endif
#include "tgl.h"
@ -65,7 +67,7 @@ static const char *filenameOnly(const char *path) {
//-----------------------------------------------------------------------------
static QString obfuscateUsername(QString path) {
QString username = TSystem::getUserName();
QString newPath = path;
QString newPath = path;
newPath.replace("/" + username + "/", "/USER/");
newPath.replace("\\" + username + "\\", "\\USER\\");
return newPath;
@ -307,33 +309,13 @@ static bool sh(std::string &out, const char *cmd) {
//-----------------------------------------------------------------------------
static bool addr2line(std::string &out, const char *exepath, const char *addr) {
static bool addr2line(std::string &out, const char *exepath, const size_t addr,
const size_t laddr) {
char cmd[512];
#ifdef MACOSX
std::string exe;
uintptr_t loadaddr;
int c = _dyld_image_count();
bool libFound = false;
for (int i = 0; i < c; i++) {
const char *image_name = _dyld_get_image_name(i);
const char *moduleName = strstr(image_name, exepath);
if (!moduleName)
continue;
exe = std::string(image_name);
const struct mach_header *header = _dyld_get_image_header(i);
loadaddr = (uintptr_t) header;
libFound = true;
break;
}
if(!libFound)
return true;
sprintf(cmd, "atos -o \"%.400s\" -l %p %s 2>&1", exe.c_str(), loadaddr, addr);
sprintf(cmd, "atos -o \"%.400s\" -l %p %p 2>&1", exepath, laddr, addr);
#else
sprintf(cmd, "addr2line -f -p -e \"%.400s\" %s 2>&1", exepath, addr);
sprintf(cmd, "addr2line -fpCis -e \"%.400s\" %p 2>&1", exepath, addr);
#endif
return sh(out, cmd);
}
@ -345,15 +327,32 @@ static bool generateMinidump(TFilePath dumpFile) { return false; }
//-----------------------------------------------------------------------------
#define HAS_MODULES
#ifdef LINUX
static int printModuleInfo(struct dl_phdr_info *i, size_t size, void *data) {
std::string *out = (std::string *)data;
char addr[512];
sprintf(addr, "%p", (long)i->dlpi_addr);
out->append(std::string(addr) + " - " + std::string(i->dlpi_name) + "\n");
return 0;
}
#endif
static void printModules(std::string &out) {
#ifdef MACOSX
char str[512];
int c = _dyld_image_count();
for (int i = 0; i < c; i++) {
const char *image_name = _dyld_get_image_name(i);
const char *image_name = _dyld_get_image_name(i);
const struct mach_header *header = _dyld_get_image_header(i);
uintptr_t loadaddr = (uintptr_t)header;
sprintf(str, "%p", loadaddr);
QString path = obfuscateUsername(QString(image_name));
out.append(path.toStdString());
out.append(std::string(str) + " - " + path.toStdString());
out.append("\n");
}
#else
dl_iterate_phdr(printModuleInfo, &out);
#endif
}
@ -367,59 +366,55 @@ static void printBacktrace(std::string &out) {
const int size = 256;
void *buffer[size];
// Get executable path
char exepath[512];
memset(exepath, 0, 512);
#ifndef MACOSX
if (readlink("/proc/self/exe", exepath, 512) < 0)
fprintf(stderr, "Couldn't get exe path\n");
#endif
// Back trace
int nptrs = backtrace(buffer, size);
char **bts = backtrace_symbols(buffer, nptrs);
std::regex re("\\[(.+)\\]");
if (bts) {
for (int i = 0; i < nptrs; ++i) {
// Skip first frames since they point to this function
if (frameStack++ < frameSkip) continue;
char numStr[32];
memset(numStr, 0, sizeof(numStr));
sprintf(numStr, "%3i> ", frameStack - frameSkip);
out.append(numStr);
int nptrs = backtrace(buffer, size);
for (int i = 0; i < nptrs; ++i) {
// Skip first frames since they point to this function
if (frameStack++ < frameSkip) continue;
char numStr[32];
memset(numStr, 0, sizeof(numStr));
sprintf(numStr, "%3i> ", frameStack - frameSkip);
out.append(numStr);
std::string sym = bts[i];
std::string line;
std::smatch ms;
std::string frame;
std::string module;
std::string addr;
std::string line;
std::string sym = "??? at ??:?";
std::string module = "???";
size_t addr = (size_t)buffer[i];
bool found = false;
bool found = false;
Dl_info info;
int infoFound = dladdr(buffer[i], &info);
if (infoFound) module = std::string(info.dli_fname);
#ifdef MACOSX
QString sym2 = QString::fromStdString(sym);
QStringList strlst = sym2.split(" ");
strlst.removeAll({});
module = strlst[1].toStdString();
addr = strlst[2].toStdString();
#else
module = std::string(exepath);
if (std::regex_search(sym, ms, re))
addr = ms[1];
#endif
if (addr2line(line, module.c_str(), addr.c_str())) {
found = (line.rfind("??", 0) != 0) &&
(line.find("cannot load symbol", 0) != 0) &&
(line.find("command not found") != 0);
}
out.append(found ? line : (sym + "\n"));
if (module.find("Tahoma2D.app/Contents/MacOS") != std::string::npos) {
std::string dsym = module;
int pos = dsym.find("Contents");
dsym.replace(pos, 14, "DSYM/Contents/Resources/DWARF");
TFilePath file(dsym);
if (TFileStatus(file).doesExist()) module = dsym;
}
}
free(bts);
char addrstr[512];
sprintf(addrstr, "%p", addr);
sym = std::string(addrstr) + " (in " + module + ")";
#else
link_map *link_map;
dladdr1(buffer[i], &info, (void **)&link_map, RTLD_DL_LINKMAP);
addr -= link_map->l_addr;
#endif
if (infoFound &&
addr2line(line, module.c_str(), addr, (size_t)info.dli_fbase)) {
found = (line.rfind("??", 0) != 0) &&
(line.find("cannot load symbol", 0) != 0) &&
(line.find("command not found") != 0);
}
out.append(found ? line : (sym + "\n"));
}
}
void signalHandler(int sig) {
@ -624,7 +619,7 @@ bool CrashHandler::trigger(const QString reason, bool showDialog) {
bool minidump = generateMinidump(fpDump, s_exceptionPtr);
#else
bool minidump = generateMinidump(fpDump);
#endif;
#endif
// Generate report
try {
@ -661,9 +656,11 @@ bool CrashHandler::trigger(const QString reason, bool showDialog) {
std::wstring sceneName = currentScene->getSceneName();
out.append("\nApplication Dir: ");
out.append(obfuscateUsername(QCoreApplication::applicationDirPath()).toStdString());
out.append(obfuscateUsername(QCoreApplication::applicationDirPath())
.toStdString());
out.append("\nStuff Dir: ");
out.append(obfuscateUsername(TEnv::getStuffDir().getQString()).toStdString());
out.append(
obfuscateUsername(TEnv::getStuffDir().getQString()).toStdString());
out.append("\n");
out.append("\nProject Name: ");
out.append(currentProject->getName().getQString().toStdString());