Container System 0.1.0
High-performance C++20 type-safe container framework with SIMD-accelerated serialization
Loading...
Searching...
No Matches
Troubleshooting Guide

This page collects the issues most frequently reported by users of Container System and the recommended fixes. For each issue you will find a short list of symptoms, the typical root cause, and the steps to resolve it.

1. Serialization Format Mismatch

Symptoms
  • Deserialization throws or returns an empty container.
  • A field reads back with the wrong type or a corrupted value.
  • The first few bytes of the payload do not match the expected magic.
Likely Cause
The producer and consumer are using different serializers. This commonly happens when one side calls value_container::serialize() (binary) while the other side hands the bytes to serializer_factory::create("json").
Resolution
  • Verify both sides use the same format. The default is binary; if you opted into JSON, XML, or MessagePack on the producer, use the same factory key on the consumer.
  • Confirm the format version matches. If the producer is on a newer release, upgrade the consumer or downgrade the producer to a compatible version.
  • For mixed-version environments, add a small "format probe" message at the start of the session that records the producer's library version.
auto strategy = container_module::serializer_factory::create("msgpack");
auto restored = strategy->deserialize(wire);

2. SIMD Acceleration Not Available

Symptoms
  • Numeric workloads run at the speed of the scalar fallback.
  • Logs report "SIMD path: scalar" (when SIMD logging is enabled).
  • Benchmarks show no improvement on hosts that should support AVX2 or NEON.
Likely Cause
  • The build was configured for a generic target that disabled SIMD intrinsics.
  • The CPU genuinely does not support AVX2 (older x86_64) or you are running inside a virtualization layer that masks AVX2.
  • The container is full of mixed types, so the SIMD batch path cannot fire.
Resolution
  • Rebuild with the matching architecture flags (-march=native for local builds, the project's CI presets for production builds).
  • Confirm the host's capabilities (sysctl -a | grep machdep.cpu.features on macOS, lscpu on Linux). If AVX2 is missing, the scalar fallback is the only option and is producing correct results.
  • For hot loops, group same-typed numeric values together so the SIMD batch path can engage. See the optimize_for_speed() builder hint in Tutorial: Serialization and SIMD.

3. Thread Safety Violations

Symptoms
  • Intermittent crashes under load.
  • Use-after-free reports from a sanitizer.
  • Values reading back as garbage.
  • Tests pass on a single thread but fail under TSAN.
Likely Cause
A bare value_container is being mutated from more than one thread, or being mutated on one thread while another reads it.
Resolution
  • Wrap the container in thread_safe_container for multi-writer access. Reads go through the RCU path; writes are serialized internally.
  • For "build once, share many" patterns, finish construction on one thread, then publish the std::shared_ptr<value_container> and stop mutating it.
  • Run the test suite under TSAN (--preset tsan) to confirm the fix.
#include <container/internal/thread_safe_container.h>
using namespace container_module;
thread_safe_container safe;
safe.set("user_id", static_cast<int64_t>(99));
safe.set("username", std::string("alice"));
// readers (multiple threads, lock-free)
auto snapshot = safe.snapshot();

4. Memory Issues With Large Containers

Symptoms
  • High resident memory when many containers are alive at once.
  • Allocator thrash showing up as malloc/free time in profiles.
  • Out-of-memory errors when handling oversized payloads.
Likely Cause
  • The container memory pool is disabled, or is undersized for your workload.
  • A single container is genuinely too large for in-memory processing.
  • Many small containers are being allocated and freed in a tight loop without reuse.
Resolution
  • Confirm CONTAINER_USE_MEMORY_POOL=ON (the default). If you turned it off, consider re-enabling it.
  • For oversized payloads, chunk the data into multiple smaller containers and store the bulk content out of band (for example, in object storage), then reference it from the container.
  • Reuse messaging_container_builder instances and value_container shells in hot loops instead of constructing fresh ones each iteration.
  • Profile with heaptrack (Linux) or Instruments (macOS) to identify the exact allocation site before tuning.

5. Type Conversion Errors

Symptoms
  • to_int() / to_double() / to_string() throws or returns an unexpected value.
  • Numeric fields silently truncate.
  • A field stored as a string fails to parse on the consumer.
Likely Cause
  • The producer chose a value type that does not match the receiver's expectation (for example, string_value containing "true" versus bool_value).
  • Numeric values exceed the range of the receiver's chosen type (int32_value consumer reading data that was produced as int64_value).
  • A field is missing entirely on the wire and the receiver dereferences a null lookup.
Resolution
  • Always check the type tag before converting:
auto v = container->get_value("count");
if (!v) {
// missing field
} else if (v->type() == int64_value) {
auto count = v->to_long();
} else if (v->type() == int32_value) {
auto count = v->to_int();
} else {
// unexpected wire type, log and reject
}
  • Standardize on a single canonical type per field across producers and consumers. Document it in your service contract.
  • For optional fields, use null_value rather than omitting the field entirely. It makes the schema explicit on both sides.
  • When in doubt, prefer the wider type (int64_value, double_value, string_value) and narrow it on the consumer after a range check.

More Help