]> git.saurik.com Git - apple/dyld.git/blob - dyld3/Diagnostics.cpp
dyld-519.2.2.tar.gz
[apple/dyld.git] / dyld3 / Diagnostics.cpp
1 /*
2 * Copyright (c) 2017 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <uuid/uuid.h>
30 #include <fcntl.h>
31 #include <errno.h>
32 #include <_simple.h>
33 #include <unistd.h>
34 #include <sys/uio.h>
35 #include <sys/param.h>
36 #include <sys/sysctl.h>
37 #include <sys/resource.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <sys/mman.h>
41 #include <dirent.h>
42 #include <mach/mach.h>
43 #include <mach/machine.h>
44 #include <mach-o/loader.h>
45 #include <mach-o/nlist.h>
46 #include <mach-o/fat.h>
47 #include <pthread.h>
48 #include <libc_private.h>
49
50 #include "Diagnostics.h"
51
52 #if BUILDING_CACHE_BUILDER
53 #include <dispatch/dispatch.h>
54 dispatch_queue_t sWarningQueue = dispatch_queue_create("com.apple.dyld.cache-builder.warnings", NULL);
55 #endif
56
57 Diagnostics::Diagnostics(bool verbose)
58 #if !DYLD_IN_PROCESS
59 : _verbose(verbose)
60 , _prefix("")
61 #endif
62 {
63 }
64
65 #if !DYLD_IN_PROCESS
66 Diagnostics::Diagnostics(const std::string& prefix, bool verbose)
67 : _verbose(verbose)
68 , _prefix(prefix)
69 {
70 }
71 #endif
72
73 Diagnostics::~Diagnostics()
74 {
75 clearError();
76 }
77
78 void Diagnostics::error(const char* format, ...)
79 {
80 _buffer = _simple_salloc();
81 va_list list;
82 va_start(list, format);
83 _simple_vsprintf(_buffer, format, list);
84 va_end(list);
85
86 #if !DYLD_IN_PROCESS
87 if ( !_verbose )
88 return;
89
90 char *output_string;
91 va_start(list, format);
92 vasprintf(&output_string, format, list);
93 va_end(list);
94
95 if (_prefix.empty()) {
96 fprintf(stderr, "%s", output_string);
97 } else {
98 fprintf(stderr, "[%s] %s", _prefix.c_str(), output_string);
99 }
100 #endif
101 }
102
103 bool Diagnostics::hasError() const
104 {
105 return _buffer != nullptr;
106 }
107
108 bool Diagnostics::noError() const
109 {
110 return _buffer == nullptr;
111 }
112
113 void Diagnostics::clearError()
114 {
115 if ( _buffer )
116 _simple_sfree(_buffer);
117 _buffer = nullptr;
118 }
119
120 void Diagnostics::assertNoError() const
121 {
122 if ( _buffer != nullptr )
123 abort_report_np("%s", _simple_string(_buffer));
124 }
125
126 #if DYLD_IN_PROCESS
127 const char* Diagnostics::errorMessage() const
128 {
129 return _simple_string(_buffer);
130 }
131
132 #else
133 void Diagnostics::warning(const char* format, ...)
134 {
135 _SIMPLE_STRING tmp = _simple_salloc();
136 va_list list;
137 va_start(list, format);
138 _simple_vsprintf(tmp, format, list);
139 va_end(list);
140 #if BUILDING_CACHE_BUILDER
141 dispatch_sync(sWarningQueue, ^{
142 _warnings.insert(_simple_string(tmp));
143 });
144 #else
145 _warnings.insert(_simple_string(tmp));
146 #endif
147 _simple_sfree(tmp);
148 }
149
150 void Diagnostics::verbose(const char* format, ...)
151 {
152 if ( !_verbose )
153 return;
154
155 char* output_string;
156 va_list list;
157 va_start(list, format);
158 vasprintf(&output_string, format, list);
159 va_end(list);
160
161 if (_prefix.empty()) {
162 fprintf(stderr, "%s", output_string);
163 } else {
164 fprintf(stderr, "[%s] %s", _prefix.c_str(), output_string);
165 }
166 }
167
168 const std::string Diagnostics::prefix() const
169 {
170 return _prefix;
171 }
172
173 void Diagnostics::copy(const Diagnostics& other)
174 {
175 if ( other.hasError() )
176 error("%s", other.errorMessage().c_str());
177 for (const std::string& warn : other.warnings())
178 warning("%s", warn.c_str());
179 }
180
181 std::string Diagnostics::errorMessage() const
182 {
183 if ( _buffer != nullptr )
184 return _simple_string(_buffer);
185 else
186 return std::string();
187 }
188
189 const std::set<std::string> Diagnostics::warnings() const
190 {
191 #if BUILDING_CACHE_BUILDER
192 __block std::set<std::string> retval;
193 dispatch_sync(sWarningQueue, ^{
194 retval = _warnings;
195 });
196 return retval;
197 #else
198 return _warnings;
199 #endif
200 }
201
202 void Diagnostics::clearWarnings()
203 {
204 #if BUILDING_CACHE_BUILDER
205 dispatch_sync(sWarningQueue, ^{
206 _warnings.clear();
207 });
208 #else
209 _warnings.clear();
210 #endif
211 }
212
213 #endif
214