18 hours ago
On 5/7/25 02:04, Walter Bright wrote:
> 
> Having the program stop when it enters an invalid state is a good thing, not a bad thing.

It seems you have been the one who wants `-release` to be used. While that will cause invalid instruction errors sometimes, it will also disable other checks that would detect an invalid state. This goes as far as disabling bounds checks so memory can get corrupted without the program stopping. x)
16 hours ago
On 07/05/2025 12:04 PM, Walter Bright wrote:
> On 5/6/2025 1:53 AM, Richard (Rikki) Andrew Cattermole wrote:
>> This is why its so important to switch over to calling the global functions like assert handler does.
> 
> You cannot know if the global function is corrupted or not at that stage.
> 
> A bad actor can also hijack that global function to facilitate his nefarious schemes.

Which is no different than a signal.

Or our existing assert handler.

>> People can configure it to do whatever they want, we don't have to have a default that is anything but instant crash.
> 
> It's not an instant crash. It generates an invalid instruction fault, which then goes to a handler for it, and the default behavior of that handler is to terminate the process.
> 
> I can tell I'm the oldest person here. I programmed for many years on a machine that had no concept of a fault. When your program crashed, it didn't stop. It kept running. It would execute data as instructions. Invalid opcodes would execute random snippets of microcode. It would run wild. Usually the only way to get control back is to do a cold boot. Now *that* is a crash.
> 
> Having the program stop when it enters an invalid state is a good thing, not a bad thing.
> 
> If you want to keep a program running on your customer's machine after it crashes, that is entirely up to you. But I cannot recommend it.

Right, which is why everything I've said aligns with it defaulting to crashing out with a call to a function.

Even Windows supports logging in process on a crash. In practice this does work every day right now, running on your computer.

13 hours ago

BTW, NET10 will have a new operator, the null check assignment:

someRef?.Prop = 10 will be shorthand for:

if (someRef != null)
  someRef.Prop = 10;

But the nice part is that if through flow analysis the compiler will know that someRef is not null, it will strip out the null check.

12 hours ago

On Wednesday, 7 May 2025 at 07:08:43 UTC, Python wrote:

>

BTW, NET10 will have a new operator, the null check assignment:

someRef?.Prop = 10 will be shorthand for:

if (someRef != null)
  someRef.Prop = 10;

Curious, I'd rather would have implemented that using an hidden alloca:

PropType __tmp;
(someRef ? someRef.Prop : __tmp) = 10;

Actually having ?. implemented to yield a hidden value when the LHS evaluates to false would have made the assignment case already working since years.

12 hours ago
On Tuesday, 6 May 2025 at 23:51:05 UTC, Walter Bright wrote:

> 2. if in invalid state, shut down immediately

There's one case where D blatantly violates this principle. Consider a system with allowed state transitions A->B, B->C, C->B, B->A:

```
enum State
{
    A, B, C
}

State state;

void AtoB()
{
    assert(state == State.A);
    state = State.B;
}

void BtoC()
{
    assert(state == State.B);
    state = State.C;
}

void CtoB()
{
    assert(state == State.C);
    throw new Exception("CtoB failed"); // or an Error, doesn't matter
    state = State.B;
}

void BtoA()
{
    assert(state == state.B);
    state = State.A;
}

void main()
{
    AtoB();
    scope(exit)
        BtoA(); // relies on the downstream handler having completed successfully.

    BtoC();
    scope(exit)
        CtoB(); // this handler runs, even though the program is in an invalid state.
}
```

12 hours ago
On Wednesday, 7 May 2025 at 07:42:06 UTC, Max Samukha wrote:

>         CtoB(); // this handler runs, even though the program

Misplaced comment. It's the upstream handler (BtoA) that must not run.


11 hours ago

On Tuesday, 6 May 2025 at 23:51:05 UTC, Walter Bright wrote:

> >

Well, I just don't want any hard crashes in production. Druntime throws other kinds of errors besides assert errors, by the way.

Replace the -release switch in the build of druntime with -release -checkaction=D.

I do understand you need to debug remotely, and presumably your program is not critical to your customer. Doing a custom rebuild of druntime with -release -checkaction=D is entirely appropriate for your situation. But I'm hesitant about making it the default build.

It's a quantitative problem. Druntime is stress tested by all projects using it, bugs surviving that are unlikely, bugs in user code are more likely, e.g. druntime doesn't use debug build version of malloc.

6 hours ago

On Wednesday, 7 May 2025 at 07:32:17 UTC, user1234 wrote:

>

On Wednesday, 7 May 2025 at 07:08:43 UTC, Python wrote:

>

BTW, NET10 will have a new operator, the null check assignment:

someRef?.Prop = 10 will be shorthand for:

if (someRef != null)
  someRef.Prop = 10;

Curious, I'd rather would have implemented that using an hidden alloca:

PropType __tmp;
(someRef ? someRef.Prop : __tmp) = 10;

Actually having ?. implemented to yield a hidden value when the LHS evaluates to false would have made the assignment case already working since years.

Forgot to say: this design may lead to think "the compiler will generate a useless alloca + assignment". Indeed, but dont forget that optimizing compilers are good at droping these ;)

That's how it's implemented in styx. But prior to that the concept was proved with a D template, that is still used in D-Scanner codebase I believe.

6 hours ago

On Tuesday, 6 May 2025 at 03:38:01 UTC, Timon Gehr wrote:

>

Even better would be the type system just ensuring nullable pointers are never dereferenced, the OP's experience report notwithstanding. But I guess this part is a pipe dream for now.

If you suspect null dereference, it can be logged on windows:

void test()
{
static void Show(string message)
{
	auto h=GetStdHandle(STD_ERROR_HANDLE);
	uint n;
	WriteFile(h,message.ptr,cast(int)message.length,&n,null);
}
extern(System)
static LONG VecHandler(in EXCEPTION_POINTERS* ex)
{
	const er=ex.ExceptionRecord;
	int code=er.ExceptionCode;
	if(code==STATUS_ACCESS_VIOLATION)Show("access violation");
	return EXCEPTION_CONTINUE_SEARCH;
}
	AddVectoredExceptionHandler(0,&VecHandler) || assert(false);
	byte* b=cast(byte*)1;
	assert(b[1]==1);
}
1 2 3 4 5 6 7 8 9
Next ›   Last »