Loading
Commits on Source 55
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
Co-Authored-By:Claude Opus 4.7 <noreply@anthropic.com>
-
cznic authored
Co-Authored-By:Claude Opus 4.7 <noreply@anthropic.com>
-
cznic authored
-
cznic authored
This document provides essential context and instructions for the Gemini AI assistant when working within the modernc.org/libc repository. It summarizes key architectural details, such as the split between musl-derived and hand-written code paths. It also outlines common commands for building and testing, important build tags (like libc.membrk and libc.memgrind), and conventions for symbol naming and TLS management, ensuring smoother future development sessions.
-
cznic authored
This resolves issue #4 from review-findings.md. Previously, Xfread and Xfwrite on darwin, freebsd, netbsd, openbsd, and windows would panic with a divide-by-zero error if called with size=0. This adds an early return check to match POSIX behavior (which states if size or nmemb is 0, the functions return 0 and leave stream unchanged).
-
cznic authored
This commit resolves issue #1 from review-findings.md. Previously, Xpthread_join in pthread_musl.go incorrectly read the result of the caller thread instead of the joined thread. It has been corrected to read the result from the joinee thread 't' rather than 'tls.pthread'. Additionally, issues #1 and #4 have been marked as resolved in the review-findings.md document (issue #4 was addressed in a prior commit).
-
cznic authored
This commit resolves issue #2 from review-findings.md. Previously, Xpthread_detach was incorrectly attempting to detach the caller thread (tls.pthread) instead of the target thread 't'. Additionally, it did not handle the _DT_JOINABLE state, which caused it to panic on the common case when detaching a freshly created thread. Both issues have been corrected in pthread_musl.go, and the bug has been marked as resolved in the review-findings.md document.
-
cznic authored
This commit addresses issue #6 from review-findings.md. Previously, the Xexit function in both libc.go and libc_musl.go iterated forward through the atExit and atExitHandlers slices, executing them in their order of registration. POSIX requires these handlers to be executed in reverse order. The loops have been updated to iterate backwards, ensuring correct cleanup ordering. The bug has also been struck out in the review-findings.md document.
-
cznic authored
This commit resolves issue #5 from review-findings.md. Previously, Xfgets in libc.go wrote up to 'size' characters plus a null byte, which could overflow the target buffer by one byte since fgets is only allowed to write at most 'size-1' characters plus the null terminator. The loop condition has been corrected from 'size > 0' to 'size > 1' to reserve space for the null byte. Additional checks for size <= 1 have also been added to ensure exact compliance with POSIX. The bug has been marked as resolved in the review-findings.md document.
-
cznic authored
This commit addresses issue #3 from review-findings.md. Previously, Xrealloc in mem_brk_musl.go did not check if the allocation via malloc0 failed (i.e. returned 0). If it did, it would panic when attempting to copy data via unsafe.Slice. Furthermore, it would free the old pointer, violating the POSIX requirement that the original pointer remains valid upon realloc failure. An early return check has been added to immediately return 0 on failure without freeing the old pointer. The bug has also been marked as resolved in the review-findings.md document.
-
cznic authored
This commit resolves issue #7 from review-findings.md. Previously, the AtomicAddFloat32 and AtomicAddFloat64 functions in atomic.go were implemented as non-atomic load-modify-store sequences, meaning that concurrent callers could lose their respective updates. They have now been rewritten to use an atomic.CompareAndSwap loop on the underlying bit patterns, guaranteeing correct concurrent behavior. The issue has also been struck out in the review-findings.md document.
-
cznic authored
This commit resolves issue #8 from review-findings.md. Previously, the allocators in mem.go, mem_brk.go, memgrind.go, and memgrind_musl.go calculated the requested bytes using a direct integer multiplication `n * size`. On 32-bit systems, or with sufficiently large values on 64-bit systems, this could wrap around to an incorrectly small allocation size, circumventing OOM failures. The logic has been updated to use the math/bits Mul function to safely detect overflow and correctly return 0 and set ENOMEM in all four of these allocation paths, making them consistent with the safe pattern in mem_musl.go. The bug has also been struck out in the review-findings.md document.
-
cznic authored
This commit addresses issue #9 from review-findings.md. Previously, the Xrealloc function in memgrind.go and memgrind_musl.go removed the original pointer from the auditing map (allocs) before calling the underlying allocator's realloc. If the realloc call failed (OOM), it correctly returned 0, but the pointer was left in an untracked state, causing any subsequent free() of that pointer to panic with "free of unallocated memory". The bookkeeping logic has been moved to execute only upon a successful realloc, ensuring that if realloc fails, the original pointer remains tracked and valid, in accordance with POSIX semantics. The bug has also been struck out in review-findings.md.
-
cznic authored
This commit addresses issue #10 from review-findings.md. Previously, the UsableSize function in mem_brk.go attempted to determine the allocated size of a memory block by indiscriminately inspecting memory immediately preceding the pointer. If UsableSize was called with a null pointer (0), it would panic due to an invalid memory dereference. A nil check `if p == 0 { return 0 }` has been added to safely handle null pointers, matching the implementation of Xmalloc_usable_size in mem.go and the behavior of UsableSize in mem_brk_musl.go. The bug has also been marked as resolved in the review-findings.md document.
-
cznic authored
This commit addresses issue #11 from review-findings.md. Previously, the Xsignal implementation in libc_unix.go would spawn a new goroutine and allocate a fresh NewTLS() context every time a custom signal handler was registered. If handlers were replaced, the previous goroutines were not stopped, leading to goroutine leaks and double-firing. The fresh TLS per delivery also meant that errno and sigprocmask states were lost across signal executions. The logic has been rewritten to lazily initialize a single background goroutine and a single global TLS context for signal handling. When Xsignal is called, it now multiplexes notifications into a single shared channel and uses the most recently registered handler from the signals array. This prevents leaks, ensures only the correct handler fires, and preserves the signal thread TLS state. The issue has also been struck out in the review-findings.md document.
-
cznic authored
This commit addresses issue #12 from review-findings.md. Previously, the Xpthread_join and Xpthread_detach functions in pthread.go assumed that the thread ID provided was always valid and present in the global threads map. If an unknown or already joined thread ID was passed, the map lookup returned nil, leading to a panic when attempting to modify the detached state or wait on the done channel. A nil check has been added to validate the thread lookup in both functions. If the thread is not found in the map, they now correctly return ESRCH as specified by POSIX. The issue has also been crossed out in the review-findings.md document.
-
cznic authored
This commit resolves issue #13 from review-findings.md. Previously, all 32-bit and 64-bit atomic operations (add, sub, and, or, xor, exchange, and compare_exchange) in stdatomic.go synchronized via a global int32Mu or int64Mu mutex. This created a performance bottleneck under high contention, and crucially, failed to interlock correctly with functions like X__c11_atomic_exchangeInt32 which used atomic.SwapInt32 on the same memory without holding the lock. To fix both the performance and synchronization bugs, all relevant 32-bit and 64-bit functions in stdatomic.go have been rewritten to use native Go lock-free primitives from the sync/atomic package. The bug has also been struck out in the review-findings.md document.
-
cznic authored
This commit resolves issue #14 from review-findings.md. Previously, the recursive mutex lock path in pthread_musl.go (Xpthread_mutex_lock) modified the owner's lock count using plain assignments (`count = 1`) and increments (`count++`). While functionally correct since only the owning thread modifies the count, these non-atomic writes could trigger data races when analyzed by tools like Go's `-race` detector, especially because Xpthread_mutex_unlock uses atomic.AddInt32 to decrement it. The assignments and increments have been updated to use atomic.StoreInt32 and atomic.AddInt32 respectively to ensure strict synchronization consistency across all paths. The issue has also been struck out in the review-findings.md document.
-
cznic authored
This commit resolves issue #15 from review-findings.md. Previously, the Xpthread_exit implementation in pthread_musl.go only unlocked the internal __ccgo_join_mutex if the thread's state was strictly _DT_JOINABLE at the time the function began. If a joinable thread was detached concurrently via pthread_detach, the state would change to _DT_DETACHED, causing Xpthread_exit to skip the unlock and leave the mutex permanently locked. The conditional unlock logic has been replaced with an unconditional TryLock followed by an Unlock on the mutex. This reliably guarantees that if the mutex was previously locked during thread creation, it will be properly unlocked and freed exactly once upon exit, regardless of any intermediate state transitions. The bug has also been marked as resolved in the review-findings.md document.
-
cznic authored
This commit resolves issue #16 from review-findings.md. In etc.go, the functions getObject and removeObject paniced when an object wasn't found while still holding objectMu. Since the internal todo() helper terminates the program via os.Exit(1), this wasn't problematic in typical execution. However, if any tool or test suite ever recovered the panic, objectMu would be permanently left in a locked state, leading to subsequent deadlocks. This issue has been fixed by replacing the explicit objectMu.Unlock() calls with defer objectMu.Unlock() statements immediately following the lock acquisition. The bug has also been marked as resolved in the review-findings.md document.
-
cznic authored
This commit resolves issue #17 from review-findings.md. Previously, the Xpthread_cond_timedwait implementation in pthread.go contained a race condition. If a timeout elapsed concurrently with a condition variable signal, the timeout path would remove the thread from the cond's waiters map but could leave the wakeup token lingering in the thread's buffered `t.wait` channel. This old token would then spuriously wake up the thread on its next call to cond_wait. This has been fixed by draining the `t.wait` channel using a non-blocking select statement while holding the condition variable's lock in the timeout handler. This guarantees that any concurrently sent token is safely discarded. The issue has also been marked as resolved in the review-findings.md document.
-
cznic authored
This commit resolves issue #18 from review-findings.md. In libc_windows.go, the dmesg tracing format strings for Xfread and Xfwrite expected six formatting verbs (`%v %d %#x %#x %#x %s`), but only five arguments were provided because the sixth argument (a hex dump) was previously removed. This resulted in a `!s(MISSING)` error formatting message when `libc.dmesg` was enabled. The trailing `\n%s` has been removed from the format strings to accurately match the five arguments provided. The issue has also been marked as resolved in the review-findings.md document.
-
cznic authored
This commit resolves issue #19 from review-findings.md. In libc_openbsd.go, the strace dump within Xfread previously attempted to read and log the contents of the output buffer immediately upon function entry. This was problematic as the buffer is uninitialized at that stage, resulting in garbage being logged and potential memory safety violations. Furthermore, the stream argument (an opaque FILE*) was incorrectly dereferenced as a *int32. The strace format string and arguments have been updated to match the safer implementation found in Xfwrite, which logs the raw pointer values and size metadata without attempting to dereference uninitialized or opaque data. The bug has also been crossed out in the review-findings.md document.
-
cznic authored
This commit resolves issue #20 from review-findings.md. Previously, the musl implementation of Xsysctlbyname in libc_musl.go unconditionally panicked with todo("") for any unsupported sysctl queries before attempting to return an ENOENT error code. This made the return logic unreachable and aggressively crashed programs querying for unhandled properties. The panic has been removed from the default switch case, allowing the function to gracefully return -1 and set errno to ENOENT as expected for unsupported system configuration queries. The issue has been marked as resolved in the review-findings.md document.
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
The shared libc_freebsd.go was hand-written assuming amd64: it stores int64 into time.Tm.Ftm_gmtoff (which is int32 on freebsd/386 and freebsd/arm), mixes raw uint64 literals with size_t arithmetic (size_t is uint32 on 32-bit FreeBSD), reads 8 bytes at a time in the strchrnul SWAR loop, and advances env pointers by hardcoded 8. None of this compiles on freebsd/386 or freebsd/arm. Fixes: * setTmGmtoff: new per-arch helper in libc_freebsd_{386,amd64,arm,arm64}.go, stores at the platform-native width matching time.Tm.Ftm_gmtoff. * assignSizeT / postIncSizeT: size_t analogues of AssignUint64 / PostIncUint64, added to libc_freebsd.go (works on every FreeBSD arch since size_t is the right width by definition). * Replace uint64(N) literals in setenv/__putenv/__env_rm_add with size_t(N) so they participate in size_t arithmetic at the native width. * Rewrite the strchrnul SWAR word loop to step by unsafe.Sizeof(size_t(0)) and read *(*size_t), so the all-ones / high-bit masks are computed at native word width. * Replace hardcoded *8 pointer-array indexing in env code with *unsafe.Sizeof(uintptr(0)) and "e += 8" with "e += unsafe.Sizeof(uintptr(0))". Verified with "go build ./..." and "go vet ./..." for GOOS=freebsd GOARCH={386,amd64,arm,arm64}; vet output is identical to the v1.72.3 baseline (no new warnings). -
cznic authored