lib: assign a unique ID to each pre/postcond. and report it on failure
[babeltrace.git] / doc / api / libbabeltrace2 / dox / api-fund.dox
... / ...
CommitLineData
1/*!
2@page api-fund API fundamentals
3
4This page explains the basic principles of the \bt_api.
5
6You \em must understand what the API expects before you create a
7\bt_name \bt_plugin or an application which uses the API.
8
9@section api-fund-header Header file
10
11To use the \bt_api, include <code>%babeltrace2/babeltrace.h</code>:
12
13@code
14#include <babeltrace2/babeltrace.h>
15@endcode
16
17Do \em not include any other header file found in the \c babeltrace2
18directory: the compiler prints an error when you try to.
19
20@section api-fund-ns Namespace
21
22- All libbabeltrace2 functions and types start with \c bt_.
23
24- All libbabeltrace2 definitions, macros, and enumerators start
25 with \c BT_.
26
27@section api-fund-pre-post Function contract checking
28
29All the functions of libbabeltrace2 check that the caller meets their
30<a href="https://en.wikipedia.org/wiki/Precondition">preconditions</a>.
31
32All the functions of libbabeltrace2 which call a user function check
33that it meets its
34<a href="https://en.wikipedia.org/wiki/Postcondition">postconditions</a>
35when it returns.
36
37The function descriptions in the
38<a class="el" href="modules.html">API reference modules</a>
39list all their preconditions and postconditions, if any.
40
41The libbabeltrace2 public functions offer a
42<strong>narrow contract</strong>: when you break it, the library
43prints how the precondition or postcondition was not satisfied, with
44details, and then calls <code>abort()</code>.
45
46Here's an example of what the library prints to the standard error
47before aborting when you break a precondition (call
48bt_value_bool_set() with a \c NULL value);
49\ref api-fund-logging "logging" prefixes are removed for clarity:
50
51@code{.unparsed}
52Babeltrace 2 library precondition not satisfied.
53------------------------------------------------------------------------
54Condition ID: `pre:value-bool-set:not-null:value-object`.
55Function: bt_value_bool_set().
56------------------------------------------------------------------------
57Error is:
58Value object is NULL.
59Aborting...
60@endcode
61
62In the output above:
63
64- <code>pre:value-bool-set:not-null:value-object</code> is the unique,
65 permanent ID of this precondition.
66
67 We use this ID for internal libbabeltrace2 testing.
68
69- The <code>Function:</code> line shows which function's contract was
70 broken.
71
72Because precondition and postcondition checks detect programming errors,
73libbabeltrace2's approach is to abort as soon as possible so that you
74fix the error. Therefore, the libbabeltrace2 functions never return a
75programming error status (like what \c EINVAL means on Unix systems, for
76example).
77
78@attention
79 Some precondition and postcondition checks which occur on the fast
80 path and which would therefore significantly impact performance
81 during a typical trace processing \bt_graph run are only enabled in
82 \ref guide-build-bt2-dev "developer mode".
83
84Common function preconditions are:
85
86- A pointer parameter is not \c NULL.
87
88- An index parameter is not ouf of bounds.
89
90- A string or container parameter is not empty.
91
92- An object parameter has a given conceptual type. For example, you
93 cannot call bt_value_array_get_length() with a
94 \bt_bool_val.
95
96- An object parameter is not \ref api-fund-freezing "frozen".
97
98- An object parameter has some specific state.
99
100@section api-fund-object Object model
101
102The \bt_api is
103<a href="https://en.wikipedia.org/wiki/Object-oriented_programming">object-oriented</a>.
104
105With a few exceptions, API functions are actually
106<a href="https://en.wikipedia.org/wiki/Method_(computer_programming)"><em>methods</em></a>
107which operate on objects: their first parameter points to said object.
108For example:
109
110@code
111uint64_t bt_value_array_get_length(const bt_value *value);
112@endcode
113
114You can create some types of objects with functions that contain the
115word \c create, while for some other types, only the library can create
116them behind the scenes. For example, you can create a
117\bt_bool_val object with bt_value_bool_create(), but you cannot directly
118create a \bt_ev object: you need to borrow one from a \bt_ev_msg which
119contains it.
120
121Each type of object has its own C type. Learn more about typing in
122\ref api-fund-c-typing below.
123
124Some types of objects conceptually inherit other types of objects. If an
125object type A inherits an object type B, then you can use both the A and
126B API functions with an object of type A. For example, because an
127\bt_enum_fc \em is conceptually an \bt_int_fc, you can use any integer
128field class function with an enumeration field class.
129The <a class="el" href="modules.html">API reference modules</a> always
130indicate the inheritance relations.
131
132@subsection api-fund-object-shared-unique Shared vs. unique objects
133
134Some \bt_name objects are \em shared while some others are \em unique:
135
136<dl>
137 <dt>\anchor api-fund-shared-object Shared object</dt>
138 <dd>
139 A \em shared object has a <a
140 href="https://en.wikipedia.org/wiki/Reference_counting">reference
141 count</a>.
142
143 A shared object's creation function returns a \em new reference.
144
145 The API of a given shared object type contains:
146
147 - A function to get a new reference, increasing the reference count,
148 which ends with \c _get_ref.
149
150 - A function to put an existing reference, decreasing the reference
151 count, which ends with \c _put_ref.
152
153 - A macro to put an existing reference and then set the passed
154 expression to \c NULL. This macro ends with \c _PUT_REF_AND_RESET.
155
156 - A macro to move an existing reference from a source expression to
157 a destination expression, putting the destination expression's
158 existing reference, and setting the source expression to \c NULL.
159 This macro ends with \c _MOVE_REF.
160
161 For example, bt_value_get_ref() and bt_value_put_ref() get and put
162 \bt_val object references, BT_VALUE_PUT_REF_AND_RESET() puts a
163 value reference and sets the expression to \c NULL, and
164 BT_VALUE_MOVE_REF() moves a value reference.
165
166 All <code>*_get_ref()</code> and <code>*_put_ref()</code> functions,
167 and all <code>*_PUT_REF_AND_RESET()</code> macros accept a \c NULL
168 parameter.
169
170 When the reference count of a given object reaches zero, it \em can
171 be destroyed. Some shared objects, however, have a lifetime that is
172 managed by another shared object. For example, an \bt_ev_cls is not
173 destroyed until its parent \bt_stream_cls is also destroyed, even if
174 its reference count technically reaches zero.
175
176 A function which accepts a shared object never "takes" or steals the
177 caller's reference unless its name contains the word \c move: you
178 still have your own reference when the function returns. For
179 example:
180
181 @code
182 bt_event_class *event_class = bt_event_class_create(stream_class);
183
184 /*
185 * At this point, we still have a reference of `stream_class`.
186 * We need to put it with bt_stream_class_put_ref() at some point.
187 */
188 @endcode
189
190 A function which contains the word \c borrow returns a
191 <em>borrowed reference</em>: if you need your own reference, get
192 one with the appropriate <code>*_get_ref()</code> function.
193 </dd>
194
195 <dt>\anchor api-fund-unique-object Unique object</dt>
196 <dd>
197 A \em unique object does not have a reference count: another object
198 is always its sole owner.
199
200 Because you cannot get a new unique object reference, you \em must
201 ensure that you own the unique object's owner to keep it alive. The
202 <a class="el" href="modules.html">API reference modules</a> make it
203 clear, depending on the context, which
204 shared object is the ultimate owner of a given unique object.
205
206 In general, you cannot create a unique object: the library creates
207 it, and then you \em borrow it from another object (shared or unique
208 itself).
209
210 Unique objects exist for performance reasons: some optimizations are
211 challenging to implement without this concept.
212 </dd>
213</dl>
214
215In the <a class="el" href="modules.html">API reference</a>, each module
216indicates whether the documented objects are shared or unique.
217
218@subsection api-fund-freezing Object freezing
219
220The library can \em freeze some types of \bt_name objects when specific
221functions succeed.
222
223A frozen object is immutable: trying to set an object's property once
224it's frozen represents a \ref api-fund-pre-post "precondition" break.
225
226For example, the library freezes the source \bt_comp initialization
227parameters when you call bt_graph_add_source_component(): this
228guarantees to the component's
229\ref api-comp-cls-dev-meth-init "initialization method" that the
230parameters will never change for the rest of their lifetime.
231
232When an object becomes frozen, its contained objects, if any, also
233become frozen, recursively.
234
235There's no function to check whether or not a given object is frozen.
236Because the <a class="el" href="modules.html">API reference modules</a>
237document which functions freeze which objects,
238the "frozen" property is only useful for libbabeltrace2 to catch
239programming errors (\ref api-fund-pre-post "precondition checks").
240
241@attention
242 Some "frozen" property checks which occur on the fast path and which
243 would therefore significantly impact performance during a typical trace
244 processing \bt_graph run are only enabled in
245 \ref guide-build-bt2-dev "developer mode".
246
247@section api-fund-c-typing C typing
248
249The \bt_api typing system is very strict to catch many programming
250errors at compile time.
251
252Each type of object has its own C type. Consequently, functions accept
253and return specific C types. For example, all the \bt_ev functions
254accept a #bt_event pointer.
255
256The API uses
257<a href="https://en.wikipedia.org/wiki/Opaque_pointer">opaque pointers</a>,
258so that you don't having access to the object type's actual C structure.
259This helps with the development of features and fixes in future releases
260of \bt_name.
261
262Some objects share the same C type when different conceptual types can
263be contained in some collection. For example, all \bt_val objects have
264the type #bt_value because an \bt_array_val can contain different
265types of values. You must be careful to only call the functions which
266apply to a specific type of such objects.
267The <a class="el" href="modules.html">API reference modules</a> make
268this clear in the precondition section. Such objects always have a
269<code>*_get_type()</code> function to get the object's exact type
270enumerator. For example, bt_value_get_type() returns the type enumerator
271of a given \bt_val object.
272
273When an object type A conceptually inherits an object type B, and when A
274and B have different C types, the API offers a dedicated, inline
275upcasting function named <code>bt_A_as_B()</code> to have access to the B
276API at no cost. For example, an \bt_uenum_fc mapping \em is conceptually
277an \bt_enum_fc mapping, but they have different C types:
278#bt_field_class_enumeration_unsigned_mapping and
279#bt_field_class_enumeration_mapping. Get the latter from the former with
280bt_field_class_enumeration_unsigned_mapping_as_mapping_const().
281The <code>bt_A_as_B()</code> functions do not change the object's
282reference count and they accept \c NULL.
283
284@attention
285 \b Never directly cast a \bt_name object pointer from some C type to
286 another C type: the API is designed so that you never need to do
287 that.
288
289@subsection api-fund-const const correctness
290
291The \bt_api is <code>const</code>-correct: when a function has a
292\c const object pointer parameter, it never modifies that object from
293the user's viewpoint.
294
295As such, when a function returns a \c const object pointer, directly or
296through an output parameter, you can't modify the object.
297
298@attention
299 \b Never remove a \bt_name object pointer's \c const qualifier. The
300 API is designed so that you never need to do that.
301
302Functions which accept or return a \c const object pointer end with
303\c _const when they have (or could have in the future) a non \c const
304equivalent. For example, bt_value_map_borrow_entry_value_const() is the
305\c const version of bt_value_map_borrow_entry_value().
306
307Simple property getter functions do not end with \c _const.
308
309\ref api-fund-shared-object "Reference count" changing functions, ending
310with \c _get_ref and \c _put_ref(), accept a \c const object pointer
311parameter: the library does not consider that an object's nature is
312altered when its reference count changes.
313
314@subsection api-fund-int-types C integer types
315
316The API only uses \c uint64_t and \c int64_t as C integer types for
317clarity and consistency.
318
319@subsection api-fund-common-types Common C types and definitions
320
321There are a few C types and definitions which are common to many parts
322of the \bt_api.
323
324See \ref api-common-types.
325
326@section api-fund-func-status Function return
327
328libbabeltrace2 functions which cannot fail return a property or an
329object pointer directly. For example, bt_value_array_get_length()
330returns the length of an \bt_array_val, and
331bt_value_array_borrow_element_by_index_const() returns a \bt_val
332contained in an \bt_array_val. Both functions cannot fail: any
333programming error \ref api-fund-pre-post "makes the program abort".
334
335When a function returns an optional property or object:
336
337<dl>
338 <dt>If it's a pointer</dt>
339 <dd>
340 The function returns \c NULL if the property/object is missing.
341 </dd>
342
343 <dt>If it's not a pointer</dt>
344 <dd>
345 <dl>
346 <dt>If the property is available</dt>
347 <dd>
348 The function returns the property by output parameter and returns
349 #BT_PROPERTY_AVAILABILITY_AVAILABLE.
350 </dd>
351
352 <dt>If the property is not available</dt>
353 <dd>
354 The function returns #BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE.
355 </dd>
356 </dl>
357 </dd>
358</dl>
359
360Many libbabeltrace2 functions return a status code, that is, a C
361enumerator containing the word \c STATUS. For example,
362bt_value_copy() returns either #BT_VALUE_COPY_STATUS_OK or
363#BT_VALUE_COPY_STATUS_MEMORY_ERROR.
364
365Although the API guarantees that any status enumerator which has the
366\c _OK status has the value 0, we recommend that you compare the
367returned value to exact status enumerators for clarity, for example:
368
369@code
370bt_value_copy_status status = bt_value_copy(obj, &val_copy);
371
372if (status != BT_VALUE_COPY_STATUS_OK) {
373 /* handle error */
374}
375@endcode
376
377The <a class="el" href="modules.html">API reference modules</a>
378document, for each function, what each return status enumerator means.
379
380Some functions return properties or objects by output parameter. When
381such a function which accepts a property or object pointer \c ptr fails,
382the library does \em not guarantee that <code>*ptr</code> remains
383unchanged. Therefore, such a pattern is \em not safe:
384
385@code
386bt_some_object *some_object = NULL;
387
388status = bt_get_some_object(obj, &some_object);
389
390if (some_object) {
391 /* ... */
392}
393@endcode
394
395Always rely on the returned status code:
396
397@code
398bt_some_object *some_object;
399
400status = bt_get_some_object(obj, &some_object);
401
402if (status == BT_GET_SOME_OBJECT_STATUS_OK) {
403 /* ... */
404}
405@endcode
406
407@section api-fund-user-classes User classes
408
409The whole \bt_name project is about extensibility: you can implement
410\bt_p_comp_cls, and then package and distribute them as
411\bt_p_plugin.
412
413When you implement a \bt_name \bt_comp_cls, you override protected
414methods, just like you would do in any
415<a href="https://en.wikipedia.org/wiki/Object-oriented_programming">object-oriented programming</a>
416(OOP) language.
417
418Here's the mapping of typical OOP language features to the
419\bt_name library domain:
420
421<table>
422 <tr>
423 <th>OOP concept
424 <th>\bt_name equivalent
425 <tr>
426 <td>User class.
427 <td>
428 Class object with implemented user functions.
429
430 For example: #bt_component_class_source.
431 <tr>
432 <td>User class instance.
433 <td>
434 Instance object, created from a class object.
435
436 For example: #bt_component_source.
437 <tr>
438 <td>
439 Instance pointer (\c this keyword in C++/Java and \c self variable
440 in Python, for example).
441 <td>
442 "Self" (private) object.
443
444 A "self" object has a specific, dedicated C type which starts
445 with <code>bt_self_</code>.
446
447 For example: #bt_self_component_source.
448 <tr>
449 <td>Protected, final method.
450 <td>
451 Library function accepting an instance pointer ("self" object) as
452 its first parameter.
453
454 Those functions always start with <code>bt_self_</code>.
455
456 For example: bt_self_component_source_add_output_port().
457 <tr>
458 <td>Protected, overridable method.
459 <td>
460 User function with a specific signature, accepting an instance
461 pointer ("self" object) as its first parameter.
462
463 For example: #bt_component_class_source_initialize_method.
464 <tr>
465 <td>Private user method.
466 <td>
467 Custom \c static user function having access to the instance
468 pointer ("self" object) somehow.
469 <tr>
470 <td>Private user property or attribute.
471 <td>
472 Custom \bt_voidp data which you set and get using
473 dedicated protected methods (for example,
474 bt_self_component_set_data() and bt_self_component_get_data()).
475</table>
476
477@section api-fund-error Error reporting
478
479libbabeltrace2 features a rich \ref api-error "error reporting"
480mechanism to augment an error with custom causes without having to
481explicitly pass an error object to the library functions.
482
483When a library function or \ref api-fund-user-classes "user method"
484returns an error status code (any status enumerator which contains
485the word \c ERROR), it \em can add one or more error causes to the
486current thread's error object.
487
488This makes it possible for the end user to understand the contexts which
489lead to the error, possibly across many \bt_p_plugin written by
490different developers.
491
492An error cause contains information about the source location where the
493error occurred, the actor involved in the error, and a message.
494
495When you "catch" an error, that is, react to a function returning an
496error status code without returning an error status code yourself,
497you can:
498
499- Take the current thread's error with bt_current_thread_take_error() to
500 get its causes, possibly presenting them to the end user.
501
502 You then need to release the error with bt_error_release().
503
504- Clear the current thread's error with bt_current_thread_clear_error().
505
506@attention
507 You \em cannot call any libbabeltrace2 function when the current
508 thread has an error, except the
509 \ref api-fund-shared-object "reference counting" functions (ending
510 with <code>_get_ref()</code> or <code>_put_ref()</code>).
511
512The
513<a href="https://babeltrace.org/docs/v\bt_version_min_maj/man1/babeltrace2.1"><code>babeltrace2</code></a>
514CLI uses this feature to pretty-print an error's causes to the end user,
515for example:
516
517@code{.unparsed}
518ERROR: [Babeltrace CLI] (babeltrace2.c:2521)
519 Cannot create components.
520CAUSED BY [Babeltrace CLI] (babeltrace2.c:2336)
521 Cannot create component: plugin-name="ctf", comp-cls-name="fs", comp-cls-type=0,
522 comp-name="auto-disc-source-ctf-fs"
523CAUSED BY [libbabeltrace2] (graph.c:1343)
524 Component initialization method failed: status=ERROR, comp-addr=0x562fbd275f40,
525 comp-name="auto-disc-source-ctf-fs", comp-log-level=WARNING, comp-class-type=SOURCE,
526 comp-class-name="fs", comp-class-partial-descr="Read CTF traces from the file sy",
527 comp-class-is-frozen=1, comp-class-so-handle-addr=0x562fbd285810,
528 comp-class-so-handle-path="/usr/lib/babeltrace2/plugins/babeltrace-plugin-ctf.so",
529 comp-input-port-count=0, comp-output-port-count=0
530CAUSED BY [auto-disc-source-ctf-fs: 'source.ctf.fs'] (fs.c:1148)
531 Cannot create trace for `/path/to/trace`.
532CAUSED BY [auto-disc-source-ctf-fs: 'source.ctf.fs'] (fs.c:928)
533 Cannot add stream file `/path/to/trace/channel0_1` to stream file group
534CAUSED BY [auto-disc-source-ctf-fs: 'source.ctf.fs'] (fs.c:734)
535 Cannot get stream file's first packet's header and context fields (`/path/to/trace/channel0_1`).
536@endcode
537
538@section api-fund-logging Logging
539
540libbabeltrace2 contains many hundreds of logging statements to help you
541follow and debug your \bt_plugin or program.
542
543By default, the library's logging is disabled. To enable it, use
544bt_logging_set_global_level().
545
546To set the library's initial logging level (checked once at library
547loading time), set the \c LIBBABELTRACE2_INIT_LOG_LEVEL environment
548variable, with one of:
549
550- \c N or \c NONE
551- \c F or \c FATAL
552- \c E or \c ERROR
553- \c W, \c WARN, or \c WARNING
554- \c I or \c INFO
555- \c D or \c DEBUG
556- \c T or \c TRACE
557
558By default, the minimal, build-time logging level is \em DEBUG. We
559recommend that you build libbabeltrace2 with the \em TRACE minimal
560logging level for development. See \ref guide-build-bt2-dev.
561
562libbabeltrace2 writes its logging statements to the standard error
563stream.
564
565A libbabeltrace2 (and \bt_name project plugin) logging line looks like
566this:
567
568@code{.unparsed}
56905-11 00:58:03.691 23402 23402 D VALUES bt_value_destroy@values.c:498 Destroying value: addr=0xb9c3eb0
570@endcode
571
572The line contains, in order:
573
574-# The date and time (<code>05-11 00:58:03.691</code>).
575
576-# The process and thread IDs (<code>23402 23402</code>).
577
578-# The logging level (\c D for \em DEBUG).
579
580-# The function logging (\c bt_value_destroy).
581
582-# The file and line number logging (<code>values.c:498</code>).
583
584-# The message, which typically ends with a list of fields adding
585 details.
586*/
This page took 0.024951 seconds and 4 git commands to generate.