On Tuesday, 14 September 2021 at 20:59:14 UTC, Ali Çehreli wrote:
On 9/14/21 9:56 AM, eugene wrote:

> On Tuesday, 14 September 2021 at 16:43:50 UTC, jfondren wrote:

>> The misaligned pointer and the
>> reference-containing struct that vanishes on the return of
your
>> corresponding function are both problems for this.
>
> where did you find 'misaligned pointer'?...

I think it's the align(1) for EpollEvent.

I was able to reproduce the segmentation fault and was seemingly able to fix it by making the EventSource class references alive by adding a constructor:

align (1) struct EpollEvent {
    align(1):
    uint event_mask;
    EventSource es;

  this(uint event_mask, EventSource es) {
    this.event_mask = event_mask;
    this.es = es;
living ~= es; // <-- Introduced this constructor for this line
  }
    /* just do not want to use that union, epoll_data_t */
}

// Here is the array that keeps EventSource alive:
EventSource[] living;

If that really is the fix, of course the references must be taken out of that container when possible.

Ali

Yep. This patch is sufficient to prevent the segfault:

```
diff --git a/engine/ecap.d b/engine/ecap.d
index 71cb646..d57829c 100644
--- a/engine/ecap.d
+++ b/engine/ecap.d
@@ -32,6 +32,7 @@ final class EventQueue {
     private int id;
     private bool done;
     private MessageQueue mq;
+    private EventSource[] sources;

     private this() {
         id = epoll_create1(0);
@@ -52,6 +53,7 @@ final class EventQueue {

     void registerEventSource(EventSource es) {
         auto e = EpollEvent(0, es);
+        sources ~= es;
         int r = epoll_ctl(id, EPOLL_CTL_ADD, es.id, &e);
         assert(r == 0, "epoll_ctl(ADD) failed");
     }
@@ -63,7 +65,10 @@ final class EventQueue {
     }

     void deregisterEventSource(EventSource es) {
+        import std.algorithm : countUntil, remove;
+
         auto e = EpollEvent(0, es);
+        sources = sources.remove(sources.countUntil(es));
         int r = epoll_ctl(id, EPOLL_CTL_DEL, es.id, &e);
         assert(r == 0, "epoll_ctl(DEL) failed");
     }
```

Going through the project and adding @safe: to the top of everything results in these errors: https://gist.github.com/jrfondren/c7f7b47be057273830d6a31372895895 some I/O, some @system functions, some weird C APIs ... and misaligned assignments to EpollEvent.es. So debugging with @safe isn't bad, but I'd still like rustc-style error codes:

```
engine/ecap.d(89): Error E415: field `EpollEvent.es` cannot assign to misaligned pointers in `@safe` code

$ dmd --explain E415

Yeah see, the garbage collector only looks for pointers at pointer-aligned addresses.
```

Reply via email to