Lynxbee topic

C Programming

Build and Use libusb on Ubuntu Linux

Use Ubuntu’s libusb development package for ordinary application builds, or compile a reviewed upstream release into an isolated prefix when you need a newer or controlled version. Then verify the complete toolchain with pkg-config and a real USB device-enumeration program.

Fix curl/curl.h Missing on Ubuntu C Builds

The `curl` command is not the libcurl development kit. Current Ubuntu builds normally need `libcurl4-openssl-dev`, which supplies headers and build metadata. Use pkg-config or CMake’s CURL target so transitive link flags and non-default installation paths remain correct.

Fix openssl/ssl.h Missing on Ubuntu Builds

The OpenSSL command and runtime library are not enough to compile C/C++ code. Ubuntu puts headers, unversioned linker files, and pkg-config metadata in `libssl-dev`. Install it for the correct architecture, then let pkg-config or CMake supply paths instead of hard-coding `/usr/include`.

C atexit(): Cleanup on Normal Termination, Not Every Exit

`atexit()` registers no-argument callbacks for normal program termination. They run in reverse registration order after `main` returns or `exit()` is called—but not after `_Exit()`, `_exit()`, `abort()`, an unhandled fatal signal, a crash, or a forced kill.

Use Splint for C Analysis—and Know When to Move On

Splint can still expose useful C mistakes through annotations and strict checking, but its last upstream release is from 2007. Use it for legacy compatibility or learning—not as the only security control—and pair it with current compilers, path-sensitive analyzers, sanitizers, tests, and human review.

Protect Shared State with pthread_mutex_lock

A POSIX mutex does not make a variable magically private; it gives cooperating threads one serialized critical section and establishes synchronization around protected state. Build a checked C example, understand why the unlocked version is undefined, find races with ThreadSanitizer, and choose between mutexes and atomics.

Link Multiple C Object Files into One Executable

Build one C executable from multiple translation units without turning the project into a library first. The example separates declarations from definitions, compiles object files independently, links them with GCC, inspects symbols, diagnoses common failures, and automates correct incremental rebuilds.

Call C from Java with JNI on Linux

This modern JNI example replaces removed `javah` instructions with `javac -h`, derives the active JDK include path, compiles position-independent C into a shared library, and verifies both the exported symbol and Java-to-native call.

Explore a Running Linux Process Through /proc

Linux procfs exposes a live, file-like view of process state without creating ordinary files on disk. This lab starts a harmless C process, captures its PID, inspects the useful `/proc/PID` entries, and cleans up reliably.

How C Code Becomes a Running Linux Process

A single GCC command hides several distinct transformations, followed later by Linux process startup. Saving each intermediate file makes macros, assembly, ELF objects, linking, and dynamic loading much easier to reason about.

Debug C Programs with GDB on Ubuntu

A debugger becomes useful when a crash that looked random becomes one source line, one call path, and one impossible value. Follow a complete GDB investigation from failure to verified fix.

Fix “Invalid Operands to Binary %” in C

This compiler error means `%` received a floating-point operand. Fix the underlying type choice with integer arithmetic or the appropriate `fmod` function—not a reflexive cast.

Engineering weekly

Useful technical knowledge, not inbox noise.

Receive verified fixes, references, labs, and tools. Confirm by email; unsubscribe any time.