Skip to content

PTHREAD_COND_INITIALIZER support#4

Open
gc00 wants to merge 4 commits into
mainfrom
pthread-cond-initializer-support
Open

PTHREAD_COND_INITIALIZER support#4
gc00 wants to merge 4 commits into
mainfrom
pthread-cond-initializer-support

Conversation

@gc00

@gc00 gc00 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Port from classic McMing

@gc00 gc00 requested review from aayushi363 and maxwellpirtle June 30, 2026 17:55
@gc00 gc00 added the enhancement New feature or request label Jun 30, 2026

@maxwellpirtle maxwellpirtle left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comments in PR #3. A similar concept applies and I think we can make these changes on the libmcmini.so side fairly easily. Also, it appears this PR simply concatenates the work of PRs #2 and #3. You may have intended to only include the cond initializer commit?

@gc00

gc00 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Yes, in this case, it's only the last commit that is important. Now that you've accepted PR #2, I no longer have a problem of multiple PRs needed for further code development. I'll push this again with just the last (cond initializer) commit.

And as before, since you're more familiar with the deep-debug code, could you change this code to do everything on the model side? You could do it faster than me -- especially with the help of AI.

@gc00 gc00 force-pushed the pthread-cond-initializer-support branch from 2d935d7 to ed8e78f Compare July 1, 2026 03:42
gc00 and others added 4 commits June 30, 2026 23:44
A mutex declared with PTHREAD_MUTEX_INITIALIZER never flows through the
pthread_mutex_init wrapper, so the model never observes it being
initialized. Previously mutex_lock_callback threw "uninitialized mutex"
in that case (the `// TODO: add code from Gene's PR here` placeholder).

Port the original McMini behavior: on a lock of a mutex the model has
not seen, read the target's memory via process_vm_readv and compare
against PTHREAD_MUTEX_INITIALIZER. On a match, lazily register the mutex
as initialized+unlocked; otherwise report undefined behavior. Unlock is
left reporting undefined behavior for an unknown mutex (faithful to the
original, which does not lazily register on unlock).

- model_to_system_map: expose get_target_pid() so callbacks can read the
  live target's memory.
- coordinator: implement get_target_pid() from the current process handle.
- mutex.cpp: add the process_vm_readv validation helper and port the lock
  callback; fix the mis-copied unlock message.

A FIXME documents that, as in the original McMini, this only detects an
uninitialized mutex for stack/garbage mutexes; a never-initialized
data/heap mutex is zero-filled (== PTHREAD_MUTEX_INITIALIZER on glibc)
and still slips through.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Exercises the reject path of the PTHREAD_MUTEX_INITIALIZER support: a
stack-allocated pthread_mutex_t filled with non-zero garbage (so it cannot
be mistaken for the all-zero PTHREAD_MUTEX_INITIALIZER) is locked without
initialization. McMini reports:

  UNDEFINED BEHAVIOR:
  Attempting to lock an uninitialized mutex

Note the data/heap case is intentionally not detected (zero-filled ==
PTHREAD_MUTEX_INITIALIZER); see the FIXME in
src/mcmini/model/transitions/mutex.cpp.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A condition variable declared with PTHREAD_COND_INITIALIZER never flows
through the pthread_cond_init wrapper, so the model never observes it
being initialized. Previously the enqueue/wait, signal, and broadcast
callbacks threw "uninitialized condition variable" in that case.

Port the original McMini behavior (mirrors the PTHREAD_MUTEX_INITIALIZER
support): on the first operation against a condition variable the model
has not seen, read the target's memory via process_vm_readv and compare
against PTHREAD_COND_INITIALIZER. On a match, lazily register it as
initialized with the arbitrary wakeup policy (as cond_init_callback
does); otherwise report undefined behavior.

The shared logic lives in ensure_cond_initialized(), used by the
enqueue, signal, and broadcast callbacks (the operations that can first
touch a statically-initialized cv). The actual wait callback is
unchanged: it always follows enqueue, which has already registered the
cv. Destroy is also unchanged (destroying a never-initialized cv stays
undefined behavior, faithful to the original).

A FIXME documents that, as in the original McMini, this only detects an
uninitialized cv for stack/garbage cvs; a never-initialized data/heap cv
is zero-filled (== PTHREAD_COND_INITIALIZER on glibc) and still slips
through.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Exercises the reject path of the PTHREAD_COND_INITIALIZER support: a
stack-allocated pthread_cond_t filled with non-zero garbage (so it cannot
be mistaken for the all-zero PTHREAD_COND_INITIALIZER) is signaled without
initialization. McMini reports:

  UNDEFINED BEHAVIOR:
  Attempting to signal an uninitialized condition variable

This complements src/examples/cv-test.c (a global PTHREAD_COND_INITIALIZER
cv, which is accepted). Note the data/heap case is intentionally not
detected (zero-filled == PTHREAD_COND_INITIALIZER); see the FIXME in
src/mcmini/model/transitions/condition_variables.cpp.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gc00 gc00 force-pushed the pthread-cond-initializer-support branch from bcc35a5 to 7dd612d Compare July 1, 2026 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants