all OS functions should be "nothrow @trusted @nogc"

Moritz Maxeiner via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 27 06:24:40 PDT 2017


On Wednesday, 26 July 2017 at 01:09:50 UTC, Steven Schveighoffer 
wrote:
> On 7/25/17 8:45 PM, Timon Gehr wrote:
>> On 26.07.2017 02:35, Steven Schveighoffer wrote:
>>> On 7/25/17 5:23 PM, Moritz Maxeiner wrote:
>>>> On Tuesday, 25 July 2017 at 20:16:41 UTC, Steven 
>>>> Schveighoffer wrote:
>>>>> The behavior is defined. It will crash with a segfault.
>>>>
>>>> In C land that behaviour is a platform (hardware/OS/libc) 
>>>> specific implementation detail (it's what you generally 
>>>> expect to happen, but AFAIK it isn't defined in official 
>>>> ISO/IEC C).
>>>
>>> In cases where C does not crash when dereferencing null, then 
>>> D would not crash when dereferencing null. D depends on the 
>>> hardware doing this (Walter has said so many times), so if C 
>>> doesn't do it, then D won't. So those systems would have to 
>>> be treated specially, and you'd have to work out your own 
>>> home-grown mechanism for memory safety.
>> 
>> What Moritz is saying is that the following implementation of 
>> fclose is correct according to the C standard:
>> 
>> int fclose(FILE *stream){
>>      if(stream == NULL){
>>          go_wild_and_corrupt_all_the_memory();
>>      }else{
>>          actually_close_the_file(stream);
>>      }
>> }
>
> I think we can correctly assume no fclose implementations exist 
> that do anything but access data pointed at by stream. Which 
> means a segfault on every platform we support.
>
> On platforms that may not segfault, you'd be on your own.
>
> In other words, I think we can assume for any C functions that 
> are passed pointers that dereference those pointers, passing 
> null is safely going to segfault.
>
> Likewise, because D depends on hardware flagging of 
> dereferencing null as a segfault, any platforms that *don't* 
> have that for C also won't have it for D. And then @safe 
> doesn't even work in D code either.
>
> As we have good support for different prototypes for different 
> platforms, we could potentially unmark those as @trusted in 
> those cases.

--- null.d ---
version (linux):

import core.stdc.stdio : FILE;
import core.sys.linux.sys.mman;

extern (C) @safe int fgetc(FILE* stream);

void mmapNull()
{
	void* mmapNull = mmap(null, 4096, PROT_READ | PROT_WRITE, 
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_POPULATE, -1, 0);
	assert (mmapNull == null, "Do `echo 0 > 
/proc/sys/vm/mmap_min_addr` as root");
	*(cast (char*) null) = 'D';
}

void nullDeref() @safe
{
	fgetc(null);
}

void main(string[] args)
{
	mmapNull();
	nullDeref();
}
---

For some fun on Linux, try out
# echo 0 > /proc/sys/vm/mmap_min_addr
$ rdmd null.d

Consider `mmapNull` being run in some third party shared lib you 
don't control.


More information about the Digitalmars-d mailing list