]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_utilities/lib/debugsupport.h
Security-57031.40.6.tar.gz
[apple/security.git] / Security / libsecurity_utilities / lib / debugsupport.h
1 /*
2 * Copyright (c) 2000-2004,2011-2012,2014 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 //
26 // debugsupport - support interface for making and managing debugger objects.
27 //
28 // This header is not needed for logging debug messages.
29 //
30 #ifndef _H_DEBUGSUPPORT
31 #define _H_DEBUGSUPPORT
32
33 //
34 // Generate stub-code support if NDEBUG (but not CLEAN_NDEBUG) is set, to support
35 // client code that may have been generated with debug enabled. You don't actually
36 // get *real* debug logging, of course, just cheap dummy stubs to keep the linker happy.
37 //
38 #include <security_utilities/debugging.h>
39 #include <security_utilities/threading.h>
40 #include <security_utilities/globalizer.h>
41 #include <cstdarg>
42 #include <set>
43
44 namespace Security {
45 namespace Debug {
46
47
48 //
49 // Debug scope names - short strings with value semantics.
50 // We don't use STL strings because of overhead.
51 //
52 class Name {
53 public:
54 static const int maxLength = 12;
55
56 Name(const char *s)
57 { strncpy(mName, s, maxLength-1); mName[maxLength-1] = '\0'; }
58
59 Name(const char *start, const char *end)
60 {
61 intptr_t length = end - start; if (length >= maxLength) length = maxLength - 1;
62 memcpy(mName, start, length); memset(mName + length, 0, maxLength - length);
63 }
64
65 operator const char *() const { return mName; }
66
67 bool operator < (const Name &other) const
68 { return memcmp(mName, other.mName, maxLength) < 0; }
69
70 bool operator == (const Name &other) const
71 { return memcmp(mName, other.mName, maxLength) == 0; }
72
73 private:
74 char mName[maxLength]; // null terminated for easy printing
75 };
76
77
78 //
79 // A debugging Target. This is an object that receives debugging requests.
80 // You can have many, but one default one is always provided.
81 //
82 class Target {
83 public:
84 Target();
85 virtual ~Target();
86
87 // get default (singleton) Target
88 static Target &get();
89
90 void setFromEnvironment();
91
92 public:
93 class Sink {
94 public:
95 virtual ~Sink();
96 virtual void put(const char *buffer, unsigned int length) = 0;
97 virtual void dump(const char *buffer);
98 virtual void configure(const char *argument);
99 const bool needsDate;
100
101 protected:
102 Sink(bool nd = true) : needsDate(nd) { }
103 };
104
105 void to(Sink *sink);
106 void to(const char *filename);
107 void to(int syslogPriority);
108 void to(FILE *openFile);
109
110 void configure(); // from DEBUGOPTIONS
111 void configure(const char *options); // from explicit string
112
113 public:
114 void message(const char *scope, const char *format, va_list args);
115 bool debugging(const char *scope);
116 void dump(const char *format, va_list args);
117 bool dump(const char *scope);
118
119 protected:
120 class Selector {
121 public:
122 Selector();
123 void operator = (const char *config);
124
125 bool operator () (const char *name) const;
126
127 private:
128 bool useSet; // use contents of enableSet
129 bool negate; // negate meaning of enableSet
130 set<Name> enableSet; // set of names
131 };
132
133 protected:
134 class PerThread {
135 public:
136 PerThread() { id = ++lastUsed; }
137 unsigned int id; // arbitrary (sequential) ID number
138
139 private:
140 static unsigned int lastUsed; // last id used
141 };
142 ThreadNexus<PerThread> perThread;
143
144 protected:
145 static const size_t messageConstructionSize = 512; // size of construction buffer
146
147 Selector logSelector; // selector for logging
148 Selector dumpSelector; // selector for dumping
149
150 // output option state (from last configure call)
151 bool showScope; // include scope in output lines
152 bool showScopeRight; // scope after proc/thread, not before
153 bool showThread; // include thread and pid in output lines
154 bool showProc; // include "nice" process/thread id in output lines
155 bool showDate; // include date in output lines
156 size_t dumpLimit; // max. # of bytes dumped by dumpData & friends
157
158 // misc. global state
159 static const size_t maxProgNameLength = 20; // max. program name remembered
160 static const size_t procLength = 14; // characters for proc/thread column
161 static char progName[]; // (short truncated form of) program name
162
163 // current output support
164 Sink *sink;
165
166 static terminate_handler previousTerminator; // for chaining
167 static void terminator();
168
169 // the default Target
170 static Target *singleton;
171 };
172
173
174 //
175 // Standard Target::Sinks
176 //
177 class FileSink : public Target::Sink {
178 public:
179 FileSink(FILE *f) : Sink(true), file(f) { }
180 void put(const char *, unsigned int);
181 void dump(const char *text);
182 void configure(const char *);
183
184 private:
185 FILE *file;
186 };
187
188 class SyslogSink : public Target::Sink {
189 public:
190 SyslogSink(int pri)
191 : Sink(false), priority(pri), dumpBase(dumpBuffer), dumpPtr(dumpBuffer) { }
192 void put(const char *, unsigned int);
193 void dump(const char *text);
194 void configure(const char *);
195
196 private:
197 int priority;
198
199 // a sliding buffer to hold partial line output
200 static const size_t dumpBufferSize = 1024; // make this about 2 * maximum line length of dumps
201 char dumpBuffer[dumpBufferSize];
202 char *dumpBase, *dumpPtr;
203 };
204
205
206 } // end namespace Debug
207 } // end namespace Security
208
209
210 #endif //_H_DEBUGSUPPORT