···11+/*
22+ * Copyright (c) 2013-2016 Apple Inc. All rights reserved.
33+ *
44+ * @APPLE_LICENSE_HEADER_START@
55+ *
66+ * This file contains Original Code and/or Modifications of Original Code
77+ * as defined in and that are subject to the Apple Public Source License
88+ * Version 2.0 (the 'License'). You may not use this file except in
99+ * compliance with the License. Please obtain a copy of the License at
1010+ * http://www.opensource.apple.com/apsl/ and read it before using this
1111+ * file.
1212+ *
1313+ * The Original Code and all software distributed under the License are
1414+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1515+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
1616+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
1717+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
1818+ * Please see the License for the specific language governing rights and
1919+ * limitations under the License.
2020+ *
2121+ * @APPLE_LICENSE_HEADER_END@
2222+ */
2323+2424+#ifndef __OS_ACTIVITY_H__
2525+#define __OS_ACTIVITY_H__
2626+2727+#include <os/object.h>
2828+#include <stdint.h>
2929+#include <stdbool.h>
3030+#include <mach-o/loader.h>
3131+3232+__BEGIN_DECLS
3333+3434+#if ((defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) \
3535+ || (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && __WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0) \
3636+ || (defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) \
3737+ || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12))
3838+#define OS_ACTIVITY_OBJECT_API 1
3939+#else
4040+#if OS_ACTIVITY_OBJECT_API
4141+#error Please change your minimum OS requirements because OS_ACTIVITY_OBJECT_API is not available
4242+#endif // OS_ACTIVITY_OBJECT_API
4343+#define OS_ACTIVITY_OBJECT_API 0
4444+#endif
4545+4646+extern void* __dso_handle;
4747+4848+#define OS_LOG_STRING(_var, _str) \
4949+ _Static_assert(__builtin_constant_p(_str), "formatters/labels/descriptions must be a constant string"); \
5050+ __attribute__((section("__TEXT,__oslogstring,cstring_literals"),internal_linkage)) static const char _var[] __asm(OS_STRINGIFY(OS_CONCAT(LOSACTIVITY_, __COUNTER__))) = _str
5151+5252+/*!
5353+ * @typedef os_breadcrumb_t
5454+ * An opaque value for the breadcrumb ID.
5555+ */
5656+__API_DEPRECATED("No longer supported", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0))
5757+typedef uint32_t os_breadcrumb_t;
5858+5959+#define OS_ACTIVITY_NULL 0
6060+6161+/*!
6262+ * @enum os_activity_flag_t
6363+ *
6464+ * @discussion
6565+ * Support flags for os_activity_create or os_activity_start.
6666+ *
6767+ * @constant OS_ACTIVITY_FLAG_DEFAULT
6868+ * Use the default flags.
6969+ *
7070+ * @constant OS_ACTIVITY_FLAG_DETACHED
7171+ * Detach the newly created activity from the provided activity (if any). If passed in conjunction
7272+ * with an exiting activity, the activity will only note what activity "created" the new one, but
7373+ * will make the new activity a top level activity. This allows users to see what activity triggered
7474+ * work without actually relating the activities.
7575+ *
7676+ * @constant OS_ACTIVITY_FLAG_IF_NONE_PRESENT
7777+ * Will only create a new activity if none present. If an activity ID is already present, a new object
7878+ * will be returned with the same activity ID underneath.
7979+ */
8080+OS_ENUM(os_activity_flag, uint32_t,
8181+ OS_ACTIVITY_FLAG_DEFAULT = 0,
8282+ OS_ACTIVITY_FLAG_DETACHED = 0x1,
8383+ OS_ACTIVITY_FLAG_IF_NONE_PRESENT = 0x2
8484+);
8585+8686+#if OS_ACTIVITY_OBJECT_API
8787+8888+#define OS_ACTIVITY_NULL NULL
8989+9090+/*!
9191+ * @typedef os_activity_t
9292+ * An opaque activity object.
9393+ */
9494+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
9595+#if OS_OBJECT_USE_OBJC
9696+OS_OBJECT_DECL(os_activity);
9797+#else
9898+typedef struct os_activity_s *os_activity_t;
9999+#endif /* OS_OBJECT_USE_OBJC */
100100+101101+/*!
102102+ * @const OS_ACTIVITY_NONE
103103+ *
104104+ * @discussion
105105+ * Create activity with no current traits, this is the equivalent of a
106106+ * detached activity.
107107+ */
108108+#define OS_ACTIVITY_NONE OS_OBJECT_GLOBAL_OBJECT(os_activity_t, _os_activity_none)
109109+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
110110+OS_EXPORT
111111+const struct os_activity_s _os_activity_none;
112112+113113+/*!
114114+ * @const OS_ACTIVITY_CURRENT
115115+ *
116116+ * @discussion
117117+ * Create activity and links to the current activity if one is present.
118118+ * If no activity is present it is treated as if it is detached.
119119+ */
120120+#define OS_ACTIVITY_CURRENT OS_OBJECT_GLOBAL_OBJECT(os_activity_t, _os_activity_current)
121121+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
122122+OS_EXPORT
123123+const struct os_activity_s _os_activity_current;
124124+125125+#else // !OS_ACTIVITY_OBJECT_API
126126+127127+#define OS_ACTIVITY_NULL 0
128128+129129+/*!
130130+ * @typedef os_activity_t
131131+ * An opaque activity identifier.
132132+ */
133133+__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(9.0))
134134+typedef uint64_t os_activity_t;
135135+136136+#endif // OS_ACTIVITY_OBJECT_API
137137+138138+/*!
139139+ * @typedef os_activity_id_t
140140+ * An value representing the activity ID assigned to an newly created activity.
141141+ */
142142+__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(9.0))
143143+typedef uint64_t os_activity_id_t;
144144+145145+#if !defined(__TRACE_BUILDING_TRACE__)
146146+/*!
147147+ * @typedef os_activity_scope_state_t
148148+ * Structure that is populated by os_activity_scope_enter and restored using
149149+ * os_activity_scope_leave.
150150+ */
151151+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
152152+typedef struct os_activity_scope_state_s {
153153+ uint64_t opaque[2];
154154+} *os_activity_scope_state_t;
155155+#else
156156+typedef struct os_activity_scope_state_s *os_activity_scope_state_t;
157157+#endif
158158+159159+#pragma mark - Internal support functions
160160+161161+#if OS_ACTIVITY_OBJECT_API
162162+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
163163+OS_EXPORT OS_NOTHROW OS_WARN_RESULT_NEEDS_RELEASE OS_NOT_TAIL_CALLED OS_OBJECT_RETURNS_RETAINED
164164+os_activity_t
165165+_os_activity_create(void *dso, const char *description, os_activity_t activity, os_activity_flag_t flags);
166166+#endif
167167+168168+/*!
169169+ * @function _os_activity_label_useraction
170170+ *
171171+ * @abstract
172172+ * Internal function for use by os_activity_label_useraction. Do not use directly.
173173+ */
174174+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
175175+OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED
176176+void
177177+_os_activity_label_useraction(void *dso, const char *name);
178178+179179+/*!
180180+ * @function _os_activity_initiate
181181+ *
182182+ * @abstract
183183+ * Do not use directly because your description will not be preserved.
184184+ */
185185+__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(9.0))
186186+OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED
187187+void
188188+_os_activity_initiate(void *dso, const char *description, os_activity_flag_t flags, os_block_t activity_block OS_NOESCAPE);
189189+190190+/*!
191191+ * @function _os_activity_initiate_f
192192+ *
193193+ * @abstract
194194+ * Do not use directly because your description will not be preserved.
195195+ */
196196+__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(9.0))
197197+OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED
198198+void
199199+_os_activity_initiate_f(void *dso, const char *description, os_activity_flag_t flags, void *context, os_function_t function);
200200+201201+#pragma mark - Internal deprecated function support
202202+203203+/*!
204204+ * @function _os_activity_set_breadcrumb
205205+ *
206206+ * @abstract
207207+ * Internal function for setting breadcrumb. Do not use directly.
208208+ */
209209+__API_DEPRECATED_WITH_REPLACEMENT("os_activity_label_useraction", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0))
210210+OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED
211211+void
212212+_os_activity_set_breadcrumb(void *dso, const char *name);
213213+214214+/*!
215215+ * @function _os_activity_start
216216+ *
217217+ * @abstract
218218+ * Internal function for activity start, do not use directly will not preserve
219219+ * description.
220220+ */
221221+__API_DEPRECATED("use combination of os_activity_create and os_activity_apply/os_activity_scope", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0))
222222+OS_EXPORT OS_NOTHROW OS_WARN_RESULT OS_NOT_TAIL_CALLED
223223+os_activity_t
224224+_os_activity_start(void *dso, const char *description, os_activity_flag_t flags);
225225+226226+#pragma mark - activity related
227227+228228+/*!
229229+ * @function os_activity_initiate
230230+ *
231231+ * @abstract
232232+ * Synchronously initiates an activity using provided block.
233233+ *
234234+ * @discussion
235235+ * Synchronously initiates an activity using the provided block and creates
236236+ * a tracing buffer as appropriate. All new activities are created as a
237237+ * subactivity of an existing activity on the current thread.
238238+ *
239239+ * os_activity_initiate("indexing database", OS_ACTIVITY_FLAG_DEFAULT, ^(void) {
240240+ * // either do work directly or issue work asynchronously
241241+ * });
242242+ *
243243+ * @param description
244244+ * A constant string describing the activity, e.g., "performClick" or
245245+ * "menuSelection".
246246+ *
247247+ * @param flags
248248+ * Flags to be used when initiating the activity, typically OS_ACTIVITY_FLAG_DEFAULT.
249249+ *
250250+ * @param activity_block
251251+ * The block to execute a given activity
252252+ */
253253+#define os_activity_initiate(description, flags, activity_block) __extension__({ \
254254+ OS_LOG_STRING(__description, description); \
255255+ _os_activity_initiate(&__dso_handle, __description, flags, activity_block); \
256256+})
257257+258258+/*!
259259+ * @function os_activity_initiate_f
260260+ *
261261+ * @abstract
262262+ * Synchronously initiates an activity using the provided function.
263263+ *
264264+ * @discussion
265265+ * Synchronously initiates an activity using the provided function and creates
266266+ * a tracing buffer as appropriate. All new activities are created as a
267267+ * subactivity of an existing activity on the current thread.
268268+ *
269269+ * os_activity_initiate_f("indexing database", OS_ACTIVITY_FLAG_DEFAULT, context, function);
270270+ *
271271+ * @param description
272272+ * A constant string describing the activity, e.g., "performClick" or
273273+ * "menuSelection".
274274+ *
275275+ * @param flags
276276+ * Flags to be used when initiating the activity, typically OS_ACTIVITY_FLAG_DEFAULT.
277277+ *
278278+ * @param context
279279+ * An optional context that will be supplied to the activity function.
280280+ *
281281+ * @param activity_func
282282+ * The function to execute for the new activity.
283283+ */
284284+#define os_activity_initiate_f(description, flags, context, function) __extension__({ \
285285+ OS_LOG_STRING(__description, description); \
286286+ _os_activity_initiate_f(&__dso_handle, __description, flags, context, function); \
287287+})
288288+289289+#if OS_ACTIVITY_OBJECT_API
290290+/*!
291291+ * @function os_activity_create
292292+ *
293293+ * @abstract
294294+ * Creates an os_activity_t object which can be passed to os_activity_apply function.
295295+ *
296296+ * @discussion
297297+ * Creates an os_activity_t object which can be passed to os_activity_apply function.
298298+ *
299299+ * @param description
300300+ * Pass a description for the activity. The description must be a constant string
301301+ * within the calling executable or library.
302302+ *
303303+ * @param parent_activity
304304+ * Depending on flags will link the newly created activity to the value passed or
305305+ * note where the activity was created. Possible activities include: OS_ACTIVITY_NONE,
306306+ * OS_ACTIVITY_CURRENT or any existing os_activity_t object created using os_activity_create.
307307+ *
308308+ * @param flags
309309+ * A valid os_activity_flag_t which will determine behavior of the newly created activity.
310310+ *
311311+ * @result
312312+ * Returns an os_activity_t object which can be used with os_activity_apply.
313313+ */
314314+#define os_activity_create(description, parent_activity, flags) __extension__({ \
315315+ OS_LOG_STRING(__description, description); \
316316+ os_activity_t __activity = _os_activity_create(&__dso_handle, __description, parent_activity, flags); \
317317+ __activity; \
318318+})
319319+320320+/*!
321321+ * @function os_activity_apply
322322+ *
323323+ * @abstract
324324+ * Execute a block using a given activity object.
325325+ *
326326+ * @discussion
327327+ * Execute a block using a given activity object.
328328+ *
329329+ * @param activity
330330+ * There are global objects available which include: OS_ACTIVITY_NONE, OS_ACTIVITY_CURRENT
331331+ * or an existing os_activity_t object.
332332+ *
333333+ * @param block
334334+ * Pass the block to be executed within the context of the given activity.
335335+ */
336336+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
337337+OS_EXPORT OS_NOTHROW
338338+void
339339+os_activity_apply(os_activity_t activity, os_block_t block OS_NOESCAPE);
340340+341341+/*!
342342+ * @function os_activity_apply_f
343343+ *
344344+ * @abstract
345345+ * Execute a given function with a provided activity.
346346+ *
347347+ * @discussion
348348+ * Execute a given function with a provided activity.
349349+ *
350350+ * @param activity
351351+ * There are global objects available which include: OS_ACTIVITY_NONE, OS_ACTIVITY_CURRENT
352352+ * or an existing os_activity_t object.
353353+ *
354354+ * @param context
355355+ * Context to pass to the function which may be NULL.
356356+ *
357357+ * @param function
358358+ * Pass the function to be executed within the context of the given activity.
359359+ */
360360+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
361361+OS_EXPORT OS_NOTHROW
362362+void
363363+os_activity_apply_f(os_activity_t activity, void *context, os_function_t function);
364364+365365+/*!
366366+ * @function os_activity_scope_enter
367367+ *
368368+ * @abstract
369369+ * Will change the current execution context to use the provided activity.
370370+ *
371371+ * @discussion
372372+ * Will change the current execution context to use the provided activity. An activity
373373+ * can be created and then applied to the current scope by doing:
374374+ *
375375+ * struct os_activity_scope_state_s state;
376376+ * os_activity_t activity = os_activity_create("my new activity", 0);
377377+ * os_activity_scope_enter(activity, &state);
378378+ * ... do some work ...
379379+ * os_activity_scope_leave(&state);
380380+ *
381381+ * To auto-cleanup state call:
382382+ *
383383+ * os_activity_scope(activity);
384384+ *
385385+ * @param activity
386386+ * Pass a valid activity created with os_activity_create or any global object.
387387+ *
388388+ * @param state
389389+ * A stack-based struct os_activity_scope_state_s to store the state.
390390+ */
391391+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
392392+OS_EXPORT OS_NOTHROW
393393+void
394394+os_activity_scope_enter(os_activity_t activity, os_activity_scope_state_t state);
395395+396396+/*!
397397+ * @function os_activity_scope_leave
398398+ *
399399+ * @abstract
400400+ * Will pop state up to the state provided.
401401+ *
402402+ * @discussion
403403+ * Will leave scope using the state provided. If state is not present an error will be
404404+ * generated.
405405+ *
406406+ * @param state
407407+ * Must be a valid value filled by os_activity_scope_enter call.
408408+ */
409409+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
410410+OS_EXPORT OS_NOTHROW
411411+void
412412+os_activity_scope_leave(os_activity_scope_state_t state);
413413+414414+#if defined(__GNUC__)
415415+#define _os_activity_scope(var, activity) \
416416+ struct os_activity_scope_state_s var __attribute__((__cleanup__(os_activity_scope_leave))); \
417417+ os_activity_scope_enter(activity, &var)
418418+#define os_activity_scope(activity) _os_activity_scope(OS_CONCAT(scope, __COUNTER__), activity)
419419+#endif
420420+421421+#endif // OS_ACTIVITY_OBJECT_API
422422+423423+/*!
424424+ * @function os_activity_start
425425+ *
426426+ * @abstract
427427+ * Starts a new activity immediately within the current context.
428428+ *
429429+ * @discussion
430430+ * Starts a new activity immediately within the current context. Deprecated please use new
431431+ * os_activity_create and os_activity_apply.
432432+ *
433433+ * os_activity_t activity = os_activity_start("indexing database", OS_ACTIVITY_FLAG_DEFAULT);
434434+ * < do some work >
435435+ * os_activity_end(activity);
436436+ *
437437+ * @param description
438438+ * A constant string describing the activity, e.g., "performClick" or
439439+ * "menuSelection".
440440+ *
441441+ * @param flags
442442+ * Flags to be used when initiating the activity, typically OS_ACTIVITY_FLAG_DEFAULT.
443443+ *
444444+ * @result
445445+ * Returns a valid os_activity_id_t or 0 on failure.
446446+ */
447447+#define os_activity_start(description, flags) __extension__({ \
448448+ OS_LOG_STRING(__description, description); \
449449+ os_activity_t _aid = _os_activity_start(&__dso_handle, __description, flags); \
450450+ _aid; \
451451+})
452452+453453+/*!
454454+ * @function os_activity_end
455455+ *
456456+ * @abstract
457457+ * Ends the specified activity on the current thread.
458458+ *
459459+ * @discussion
460460+ * Ends the specified activity on the current thread. Does not signify anything
461461+ * other than the originator has received control back from the activity. Work
462462+ * could still be in flight related to the activity.
463463+ *
464464+ * @param activity
465465+ * An os_activity_t returned from os_activity_start.
466466+ */
467467+__API_DEPRECATED("use combination of os_activity_create and os_activity_apply/os_activity_scope", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0))
468468+OS_EXPORT OS_NOTHROW
469469+void
470470+os_activity_end(os_activity_t activity);
471471+472472+/*!
473473+ * @function os_activity_get_active
474474+ *
475475+ * @abstract
476476+ * Returns the stack of nested activities associated with the current thread.
477477+ *
478478+ * @discussion
479479+ * Activities have a sense of nesting and therefore there could be more than
480480+ * one activity involved on the current thread. This should be used by
481481+ * diagnostic tools only for making additional decisions about a situation.
482482+ *
483483+ * @param entries
484484+ * Pass a buffer of sufficient size to hold the the number of os_activity_id_t
485485+ * being requested.
486486+ *
487487+ * @param count
488488+ * Pointer to the requested number of activity identifiers.
489489+ * On output will be filled with the number of activities that are available.
490490+ *
491491+ * @result
492492+ * Number of activity identifiers written to 'entries'
493493+ */
494494+__API_DEPRECATED("No longer supported", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0))
495495+OS_EXPORT OS_NOTHROW
496496+unsigned int
497497+os_activity_get_active(os_activity_id_t *entries, unsigned int *count);
498498+499499+/*!
500500+ * @function os_activity_get_identifier
501501+ *
502502+ * @abstract
503503+ * Returns the current activity ID and will fill the parent_id if present.
504504+ *
505505+ * @discussion
506506+ * Returns the current activity ID and will fill the parent_id if present.
507507+ *
508508+ * @param parent_id
509509+ * If non-null will set the parent activity ID.
510510+ *
511511+ * @result
512512+ * The identifier for the provided activity.
513513+ */
514514+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
515515+OS_EXPORT OS_NOTHROW OS_NONNULL1 OS_WARN_RESULT
516516+os_activity_id_t
517517+os_activity_get_identifier(os_activity_t activity, os_activity_id_t *parent_id);
518518+519519+/*!
520520+ * @function os_activity_label_useraction
521521+ *
522522+ * @abstract
523523+ * Label an activity that is auto-generated by AppKit/UIKit with a name that is useful
524524+ * for debugging macro-level user actions.
525525+ *
526526+ * @discussion
527527+ * Label an activity that is auto-generated by AppKit/UIKit with a name that is useful
528528+ * for debugging macro-level user actions. The API should be called early within the scope
529529+ * of the IBAction and before any sub-activities are created. The name provided will
530530+ * be shown in tools in additon to the underlying AppKit/UIKit provided name. This API
531531+ * can only be called once and only on the activity created by AppKit/UIKit. These actions
532532+ * help determine workflow of the user in order to reproduce problems that occur.
533533+ * For example, a control press and/or menu item selection can be labeled:
534534+ *
535535+ * os_activity_label_useraction("New mail message");
536536+ * os_activity_label_useraction("Empty trash");
537537+ *
538538+ * Where the underlying AppKit/UIKit name will be "gesture:" or "menuSelect:".
539539+ *
540540+ * @param name
541541+ * A constant string that describes the the action.
542542+ */
543543+#define os_activity_label_useraction(label) __extension__({ \
544544+ OS_LOG_STRING(__label, label); \
545545+ _os_activity_label_useraction(&__dso_handle, __label); \
546546+})
547547+548548+#pragma mark - application breadcrumbs
549549+550550+/*!
551551+ * @function os_activity_set_breadcrumb
552552+ *
553553+ * @abstract
554554+ * This flags the current activity as a "breadcrumb", i.e., an interesting event.
555555+ *
556556+ * @discussion
557557+ * Not all activities are interesting events at the macro-level. Some activities
558558+ * can be flagged as a breadcrumb for evalutating cross activity interactions.
559559+ * This can only be called once per activity, other requests will be ignored.
560560+ *
561561+ * @param name
562562+ * A constant string that describes the breadcrumb.
563563+ */
564564+#define os_activity_set_breadcrumb(name) __extension__({ \
565565+ OS_LOG_STRING(__name, name); \
566566+ _os_activity_set_breadcrumb(&__dso_handle, __name); \
567567+})
568568+569569+__END_DECLS
570570+571571+#endif // __OS_ACTIVITY_H__
+473
src/libc/os/log.h
···11+/*
22+ * Copyright (c) 2015-2016 Apple Inc. All rights reserved.
33+ *
44+ * @APPLE_LICENSE_HEADER_START@
55+ *
66+ * This file contains Original Code and/or Modifications of Original Code
77+ * as defined in and that are subject to the Apple Public Source License
88+ * Version 2.0 (the 'License'). You may not use this file except in
99+ * compliance with the License. Please obtain a copy of the License at
1010+ * http://www.opensource.apple.com/apsl/ and read it before using this
1111+ * file.
1212+ *
1313+ * The Original Code and all software distributed under the License are
1414+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1515+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
1616+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
1717+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
1818+ * Please see the License for the specific language governing rights and
1919+ * limitations under the License.
2020+ *
2121+ * @APPLE_LICENSE_HEADER_END@
2222+ */
2323+2424+#ifndef __os_log_h
2525+#define __os_log_h
2626+2727+#include <os/object.h>
2828+#include <os/base.h>
2929+#include <os/trace.h>
3030+#include <stdint.h>
3131+#include <stdbool.h>
3232+#include <mach-o/loader.h>
3333+3434+#if !__has_builtin(__builtin_os_log_format)
3535+#warning using os/log.h requires Xcode 8 or later
3636+#endif
3737+3838+__BEGIN_DECLS
3939+4040+#ifdef OS_LOG_FORMAT_WARNINGS
4141+#define OS_LOG_FORMAT_ERRORS _Pragma("clang diagnostic warning \"-Wformat\"")
4242+#else
4343+#define OS_LOG_FORMAT_ERRORS _Pragma("clang diagnostic error \"-Wformat\"")
4444+#endif
4545+4646+extern void* __dso_handle;
4747+4848+#if OS_OBJECT_SWIFT3
4949+OS_OBJECT_DECL_SWIFT(os_log);
5050+#elif OS_OBJECT_USE_OBJC
5151+OS_OBJECT_DECL(os_log);
5252+#else
5353+typedef struct os_log_s *os_log_t;
5454+#endif /* OS_OBJECT_USE_OBJC */
5555+5656+/*!
5757+ * @const OS_LOG_DISABLED
5858+ *
5959+ * @discussion
6060+ * Use this to disable a specific log message.
6161+ */
6262+#define OS_LOG_DISABLED NULL
6363+6464+/*!
6565+ * @const OS_LOG_DEFAULT
6666+ *
6767+ * @discussion
6868+ * Use this to log a message in accordance with current system settings.
6969+ */
7070+#define OS_LOG_DEFAULT OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_default)
7171+__API_AVAILABLE(macosx(10.11), ios(9.0), watchos(2.0), tvos(9.0))
7272+OS_EXPORT
7373+struct os_log_s _os_log_default;
7474+7575+/*!
7676+ * @enum os_log_type_t
7777+ *
7878+ * @discussion
7979+ * Supported log message types.
8080+ *
8181+ * @constant OS_LOG_TYPE_DEFAULT
8282+ * Equivalent type for "os_log()" messages, i.e., default messages that are always
8383+ * captured to memory or disk.
8484+ *
8585+ * @constant OS_LOG_TYPE_INFO
8686+ * Equivalent type for "os_log_info()" messages, i.e., Additional informational messages.
8787+ *
8888+ * @constant OS_LOG_TYPE_DEBUG
8989+ * Equivalent type for "os_log_debug()" messages, i.e., Debug messages.
9090+ *
9191+ * @constant OS_LOG_TYPE_ERROR
9292+ * Equivalent type for "os_log_error()" messages, i.e., local process error messages.
9393+ *
9494+ * @constant OS_LOG_TYPE_FAULT
9595+ * Equivalent type for "os_log_fault()" messages, i.e., a system error that involves
9696+ * potentially more than one process, usually used by daemons and services.
9797+ */
9898+OS_ENUM(os_log_type, uint8_t,
9999+ OS_LOG_TYPE_DEFAULT = 0x00,
100100+ OS_LOG_TYPE_INFO = 0x01,
101101+ OS_LOG_TYPE_DEBUG = 0x02,
102102+ OS_LOG_TYPE_ERROR = 0x10,
103103+ OS_LOG_TYPE_FAULT = 0x11);
104104+105105+/*!
106106+ * @function os_log_create
107107+ *
108108+ * @abstract
109109+ * Creates a log object to be used with other log related functions.
110110+ *
111111+ * @discussion
112112+ * Creates a log object to be used with other log related functions. The
113113+ * log object serves two purposes: (1) tag related messages by subsystem
114114+ * and category name for easy filtering, and (2) control logging system
115115+ * behavior for messages. The log object may be NULL if logging is disabled
116116+ * on the system.
117117+ *
118118+ * @param subsystem
119119+ * The identifier of the given subsystem should be in reverse DNS form
120120+ * (i.e., com.company.mysubsystem).
121121+ *
122122+ * @param category
123123+ * The category within the given subsystem that specifies the settings for
124124+ * the log object.
125125+ *
126126+ * @result
127127+ * Returns an os_log_t value to be passed to other os_log API calls. This
128128+ * should be called once at log initialization and rely on system to detect
129129+ * changes to settings. This object should be released when no longer used
130130+ * via os_release or -[release] method.
131131+ *
132132+ * A value will always be returned to allow for dynamic enablement.
133133+ */
134134+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
135135+OS_EXPORT OS_NOTHROW OS_WARN_RESULT OS_OBJECT_RETURNS_RETAINED OS_NONNULL_ALL
136136+os_log_t
137137+os_log_create(const char *subsystem, const char *category);
138138+139139+/*!
140140+ * @function os_log_info_enabled
141141+ *
142142+ * @abstract
143143+ * Returns if additional information is enabled,
144144+ *
145145+ * @discussion
146146+ * Returns if additional information is enabled,
147147+ *
148148+ * @param log
149149+ * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
150150+ *
151151+ * @result
152152+ * Returns ‘true’ if debug log messages are enabled.
153153+ */
154154+#define os_log_info_enabled(log) os_log_type_enabled(log, OS_LOG_TYPE_INFO)
155155+156156+/*!
157157+ * @function os_log_debug_enabled
158158+ *
159159+ * @abstract
160160+ * Returns if debug log messages are enabled for a particular log object.
161161+ *
162162+ * @discussion
163163+ * Returns if debug log messages are enabled for a particular log object.
164164+ *
165165+ * @param log
166166+ * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
167167+ *
168168+ * @result
169169+ * Returns ‘true’ if debug log messages are enabled.
170170+ */
171171+#define os_log_debug_enabled(log) os_log_type_enabled(log, OS_LOG_TYPE_DEBUG)
172172+173173+/*!
174174+ * @function os_log_with_type
175175+ *
176176+ * @abstract
177177+ * Log a message using a specific type.
178178+ *
179179+ * @discussion
180180+ * Will log a message with the provided os_log_type_t.
181181+ *
182182+ * @param log
183183+ * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
184184+ *
185185+ * @param type
186186+ * Pass a valid type from os_log_type_t.
187187+ *
188188+ * @param format
189189+ * A format string to generate a human-readable log message when the log
190190+ * line is decoded. This string must be a constant string, not dynamically
191191+ * generated. Supports all standard printf types in addition to %@ (objects).
192192+ */
193193+#if !__has_builtin(__builtin_os_log_format)
194194+#define os_log_with_type(log, type, format, ...)
195195+#else
196196+#define os_log_with_type(log, type, format, ...) __extension__({ \
197197+ if (os_log_type_enabled(log, type)) { \
198198+ _Pragma("clang diagnostic push") \
199199+ _Pragma("clang diagnostic ignored \"-Wvla\"") \
200200+ OS_LOG_FORMAT_ERRORS \
201201+ __attribute__((section("__TEXT,__oslogstring,cstring_literals"),internal_linkage)) static const char __format[] __asm(OS_STRINGIFY(OS_CONCAT(LOSLOG_, __COUNTER__))) = format; \
202202+ uint8_t _os_log_buf[__builtin_os_log_format_buffer_size(format, ##__VA_ARGS__)]; \
203203+ _os_log_impl(&__dso_handle, log, type, __format, (uint8_t *) __builtin_os_log_format(_os_log_buf, format, ##__VA_ARGS__), (unsigned int) sizeof(_os_log_buf)); \
204204+ _Pragma("clang diagnostic pop") \
205205+ } \
206206+})
207207+#endif
208208+209209+/*!
210210+ * @function os_log
211211+ *
212212+ * @abstract
213213+ * Insert a log message into the Unified Logging and Tracing system.
214214+ *
215215+ * @discussion
216216+ * Insert a log message into the Unified Logging and Tracing system in
217217+ * accordance with the preferences specified by the provided log object.
218218+ * These messages cannot be disabled and therefore always captured either
219219+ * to memory or disk.
220220+ *
221221+ * When an os_activity_id_t is present, the log message will also be scoped by
222222+ * that identifier. Activities provide granular filtering of log messages
223223+ * across threads and processes.
224224+ *
225225+ * There is a physical cap of 1024 bytes per log line for dynamic content,
226226+ * such as %s and %@, that can be written to the persistence store.
227227+ * All content exceeding the limit will be truncated before it is
228228+ * written to disk.
229229+ *
230230+ * @param log
231231+ * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
232232+ *
233233+ * @param format
234234+ * A format string to generate a human-readable log message when the log
235235+ * line is decoded. This string must be a constant string, not dynamically
236236+ * generated. Supports all standard printf types and %@ (objects).
237237+ */
238238+#define os_log(log, format, ...) os_log_with_type(log, OS_LOG_TYPE_DEFAULT, format, ##__VA_ARGS__)
239239+240240+/*!
241241+ * @function os_log_info
242242+ *
243243+ * @abstract
244244+ * Insert an additional information log message into the Unified Logging
245245+ * and Tracing system.
246246+ *
247247+ * @discussion
248248+ * Insert a log message into the Unified Logging and Tracing system in
249249+ * accordance with the preferences specified by the provided log object.
250250+ *
251251+ * When an os_activity_id_t is present, the log message will also be scoped by
252252+ * that identifier. Activities provide granular filtering of log messages
253253+ * across threads and processes.
254254+ *
255255+ * There is a physical cap of 256 bytes per entry for dynamic content,
256256+ * i.e., %s and %@, that can be written to the persistence store. As such,
257257+ * all content exceeding the limit will be truncated before written to disk.
258258+ * Live streams will continue to show the full content.
259259+ *
260260+ * @param log
261261+ * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
262262+ *
263263+ * @param format
264264+ * A format string to generate a human-readable log message when the log
265265+ * line is decoded. This string must be a constant string, not dynamically
266266+ * generated. Supports all standard printf types and %@ (objects).
267267+ */
268268+#define os_log_info(log, format, ...) os_log_with_type(log, OS_LOG_TYPE_INFO, format, ##__VA_ARGS__)
269269+270270+/*!
271271+ * @function os_log_debug
272272+ *
273273+ * @abstract
274274+ * Insert a debug log message into the Unified Logging and Tracing system.
275275+ *
276276+ * @discussion
277277+ * Insert a debug log message into the Unified Logging and Tracing system in
278278+ * accordance with the preferences specified by the provided log object.
279279+ *
280280+ * When an os_activity_id_t is present, the log message will also be scoped by
281281+ * that identifier. Activities provide granular filtering of log messages
282282+ * across threads and processes.
283283+ *
284284+ * There is a physical cap of 256 bytes per entry for dynamic content,
285285+ * i.e., %s and %@, that can be written to the persistence store. As such,
286286+ * all content exceeding the limit will be truncated before written to disk.
287287+ * Live streams will continue to show the full content.
288288+ *
289289+ * @param log
290290+ * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
291291+ *
292292+ * @param format
293293+ * A format string to generate a human-readable log message when the log
294294+ * line is decoded. This string must be a constant string, not dynamically
295295+ * generated. Supports all standard printf types and %@ (objects).
296296+ */
297297+#define os_log_debug(log, format, ...) os_log_with_type(log, OS_LOG_TYPE_DEBUG, format, ##__VA_ARGS__)
298298+299299+/*!
300300+ * @function os_log_error
301301+ *
302302+ * @abstract
303303+ * Insert an error log message into the Unified Logging and Tracing system.
304304+ *
305305+ * @discussion
306306+ * Insert an error log message into the Unified Logging and Tracing system.
307307+ *
308308+ * When an os_activity_id_t is present, the log message will also be scoped by
309309+ * that identifier. Activities provide granular filtering of log messages
310310+ * across threads and processes.
311311+ *
312312+ * There is a physical cap of 256 bytes per entry for dynamic content,
313313+ * i.e., %s and %@, that can be written to the persistence store. As such,
314314+ * all content exceeding the limit will be truncated before written to disk.
315315+ * Live streams will continue to show the full content.
316316+ *
317317+ * @param log
318318+ * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
319319+ *
320320+ * @param format
321321+ * A format string to generate a human-readable log message when the log
322322+ * line is decoded. This string must be a constant string, not dynamically
323323+ * generated. Supports all standard printf types and %@ (objects).
324324+ */
325325+#define os_log_error(log, format, ...) os_log_with_type(log, OS_LOG_TYPE_ERROR, format, ##__VA_ARGS__)
326326+327327+/*!
328328+ * @function os_log_fault
329329+ *
330330+ * @abstract
331331+ * Insert a fault log message into the Unified Logging and Tracing system.
332332+ *
333333+ * @discussion
334334+ * Log a fault message issue into the Unified Logging and Tracing system
335335+ * signifying a multi-process (i.e., system error) related issue, either
336336+ * due to interaction via IPC or some other. Faults will gather information
337337+ * from the entire process chain and record it for later inspection.
338338+ *
339339+ * When an os_activity_id_t is present, the log message will also be scoped by
340340+ * that identifier. Activities provide granular filtering of log messages
341341+ * across threads and processes.
342342+ *
343343+ * There is a physical cap of 256 bytes per entry for dynamic content,
344344+ * i.e., %s and %@, that can be written to the persistence store. As such,
345345+ * all content exceeding the limit will be truncated before written to disk.
346346+ * Live streams will continue to show the full content.
347347+ *
348348+ * @param log
349349+ * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
350350+ *
351351+ * @param format
352352+ * A format string to generate a human-readable log message when the log
353353+ * line is decoded. This string must be a constant string, not dynamically
354354+ * generated. Supports all standard printf types and %@ (objects).
355355+ */
356356+#define os_log_fault(log, format, ...) os_log_with_type(log, OS_LOG_TYPE_FAULT, format, ##__VA_ARGS__)
357357+358358+/*!
359359+ * @function os_log_type_enabled
360360+ *
361361+ * @abstract
362362+ * Evaluate if a specific log type is enabled before doing work
363363+ *
364364+ * @discussion
365365+ * Evaluate if a specific log type is enabled before doing work
366366+ *
367367+ * @param log
368368+ * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
369369+ *
370370+ * @param type
371371+ * Pass a valid type from os_log_type_t.
372372+ *
373373+ * @result
374374+ * Will return a boolean.
375375+ */
376376+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
377377+OS_EXPORT OS_NOTHROW OS_WARN_RESULT
378378+bool
379379+os_log_type_enabled(os_log_t oslog, os_log_type_t type);
380380+381381+/*!
382382+ * @function _os_log_impl
383383+ *
384384+ * @abstract
385385+ * Internal function that takes compiler generated encoding and captures the necessary content.
386386+ */
387387+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
388388+OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED
389389+void
390390+_os_log_impl(void *dso, os_log_t log, os_log_type_t type, const char *format, uint8_t *buf, unsigned int size);
391391+392392+/*
393393+ * Support for older iteration of API for source compatibility only...
394394+ */
395395+396396+__API_DEPRECATED("no longer supported, use os_log_debug(OS_LOG_DEFAULT, ...)", macosx(10.11,10.12), ios(9.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0))
397397+OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED
398398+void
399399+_os_log_internal(void *dso, os_log_t log, os_log_type_t type, const char *message, ...);
400400+401401+__API_AVAILABLE(macosx(10.11), ios(9.0), watchos(2.0), tvos(9.0))
402402+OS_EXPORT OS_NOTHROW OS_WARN_RESULT OS_OBJECT_RETURNS_RETAINED OS_NOT_TAIL_CALLED OS_NONNULL_ALL
403403+os_log_t
404404+_os_log_create(void *dso, const char *subsystem, const char *category);
405405+406406+__API_DEPRECATED("no longer suppored - always returns true", macosx(10.11,10.12), ios(9.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0))
407407+OS_EXPORT OS_NOTHROW OS_WARN_RESULT
408408+bool
409409+os_log_is_enabled(os_log_t log);
410410+411411+__API_DEPRECATED_WITH_REPLACEMENT("os_log_debug_enabled", macosx(10.11,10.12), ios(9.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0))
412412+OS_EXPORT OS_NOTHROW OS_WARN_RESULT
413413+bool
414414+os_log_is_debug_enabled(os_log_t log);
415415+416416+__API_DEPRECATED("no longer supported - use os_log with per-parameter privacy options", macosx(10.11,10.12), ios(9.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0))
417417+OS_NOTHROW OS_ALWAYS_INLINE
418418+static inline void
419419+_os_log_sensitive_deprecated(void) { }
420420+421421+#define os_log_sensitive(log, format, ...) __extension__({ \
422422+ os_log_with_type(log, OS_LOG_TYPE_DEFAULT, format, ##__VA_ARGS__); \
423423+ _os_log_sensitive_deprecated(); \
424424+})
425425+426426+#define os_log_sensitive_debug(log, format, ...) __extension__({ \
427427+ os_log_with_type(log, OS_LOG_TYPE_DEBUG, format, ##__VA_ARGS__); \
428428+ _os_log_sensitive_deprecated(); \
429429+})
430430+431431+#define OS_LOG_RELEASE OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_release)
432432+__API_DEPRECATED("use os_log(OS_LOG_DEFAULT, ...)", macosx(10.11,10.11), ios(9.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0))
433433+OS_EXPORT
434434+struct os_log_s _os_log_release;
435435+436436+#define OS_LOG_DEBUG OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_debug)
437437+__API_DEPRECATED("use os_log_debug(OS_LOG_DEFAULT, ...)", macosx(10.11,10.11), ios(9.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0))
438438+OS_EXPORT
439439+struct os_log_s _os_log_debug;
440440+441441+#define OS_LOG_ERROR OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_error)
442442+__API_DEPRECATED("use os_log_error(OS_LOG_DEFAULT, ...)", macosx(10.11,10.11), ios(9.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0))
443443+OS_EXPORT
444444+struct os_log_s _os_log_error;
445445+446446+#define OS_LOG_FAULT OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_fault)
447447+__API_DEPRECATED("use os_log_fault(OS_LOG_DEFAULT, ...)", macosx(10.11,10.11), ios(9.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0))
448448+OS_EXPORT
449449+struct os_log_s _os_log_fault;
450450+451451+#if ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12) \
452452+ || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(__TV_OS_VERSION_MIN_REQUIRED) \
453453+ && !defined(__WATCH_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0) \
454454+ || (defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < __TVOS_10_0) \
455455+ || (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && __WATCH_OS_VERSION_MIN_REQUIRED < __WATCHOS_3_0))
456456+#undef os_log_with_type
457457+#define os_log_with_type(log, type, format, ...) __extension__({ \
458458+ _Pragma("clang diagnostic push") \
459459+ _Pragma("clang diagnostic error \"-Wformat\"") \
460460+ _os_log_internal(&__dso_handle, log, type, format, ##__VA_ARGS__); \
461461+ _Pragma("clang diagnostic pop") \
462462+})
463463+464464+#undef os_log_debug_enabled
465465+#define os_log_debug_enabled(...) os_log_is_debug_enabled(__VA_ARGS__)
466466+467467+#undef os_log_create
468468+#define os_log_create(subsystem, category) _os_log_create(&__dso_handle, subsystem, category)
469469+#endif
470470+471471+__END_DECLS
472472+473473+#endif /* __os_log_h */