addr2line.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2018 Alexey Matveichev
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26Application
27 addr2line
28
29Description
30 A simple, partial emulation of addr2line utility for Mac-OS.
31
32\*---------------------------------------------------------------------------*/
33
34#include <getopt.h>
35#include <cstdlib>
36#include <string>
37#include <vector>
38#include <iostream>
39
40#include "regExp.H"
41#include "SubStrings.H"
42
43static void usage();
44static void version();
45static std::string getLine(const std::string&, const std::string&);
46static std::string pOpen(const std::string&, int line=0);
47
48
49// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50
51int main(int argc, char *argv[])
52{
53 int optHelp = 0, optFunctions = 0, optVersion = 0;
54 int ch;
55 std::string filename = "a.out";
56 std::vector<std::string> addresses;
57
58 static struct option opts[] =
59 {
60 { "target", required_argument, nullptr, 'b' },
61 { "demangle", required_argument, nullptr, 'C' },
62 { "exe", required_argument, nullptr, 'e' },
63 { "functions", no_argument, &optFunctions, 1 },
64 { "version", no_argument, &optVersion, 1 },
65 { "basename", no_argument, nullptr, 's' },
66 { "inlines", no_argument, nullptr, 'i' },
67 { "section", required_argument, nullptr, 'j' },
68 { "help", no_argument, &optHelp, 1 },
69 { nullptr, 0, nullptr, 0 }
70 };
71
72 while ((ch = getopt_long(argc, argv, "b:C:e:fVsij:H", opts, nullptr)) != -1)
73 {
74 switch (ch)
75 {
76 case 'e':
77 filename = std::string(optarg);
78 break;
79 case 'C':
80 // Ignoring this flag for now
81 break;
82 case 'f':
83 // Functions are demangled in printStack
84 break;
85 case 0:
86 if (optHelp) usage();
87 if (optVersion) version();
88 break;
89 default:
90 usage();
91 break;
92 }
93 }
94
95 if (optind >= argc)
96 {
97 usage();
98 }
99
100 argc -= optind;
101 argv += optind;
102
103 while (argc > 0)
104 {
105 addresses.push_back(std::string(*argv));
106 ++argv;
107 --argc;
108 }
109
110 for (const auto& addr : addresses)
111 {
112 std::cout<< '\n' << getLine(filename, addr).c_str() << '\n';
113 }
114
115 return 0;
116}
117
118
119void usage()
120{
121 std::cout
122 << "usage: addr2line [-e filename|--exe=filename]"
123 " address [address...]\n" << std::endl;
124 std::exit(1);
125}
126
127
128void version()
129{
130 std::cout<< "OpenFOAM addr2line emulator\n" << std::endl;
131 std::exit(0);
132}
133
134
135std::string pOpen(const std::string& cmd, int line)
136{
137 std::string res;
138
139 FILE* cmdPipe = popen(cmd.c_str(), "r");
140 if (!cmdPipe) return res;
141
142 char* buf = nullptr;
143
144 // Read line number of lines
145 for (int cnt = 0; cnt <= line; ++cnt)
146 {
147 size_t linecap = 0;
148 ssize_t linelen = ::getline(&buf, &linecap, cmdPipe);
149
150 if (linelen < 0)
151 {
152 break;
153 }
154
155 if (cnt == line)
156 {
157 res = std::string(buf);
158
159 // Trim trailing newline
160 if (res.size())
161 {
162 res.resize(res.size()-1);
163 }
164 break;
165 }
166 }
167
168 if (buf) free(buf);
169
170 pclose(cmdPipe);
171
172 return res;
173}
174
175
176std::string getLine(const std::string& filename, const std::string& addr)
177{
178 std::string line =
179 pOpen
180 (
181 "echo 'image lookup -va " + addr
182 + "'"
183 + " | xcrun lldb "
184 + "-O 'target create --no-dependents -a x86_64 "
185 + filename
186 + "' -o '"
187 + "target module load -f "
188 + filename
189 + " __TEXT 0x0' 2>/dev/null"
190 + " | grep LineEntry"
191 );
192
193
194 Foam::regExp re(".+LineEntry: .+: (.+):([0-9]+):[0-9]+");
195
197 if (!re.match(line, groups))
198 {
199 line = "??:0";
200 }
201 else
202 {
203 line = groups[1].str() + ":" + groups[2].str();
204 }
205
206 return line;
207}
208
209
210// ************************************************************************* //
Wrapper around C++11 regular expressions with some additional prefix-handling. The prefix-handling is...
Definition: regExpCxx.H:83
std::smatch results_type
Type for matches.
Definition: regExpCxx.H:114
const dimensionedScalar re
Classical electron radius: default SI units: [m].
const std::string version
OpenFOAM version (name or stringified number) as a std::string.
string pOpen(const string &cmd, label line=0)
Definition: printStack.C:46