In an openCL 1.2 program on windows 10, after I enqueue the kernel for several seconds, the prompt shows there is an unhandled exception at a memory location from ucrtbase.dll. So I use "try and catch" to gain more info about the exception. Then I get this:
Microsoft C++ exception: cl::Error at memory location 0x00000076482F5A28.
There might be a problem with memory read/write in my kernel. But the kernel program contains many lines, so it might be a little hard to read each line to find the wrong lines.
In this situation, How to locate the source code line which might cause this exception?
Comment out parts of the kernel and then run it. At first, comment the lower half of the kernel code. If the error persists, it is located in the upper half (->comment the lower 3/4 of the kernel), if not, in the lower half (->comment the lower 1/4 of the kernel). Repeat this binary search until you arrive at the root of the error.
I'd like to know how to force Valgrind tool to show only memory leaks!
with --leak-check=full or --leak-check=full it shows memory leaks (which is good) but also uninitialization problems and/or conditional jump taking problems
thanks!
You can remove the uninitialized value reads, including the ones for jumps with --undef-value-errors=no. I don't know if you can disable other kinds of errors, such as heap corruption and double free.
Would the OS send a warning to the user before a threshold and then the application would actually crash if there is not enough memory to allocate the stack (local) variables of the current function?
Yes, you would get a Stack Overflow run-time error.
Side note: There is a popular web site named after this very error!
Stack allocation can fail and there's nothing you can do about it.
On a modern OS, a significant amount of memory will be committed for the stack to begin with (on Linux it seems to be 128k or so these days) and a (usually much larger, e.g. 8M on Linux, and usually configurable) range of virtual addresses will be reserved for stack growth. If you exceed the committed part, committing more memory could fail due to out-of-memory condition and your program will crash with SIGSEGV. If you exceed the reserved address range, your program will definitely fail, possibly catastrophically if it ends up overwriting other data just below the stack address range.
The solution is not to do insane things with the stack. Even the initial committed amount on Linux (128k) is more stack space than you should ever use. Don't use call recursion unless you have a logarithmic bound on the number of call levels, don't use gigantic automatic arrays or structures (including ones that might result from user-provided VLA dimensions), and you'll be just fine.
Note that there is no portable and no future-safe way to measure current stack usage and remaining availability, so you just have to be safe about it.
Edit: One guarantee you do have about stack allocations, at least on real-world systems, (without the split-stack hack) is that stack space you've already verified you have won't magically disappear. For instance if you successfully once call c() from b() from a() from main(), and they're not using any VLA's that could vary in size, a second repetition of this same call pattern in the same instance of your program won't fail. You can also find tools to perform static analysis on some programs (ones without fancy use of function pointers and/or recursion) that will determine the maximum amount of stack space ever consumed by your program, after which you could setup to verify at program start that you can successfully use that much space before proceeding.
Well... semantically speaking, there is no stack.
From the point of view of the language, automatic storage just works and dynamic storage may fail in well-determined ways (malloc returns NULL, new throws a std::bad_alloc).
Of course, implementations will usually bring up a stack to implement the automatic storage, and one that is limited in size at that. However this is an implementation detail, and need not be so.
For example, gcc -fsplit-stack allows you to have a fractionned stack that grows as you need. This technic is quite recent for C or C++ AFAIK, but languages with continuations (and thousands or millions of them) like Haskell have this built-in and Go made a point about it too.
Still, at some point, the memory will get exhausted if you keep hammering at it. This is actually undefined behavior since the Standard does not attempt to deal with this, at all. In this case, typically, the OS will send a signal to the program which will shut off and the stack will not get unwound.
The process would get killed by the OS if it runs out of stack space.
The exact mechanics are OS-specific. For example, running out of stack space on Linux triggers a segfault.
While the operating system may not inform you that you're out of stack space, you can check this yourself with a bit on inline assembly:
unsigned long StackSpace()
{
unsigned long retn = 0;
unsigned long *rv = &retn;
__asm
{
mov eax, FS:[0x08]
sub eax, esp
mov [rv], eax
}
return retn;
}
You can determine the value of FS:[*] by referring to the windows Thread Information Block
Edit: Meant to subtract esp from eax, not ebx XD
I was wondering what differences and relations are between
segmentation fault and page fault?
Does segmentation fault only belong to segmented memory model?
Does page fault only belong to paged memory model?
If both are yes, since most computer systems such as x86 and Linux use paged memory model instead of segmented memory model, why does GCC C compiler sometimes report segmentation fault error?
Thanks and regards!
These two things are very dissimilar, actually. A segmentation fault means a program tried to access an invalid or illegal memory address: for example, 0, or a value larger than any valid pointer. A page fault is when a pointer tries to access a page of address space that's currently not mapped onto physical memory, so that the MMU needs to grab it off of disk before it can be used. The former is an illegal condition and the program will generally be aborted; the latter is perfectly normal and the program won't even know about it.
"Segmentation" isn't at all related to the old "segmented memory model" used by early x86 processors; it's an earlier use which just refers to a portion or segment of memory.
Segmentation faults occur when the memory is not allowed to be accessed (does not exist, or is forbidden). Most frequently they occur when you dereference a null variable or run off the end of an array. Page faults occur when memory that is mapped but not loaded is accessed. They are not errors, and signal to the operating system that it should load the appropriate page into memory.
I just read that windows programs call _alloca on function entry to grow the stack if they need more than 4k on the stack. I guss that every time the guard page is hit windows allocates a new page for the stack, therefore _alloca accesses the stack in 4k steps to allocate the space.
I also read that this only applies to windows. How does linux (or other oses) solve this problem if they don't need _alloca?
Linux relies on a heavily optimized page fault handling, so what happens is that the program just pushes things on the stack and the page fault handler will extend the stack on the fly.