diff --git a/applications/utilities/miscellaneous/OSspecific/Allwmake b/applications/utilities/miscellaneous/OSspecific/Allwmake new file mode 100755 index 0000000000000000000000000000000000000000..cf32b145cec420dcbec3ab1a4dfa3e65f7cc589c --- /dev/null +++ b/applications/utilities/miscellaneous/OSspecific/Allwmake @@ -0,0 +1,13 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory +. $WM_PROJECT_DIR/wmake/scripts/sysFunctions + +#------------------------------------------------------------------------------ + +if isDarwin +then + echo "==> Darwin-specific utilities" + wmake addr2line +fi + +#------------------------------------------------------------------------------ diff --git a/applications/utilities/miscellaneous/OSspecific/addr2line/Make/files b/applications/utilities/miscellaneous/OSspecific/addr2line/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..a3dc48dff5b515b589e3932d34f85fee6710fe3a --- /dev/null +++ b/applications/utilities/miscellaneous/OSspecific/addr2line/Make/files @@ -0,0 +1,3 @@ +addr2line.C + +EXE = $(FOAM_APPBIN)/addr2line diff --git a/applications/utilities/miscellaneous/OSspecific/addr2line/Make/options b/applications/utilities/miscellaneous/OSspecific/addr2line/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..4c3dd783cb4170feefb3f5385510a83257b43b18 --- /dev/null +++ b/applications/utilities/miscellaneous/OSspecific/addr2line/Make/options @@ -0,0 +1,3 @@ +EXE_INC = + +EXE_LIBS = diff --git a/applications/utilities/miscellaneous/OSspecific/addr2line/addr2line.C b/applications/utilities/miscellaneous/OSspecific/addr2line/addr2line.C new file mode 100644 index 0000000000000000000000000000000000000000..6ebd7b0d59cada70e9edf7116b481df9434f8a81 --- /dev/null +++ b/applications/utilities/miscellaneous/OSspecific/addr2line/addr2line.C @@ -0,0 +1,208 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 Alexey Matveichev + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM 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 General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + addr2line + +Description + A simple, partial emulation of addr2line utility for Mac-OS. + +\*---------------------------------------------------------------------------*/ + +#include <getopt.h> +#include <cstdlib> +#include <string> +#include <vector> +#include <iostream> + +#include "regExp.H" +#include "SubStrings.H" + +static void usage(); +static void version(); +static std::string getLine(const std::string&, const std::string&); +static std::string pOpen(const std::string&, int line=0); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + int optHelp = 0, optFunctions = 0, optVersion = 0; + int ch; + std::string filename = "a.out"; + std::vector<std::string> addresses; + + static struct option opts[] = + { + { "target", required_argument, nullptr, 'b' }, + { "demangle", required_argument, nullptr, 'C' }, + { "exe", required_argument, nullptr, 'e' }, + { "functions", no_argument, &optFunctions, 1 }, + { "version", no_argument, &optVersion, 1 }, + { "basename", no_argument, nullptr, 's' }, + { "inlines", no_argument, nullptr, 'i' }, + { "section", required_argument, nullptr, 'j' }, + { "help", no_argument, &optHelp, 1 }, + { nullptr, 0, nullptr, 0 } + }; + + while ((ch = getopt_long(argc, argv, "b:C:e:fVsij:H", opts, nullptr)) != -1) + { + switch (ch) + { + case 'e': + filename = std::string(optarg); + break; + case 'C': + // Ignoring this flag for now + break; + case 'f': + // Functions are demangled in printStack + break; + case 0: + if (optHelp) usage(); + if (optVersion) version(); + break; + default: + usage(); + break; + } + } + + if (optind >= argc) + { + usage(); + } + + argc -= optind; + argv += optind; + + while (argc > 0) + { + addresses.push_back(std::string(*argv)); + ++argv; + --argc; + } + + for (const auto& addr : addresses) + { + std::cout<< '\n' << getLine(filename, addr).c_str() << '\n'; + } + + return 0; +} + + +void usage() +{ + std::cout + << "usage: addr2line [-e filename|--exe=filename]" + " address [address...]\n" << std::endl; + ::exit(1); +} + + +void version() +{ + std::cout<< "OpenFOAM addr2line emulator\n" << std::endl; + ::exit(0); +} + + +std::string pOpen(const std::string& cmd, int line) +{ + std::string res; + + FILE* cmdPipe = popen(cmd.c_str(), "r"); + if (!cmdPipe) return res; + + char* buf = nullptr; + + // Read line number of lines + for (int cnt = 0; cnt <= line; ++cnt) + { + size_t linecap = 0; + ssize_t linelen = ::getline(&buf, &linecap, cmdPipe); + + if (linelen < 0) + { + break; + } + + if (cnt == line) + { + res = std::string(buf); + + // Trim trailing newline + if (res.size()) + { + res.resize(res.size()-1); + } + break; + } + } + + if (buf) free(buf); + + pclose(cmdPipe); + + return res; +} + + +std::string getLine(const std::string& filename, const std::string& addr) +{ + std::string line = + pOpen + ( + "echo 'image lookup -va " + addr + + "'" + + " | xcrun lldb " + + "-O 'target create --no-dependents -a x86_64 " + + filename + + "' -o '" + + "target module load -f " + + filename + + " __TEXT 0x0' 2> /dev/null" + + " | grep LineEntry" + ); + + + Foam::regExp re(".+LineEntry: .+: (.+):([0-9]+):[0-9]+"); + + Foam::regExp::results_type groups; + if (!re.match(line, groups)) + { + line = "??:0"; + } + else + { + line = groups[1].str() + ":" + groups[2].str(); + } + + return line; +} + + +// ************************************************************************* //