Skip to content
Snippets Groups Projects
Commit 5e9ba0bc authored by Alexey Matveichev's avatar Alexey Matveichev Committed by Mark OLESEN
Browse files

ENH: Darwin emulation for addr2line

parent bd33a382
Branches
Tags
No related merge requests found
#!/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
#------------------------------------------------------------------------------
addr2line.C
EXE = $(FOAM_APPBIN)/addr2line
EXE_INC =
EXE_LIBS =
/*---------------------------------------------------------------------------*\
========= |
\\ / 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;
}
// ************************************************************************* //
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment