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.