Re: testing if data is allocated on the stack or heap
It's worth pointing out, btw, that the main reason for this code is to help drug diagnose his or her problem, not to be the be-all, end-all of stack identifying functions. :) It will of course not correctly identify pointers to variables on other threads' stacks, and fiber stacks probably trip it up bad. -- Biotronic
Re: testing if data is allocated on the stack or heap
On Tuesday, 17 October 2017 at 23:59:19 UTC, Steven Schveighoffer wrote: On 10/17/17 7:32 PM, flamencofantasy wrote: On Tuesday, 17 October 2017 at 17:27:17 UTC, Biotronic wrote: On Tuesday, 17 October 2017 at 15:33:02 UTC, drug wrote: [...] I have very little knowledge about sbrk, so here's my solution. Tested on win32 and win64. [...] Try this; unittest { int[5*1024] n; int* p = new int; assert(n.onStack); assert(!p.onStack); } The second is wrong. You are asserting that the storage of p is not on the stack, but it is. What p *points at* is not on the stack. So the correct call should be: assert(!(*p).onStack); or (IMO) less ugly: assert(!onStack(*p)); -Steve No, the second is correct - the ref overload is only chosen when p is not implicitly castable to void*. In fact, the second assert passes, it's the first one that causes problems. I've written an improved version, that probably still has problems. If flamencofantasy would like to point out other shortcomings, I'd love to learn. module stackCheck; private size_t stackStart; enum size_t pageSize = 0x1000; static this() { import core.stdc.stdlib : alloca; stackStart = cast(size_t)alloca(size_t.sizeof); } bool onStack(void* p) { size_t end = cast(size_t) size_t pp = cast(size_t)p; size_t ss = stackStart; if (end > ss) { end &= ~(pageSize-1); ss &= ~(pageSize-1); end += pageSize; return pp >= ss && pp <= end; } else { end &= ~(pageSize-1); ss &= ~(pageSize-1); ss += pageSize; return pp <= ss && pp >= end; } } bool onStack(T)(ref T p) { return ().onStack; } unittest { int n; int* p = new int; assert(n.onStack); assert(!p.onStack); } unittest { int[5*1023] n; int* p = new int; assert(n.onStack); assert(!p.onStack); }
Re: testing if data is allocated on the stack or heap
On Tuesday, October 17, 2017 18:33:02 drug via Digitalmars-d-learn wrote: > My code fails and I guess the reason is I have a slice to data in the > stack and it becomes garbage in some moment. So I need a way to check > where data is placed. Is it right that it can be done in linux using > `sbrk` so that if the addr of data is less than `sbrk(0)` returning then > data is on the stack and on the heap in other case? In theory, @safe is supposed to help with this such that any code that sliced a static array would be @system or @trusted, which would seriously narrow down the search space when something goes wrong with memory, but the slicing of static arrays typically being treated as @safe is one of the major, outstanding bugs for @safe. It looks like it's now caught when simply returning a slice of a static array, but simply slicing a static array is still considered @safe (even though taking the address of a local variable does, and it's really the same thing). So, if you try and use @safe throughout your code, you'll find _some_ of the potential memory problems but not all of them. All of the work that Walter has been doing with DIP 1000 should help though. - Jonathan M Davis
Re: testing if data is allocated on the stack or heap
On Tuesday, 17 October 2017 at 23:59:19 UTC, Steven Schveighoffer wrote: On 10/17/17 7:32 PM, flamencofantasy wrote: On Tuesday, 17 October 2017 at 17:27:17 UTC, Biotronic wrote: On Tuesday, 17 October 2017 at 15:33:02 UTC, drug wrote: [...] I have very little knowledge about sbrk, so here's my solution. Tested on win32 and win64. [...] Try this; unittest { int[5*1024] n; int* p = new int; assert(n.onStack); assert(!p.onStack); } The second is wrong. You are asserting that the storage of p is not on the stack, but it is. What p *points at* is not on the stack. So the correct call should be: assert(!(*p).onStack); or (IMO) less ugly: assert(!onStack(*p)); -Steve you misunderstood, the code is from biotronic's post, i just made a static array of 5kb to point out how it fails, in just one way out of a dozen other possibilities.
Re: testing if data is allocated on the stack or heap
On 10/17/17 7:32 PM, flamencofantasy wrote: On Tuesday, 17 October 2017 at 17:27:17 UTC, Biotronic wrote: On Tuesday, 17 October 2017 at 15:33:02 UTC, drug wrote: [...] I have very little knowledge about sbrk, so here's my solution. Tested on win32 and win64. [...] Try this; unittest { int[5*1024] n; int* p = new int; assert(n.onStack); assert(!p.onStack); } The second is wrong. You are asserting that the storage of p is not on the stack, but it is. What p *points at* is not on the stack. So the correct call should be: assert(!(*p).onStack); or (IMO) less ugly: assert(!onStack(*p)); -Steve
Re: testing if data is allocated on the stack or heap
On Tuesday, 17 October 2017 at 17:27:17 UTC, Biotronic wrote: On Tuesday, 17 October 2017 at 15:33:02 UTC, drug wrote: [...] I have very little knowledge about sbrk, so here's my solution. Tested on win32 and win64. [...] Try this; unittest { int[5*1024] n; int* p = new int; assert(n.onStack); assert(!p.onStack); }
Re: testing if data is allocated on the stack or heap
On Tuesday, 17 October 2017 at 17:27:17 UTC, Biotronic wrote: On Tuesday, 17 October 2017 at 15:33:02 UTC, drug wrote: [...] I have very little knowledge about sbrk, so here's my solution. Tested on win32 and win64. [...] Nice solution. Is `stackStart` thread local on purpose?
Re: testing if data is allocated on the stack or heap
17.10.2017 20:27, Biotronic пишет: module stackCheck; private size_t stackStart; enum size_t pageSize = 0x1000; static this() { import core.stdc.stdlib : alloca; stackStart = cast(size_t)alloca(size_t.sizeof) & ~(pageSize-1); } bool onStack(void* p) { size_t end = (cast(size_t) & ~(pageSize-1)) + pageSize; size_t pp = cast(size_t)p; if (end > stackStart) { return pp >= stackStart && pp <= end; } else { return pp <= stackStart && pp >= end; } } bool onStack(T)(ref T p) { return ().onStack; } unittest { int n; int* p = new int; assert(n.onStack); assert(!p.onStack); } Thanks! Your solution not only works but is portable also.
Re: testing if data is allocated on the stack or heap
On Tuesday, 17 October 2017 at 15:33:02 UTC, drug wrote: My code fails and I guess the reason is I have a slice to data in the stack and it becomes garbage in some moment. So I need a way to check where data is placed. Is it right that it can be done in linux using `sbrk` so that if the addr of data is less than `sbrk(0)` returning then data is on the stack and on the heap in other case? I have very little knowledge about sbrk, so here's my solution. Tested on win32 and win64. module stackCheck; private size_t stackStart; enum size_t pageSize = 0x1000; static this() { import core.stdc.stdlib : alloca; stackStart = cast(size_t)alloca(size_t.sizeof) & ~(pageSize-1); } bool onStack(void* p) { size_t end = (cast(size_t) & ~(pageSize-1)) + pageSize; size_t pp = cast(size_t)p; if (end > stackStart) { return pp >= stackStart && pp <= end; } else { return pp <= stackStart && pp >= end; } } bool onStack(T)(ref T p) { return ().onStack; } unittest { int n; int* p = new int; assert(n.onStack); assert(!p.onStack); } -- Biotronic
testing if data is allocated on the stack or heap
My code fails and I guess the reason is I have a slice to data in the stack and it becomes garbage in some moment. So I need a way to check where data is placed. Is it right that it can be done in linux using `sbrk` so that if the addr of data is less than `sbrk(0)` returning then data is on the stack and on the heap in other case?
Re: testing if data is allocated on the stack or heap
https://run.dlang.io/is/vOh6YY