]>
git.proxmox.com Git - rustc.git/blob - src/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cc
1 //===-- sanitizer_symbolizer_mac.cc ---------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is shared between various sanitizers' runtime libraries.
12 // Implementation of Mac-specific "atos" symbolizer.
13 //===----------------------------------------------------------------------===//
15 #include "sanitizer_platform.h"
18 #include "sanitizer_allocator_internal.h"
19 #include "sanitizer_mac.h"
20 #include "sanitizer_symbolizer_mac.h"
22 namespace __sanitizer
{
31 bool DlAddrSymbolizer::SymbolizePC(uptr addr
, SymbolizedStack
*stack
) {
33 int result
= dladdr((const void *)addr
, &info
);
34 if (!result
) return false;
35 const char *demangled
= DemangleCXXABI(info
.dli_sname
);
36 stack
->info
.function
= internal_strdup(demangled
);
40 bool DlAddrSymbolizer::SymbolizeData(uptr addr
, DataInfo
*info
) {
44 class AtosSymbolizerProcess
: public SymbolizerProcess
{
46 explicit AtosSymbolizerProcess(const char *path
, pid_t parent_pid
)
47 : SymbolizerProcess(path
, /*use_forkpty*/ true) {
48 // Put the string command line argument in the object so that it outlives
49 // the call to GetArgV.
50 internal_snprintf(pid_str_
, sizeof(pid_str_
), "%d", parent_pid
);
54 bool ReachedEndOfOutput(const char *buffer
, uptr length
) const override
{
55 return (length
>= 1 && buffer
[length
- 1] == '\n');
58 void GetArgV(const char *path_to_binary
,
59 const char *(&argv
)[kArgVMax
]) const override
{
61 argv
[i
++] = path_to_binary
;
63 argv
[i
++] = &pid_str_
[0];
64 if (GetMacosVersion() == MACOS_VERSION_MAVERICKS
) {
65 // On Mavericks atos prints a deprecation warning which we suppress by
66 // passing -d. The warning isn't present on other OSX versions, even the
76 static const char *kAtosErrorMessages
[] = {
77 "atos cannot examine process",
78 "unable to get permission to examine process",
79 "An admin user name and password is required",
80 "could not load inserted library",
81 "architecture mismatch between analysis process",
84 static bool IsAtosErrorMessage(const char *str
) {
85 for (uptr i
= 0; i
< ARRAY_SIZE(kAtosErrorMessages
); i
++) {
86 if (internal_strstr(str
, kAtosErrorMessages
[i
])) {
93 static bool ParseCommandOutput(const char *str
, SymbolizedStack
*res
) {
94 // Trim ending newlines.
96 ExtractTokenUpToDelimiter(str
, "\n", &trim
);
98 // The line from `atos` is in one of these formats:
99 // myfunction (in library.dylib) (sourcefile.c:17)
100 // myfunction (in library.dylib) + 0x1fe
101 // 0xdeadbeef (in library.dylib) + 0x1fe
102 // 0xdeadbeef (in library.dylib)
105 if (IsAtosErrorMessage(trim
)) {
106 Report("atos returned an error: %s\n", trim
);
111 const char *rest
= trim
;
113 rest
= ExtractTokenUpToDelimiter(rest
, " (in ", &function_name
);
114 if (internal_strncmp(function_name
, "0x", 2) != 0)
115 res
->info
.function
= function_name
;
117 InternalFree(function_name
);
118 rest
= ExtractTokenUpToDelimiter(rest
, ") ", &res
->info
.module
);
120 if (rest
[0] == '(') {
122 rest
= ExtractTokenUpToDelimiter(rest
, ":", &res
->info
.file
);
123 char *extracted_line_number
;
124 rest
= ExtractTokenUpToDelimiter(rest
, ")", &extracted_line_number
);
125 res
->info
.line
= internal_atoll(extracted_line_number
);
126 InternalFree(extracted_line_number
);
133 AtosSymbolizer::AtosSymbolizer(const char *path
, LowLevelAllocator
*allocator
)
134 : process_(new(*allocator
) AtosSymbolizerProcess(path
, getpid())) {}
136 bool AtosSymbolizer::SymbolizePC(uptr addr
, SymbolizedStack
*stack
) {
137 if (!process_
) return false;
139 internal_snprintf(command
, sizeof(command
), "0x%zx\n", addr
);
140 const char *buf
= process_
->SendCommand(command
);
141 if (!buf
) return false;
142 if (!ParseCommandOutput(buf
, stack
)) {
149 bool AtosSymbolizer::SymbolizeData(uptr addr
, DataInfo
*info
) { return false; }
151 } // namespace __sanitizer
153 #endif // SANITIZER_MAC