Thread overview
Issue with socket recieve
Jan 20, 2021
Tim
Jan 21, 2021
Adam D. Ruppe
Jan 21, 2021
Tim
Jan 21, 2021
Adam D. Ruppe
Jan 21, 2021
Tim
Jan 21, 2021
Tim
Jan 22, 2021
Imperatorn
Jan 22, 2021
Mike Parker
January 20, 2021
Hi all,

I'm having a really terrible bug that seemed to come from nowhere and is really hard to narrow down. I have a threaded message service that works via local TcpSocket. Every time I run it, either an error saying:
>Unable to open 'recv.c': Unable to read file '/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c' (Error: Unable to resolve non-existing file '/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c').
when socket.receive() is called. Sometimes I get the same thing but for socket.accept() instead (different file). This seems to generate a core.exception.InvalidMemoryOperationError that I can't catch.

Yesterday, this came up after a couple of minutes of the program running, now it happens straight away. I haven't touched this class in a week or so and can't think of why all of a sudden it has come up with this issue. Code dump below

---------------------------------------------


>module message_service;
>
>import std.stdio;
>import std.socket;
>import core.thread;
>
>
>/**
>Threaded socket manager to serve inter-service communication
>
>Calls delegates when the appropriate command is received
>*/
>class MessageService : Thread{
>    /// The socket over which communication is possible
>    private Socket server;
>    /// The connection to the client that sends commands
>    private Socket client;
>    /// Associative array of command strings and relative functions to call
>    private void delegate()[string] commands;
>    /// Global buffer. Holds the command being recieved
>    private char[1024] buffer = 0;
> 
>
>    ///
>    this(ushort port, void delegate()[string] _commands){
>        commands = _commands;
>        server = new TcpSocket();
>        server.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true);
>        server.bind(new InternetAddress(port));
>        writefln("Message service started on port %d", port);
>        super(&mainLoop);
>        start();
>    }
>
>
>    /// Loops over polling the client socket for commands
>    void mainLoop(){
>        while(true){
>            pollMessages();
>        }
>    }
>
>
>    /**
>    Polls the client socket for characters to build up the message buffer
> 
>    When a string command is found, it calls the appropriate function
>    */
>    void pollMessages(){
>        server.listen(1);
>        if(client is null) client = server.accept();
>
>        // Add to the message buffer
>        auto buffLength = client.receive(buffer);
>
>        if(buffLength){
>            auto message = cast(string) buffer[0 .. buffLength];
> 
>            foreach(cmd; commands.byKey){
>                if(cmd == message){
>                    // Reset the message buffer
>                    buffer = 0;
>                    commands[cmd]();
>                    return;
>                }
>            }
>        }
>    }
>}
January 21, 2021
On Wednesday, 20 January 2021 at 21:31:54 UTC, Tim wrote:
>>Unable to open 'recv.c': Unable to read file '/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c' (Error: Unable to resolve non-existing file '/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c').
> [snip]
> generate a core.exception.InvalidMemoryOperationError that I can't catch.


None of this makes much sense given the code you provided. InvalidMemoryOperationError (the scariest thing in D btw, such a pain to debug) is usually caused by a class destructor somewhere, and none of those should be trying to resolve those files.

Do you have any destructors defined?
January 21, 2021
On Thursday, 21 January 2021 at 03:21:41 UTC, Adam D. Ruppe wrote:
> On Wednesday, 20 January 2021 at 21:31:54 UTC, Tim wrote:
>>>Unable to open 'recv.c': Unable to read file '/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c' (Error: Unable to resolve non-existing file '/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c').
>> [snip]
>> generate a core.exception.InvalidMemoryOperationError that I can't catch.
>
>
> None of this makes much sense given the code you provided. InvalidMemoryOperationError (the scariest thing in D btw, such a pain to debug) is usually caused by a class destructor somewhere, and none of those should be trying to resolve those files.
>
> Do you have any destructors defined?

No, I don't. It should be all garbage collected right?

Hahahaha, about 50% of my troubles are InvalidMemoryOperationError! It's so frustrating. This whole project has been a nightmare
January 21, 2021
On Thursday, 21 January 2021 at 03:21:41 UTC, Adam D. Ruppe wrote:
> On Wednesday, 20 January 2021 at 21:31:54 UTC, Tim wrote:
>>>Unable to open 'recv.c': Unable to read file '/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c' (Error: Unable to resolve non-existing file '/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c').
>> [snip]
>> generate a core.exception.InvalidMemoryOperationError that I can't catch.
>
>
> None of this makes much sense given the code you provided. InvalidMemoryOperationError (the scariest thing in D btw, such a pain to debug) is usually caused by a class destructor somewhere, and none of those should be trying to resolve those files.
>
> Do you have any destructors defined?

You seem like a rather switched-on fellow. Would you be able to send me an email at some point at tim.oliver@tutanota.com. I have a proposition for you.
January 21, 2021
On Thursday, 21 January 2021 at 03:24:13 UTC, Tim wrote:
> No, I don't. It should be all garbage collected right?

Yeah, but that's where the problem comes.

Note that by destructor, I mean *any* function in your code called `~this() {}`. If there are any and they call a memory allocation function, that's how you get the InvalidMemoryOperationError.

I'd have to look up if there's any other causes of that...


January 21, 2021
On Thursday, 21 January 2021 at 03:35:05 UTC, Adam D. Ruppe wrote:
> On Thursday, 21 January 2021 at 03:24:13 UTC, Tim wrote:
>> No, I don't. It should be all garbage collected right?
>
> Yeah, but that's where the problem comes.
>
> Note that by destructor, I mean *any* function in your code called `~this() {}`. If there are any and they call a memory allocation function, that's how you get the InvalidMemoryOperationError.
>
> I'd have to look up if there's any other causes of that...

I am aware of this, there is absolutely no ~this in *my* code
January 22, 2021
On Thursday, 21 January 2021 at 03:30:50 UTC, Tim wrote:
> On Thursday, 21 January 2021 at 03:21:41 UTC, Adam D. Ruppe wrote:
>> On Wednesday, 20 January 2021 at 21:31:54 UTC, Tim wrote:
>>>>[...]
>>> [snip]
>>> generate a core.exception.InvalidMemoryOperationError that I can't catch.
>>
>>
>> None of this makes much sense given the code you provided. InvalidMemoryOperationError (the scariest thing in D btw, such a pain to debug) is usually caused by a class destructor somewhere, and none of those should be trying to resolve those files.
>>
>> Do you have any destructors defined?
>
> You seem like a rather switched-on fellow. Would you be able to send me an email at some point at tim.oliver@tutanota.com. I have a proposition for you.

On Discord fyi
January 22, 2021
On Wednesday, 20 January 2021 at 21:31:54 UTC, Tim wrote:
> Hi all,
>
> I'm having a really terrible bug that seemed to come from nowhere and is really hard to narrow down.

You may be hitting this issue:

https://issues.dlang.org/show_bug.cgi?id=7349

FWIW, popped onto the radar in the most recent Foundation meeting.