Skip to content

Conversation

@wayne-o
Copy link

@wayne-o wayne-o commented Dec 6, 2025

Summary

  • Add sync.Mutex to serialize all exported CGO functions
  • Prevents SIGSEGV crashes when the shared library is called concurrently from multiple threads

Problem

When using the compiled shared library (.so/.dylib) from .NET via P/Invoke, concurrent calls to exported functions cause segmentation faults (exit code 139). This happens because:

  1. The global chainId variable is written without synchronization
  2. The client.GetClient() / client.CreateClient() functions use a non-thread-safe map internally

Solution

Wrap all 19 exported functions with mu.Lock() / defer mu.Unlock() to ensure only one thread can access the Go runtime state at a time.

Testing

Tested with concurrent .NET threads (20 threads × 10 iterations = 200 concurrent signing operations) - all pass without crashes.

@alexvelea
Copy link
Collaborator

The global chainId variable is written without synchronization

This is true. I'm gonna fix this.

The client.GetClient() / client.CreateClient() functions use a non-thread-safe map internally

This is not true, all the access to maps / defaults are guarded by txClientMu

Wrapping all methods in a Mutex is not desired, as signing takes around 2ms and signing in paralel should be supported

@alexvelea
Copy link
Collaborator

Can you check if it works in #43 @wayne-o ?
I've added tmp-build to the repo.

Also, if you could provide some stack traces, highly welcomed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants