From 195469f3e8f3e079fe58fdca8db1563e94ac968e Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Tue, 7 Apr 2020 17:14:02 +0200 Subject: [PATCH] docs: Clean up both public and internal docs. (#222) --- include/sentry.h | 531 +++++++++++++-------- src/path/sentry_path_unix.c | 11 + src/sentry_alloc.h | 3 + src/sentry_backend.h | 13 + src/sentry_core.h | 33 +- src/sentry_database.h | 42 +- src/sentry_envelope.h | 63 +++ src/sentry_json.h | 67 +++ src/sentry_modulefinder.h | 8 + src/sentry_path.h | 127 ++++- src/sentry_random.h | 4 +- src/sentry_scope.h | 37 ++ src/sentry_session.h | 35 ++ src/sentry_slice.h | 42 ++ src/sentry_string.c | 2 +- src/sentry_string.h | 76 ++- src/sentry_symbolizer.h | 4 + src/sentry_sync.h | 29 ++ src/sentry_transport.h | 33 ++ src/sentry_unix_pageallocator.h | 18 + src/sentry_unix_spinlock.h | 6 + src/sentry_utils.h | 74 ++- src/sentry_uuid.h | 3 + src/sentry_value.h | 57 ++- src/sentry_windows_dbghelp.h | 4 + src/transports/sentry_disk_transport.h | 5 + src/transports/sentry_function_transport.h | 3 + 27 files changed, 1073 insertions(+), 257 deletions(-) diff --git a/include/sentry.h b/include/sentry.h index 60ab83fc5..cbdbdc493 100644 --- a/include/sentry.h +++ b/include/sentry.h @@ -1,4 +1,4 @@ -/* +/** * sentry-native * * sentry-native is a C client to send events to native from @@ -70,7 +70,35 @@ extern "C" { # include #endif -/* +/** + * The library internally uses the system malloc and free functions to manage + * memory. It does not use realloc. The reason for this is that on unix + * platforms we fall back to a simplistic page allocator once we have + * encountered a SIGSEGV or other terminating signal as malloc is no longer + * safe to use. Since we cannot portably reallocate allocations made on the + * pre-existing allocator we're instead not using realloc. + * + * Note also that after SIGSEGV sentry_free() becomes a noop. + */ + +/** + * Allocates memory with the underlying allocator. + */ +SENTRY_API void *sentry_malloc(size_t size); + +/** + * Releases memory allocated from the underlying allocator. + */ +SENTRY_API void sentry_free(void *ptr); + +/** + * Legacy function. Alias for `sentry_free`. + */ +#define sentry_string_free sentry_free + +/* -- Protocol Value API -- */ + +/** * Type of a sentry value. */ typedef enum { @@ -83,27 +111,7 @@ typedef enum { SENTRY_VALUE_TYPE_OBJECT, } sentry_value_type_t; -/* the library internally uses the system malloc and free functions to manage - memory. It does not use realloc. The reason for this is that on unix - platforms we fall back to a simplistic page allocator once we have - encountered a SIGSEGV or other terminating signal as malloc is no longer - safe to use. Since we cannot portably reallocate allocations made on the - pre-existing allocator we're instead not using realloc. - - Note also that after SIGSEGV sentry_free() becomes a noop. */ - -/* allocates memory with the underlying allocator */ -SENTRY_API void *sentry_malloc(size_t size); - -/* releases memory allocated from the underlying allocator */ -SENTRY_API void sentry_free(void *ptr); - -/* legacy function. Alias for `sentry_free`. */ -#define sentry_string_free sentry_free - -/* -- Protocol Value API -- */ - -/* +/** * Represents a sentry protocol value. * * The members of this type should never be accessed. They are only here @@ -125,47 +133,73 @@ union sentry_value_u { }; typedef union sentry_value_u sentry_value_t; -/* increments the reference count on the value */ +/** + * Increments the reference count on the value. + */ SENTRY_API void sentry_value_incref(sentry_value_t value); -/* decrements the reference count on the value */ +/** + * Decrements the reference count on the value. + */ SENTRY_API void sentry_value_decref(sentry_value_t value); -/* returns the refcount of a value. */ +/** + * Returns the refcount of a value. + */ SENTRY_API size_t sentry_value_refcount(sentry_value_t value); -/* freezes a value */ +/** + * Freezes a value. + */ SENTRY_API void sentry_value_freeze(sentry_value_t value); -/* checks if a value is frozen */ +/** + * Checks if a value is frozen. + */ SENTRY_API int sentry_value_is_frozen(sentry_value_t value); -/* creates a null value */ +/** + * Creates a null value. + */ SENTRY_API sentry_value_t sentry_value_new_null(void); -/* creates anew 32bit signed integer value. */ +/** + * Creates a new 32-bit signed integer value. + */ SENTRY_API sentry_value_t sentry_value_new_int32(int32_t value); -/* creates a new double value */ +/** + * Creates a new double value. + */ SENTRY_API sentry_value_t sentry_value_new_double(double value); -/* creates a new boolen value */ +/** + * Creates a new boolen value. + */ SENTRY_API sentry_value_t sentry_value_new_bool(int value); -/* creates a new null terminated string */ +/** + * Creates a new null terminated string. + */ SENTRY_API sentry_value_t sentry_value_new_string(const char *value); -/* creates a new list value */ +/** + * Creates a new list value. + */ SENTRY_API sentry_value_t sentry_value_new_list(void); -/* creates a new object */ +/** + * Creates a new object. + */ SENTRY_API sentry_value_t sentry_value_new_object(void); -/* returns the type of the value passed */ +/** + * Returns the type of the value passed. + */ SENTRY_API sentry_value_type_t sentry_value_get_type(sentry_value_t value); -/* - * sets a key to a value in the map. +/** + * Sets a key to a value in the map. * * This moves the ownership of the value into the map. The caller does not * have to call `sentry_value_decref` on it. @@ -173,19 +207,21 @@ SENTRY_API sentry_value_type_t sentry_value_get_type(sentry_value_t value); SENTRY_API int sentry_value_set_by_key( sentry_value_t value, const char *k, sentry_value_t v); -/* This removes a value from the map by key */ +/** + * This removes a value from the map by key. + */ SENTRY_API int sentry_value_remove_by_key(sentry_value_t value, const char *k); -/* - * appends a value to a list. +/** + * Appends a value to a list. * * This moves the ownership of the value into the list. The caller does not * have to call `sentry_value_decref` on it. */ SENTRY_API int sentry_value_append(sentry_value_t value, sentry_value_t v); -/* - * inserts a value into the list at a certain position. +/** + * Inserts a value into the list at a certain position. * * This moves the ownership of the value into the list. The caller does not * have to call `sentry_value_decref` on it. @@ -196,64 +232,86 @@ SENTRY_API int sentry_value_append(sentry_value_t value, sentry_value_t v); SENTRY_API int sentry_value_set_by_index( sentry_value_t value, size_t index, sentry_value_t v); -/* This removes a value from the list by index */ +/** + * This removes a value from the list by index. + */ SENTRY_API int sentry_value_remove_by_index(sentry_value_t value, size_t index); -/* looks up a value in a map by key. If missing a null value is returned. - The returned value is borrowed. */ +/** + * Looks up a value in a map by key. If missing a null value is returned. + * The returned value is borrowed. + */ SENTRY_API sentry_value_t sentry_value_get_by_key( sentry_value_t value, const char *k); -/* looks up a value in a map by key. If missing a null value is returned. - The returned value is owned. - - If the caller no longer needs the value it must be released with - `sentry_value_decref`. */ +/** + * Looks up a value in a map by key. If missing a null value is returned. + * The returned value is owned. + * + * If the caller no longer needs the value it must be released with + * `sentry_value_decref`. + */ SENTRY_API sentry_value_t sentry_value_get_by_key_owned( sentry_value_t value, const char *k); -/* looks up a value in a list by index. If missing a null value is - returned. The returned value is borrowed. */ +/** + * Looks up a value in a list by index. If missing a null value is returned. + * The returned value is borrowed. + */ SENTRY_API sentry_value_t sentry_value_get_by_index( sentry_value_t value, size_t index); -/* looks up a value in a list by index. If missing a null value is - returned. The returned value is owned. - - If the caller no longer needs the value it must be released with - `sentry_value_decref`. */ +/** + * Looks up a value in a list by index. If missing a null value is + * returned. The returned value is owned. + * + * If the caller no longer needs the value it must be released with + * `sentry_value_decref`. + */ SENTRY_API sentry_value_t sentry_value_get_by_index_owned( sentry_value_t value, size_t index); -/* returns the length of the given map or list. - - If an item is not a list or map the return value is 0. */ +/** + * Returns the length of the given map or list. + * + * If an item is not a list or map the return value is 0. + */ SENTRY_API size_t sentry_value_get_length(sentry_value_t value); -/* converts a value into a 32bit signed integer */ +/** + * Converts a value into a 32bit signed integer. + */ SENTRY_API int32_t sentry_value_as_int32(sentry_value_t value); -/* converts a value into a double value. */ +/** + * Converts a value into a double value. + */ SENTRY_API double sentry_value_as_double(sentry_value_t value); -/* returns the value as c string */ +/** + * Returns the value as c string. + */ SENTRY_API const char *sentry_value_as_string(sentry_value_t value); -/* returns `true` if the value is boolean true. */ +/** + * Returns `true` if the value is boolean true. + */ SENTRY_API int sentry_value_is_true(sentry_value_t value); -/* returns `true` if the value is null. */ +/** + * Returns `true` if the value is null. + */ SENTRY_API int sentry_value_is_null(sentry_value_t value); -/* - * serialize a sentry value to JSON. +/** + * Serialize a sentry value to JSON. * - * the string is freshly allocated and must be freed with + * The string is freshly allocated and must be freed with * `sentry_string_free`. */ SENTRY_API char *sentry_value_to_json(sentry_value_t value); -/* +/** * Sentry levels for events and breadcrumbs. */ typedef enum sentry_level_e { @@ -264,30 +322,21 @@ typedef enum sentry_level_e { SENTRY_LEVEL_FATAL = 3, } sentry_level_t; -/* - * The state of user consent. - */ -typedef enum { - SENTRY_USER_CONSENT_UNKNOWN = -1, - SENTRY_USER_CONSENT_GIVEN = 1, - SENTRY_USER_CONSENT_REVOKED = 0, -} sentry_user_consent_t; - -/* - * creates a new empty event value. +/** + * Creates a new empty event value. */ SENTRY_API sentry_value_t sentry_value_new_event(void); -/* - * creates a new message event value. +/** + * Creates a new message event value. * * `logger` can be NULL to omit the logger value. */ SENTRY_API sentry_value_t sentry_value_new_message_event( sentry_level_t level, const char *logger, const char *text); -/* - * creates a new breadcrumb with a specific type and message. +/** + * Creates a new breadcrumb with a specific type and message. * * Either parameter can be NULL in which case no such attributes is created. */ @@ -296,18 +345,18 @@ SENTRY_API sentry_value_t sentry_value_new_breadcrumb( /* -- Experimental APIs -- */ -/* - * serialize a sentry value to msgpack. +/** + * Serialize a sentry value to msgpack. * - * the string is freshly allocated and must be freed with + * The string is freshly allocated and must be freed with * `sentry_string_free`. Since msgpack is not zero terminated * the size is written to the `size_out` parameter. */ SENTRY_EXPERIMENTAL_API char *sentry_value_to_msgpack( sentry_value_t value, size_t *size_out); -/* - * adds a stacktrace to an event. +/** + * Adds a stacktrace to an event. * * If `ips` is NULL the current stacktrace is captured, otherwise `len` * stacktrace instruction pointers are attached to the event. @@ -315,7 +364,10 @@ SENTRY_EXPERIMENTAL_API char *sentry_value_to_msgpack( SENTRY_EXPERIMENTAL_API void sentry_event_value_add_stacktrace( sentry_value_t event, void **ips, size_t len); -/* context types */ +/** + * This represents the OS dependent user context in the case of a crash, and can + * be used to manually capture a crash. + */ typedef struct sentry_ucontext_s { #ifdef _WIN32 EXCEPTION_POINTERS exception_ptrs; @@ -326,7 +378,7 @@ typedef struct sentry_ucontext_s { #endif } sentry_ucontext_t; -/* +/** * Unwinds the stack from the given address. * * If the address is given in `addr` the stack is unwound form there. @@ -338,7 +390,7 @@ typedef struct sentry_ucontext_s { SENTRY_EXPERIMENTAL_API size_t sentry_unwind_stack( void *addr, void **stacktrace_out, size_t max_len); -/* +/** * Unwinds the stack from the given context. * * The stacktrace is written to `stacktrace_out` with upt o `max_len` frames @@ -347,45 +399,45 @@ SENTRY_EXPERIMENTAL_API size_t sentry_unwind_stack( SENTRY_EXPERIMENTAL_API size_t sentry_unwind_stack_from_ucontext( const sentry_ucontext_t *uctx, void **stacktrace_out, size_t max_len); -/* +/** * A UUID */ typedef struct sentry_uuid_s { char bytes[16]; } sentry_uuid_t; -/* - * creates the nil uuid +/** + * Creates the nil uuid. */ SENTRY_API sentry_uuid_t sentry_uuid_nil(void); -/* - * creates a new uuid4 +/** + * Creates a new uuid4. */ SENTRY_API sentry_uuid_t sentry_uuid_new_v4(void); -/* - * parses a uuid from a string +/** + * Parses a uuid from a string. */ SENTRY_API sentry_uuid_t sentry_uuid_from_string(const char *str); -/* - * creates a uuid from bytes +/** + * Creates a uuid from bytes. */ SENTRY_API sentry_uuid_t sentry_uuid_from_bytes(const char bytes[16]); -/* - * checks if the uuid is nil +/** + * Checks if the uuid is nil. */ SENTRY_API int sentry_uuid_is_nil(const sentry_uuid_t *uuid); -/* - * returns the bytes of the uuid +/** + * Returns the bytes of the uuid. */ SENTRY_API void sentry_uuid_as_bytes(const sentry_uuid_t *uuid, char bytes[16]); -/* - * formats the uuid into a string buffer +/** + * Formats the uuid into a string buffer. */ SENTRY_API void sentry_uuid_as_string(const sentry_uuid_t *uuid, char str[37]); @@ -395,35 +447,47 @@ typedef struct sentry_options_s sentry_options_t; struct sentry_envelope_s; typedef struct sentry_envelope_s sentry_envelope_t; -/* frees an envelope */ +/** + * Frees an envelope. + */ SENTRY_API void sentry_envelope_free(sentry_envelope_t *envelope); -/* given an envelope returns the embedded event if there is one. - - This returns a borrowed value to the event in the envelope. */ +/** + * Given an envelope returns the embedded event if there is one. + * + * This returns a borrowed value to the event in the envelope. + */ SENTRY_API sentry_value_t sentry_envelope_get_event( const sentry_envelope_t *envelope); -/* - * serializes the envelope +/** + * Serializes the envelope. * * The return value needs to be freed with sentry_string_free(). */ SENTRY_API char *sentry_envelope_serialize( const sentry_envelope_t *envelope, size_t *size_out); -/* - * serializes the envelope into a file +/** + * serializes the envelope into a file. * * returns 0 on success. */ SENTRY_API int sentry_envelope_write_to_file( const sentry_envelope_t *envelope, const char *path); -/* type of the callback for transports */ +/** + * Type of the callback for transports. + */ typedef void (*sentry_transport_function_t)( const sentry_envelope_t *envelope, void *data); +/** + * This represents an interface for user-defined transports. + * + * This type is *deprecated*, and will be replaced by an opaque pointer type and + * builder methods in a future version. + */ struct sentry_transport_s; typedef struct sentry_transport_s { void (*send_envelope_func)( @@ -434,55 +498,83 @@ typedef struct sentry_transport_s { void *data; } sentry_transport_t; -struct sentry_backend_s; -typedef struct sentry_backend_s sentry_backend_t; - +/** + * Creates a new function transport. + */ SENTRY_API sentry_transport_t *sentry_new_function_transport( void (*func)(sentry_envelope_t *envelope, void *data), void *data); -/* generic way to free a transport */ +/** + * Generic way to free a transport. + */ SENTRY_API void sentry_transport_free(sentry_transport_t *transport); -/* generic way to free a backend */ +/** + * This represents an opaque backend. + * + * This declaration is *deprecated* and will be removed in a future version. + */ +struct sentry_backend_s; +typedef struct sentry_backend_s sentry_backend_t; + +/** + * Generic way to free a backend. + * + * This function is *deprecated* and will be removed in a future version. + */ SENTRY_API void sentry_backend_free(sentry_backend_t *backend); -/* type of the callback for modifying events */ +/** + * Type of the callback for modifying events. + */ typedef sentry_value_t (*sentry_event_function_t)( sentry_value_t event, void *hint, void *closure); -/* - * creates a new options struct. Can be freed with `sentry_options_free` +/* -- Options APIs -- */ + +/** + * The state of user consent. + */ +typedef enum { + SENTRY_USER_CONSENT_UNKNOWN = -1, + SENTRY_USER_CONSENT_GIVEN = 1, + SENTRY_USER_CONSENT_REVOKED = 0, +} sentry_user_consent_t; + +/** + * Creates a new options struct. + * Can be freed with `sentry_options_free`. */ SENTRY_API sentry_options_t *sentry_options_new(void); -/* - * deallocates previously allocated sentry options +/** + * Deallocates previously allocated sentry options. */ SENTRY_API void sentry_options_free(sentry_options_t *opts); -/* - * sets a transport. +/** + * Sets a transport. */ SENTRY_API void sentry_options_set_transport( sentry_options_t *opts, sentry_transport_t *transport); -/* - * sets the before send callback +/** + * Sets the before send callback. */ SENTRY_API void sentry_options_set_before_send( sentry_options_t *opts, sentry_event_function_t func, void *data); -/* - * sets the DSN +/** + * Sets the DSN. */ SENTRY_API void sentry_options_set_dsn(sentry_options_t *opts, const char *dsn); -/* - * gets the DSN +/** + * Gets the DSN. */ SENTRY_API const char *sentry_options_get_dsn(const sentry_options_t *opts); -/* +/** * Sets the sample rate, which should be a double between `0.0` and `1.0`. * Sentry will randomly discard any event that is captured using * `sentry_capture_event` when a sample rate < 1 is set. @@ -490,81 +582,81 @@ SENTRY_API const char *sentry_options_get_dsn(const sentry_options_t *opts); SENTRY_API void sentry_options_set_sample_rate( sentry_options_t *opts, double sample_rate); -/* - * Gets the sample rate +/** + * Gets the sample rate. */ SENTRY_API double sentry_options_get_sample_rate(const sentry_options_t *opts); -/* - * sets the release +/** + * Sets the release. */ SENTRY_API void sentry_options_set_release( sentry_options_t *opts, const char *release); -/* - * gets the release +/** + * Gets the release. */ SENTRY_API const char *sentry_options_get_release(const sentry_options_t *opts); -/* - * sets the environment +/** + * Sets the environment. */ SENTRY_API void sentry_options_set_environment( sentry_options_t *opts, const char *environment); -/* - * gets the environment +/** + * Gets the environment. */ SENTRY_API const char *sentry_options_get_environment( const sentry_options_t *opts); -/* - * sets the dist +/** + * Sets the dist. */ SENTRY_API void sentry_options_set_dist( sentry_options_t *opts, const char *dist); -/* - * gets the dist +/** + * Gets the dist. */ SENTRY_API const char *sentry_options_get_dist(const sentry_options_t *opts); -/* - * configures the http proxy +/** + * Configures the http proxy. */ SENTRY_API void sentry_options_set_http_proxy( sentry_options_t *opts, const char *proxy); -/* - * returns the configured http proxy +/** + * Returns the configured http proxy. */ SENTRY_API const char *sentry_options_get_http_proxy( const sentry_options_t *opts); -/* - * configures the path to a file containing ssl certificates for +/** + * Configures the path to a file containing ssl certificates for * verification. */ SENTRY_API void sentry_options_set_ca_certs( sentry_options_t *opts, const char *path); -/* - * returns the configured path for ca certificates. +/** + * Returns the configured path for ca certificates. */ SENTRY_API const char *sentry_options_get_ca_certs( const sentry_options_t *opts); -/* - * enables or disables debug printing mode +/** + * Enables or disables debug printing mode. */ SENTRY_API void sentry_options_set_debug(sentry_options_t *opts, int debug); -/* - * returns the current value of the debug flag. +/** + * Returns the current value of the debug flag. */ SENTRY_API int sentry_options_get_debug(const sentry_options_t *opts); -/* +/** * Enables or disabled user consent requirements for uploads. * * This disables uploads until the user has given the consent to the SDK. @@ -573,45 +665,70 @@ SENTRY_API int sentry_options_get_debug(const sentry_options_t *opts); */ SENTRY_API void sentry_options_set_require_user_consent( sentry_options_t *opts, int val); -/* - * returns true if user consent is required. + +/** + * Returns true if user consent is required. */ SENTRY_API int sentry_options_get_require_user_consent( const sentry_options_t *opts); -/* - * adds a new attachment to be sent along +/** + * Adds a new attachment to be sent along. */ SENTRY_API void sentry_options_add_attachment( sentry_options_t *opts, const char *name, const char *path); -/* - * sets the path to the crashpad handler if the crashpad backend is used +/** + * Sets the path to the crashpad handler if the crashpad backend is used. + * + * The path defaults to the `crashpad_handler`/`crashpad_handler.exe` + * executable, depending on platform, which is expected to be present in the + * same directory as the app executable. + * + * It is recommended that library users set an explicit handler path, depending + * on the directory/executable structure of their app. */ SENTRY_API void sentry_options_set_handler_path( sentry_options_t *opts, const char *path); -/* - * sets the path to the sentry-native/crashpad/breakpad database +/** + * Sets the path to the Sentry Database Directory. + * + * Sentry will use this path to persist user consent, sessions, and other + * artifacts in case of a crash. This will also be used by the crashpad backend + * if it is configured. + * + * The path defaults to `.sentry-native` in the current working directory, will + * be created if it does not exist, and will be resolved to an absolute path + * inside of `sentry_init`. + * + * It is recommended that library users set an explicit absolute path, depending + * on their own apps directory. */ SENTRY_API void sentry_options_set_database_path( sentry_options_t *opts, const char *path); #ifdef SENTRY_PLATFORM_WINDOWS -/* wide char version of `sentry_options_add_attachment` */ +/** + * Wide char version of `sentry_options_add_attachment`. + */ SENTRY_API void sentry_options_add_attachmentw( sentry_options_t *opts, const char *name, const wchar_t *path); -/* wide char version of `sentry_options_set_handler_path` */ +/** + * Wide char version of `sentry_options_set_handler_path`. + */ SENTRY_API void sentry_options_set_handler_pathw( sentry_options_t *opts, const wchar_t *path); -/* wide char version of `sentry_options_set_database_path` */ +/** + * Wide char version of `sentry_options_set_database_path`. + */ SENTRY_API void sentry_options_set_database_pathw( sentry_options_t *opts, const wchar_t *path); #endif -/* +/** * Enables forwarding to the system crash reporter. Disabled by default. * * This setting only has an effect when using Crashpad on macOS. If enabled, @@ -622,7 +739,9 @@ SENTRY_API void sentry_options_set_database_pathw( SENTRY_API void sentry_options_set_system_crash_reporter_enabled( sentry_options_t *opts, int enabled); -/* +/* -- Global APIs -- */ + +/** * Initializes the Sentry SDK with the specified options. * * This takes ownership of the options. After the options have been set @@ -630,12 +749,14 @@ SENTRY_API void sentry_options_set_system_crash_reporter_enabled( */ SENTRY_API int sentry_init(sentry_options_t *options); -/* +/** * Shuts down the sentry client and forces transports to flush out. */ SENTRY_API void sentry_shutdown(void); /** + * Clears the internal module cache. + * * For performance reasons, sentry will cache the list of loaded libraries when * capturing events. This cache can get out-of-date when loading or unloading * libraries at runtime. It is therefore recommended to call @@ -644,120 +765,122 @@ SENTRY_API void sentry_shutdown(void); */ SENTRY_EXPERIMENTAL_API void sentry_clear_modulecache(void); -/* +/** * Returns the client options. + * + * This might return NULL if sentry is not yet initialized. */ SENTRY_API const sentry_options_t *sentry_get_options(void); -/* - * Gives user consent +/** + * Gives user consent. */ SENTRY_API void sentry_user_consent_give(void); -/* - * Revokes user consent +/** + * Revokes user consent. */ SENTRY_API void sentry_user_consent_revoke(void); -/* - * Resets the user consent (back to unknown) +/** + * Resets the user consent (back to unknown). */ SENTRY_API void sentry_user_consent_reset(void); -/* +/** * Checks the current state of user consent. */ SENTRY_API sentry_user_consent_t sentry_user_consent_get(void); -/* +/** * Sends a sentry event. */ SENTRY_API sentry_uuid_t sentry_capture_event(sentry_value_t event); -/* +/** * Captures an exception to be handled by the backend. * * This is safe to be called from a crashing thread and may not return. */ SENTRY_EXPERIMENTAL_API void sentry_handle_exception(sentry_ucontext_t *uctx); -/* +/** * Adds the breadcrumb to be sent in case of an event. */ SENTRY_API void sentry_add_breadcrumb(sentry_value_t breadcrumb); -/* +/** * Sets the specified user. */ SENTRY_API void sentry_set_user(sentry_value_t user); -/* +/** * Removes a user. */ SENTRY_API void sentry_remove_user(void); -/* +/** * Sets a tag. */ SENTRY_API void sentry_set_tag(const char *key, const char *value); -/* +/** * Removes the tag with the specified key. */ SENTRY_API void sentry_remove_tag(const char *key); -/* +/** * Sets extra information. */ SENTRY_API void sentry_set_extra(const char *key, sentry_value_t value); -/* +/** * Removes the extra with the specified key. */ SENTRY_API void sentry_remove_extra(const char *key); -/* +/** * Sets a context object. */ SENTRY_API void sentry_set_context(const char *key, sentry_value_t value); -/* +/** * Removes the context object with the specified key. */ SENTRY_API void sentry_remove_context(const char *key); -/* +/** * Sets the event fingerprint. */ SENTRY_API void sentry_set_fingerprint(const char *fingerprint, ...); -/* +/** * Removes the fingerprint. */ SENTRY_API void sentry_remove_fingerprint(void); -/* +/** * Sets the transaction. */ SENTRY_API void sentry_set_transaction(const char *transaction); -/* +/** * Removes the transaction. */ SENTRY_API void sentry_remove_transaction(void); -/* +/** * Sets the event level. */ SENTRY_API void sentry_set_level(sentry_level_t level); -/* +/** * Starts a new session. */ SENTRY_EXPERIMENTAL_API void sentry_start_session(void); -/* - * Ends a session +/** + * Ends a session. */ SENTRY_EXPERIMENTAL_API void sentry_end_session(void); diff --git a/src/path/sentry_path_unix.c b/src/path/sentry_path_unix.c index aafccc31f..30be7f01b 100644 --- a/src/path/sentry_path_unix.c +++ b/src/path/sentry_path_unix.c @@ -259,6 +259,17 @@ sentry__path_clone(const sentry_path_t *path) return rv; } +#define EINTR_RETRY(X, Y) \ + do { \ + int _tmp; \ + do { \ + _tmp = (X); \ + } while (_tmp == -1 && errno == EINTR); \ + if (Y != 0) { \ + *(int *)Y = _tmp; \ + } \ + } while (false) + int sentry__path_remove(const sentry_path_t *path) { diff --git a/src/sentry_alloc.h b/src/sentry_alloc.h index 1d6053f16..fe7851369 100644 --- a/src/sentry_alloc.h +++ b/src/sentry_alloc.h @@ -3,6 +3,9 @@ #include "sentry_boot.h" +/** + * This is a shortcut for a typed `malloc`. + */ #define SENTRY_MAKE(Type) (Type *)sentry_malloc(sizeof(Type)) #endif diff --git a/src/sentry_backend.h b/src/sentry_backend.h index cd7ea1f14..9035d7ae1 100644 --- a/src/sentry_backend.h +++ b/src/sentry_backend.h @@ -5,6 +5,12 @@ #include "sentry_scope.h" +/** + * This represents the crash handling backend. + * It consists of a few hooks that integrate into the sentry lifecycle and which + * can ensure that any captured crash contains the sentry scope and other + * information. + */ struct sentry_backend_s; typedef struct sentry_backend_s { void (*startup_func)(struct sentry_backend_s *); @@ -19,7 +25,14 @@ typedef struct sentry_backend_s { void *data; } sentry_backend_t; +/** + * This will free a previously allocated backend. + */ void sentry__backend_free(sentry_backend_t *backend); + +/** + * Create a new backend, depending on build-time configuration. + */ sentry_backend_t *sentry__backend_new(void); #endif diff --git a/src/sentry_core.h b/src/sentry_core.h index 1b93fd48a..befb7c6fe 100644 --- a/src/sentry_core.h +++ b/src/sentry_core.h @@ -48,7 +48,10 @@ struct sentry_backend_s; -// We save the attachments as a linked list basically +/** + * This is a linked list of all the attachments registered via + * `sentry_options_add_attachment`. + */ typedef struct sentry_attachment_s sentry_attachment_t; struct sentry_attachment_s { char *name; @@ -56,6 +59,10 @@ struct sentry_attachment_s { sentry_attachment_t *next; }; +/** + * This is the main options struct, which is being accessed throughout all of + * the sentry internals. + */ struct sentry_options_s { char *raw_dsn; sentry_dsn_t dsn; @@ -84,15 +91,39 @@ struct sentry_options_s { sentry_user_consent_t user_consent; }; +/** + * This will free a previously allocated attachment. + */ void sentry__attachment_free(sentry_attachment_t *attachment); +/** + * This function will check the user consent, and return `true` if uploads + * should *not* be sent to the sentry server, and be discarded instead. + */ bool sentry__should_skip_upload(void); +/** + * This function is essential to capture reports in the case of a hard crash. + * It will set a special transport that will dump events to disk. + * See `sentry__run_write_envelope`. + */ void sentry__enforce_disk_transport(void); +/** + * This function will submit the given `envelope` to the configured transport. + */ void sentry__capture_envelope(sentry_envelope_t *envelope); +/** + * Generates a new random UUID for events. + */ sentry_uuid_t sentry__new_event_id(void); + +/** + * This will ensure that the given `event` has a UUID, generating a new one on + * demand. It will return a serialized UUID as `sentry_value_t` and also write + * it into the `uuid_out` parameter. + */ sentry_value_t sentry__ensure_event_id( sentry_value_t event, sentry_uuid_t *uuid_out); diff --git a/src/sentry_database.h b/src/sentry_database.h index dea828358..a22c50c8c 100644 --- a/src/sentry_database.h +++ b/src/sentry_database.h @@ -13,25 +13,61 @@ typedef struct { sentry_filelock_t *lock; } sentry_run_t; +/** + * This creates a new application run including its associated directory and + * lockfile: + * * `/.run/` + * * `/.run.lock` + */ sentry_run_t *sentry__run_new(const sentry_path_t *database_path); /** - * This will clean up all the files belonging to this to this run. + * This will clean up all the files belonging to this run. */ void sentry__run_clean(sentry_run_t *run); + +/** + * Free the previously allocated run. + * Make sure to call `sentry__run_clean` first, to not leave any files or + * directories laying around. + */ void sentry__run_free(sentry_run_t *run); +/** + * This will serialize and write the given envelope to disk into a file named + * like so: + * `/.run/.envelope` + */ bool sentry__run_write_envelope( const sentry_run_t *run, const sentry_envelope_t *envelope); + +/** + * This will serialize and write the given session to disk into a file named: + * `/.run/session.json` + */ bool sentry__run_write_session( const sentry_run_t *run, const sentry_session_t *session); + +/** + * This will remove any previously created session file. + * See `sentry__run_write_session`. + */ bool sentry__run_clear_session(const sentry_run_t *run); +/** + * This function is essential to send crash reports from previous runs of the + * program. + * More specifically, this function will iterate over all the directories + * inside the `database_path`. Directories matching `/.run/` + * will be locked, and any files named `.envelope` or + * `session.json` will be queued for sending to the backend. The files and + * directories matching these criteria will be deleted afterwards. + */ void sentry__process_old_runs(const sentry_options_t *options); /** - * This will write the current timestamp (ISO formatted) into the - * `${database_path}/last_crash` file. + * This will write the current ISO8601 formatted timestamp into the + * `/last_crash` file. */ bool sentry__write_crash_marker(const sentry_options_t *options); diff --git a/src/sentry_envelope.h b/src/sentry_envelope.h index 333ad0eea..b48a56666 100644 --- a/src/sentry_envelope.h +++ b/src/sentry_envelope.h @@ -19,6 +19,9 @@ typedef struct sentry_prepared_http_header_s { char *value; } sentry_prepared_http_header_t; +/** + * This represents a HTTP request, with method, url, headers and a body. + */ typedef struct sentry_prepared_http_request_s { char *url; const char *method; @@ -29,34 +32,94 @@ typedef struct sentry_prepared_http_request_s { bool payload_owned; } sentry_prepared_http_request_t; +/** + * Free a previously allocated HTTP request. + */ void sentry__prepared_http_request_free(sentry_prepared_http_request_t *req); +/** + * Create a new empty envelope. + */ sentry_envelope_t *sentry__envelope_new(void); + +/** + * This loads a previously serialized envelope from disk. + */ sentry_envelope_t *sentry__envelope_from_path(const sentry_path_t *path); + +/** + * This returns the UUID of the event associated with this envelope. + * If there is no event inside this envelope, or the envelope was previously + * loaded from disk, the empty nil UUID will be returned. + */ sentry_uuid_t sentry__envelope_get_event_id(const sentry_envelope_t *envelope); + +/** + * Add an event to this envelope. + */ sentry_envelope_item_t *sentry__envelope_add_event( sentry_envelope_t *envelope, sentry_value_t event); + +/** + * Add a session to this envelope. + */ sentry_envelope_item_t *sentry__envelope_add_session( sentry_envelope_t *envelope, const sentry_session_t *session); + +/** + * This will add the file contents from `path` as an envelope item of type + * `type`. + */ sentry_envelope_item_t *sentry__envelope_add_from_path( sentry_envelope_t *envelope, const sentry_path_t *path, const char *type); + +/** + * This will add the given buffer as a new envelope item of type `type`. + */ sentry_envelope_item_t *sentry__envelope_add_from_buffer( sentry_envelope_t *envelope, const char *buf, size_t buf_len, const char *type); + +/** + * This sets an explicit header for the given envelope item. + */ void sentry__envelope_item_set_header( sentry_envelope_item_t *item, const char *key, sentry_value_t value); + +/** + * This will call the provided `callback` once for each HTTP request that an + * envelope generates. The callback will be called zero or more times, depending + * on the envelope items, and the rate limits enforced by `rl`. Rate limited + * items will be skipped. + */ void sentry__envelope_for_each_request(const sentry_envelope_t *envelope, bool (*callback)(sentry_prepared_http_request_t *, const sentry_envelope_t *, void *data), const struct sentry_rate_limiter_s *rl, void *data); +/** + * Serialize the envelope header into the given string builder. + */ void sentry__envelope_serialize_headers_into_stringbuilder( const sentry_envelope_t *envelope, sentry_stringbuilder_t *sb); + +/** + * Serialize a single envelope item into the given string builder. + */ void sentry__envelope_serialize_item_into_stringbuilder( const sentry_envelope_item_t *item, sentry_stringbuilder_t *sb); + +/** + * Serialize a complete envelope with all its items into the given string + * builder. + */ void sentry__envelope_serialize_into_stringbuilder( const sentry_envelope_t *envelope, sentry_stringbuilder_t *sb); +/** + * Serialize the envelope, and write it to a new file at `path`. + * The envelope can later be loaded using `sentry__envelope_from_path`. + */ MUST_USE int sentry_envelope_write_to_path( const sentry_envelope_t *envelope, const sentry_path_t *path); diff --git a/src/sentry_json.h b/src/sentry_json.h index 1fcef71e5..d3e533278 100644 --- a/src/sentry_json.h +++ b/src/sentry_json.h @@ -6,25 +6,92 @@ struct sentry_jsonwriter_s; typedef struct sentry_jsonwriter_s sentry_jsonwriter_t; +/** + * This creates a new in-memory JSON writer, based on `sentry_stringbuilder_s`. + */ sentry_jsonwriter_t *sentry__jsonwriter_new_in_memory(void); + +/** + * Deallocates a JSON writer. + */ void sentry__jsonwriter_free(sentry_jsonwriter_t *jw); + +/** + * This will consume and deallocate the JSON writer, returning the generated + * JSON string, and writing its length into `len_out`. + */ char *sentry__jsonwriter_into_string(sentry_jsonwriter_t *jw, size_t *len_out); +/** + * Write a `null` into the JSON. + */ void sentry__jsonwriter_write_null(sentry_jsonwriter_t *jw); + +/** + * Write a JSON boolean. + */ void sentry__jsonwriter_write_bool(sentry_jsonwriter_t *jw, bool val); + +/** + * Write a 32-bit number, which will be encoded in a JSON number. + */ void sentry__jsonwriter_write_int32(sentry_jsonwriter_t *jw, int32_t val); + +/** + * Write a 64-bit float, encoded as JSON number. + */ void sentry__jsonwriter_write_double(sentry_jsonwriter_t *jw, double val); + +/** + * Write a zero-terminated string. + */ void sentry__jsonwriter_write_str(sentry_jsonwriter_t *jw, const char *val); + +/** + * Write a UUID as a JSON string. + * See `sentry_uuid_as_string`. + */ void sentry__jsonwriter_write_uuid( sentry_jsonwriter_t *jw, const sentry_uuid_t *uuid); + +/** + * This will write a millisecond resolution timestamp formattad as an ISO8601 + * string. + * See `sentry__msec_time_to_iso8601`. + */ void sentry__jsonwriter_write_msec_timestamp( sentry_jsonwriter_t *jw, uint64_t time); + +/** + * Writes the *Key* part of an object Key-Value pair. + */ void sentry__jsonwriter_write_key(sentry_jsonwriter_t *jw, const char *val); + +/** + * Start a new JSON array. + * Needs to be closed with `sentry__jsonwriter_write_list_end`. + */ void sentry__jsonwriter_write_list_start(sentry_jsonwriter_t *jw); + +/** + * End the previously started JSON array. + */ void sentry__jsonwriter_write_list_end(sentry_jsonwriter_t *jw); + +/** + * Start a new JSON object. + * Needs to be closed with `sentry__jsonwriter_write_object_end`. + */ void sentry__jsonwriter_write_object_start(sentry_jsonwriter_t *jw); + +/** + * End the previously started JSON object. + */ void sentry__jsonwriter_write_object_end(sentry_jsonwriter_t *jw); +/** + * Parse the given JSON string into a new Value. + */ sentry_value_t sentry__value_from_json(const char *buf, size_t buflen); #endif diff --git a/src/sentry_modulefinder.h b/src/sentry_modulefinder.h index 248cd97bd..c182a3b89 100644 --- a/src/sentry_modulefinder.h +++ b/src/sentry_modulefinder.h @@ -3,8 +3,16 @@ #include "sentry_boot.h" +/** + * This will lazily load and cache a list of all the loaded modules. + * The returned value is borrowed. + */ sentry_value_t sentry__modules_get_list(void); +/** + * This will clean up the internal module cache. The list will be lazily loaded + * again on the next call to `sentry__modules_get_list`. + */ void sentry__modulefinder_cleanup(void); #endif diff --git a/src/sentry_path.h b/src/sentry_path.h index 54fa02850..57a739397 100644 --- a/src/sentry_path.h +++ b/src/sentry_path.h @@ -32,50 +32,175 @@ typedef struct sentry_filelock_s sentry_filelock_t; */ sentry_path_t *sentry__path_absolute(const sentry_path_t *path); +/** + * This will return the path to the current executable running the code. + */ sentry_path_t *sentry__path_current_exe(void); + +/** + * This will return the parent directory name of the given `path`. + */ sentry_path_t *sentry__path_dir(const sentry_path_t *path); + +/** + * Create a new path from the given string. + */ sentry_path_t *sentry__path_from_str(const char *s); + +/** + * Create a new path from the given string. + * The string is moved into the returned path instead of copied. + */ sentry_path_t *sentry__path_from_str_owned(char *s); + +/** + * Return a new path with a new path segment (directory or file name) appended. + */ sentry_path_t *sentry__path_join_str( const sentry_path_t *base, const char *other); + +/** + * Creates a copy of the path. + */ sentry_path_t *sentry__path_clone(const sentry_path_t *path); + +/** + * Free the path instance. + */ void sentry__path_free(sentry_path_t *path); +/** + * This will return a copy of the last path segment, which is typically the file + * or directory name. + */ const sentry_pathchar_t *sentry__path_filename(const sentry_path_t *path); + +/** + * Returns whether the last path segment matches `filename`. + */ bool sentry__path_filename_matches( const sentry_path_t *path, const char *filename); + +/** + * This will check for a specific suffix. + */ bool sentry__path_ends_with(const sentry_path_t *path, const char *suffix); +/** + * Return whether the path refers to a directory. + */ bool sentry__path_is_dir(const sentry_path_t *path); + +/** + * Return whether the path refers to a regular file. + */ bool sentry__path_is_file(const sentry_path_t *path); + +/** + * Remove the directory or file referred to by `path`. + * This will *not* recursively delete any directory content. Use + * `sentry__path_remove_all` for that. + * Returns 0 on success. + */ int sentry__path_remove(const sentry_path_t *path); + +/** + * Recursively remove the given directory and everything in it. + * Returns 0 on success. + */ int sentry__path_remove_all(const sentry_path_t *path); + +/** + * This will create the directory referred to by `path`, and any non-existing + * parent directory. + * Returns 0 on success. + */ int sentry__path_create_dir_all(const sentry_path_t *path); + +/** + * This will touch or create an empty file at `path`. + * Returns 0 on success. + */ int sentry__path_touch(const sentry_path_t *path); + +/** + * This will return the size of the file at `path`, or 0 on failure. + */ size_t sentry__path_get_size(const sentry_path_t *path); + +/** + * This will read all the content of `path` into a newly allocated buffer, and + * write its size into `size_out`. + */ char *sentry__path_read_to_buffer(const sentry_path_t *path, size_t *size_out); + +/** + * This will truncate the given file and write the given `buf` into it. + */ int sentry__path_write_buffer( const sentry_path_t *path, const char *buf, size_t buf_len); + +/** + * This will append `buf` to an existing file. + */ int sentry__path_append_buffer( const sentry_path_t *path, const char *buf, size_t buf_len); +/** + * Create a new directory iterator for `path`. + */ sentry_pathiter_t *sentry__path_iter_directory(const sentry_path_t *path); + +/** + * This will return a borrowed path to the next file or directory for the given + * `piter`. + */ const sentry_path_t *sentry__pathiter_next(sentry_pathiter_t *piter); + +/** + * This will close and free the previously created directory iterator. + */ void sentry__pathiter_free(sentry_pathiter_t *piter); +/** + * Create a new lockfile at the given path. + */ sentry_filelock_t *sentry__filelock_new(sentry_path_t *path); + +/** + * This will try to acquire a lock on the given file. + * The function will return `false` when no lock can be acquired, for example if + * the lock is being held by another process. + */ bool sentry__filelock_try_lock(sentry_filelock_t *lock); + +/** + * This will release the lock on the given file. + */ void sentry__filelock_unlock(sentry_filelock_t *lock); + +/** + * Free the allocated lockfile. This will unlock the file first. + */ void sentry__filelock_free(sentry_filelock_t *lock); /* windows specific API additions */ #ifdef SENTRY_PLATFORM_WINDOWS +/** + * Create a new path from a Wide String. + */ sentry_path_t *sentry__path_from_wstr(const wchar_t *s); + +/** + * Create another path by appending a new path segment. + */ sentry_path_t *sentry__path_join_wstr( const sentry_path_t *base, const wchar_t *other); #endif -/* platform abstraction helper */ +/** + * Create a new path from the platform native string type. + */ static inline sentry_path_t * sentry__path_new(sentry_pathchar_t *s) { diff --git a/src/sentry_random.h b/src/sentry_random.h index 84b176666..012b3ca43 100644 --- a/src/sentry_random.h +++ b/src/sentry_random.h @@ -3,7 +3,9 @@ #include "sentry_boot.h" -/* utility function to get random bytes */ +/** + * Utility function to get random bytes. + */ int sentry__getrandom(void *dst, size_t len); #endif diff --git a/src/sentry_scope.h b/src/sentry_scope.h index 1fe98a8c8..3602ab32c 100644 --- a/src/sentry_scope.h +++ b/src/sentry_scope.h @@ -6,6 +6,9 @@ #include "sentry_session.h" #include "sentry_value.h" +/** + * This represents the current scope. + */ typedef struct sentry_scope_s { char *transaction; sentry_value_t fingerprint; @@ -19,6 +22,10 @@ typedef struct sentry_scope_s { sentry_session_t *session; } sentry_scope_t; +/** + * When applying a scope to an event object, this specifies all the additional + * data that should be added to the event. + */ typedef enum { SENTRY_SCOPE_NONE = 0x0, SENTRY_SCOPE_BREADCRUMBS = 0x1, @@ -27,16 +34,46 @@ typedef enum { SENTRY_SCOPE_ALL = ~0, } sentry_scope_mode_t; +/** + * This will acquire a lock on the global scope. + */ sentry_scope_t *sentry__scope_lock(void); + +/** + * Release the lock on the global scope. + */ void sentry__scope_unlock(void); +/** + * This will free all the data attached to the global scope + */ void sentry__scope_cleanup(void); +/** + * This will notify any backend of scope changes, and persist session + * information to disk. + */ void sentry__scope_flush(const sentry_scope_t *scope); + +/** + * This will merge the requested data which is in the given `scope` to the given + * `event`. + * See `sentry_scope_mode_t` for the different types of data that can be + * attached. + */ void sentry__scope_apply_to_event(const sentry_scope_t *scope, sentry_value_t event, sentry_scope_mode_t mode); + +/** + * This will update a sessions `distinct_id`, which is generated out of other + * scope data. + */ void sentry__scope_session_sync(sentry_scope_t *scope); +/** + * These are convenience macros to automatically lock/unlock a scope inside a + * code block. + */ #define SENTRY_WITH_SCOPE(Scope) \ for (const sentry_scope_t *Scope = sentry__scope_lock(); Scope; \ sentry__scope_unlock(), Scope = NULL) diff --git a/src/sentry_session.h b/src/sentry_session.h index 02d77a88d..15368b6e5 100644 --- a/src/sentry_session.h +++ b/src/sentry_session.h @@ -15,6 +15,10 @@ typedef enum { SENTRY_SESSION_STATUS_EXITED, } sentry_session_status_t; +/** + * This represents a session, with the number of errors, a status and other + * metadata. + */ typedef struct sentry_session_s { sentry_uuid_t session_id; sentry_value_t distinct_id; @@ -25,16 +29,47 @@ typedef struct sentry_session_s { bool init; } sentry_session_t; +/** + * This creates a new session. + */ sentry_session_t *sentry__session_new(void); + +/** + * This will free a previously allocated session. + */ void sentry__session_free(sentry_session_t *session); + +/** + * This will write the gives session into the json writer `jw`. + */ void sentry__session_to_json( const sentry_session_t *session, struct sentry_jsonwriter_s *jw); + +/** + * Given a JSON string, this will parse and create a session out of it, or NULL + * on failure. + */ sentry_session_t *sentry__session_from_json(const char *buf, size_t buf_len); + +/** + * This will read the JSON serialized session from `path`, or return NULL on + * failure. + */ sentry_session_t *sentry__session_from_path(const sentry_path_t *path); +/** + * This will end the current session with an explicit `status` code. + */ void sentry__end_current_session_with_status(sentry_session_status_t status); + +/** + * This will add `error_count` new errors to the current session. + */ void sentry__record_errors_on_current_session(uint32_t error_count); +/** + * Add the current session an a new envelope item to `envelope`. + */ void sentry__add_current_session_to_envelope(sentry_envelope_t *envelope); #endif diff --git a/src/sentry_slice.h b/src/sentry_slice.h index 28dc31406..2681446a7 100644 --- a/src/sentry_slice.h +++ b/src/sentry_slice.h @@ -6,25 +6,60 @@ #include #include +/** + * This represents an explicit non-zero-terminated string slice. + * The slice only refers to borrowed memory. + */ typedef struct { const char *ptr; size_t len; } sentry_slice_t; +/** + * Create a slice from a zero-terminated string. + */ sentry_slice_t sentry__slice_from_str(const char *str); + +/** + * Creates an owned copy from a slice. + */ char *sentry__slice_to_owned(sentry_slice_t slice); + +/** + * Compares two slices + */ bool sentry__slice_eq(sentry_slice_t a, sentry_slice_t b); +/** + * Compares a slice and a zero-terminated string + */ static inline bool sentry__slice_eqs(sentry_slice_t a, const char *str) { return sentry__slice_eq(a, sentry__slice_from_str(str)); } +/** + * Returns the left sub-slice, up to `c`, or the complete slice if `c` was not + * found. + */ sentry_slice_t sentry__slice_split_at(sentry_slice_t a, char c); + +/** + * Returns the index of `c` inside of the slice `a`, or `(size_t)-1` if `c` was + * not found. + */ size_t sentry__slice_find(sentry_slice_t a, char c); + +/** + * This trims off leading and trailing whitespace. + */ sentry_slice_t sentry__slice_trim(sentry_slice_t a); +/** + * When the given slice starts with `c`, it will skip over the character, or + * otherwise return `false`. + */ static inline bool sentry__slice_consume_if(sentry_slice_t *a, char c) { @@ -37,8 +72,15 @@ sentry__slice_consume_if(sentry_slice_t *a, char c) } } +/** + * This will consume a leading uint64 number from the slice, and write it into + * `num_out`, or otherwise return `false`. + */ bool sentry__slice_consume_uint64(sentry_slice_t *a, uint64_t *num_out); +/** + * This moves the slice ahead by `bytes`. + */ static inline sentry_slice_t sentry__slice_advance(sentry_slice_t s, size_t bytes) { diff --git a/src/sentry_string.c b/src/sentry_string.c index 82e38d370..7cd4394b7 100644 --- a/src/sentry_string.c +++ b/src/sentry_string.c @@ -78,7 +78,7 @@ sentry_stringbuilder_take_string(sentry_stringbuilder_t *sb) if (!rv) { rv = sentry__string_clone(""); } - sb->buf = 0; + sb->buf = NULL; sb->allocated = 0; sb->len = 0; return rv; diff --git a/src/sentry_string.h b/src/sentry_string.h index 55d34bd59..c537b5e3e 100644 --- a/src/sentry_string.h +++ b/src/sentry_string.h @@ -7,30 +7,44 @@ #include #include -/* a string builder can be used to concatenate bytes together. */ +/** + * A string builder, which can be used as a mutable, growable string buffer. + */ typedef struct sentry_stringbuilder_s { char *buf; size_t allocated; size_t len; } sentry_stringbuilder_t; -/* creates a new string builder */ +/** + * Initializes a new string builder, which is typically allocated on the stack. + */ void sentry__stringbuilder_init(sentry_stringbuilder_t *sb); -/* appends a zero terminated string to the builder */ +/** + * Appends a zero terminated string to the builder. + */ int sentry__stringbuilder_append(sentry_stringbuilder_t *sb, const char *s); -/* appends a buffer */ +/** + * Appends a sized buffer. + */ int sentry__stringbuilder_append_buf( sentry_stringbuilder_t *sb, const char *s, size_t len); -/* appends a character */ +/** + * Appends a single character. + */ int sentry__stringbuilder_append_char(sentry_stringbuilder_t *sb, char c); -/* appends a utf32 character */ +/** + * Appends a utf-32 character. + */ int sentry__stringbuilder_append_char32(sentry_stringbuilder_t *sb, uint32_t c); -/* appends an int64 */ +/** + * Appends an int64 value. + */ static inline int sentry__stringbuilder_append_int64(sentry_stringbuilder_t *sb, int64_t val) { @@ -39,25 +53,39 @@ sentry__stringbuilder_append_int64(sentry_stringbuilder_t *sb, int64_t val) return sentry__stringbuilder_append(sb, buf); } -/* detaches the buffer from the string builder and deallocates it */ +/** + * Detaches the buffer from the string builder and deallocates it. + */ char *sentry__stringbuilder_into_string(sentry_stringbuilder_t *sb); -/* detaches the buffer from the string builder */ +/** + * Detaches the buffer from the string builder. + */ char *sentry_stringbuilder_take_string(sentry_stringbuilder_t *sb); -/* deallocates the string builder */ +/** + * Deallocates the string builder. + */ void sentry__stringbuilder_cleanup(sentry_stringbuilder_t *sb); -/* returns the number of bytes in the string builder */ +/** + * Returns the number of bytes in the string builder. + */ size_t sentry__stringbuilder_len(const sentry_stringbuilder_t *sb); -/* duplicates a zero terminated string */ +/** + * Duplicates a zero terminated string. + */ char *sentry__string_clone(const char *str); -/* duplicates a zero terminated string with a length limit */ +/** + * Duplicates a zero terminated string with a length limit. + */ char *sentry__string_clonen(const char *str, size_t n); -/* converts a string to lowercase */ +/** + * Converts a string to lowercase. + */ static inline void sentry__string_ascii_lower(char *s) { @@ -66,14 +94,18 @@ sentry__string_ascii_lower(char *s) } } -/* shortcut for string compare */ +/** + * Shortcut for string compare. + */ static inline bool sentry__string_eq(const char *a, const char *b) { return strcmp(a, b) == 0; } -/* converts an int64_t into a string */ +/** + * Converts an int64_t into a string. + */ static inline char * sentry__int64_to_string(int64_t val) { @@ -83,12 +115,20 @@ sentry__int64_to_string(int64_t val) } #ifdef SENTRY_PLATFORM_WINDOWS -/* create a string from a wstr */ +/** + * Create a utf-8 string from a Wide String. + */ char *sentry__string_from_wstr(const wchar_t *s); -/* convert a normal string to a wstr */ +/** + * Convert a normal string to a Wide String. + */ wchar_t *sentry__string_to_wstr(const char *s); #endif +/** + * Writes the utf-8 encoding of unicode character `c` into `buf`, and returns + * the number of bytes written. + */ size_t sentry__unichar_to_utf8(uint32_t c, char *buf); #define sentry__is_lead_surrogate(c) ((c) >= 0xd800 && (c) < 0xdc00) diff --git a/src/sentry_symbolizer.h b/src/sentry_symbolizer.h index 1437408c7..8afff25c9 100644 --- a/src/sentry_symbolizer.h +++ b/src/sentry_symbolizer.h @@ -13,6 +13,10 @@ typedef struct sentry_frame_info_s { uint32_t lineno; } sentry_frame_info_t; +/** + * This will symbolize the provided `addr`, and call `func` with a populated + * frame info and the given `data`. + */ bool sentry__symbolize( void *addr, void (*func)(const sentry_frame_info_t *, void *), void *data); diff --git a/src/sentry_sync.h b/src/sentry_sync.h index 9f6e5faa9..871a3a292 100644 --- a/src/sentry_sync.h +++ b/src/sentry_sync.h @@ -275,13 +275,42 @@ typedef struct sentry_bgworker_s sentry_bgworker_t; typedef void (*sentry_task_function_t)(void *data); +/** + * Creates a new background worker thread. + */ sentry_bgworker_t *sentry__bgworker_new(void); + +/** + * Free the background worker. + */ void sentry__bgworker_free(sentry_bgworker_t *bgw); + +/** + * Start a new background worker thread associated with `bgw`. + */ void sentry__bgworker_start(sentry_bgworker_t *bgw); + +/** + * This will try to shut down the background worker thread, with a `timeout`. + * Returns 0 on success. + */ int sentry__bgworker_shutdown(sentry_bgworker_t *bgw, uint64_t timeout); + +/** + * This will submit a new task to the background thread. + * Returns 0 on success. + */ int sentry__bgworker_submit(sentry_bgworker_t *bgw, sentry_task_function_t exec_func, sentry_task_function_t cleanup_func, void *data); + +/** + * This function will iterate through all the current tasks of the worker + * thread, and will call the `callback` function for each task with a matching + * `exec_func`. The callback can return `true` to indicate if the current task + * should be dropped from the queue. + * The function will return the number of dropped tasks. + */ size_t sentry__bgworker_foreach_matching(sentry_bgworker_t *bgw, sentry_task_function_t exec_func, bool (*callback)(void *task_data, void *data), void *data); diff --git a/src/sentry_transport.h b/src/sentry_transport.h index a8175d30b..1b22b3aee 100644 --- a/src/sentry_transport.h +++ b/src/sentry_transport.h @@ -3,8 +3,15 @@ #include "sentry_boot.h" +/** + * This will create a new platform specific HTTP transport. + */ sentry_transport_t *sentry__transport_new_default(void); +/** + * This function will instruct the platform specific transport to dump all the + * envelopes in its send queue to disk. + */ void sentry__transport_dump_queue(sentry_transport_t *transport); #define SENTRY_RL_CATEGORY_ANY 0 @@ -15,16 +22,42 @@ void sentry__transport_dump_queue(sentry_transport_t *transport); struct sentry_rate_limiter_s; typedef struct sentry_rate_limiter_s sentry_rate_limiter_t; +/** + * This will create a new rate limiter. + */ sentry_rate_limiter_t *sentry__rate_limiter_new(void); + +/** + * Free a previously allocated rate limiter. + */ void sentry__rate_limiter_free(sentry_rate_limiter_t *rl); + +/** + * This will update the rate limiters internal state based on the + * `X-Sentry-Rate-Limits` header. + */ bool sentry__rate_limiter_update_from_header( sentry_rate_limiter_t *rl, const char *sentry_header); + +/** + * This will update the rate limiters internal state based on the `Retry-After` + * header. + */ bool sentry__rate_limiter_update_from_http_retry_after( sentry_rate_limiter_t *rl, const char *retry_after); + +/** + * This will return `true` if the specified `category` is currently rate + * limited. + */ bool sentry__rate_limiter_is_disabled( const sentry_rate_limiter_t *rl, int category); #if SENTRY_UNITTEST +/** + * The rate limiters state is completely opaque. Unless in tests, where we would + * want to actually peek into the specific rate limiting `category`. + */ uint64_t sentry__rate_limiter_get_disabled_until( const sentry_rate_limiter_t *rl, int category); #endif diff --git a/src/sentry_unix_pageallocator.h b/src/sentry_unix_pageallocator.h index ed6efea3d..290192bc0 100644 --- a/src/sentry_unix_pageallocator.h +++ b/src/sentry_unix_pageallocator.h @@ -3,11 +3,29 @@ #include "sentry_boot.h" +/** + * Returns the state of the page allocator. + */ bool sentry__page_allocator_enabled(void); + +/** + * Enables the special page allocator, which is used instead of `malloc` inside + * of signal handlers. + * Once it is enabled, it can not be safely disabled without leaking memory. + */ void sentry__page_allocator_enable(void); + +/** + * This is a replacement for `malloc`, but will return an allocation from + * anonymously mapped pages. + */ void *sentry__page_allocator_alloc(size_t size); #if SENTRY_UNITTEST +/** + * This disables the page allocator, which invalidates every allocation that was + * done through it. Therefore it is only safe to use in unit tests + */ void sentry__page_allocator_disable(void); #endif diff --git a/src/sentry_unix_spinlock.h b/src/sentry_unix_spinlock.h index 489d2a354..f04b7bcb4 100644 --- a/src/sentry_unix_spinlock.h +++ b/src/sentry_unix_spinlock.h @@ -5,6 +5,12 @@ typedef volatile sig_atomic_t sentry_spinlock_t; +/** + * On UNIX Systems, inside the signal handler, sentry will switch from standard + * `malloc` to a custom page-based allocator, which is protected by this special + * spinlock. + */ + #if (defined(__i386__) || defined(__amd64__)) # define sentry__cpu_relax() __asm__ __volatile__("pause\n") #else diff --git a/src/sentry_utils.h b/src/sentry_utils.h index c04a5ab58..946cfc8e6 100644 --- a/src/sentry_utils.h +++ b/src/sentry_utils.h @@ -9,6 +9,9 @@ # include #endif +/** + * This represents a URL parsed into its different parts. + */ typedef struct { char *scheme; char *host; @@ -20,10 +23,21 @@ typedef struct { char *password; } sentry_url_t; +/** + * Parse the given `url` into the pre-allocated `url_out` parameter. + * Returns 0 on success. + */ int sentry__url_parse(sentry_url_t *url_out, const char *url); +/** + * This will free all the internal members of `url`, but not `url` itself, as + * that might have been stack allocated. + */ void sentry__url_cleanup(sentry_url_t *url); +/** + * This is the internal representation of a parsed DSN. + */ typedef struct { bool is_secure; char *host; @@ -35,36 +49,45 @@ typedef struct { bool empty; } sentry_dsn_t; +/** + * This will parse the DSN URL given in `dsn` into the pre-allocated `dsn_out`. + * Returns 0 on success. + */ int sentry__dsn_parse(sentry_dsn_t *dsn_out, const char *dsn); + +/** + * This will free all the internal members of `dsn`, but not `dsn` itself, as + * that might have been stack allocated. + */ void sentry__dsn_cleanup(sentry_dsn_t *dsn); + +/** + * This will create a new string, with the contents of the `X-Sentry-Auth`, as + * described here: + * https://docs.sentry.io/development/sdk-dev/overview/#authentication + */ char *sentry__dsn_get_auth_header(const sentry_dsn_t *dsn); + +/** + * This returns a new string, with the URL for normal event and envelope + * uploads. + */ char *sentry__dsn_get_store_url(const sentry_dsn_t *dsn); + +/** + * This returns a new string, with the URL for minidump uploads. + */ char *sentry__dsn_get_minidump_url(const sentry_dsn_t *dsn); + +/** + * This returns a new string, with the URL for attachment uploads. + */ char *sentry__dsn_get_attachment_url( const sentry_dsn_t *dsn, const sentry_uuid_t *event_id); -#ifdef SENTRY_PLATFORM_WINDOWS -# define EINTR_RETRY(X, Y) \ - do { \ - int _tmp = (X); \ - if (Y) { \ - *(int *)Y = _tmp; \ - } \ - } while (false) -#else -# define EINTR_RETRY(X, Y) \ - do { \ - int _tmp; \ - do { \ - _tmp = (X); \ - } while (_tmp == -1 && errno == EINTR); \ - if (Y != 0) { \ - *(int *)Y = _tmp; \ - } \ - } while (false) -#endif - -/* returns the number of milliseconds since epoch. */ +/** + * Returns the number of milliseconds since the unix epoch. + */ static inline uint64_t sentry__msec_time(void) { @@ -90,10 +113,9 @@ sentry__msec_time(void) #endif } -/* formats a timestamp (milliseconds since epoch). */ +/** + * Formats a timestamp (milliseconds since epoch) into ISO8601 format. + */ char *sentry__msec_time_to_iso8601(uint64_t time); -#define SENTRY_CONCAT_IMPL(A, B) A##B -#define SENTRY_CONCAT(A, B) SENTRY_CONCAT_IMPL(A, B) - #endif diff --git a/src/sentry_uuid.h b/src/sentry_uuid.h index 209733fab..aacd6bbe6 100644 --- a/src/sentry_uuid.h +++ b/src/sentry_uuid.h @@ -4,6 +4,9 @@ #include "sentry_boot.h" #ifdef SENTRY_PLATFORM_WINDOWS +/** + * Create a new UUID from the windows-native GUID type. + */ sentry_uuid_t sentry__uuid_from_native(GUID *guid); #endif diff --git a/src/sentry_value.h b/src/sentry_value.h index 99a1e72c6..d591b9369 100644 --- a/src/sentry_value.h +++ b/src/sentry_value.h @@ -3,28 +3,81 @@ #include "sentry_boot.h" +/** + * Create a new Value from an owned string. + */ sentry_value_t sentry__value_new_string_owned(char *s); + #ifdef SENTRY_PLATFORM_WINDOWS +/** + * Create a new Value from a Wide String. + */ sentry_value_t sentry__value_new_string_from_wstr(const wchar_t *s); #endif + +/** + * Create a new String Value, with the hex-formatted value of `addr`. + */ sentry_value_t sentry__value_new_addr(uint64_t addr); + +/** + * Creates a new String Value, with a hex representation of `bytes`. + */ sentry_value_t sentry__value_new_hexstring(const uint8_t *bytes, size_t len); + +/** + * Creates a new String Value from the `uuid`. + * See also `sentry_uuid_as_string`. + */ sentry_value_t sentry__value_new_uuid(const sentry_uuid_t *uuid); + +/** + * Creates a new String Value from the given `level`. + * This can be `debug`, `warning`, `error`, `fatal`, or `info`. + */ sentry_value_t sentry__value_new_level(sentry_level_t level); +/** + * Creates a new List Value with a capacity of `size`. + */ sentry_value_t sentry__value_new_list_with_size(size_t size); + +/** + * Creates a new Object Value with a capacity of `size`. + */ sentry_value_t sentry__value_new_object_with_size(size_t size); +/** + * This will parse the Value into a UUID, or return a `nil` UUID on error. + * See also `sentry_uuid_from_string`. + */ sentry_uuid_t sentry__value_as_uuid(sentry_value_t value); + +/** + * This will create a simplified string representation of the value. + * Lists, Objects and `null` will be converted to an empty string. + */ char *sentry__value_stringify(sentry_value_t value); -/* performs a shallow clone. On a frozen value this produces an unfrozen one +/** + * Performs a shallow clone. + * On a frozen value this produces an unfrozen one. */ sentry_value_t sentry__value_clone(sentry_value_t value); + +/** + * This appends `v` to the List `value`. + * It will remove the first value of the list, is case the total number if items + * would exceed `max`. + * + * Returns 0 on success. + */ int sentry__value_append_bounded( sentry_value_t value, sentry_value_t v, size_t max); -// this is actually declared in sentry_json.h +/** + * Parse the given JSON string into a new Value. + */ sentry_value_t sentry__value_from_json(const char *buf, size_t buflen); #endif diff --git a/src/sentry_windows_dbghelp.h b/src/sentry_windows_dbghelp.h index 8352c0c6b..2bd03ae03 100644 --- a/src/sentry_windows_dbghelp.h +++ b/src/sentry_windows_dbghelp.h @@ -3,6 +3,10 @@ #include "sentry_boot.h" +/** + * This will initialize the symbol handler for the current process, and return a + * `HANDLE` to it. + */ HANDLE sentry__init_dbghelp(void); #endif diff --git a/src/transports/sentry_disk_transport.h b/src/transports/sentry_disk_transport.h index fdf3ebd35..64def60d8 100644 --- a/src/transports/sentry_disk_transport.h +++ b/src/transports/sentry_disk_transport.h @@ -4,6 +4,11 @@ #include "sentry_boot.h" #include "sentry_database.h" +/** + * This creates a new transport that serializes envelopes to disk in the given + * `run` directory. + * See `sentry__run_write_envelope`. + */ sentry_transport_t *sentry_new_disk_transport(const sentry_run_t *run); #endif diff --git a/src/transports/sentry_function_transport.h b/src/transports/sentry_function_transport.h index 3bc81fb18..f44b5edc9 100644 --- a/src/transports/sentry_function_transport.h +++ b/src/transports/sentry_function_transport.h @@ -3,6 +3,9 @@ #include "sentry_boot.h" +/** + * Create a new simple function transport. + */ sentry_transport_t *sentry_new_function_transport( void (*func)(sentry_envelope_t *envelope, void *data), void *data);