Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .cursor/rules/01-project-overview.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Sentry Native SDK - Project Overview

This is the **Sentry Native SDK**, a C/C++ crash reporting and error monitoring library that serves as the foundation for other Sentry SDKs (Android, Unity, Unreal Engine).

## Core Architecture

The SDK is structured around multiple **backends** for crash handling:
- **crashpad**: Out-of-process handler (default on Windows, macOS, Linux desktop)
- **breakpad**: In-process handler (desktop platforms)
- **inproc**: Minimal in-process handler (default on Android, mobile)
- **none**: No crash handling (testing only)

## Platform Support Matrix

**Officially Supported:**
- Windows (MSVC 2019/2022, MinGW, ClangCL)
- macOS 13+ (Xcode LLVM, clang 15/18)
- Linux (GCC 9-14, clang 19, x86/x64/arm64)
- Android (API 16+ with NDK 19/27)
- iOS (Xcode builds)
- Gaming platforms (Xbox, PlayStation)

**Transport Layer:**
- **curl**: Linux, macOS (requires libcurl)
- **winhttp**: Windows system library
- **none**: Custom user implementations

## SDK Foundation Role

This SDK is **NOT** meant to be used standalone - it's designed as a robust foundation for higher-level SDKs:
- [sentry-java](mdc:ndk/README.md) (Android integration)
- [sentry-unreal](mdc:README.md) (Unreal Engine)
- Unity SDK integration
- Direct C/C++ usage (experimental)

## Key Design Principles

1. **Thread Safety**: All public APIs are thread-safe
2. **Signal Safety**: Core functionality works in signal handlers
3. **Minimal Dependencies**: Self-contained with vendored dependencies
4. **Cross-Platform**: Consistent API across all platforms
5. **Performance**: Minimal overhead in normal operation
6. **Robustness**: Must not crash the host application

## Build System

- **CMake-based** with extensive configuration options
- **Static/Shared** library support
- **Cross-compilation** support for all platforms
- **Submodule dependencies** in [external/](mdc:external)

Reference the [README.md](mdc:README.md) for detailed platform support and [CONTRIBUTING.md](mdc:CONTRIBUTING.md) for development setup.
150 changes: 150 additions & 0 deletions .cursor/rules/02-api-design-conventions.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# API Design & Coding Conventions

## Naming Conventions

**Public API Functions:**
- All public functions start with `sentry_`
- Use snake_case: `sentry_capture_event()`, `sentry_options_new()`
- Experimental APIs: `SENTRY_EXPERIMENTAL_API` attribute
- Deprecated APIs: `SENTRY_DEPRECATED("message")` attribute

**Internal Functions:**
- Private functions use `sentry__` (double underscore): `sentry__scope_lock()`
- Static functions can omit prefix within compilation units
- Platform-specific suffixes: `_windows`, `_unix`, `_darwin`

**Types and Constants:**
- Types: `sentry_value_t`, `sentry_options_t` (typedef structs)
- Enums: `SENTRY_LEVEL_ERROR`, `SENTRY_VALUE_TYPE_STRING`
- Constants: `SENTRY_SDK_VERSION`, `SENTRY_BREADCRUMBS_MAX`

## Memory Management Patterns

**Reference Counting:**
```c
// Values use ref counting - always match incref/decref
sentry_value_t val = sentry_value_new_string("hello"); // starts at ref count 1
sentry_value_incref(val); // Optional increment
sentry_value_decref(val); // Required decrement

// Ownership transfer functions consume references
sentry_value_append(list, val); // `val` is consumed, don't decref
```

**Allocation Helpers:**
```c
// Use typed allocation macro
my_struct_t *obj = SENTRY_MAKE(my_struct_t);
if (!obj) return NULL; // Always check allocation failures

// Custom allocator for signal safety
#ifdef WITH_PAGE_ALLOCATOR
if (sentry__page_allocator_enabled()) {
return sentry__page_allocator_alloc(size);
}
#endif
```

## Error Handling Patterns

**Return Value Conventions:**
- `0` = success, non-zero = failure (for int returns)
- `NULL` = failure for pointer returns
- `sentry_value_new_null()` = failure for sentry_value_t returns

**Error Propagation:**
```c
static int
example_function(void) {
thing_t *thing = allocate_thing();
if (!thing) {
goto fail; // Use goto for cleanup
}

if (setup_thing(thing) != 0) {
goto fail;
}

return 0; // Success

fail:
cleanup_thing(thing); // Clean up on failure
return 1; // Failure
}
```

## Thread Safety Requirements

**Mutex Usage:**
```c
// Use dynamic mutex initialization for cross-platform support
#ifdef SENTRY__MUTEX_INIT_DYN
SENTRY__MUTEX_INIT_DYN(g_lock)
#else
static sentry_mutex_t g_lock = SENTRY__MUTEX_INIT;
#endif

// Always use RAII-style locking
sentry_scope_t *scope = sentry__scope_lock();
// ... use scope
sentry__scope_unlock();
```

**Atomic Operations:**
```c
// Use atomic operations for lock-free operations
sentry__atomic_fetch_and_add(&thing->refcount, 1);
```

## Platform Abstraction

**Conditional Compilation:**
```c
#ifdef SENTRY_PLATFORM_WINDOWS
// Windows-specific code
#elif defined(SENTRY_PLATFORM_DARWIN)
// macOS/iOS-specific code
#elif defined(SENTRY_PLATFORM_UNIX)
// Unix-like systems
#endif
```

**Feature Detection:**
```c
#ifdef SENTRY_BACKEND_CRASHPAD
# define SENTRY_BACKEND "crashpad"
#elif defined(SENTRY_BACKEND_BREAKPAD)
# define SENTRY_BACKEND "breakpad"
#endif
```

## Value System Architecture

The core `sentry_value_t` uses **tagged pointers** for efficient storage:
- Supports: null, bool, int32, double, string, list, object
- Automatic memory management with reference counting
- Immutable when frozen (thread-safe sharing)

**Value Creation Patterns:**
```c
// Prefer stack allocation for simple values
sentry_value_t obj = sentry_value_new_object();
sentry_value_set_by_key(obj, "key", sentry_value_new_string("value"));

// Use size hints for performance
sentry_value_t list = sentry__value_new_list_with_size(expected_size);
```

## String Handling

**Safe String Operations:**
```c
// Always use length-aware functions
char *str = sentry__string_clone_n(input, input_len);

// Use slices for borrowed strings
sentry_slice_t slice = sentry__slice_from_str(str);
char *owned = sentry__slice_to_owned(slice);
```

See [sentry.h](mdc:include/sentry.h) for the complete public API and [src/sentry_value.h](mdc:src/sentry_value.h) for internal patterns.
137 changes: 137 additions & 0 deletions .cursor/rules/03-testing-practices.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Testing Practices

## Test Structure

**Unit Tests** ([tests/unit/](mdc:tests/unit/)):
- Located in `tests/unit/test_*.c`
- Registered in [tests/unit/tests.inc](mdc:tests/unit/tests.inc) using `XX(test_name)` macro
- Built into single `sentry_test_unit` executable

**Integration Tests** ([tests/](mdc:tests/)):
- Python-based using pytest framework
- Test real SDK behavior with `sentry_example` binary
- HTTP server mocking with `pytest-httpserver`
- Cross-platform CI execution

## Unit Test Conventions

**Test Function Structure:**
```c
SENTRY_TEST(descriptive_test_name)
{
// Setup phase
SENTRY_TEST_OPTIONS_NEW(options);
sentry_options_set_dsn(options, "https://[email protected]/42");
sentry_init(options);

// Test phase
sentry_value_t event = sentry_value_new_event();
sentry_uuid_t event_id = sentry_capture_event(event);

// Verification phase
TEST_CHECK(!sentry_uuid_is_nil(&event_id));
TEST_CHECK_STRING_EQUAL(actual_str, "expected");

// Cleanup phase
sentry_close();
}
```

**Assertion Macros:**
- `TEST_CHECK(condition)` - Basic condition check
- `TEST_CHECK_STRING_EQUAL(actual, expected)` - String comparison
- `TEST_CHECK_INT_EQUAL(actual, expected)` - Integer comparison
- `TEST_CHECK_JSON_VALUE(value, json_string)` - JSON structure comparison

**Memory Management in Tests:**
```c
// Always clean up test artifacts
sentry_path_t *path = sentry__path_from_str(".test-db");
sentry__path_remove_all(path); // Clean before test
// ... test code ...
sentry__path_remove_all(path); // Clean after test
sentry__path_free(path);
```

## Integration Test Patterns

**Basic HTTP Test:**
```python
def test_capture_event(cmake, httpserver):
tmp_path = cmake(["sentry_example"], {"SENTRY_BACKEND": "crashpad"})

# Mock HTTP endpoint
httpserver.expect_request("/api/123456/envelope/").respond_with_data("OK")

# Run example with test DSN
run(tmp_path, "sentry_example", ["capture-event"],
env=dict(os.environ, SENTRY_DSN=make_dsn(httpserver)))

# Verify request received
assert len(httpserver.log) == 1
envelope = Envelope.deserialize(httpserver.log[0].get_data())
assert_event(envelope.get_event())
```

**Platform-Specific Tests:**
```python
# Use condition decorators for platform/feature requirements
@pytest.mark.skipif(not has_crashpad, reason="needs crashpad backend")
def test_crashpad_specific_feature():
pass

@pytest.mark.skipif(is_android, reason="not supported on Android")
def test_desktop_only_feature():
pass
```

## Test Execution Environments

**CI Matrix** (see [.github/workflows/ci.yml](mdc:.github/workflows/ci.yml)):
- Multiple compilers: GCC 9-14, Clang 19, MSVC 2019/2022
- Multiple architectures: x86, x64, arm64
- Multiple platforms: Windows, macOS, Linux, Android
- Analysis tools: ASan, Valgrind, Coverage (kcov/llvm-cov)

**Local Development:**
```bash
# Run all tests
make test

# Run specific unit test
./build/sentry_test_unit test_name

# Run integration tests with filters
pytest tests/ -k "test_pattern" --verbose
```

## Example Program Usage

The [sentry_example](mdc:examples/example.c) binary supports extensive test scenarios:

**Common Test Commands:**
- `capture-event` - Basic event capture
- `crash` - Trigger segmentation fault
- `attachment` - Test file attachments
- `before-send` - Test filtering hooks
- `capture-transaction` - Performance monitoring
- `start-session` - Release health sessions

**Platform-Specific Commands:**
- `fastfail` (Windows) - Test Control Flow Guard crashes
- `stack-overflow` - Test stack overflow handling
- `http-proxy` - Test proxy configuration

## Test Data Management

**Fixtures:** [tests/fixtures/](mdc:tests/fixtures/)
- Minidump samples for crash processing tests
- OS release files for environment detection tests
- View hierarchy JSON for UI attachment tests

**Test Isolation:**
- Each test gets isolated temporary directory
- Database paths use test-specific prefixes
- HTTP servers use random available ports

Reference [tests/README.md](mdc:tests) for detailed testing setup and [CONTRIBUTING.md](mdc:CONTRIBUTING.md) for development workflow.
Loading
Loading