Can calling an operating system function cause a stack overflow? - operating-system

(Title: Can calling an operating system function cause a stack overflow?)
Or is the function always guaranteed to return an error code of some kind to indicate the failure, without crashing the program in the process?
If it can indeed cause a stack overflow, how can you make sure your program never has a chance to crash?
I'm interested in the behavior under Windows, though answers about how other operating systems manage this (e.g. Linux syscalls) are informative as well.
[Edit: For clarification, I'm talking about the behavior of programs as machine code, run by the processor. No high level languages (other than, perhaps, C); I mean actual OS functionality].

Related

Exceeding stack space during recursion

I am running a recursive function in MATLAB and gets this error message:
"Maximum recursion limit of 500 reached. Use set(0,'RecursionLimit',N)
to change the limit. Be aware that exceeding your available stack space can
crash MATLAB and/or your computer."
I wonder, can it really happen that MATLAB and/or my computer can crash if I change the recursion limit and exceed my stack space? It seems strage to me. Why doesn't MATLAB just halt and quit automatically if the available stack space is exceeded?
And how do I know how big recursion limit I can choose without danger?
The computer isn't going to crash. Matlab might, that depends on their handling of the stack. The warning is there most likely because Matlab is multi-platform, and it can run on many different OSes and architectures, some of which might not be as safe as Windows or most POSIXes.
In practice, when working with a thread stack on a Windows machine, the "stack overflow" error is actually "access violation" - you try to access memory that doesn't belong to you not actually an access violation (instead, it's a special kind of page fault, basically), but the idea is similar - the OS notifies you first that you're reaching the ceiling of the stack, and if you exceed the last few "safety" pages, it will give you the actual stack overflow. This is very handy, since it's "free" - you don't have to check if you still have stack space every time you push, and it gives you some extra safety.
Depending on how Matlab handles that exception, it might gracefuly report an error and continue, or it might crash.
Of course, handling stack overflows can be quite tricky, but not for the OS. Windows can handle those errors just fine, it doesn't really care.
The recursion limit depends a lot on how much data Matlab actually has to store in each step of the recursion. The typical stack size of a Windows thread is about 256-1024 kiB (and it's configurable for threads you start on your own), which is actually quite a lot, unless you're passing a lot of big arguments. Consider that with a method that takes two integers and doesn't have any variables, you'd need about 20 000 call deep recursion to exceed even the 256 kiB stack space (on 32-bit).
However, stack overflows are usually a problem in code. You most often run into them by choosing the wrong recursion exit condition. That's part of the reason why the stack overflow is handled by an "exception", rather than allocating more memory for the stack - every trivial recursion error would start crashing all your applications and possibly even the OS. So, first make sure that you actually need a recursion that deep :)
Actually here is a very similar question presented by Mathworks.
Here is how they say you can produce a recursion problem, I think it had 32 bit in mind so you may need to increase the 5000:
create the following file:
function retVal = myrecursivefun(inVal, recursions)
recursions = recursions - 1;
inVal = inVal + 1;
if recursions > 0
retVal = myrecursivefun(inVal, recursions);
else
retVal = inVal;
end
Then run it as follows to crash MATLAB:
set(0,'RecursionLimit', 5000);
myrecursivefun(1, 5000);
Personal note: I think the default recursion limit of 500 makes sense. Matlab programmers won't often want to go beyond this and most of the time this limit is hit because of a mistake.
Also, I think matlab has a little more overhead for function calls than low level languages like C++, therefore you will usually want to avoid deep recursion in the first place.

What exactly happens when an OS goes into kernel mode?

I find that neither my textbooks or my googling skills give me a proper answer to this question. I know it depends on the operating system, but on a general note: what happens and why?
My textbook says that a system call causes the OS to go into kernel mode, given that it's not already there. This is needed because the kernel mode is what has control over I/O-devices and other things outside of a specific process' adress space. But if I understand it correctly, a switch to kernel mode does not necessarily mean a process context switch (where you save the current state of the process elsewhere than the CPU so that some other process can run).
Why is this? I was kinda thinking that some "admin"-process was switched in and took care of the system call from the process and sent the result to the process' address space, but I guess I'm wrong. I can't seem to grasp what ACTUALLY is happening in a switch to and from kernel mode and how this affects a process' ability to operate on I/O-devices.
Thanks alot :)
EDIT: bonus question: does a library call necessarily end up in a system call? If no, do you have any examples of library calls that do not end up in system calls? If yes, why do we have library calls?
Historically system calls have been issued with interrupts. Linux used the 0x80 vector and Windows used the 0x2F vector to access system calls and stored the function's index in the eax register. More recently, we started using the SYSENTER and SYSEXIT instructions. User applications run in Ring3 or userspace/usermode. The CPU is very tricky here and switching from kernel mode to user mode requires special care. It actually involves fooling the CPU to think it was from usermode when issuing a special instruction called iret. The only way to get back from usermode to kernelmode is via an interrupt or the already mentioned SYSENTER/EXIT instruction pairs. They both use a special structure called the TaskStateSegment or TSS for short. These allows to the CPU to find where the kernel's stack is, so yes, it essentially requires a task switch.
But what really happens?
When you issue an system call, the CPU looks for the TSS, gets its esp0 value, which is the kernel's stack pointer and places it into esp. The CPU then looks up the interrupt vector's index in another special structure the InterruptDescriptorTable or IDT for short, and finds an address. This address is where the function that handles the system call is. The CPU pushes the flags register, the code segment, the user's stack and the instruction pointer for the next instruction that is after the int instruction. After the systemcall has been serviced, the kernel issues an iret. Then the CPU returns back to usermode and your application continues as normal.
Do all library calls end in system calls?
Well most of them do, but there are some which don't. For example take a look at memcpy and the rest.

Kernel Code vs User Code

Here's a passage from the book
When executing kernel code, the system is in kernel-space execut-
ing in kernel mode.When running a regular process, the system is in user-space executing
in user mode.
Now what really is a kernel code and user code. Can someone explain with example?
Say i have an application that does printf("HelloWorld") now , while executing this application, will it be a user code, or kernel code.
I guess that at some point of time, user-code will switch into the kernel mode and kernel code will take over, but I guess that's not always the case since I came across this
For example, the open() library function does little except call the open() system call.
Still other C library functions, such as strcpy(), should (one hopes) make no direct use
of the kernel at all.
If it does not make use of the kernel, then how does it make everything work?
Can someone please explain the whole thing in a lucid way.
There isn't much difference between kernel and user code as such, code is code. It's just that the code that executes in kernel mode (kernel code) can (and does) contain instructions only executable in kernel mode. In user mode such instructions can't be executed (not allowed there for reliability and security reasons), they typically cause exceptions and lead to process termination as a result of that.
I/O, especially with external devices other than the RAM, is usually performed by the OS somehow and system calls are the entry points to get to the code that does the I/O. So, open() and printf() use system calls to exercise that code in the I/O device drivers somewhere in the kernel. The whole point of a general-purpose OS is to hide from you, the user or the programmer, the differences in the hardware, so you don't need to know or think about accessing this kind of network card or that kind of display or disk.
Memory accesses, OTOH, most of the time can just happen without the OS' intervention. And strcpy() works as is: read a byte of memory, write a byte of memory, oh, was it a zero byte, btw? repeat if it wasn't, stop if it was.
I said "most of the time" because there's often page translation and virtual memory involved and memory accesses may result in switched into the kernel, so the kernel can load something from the disk into the memory and let the accessing instruction that's caused the switch continue.

What happens when Virtual memory is exhausted

I am posting this question as I could not find the answer on googling and stackoverflowing it...
The question is :
What happens when Virtual memory's swap space is exhausted. How does OS handles this situation when all the RAM and Virtual Memory is exhauseted.
Does it secretly use more space on HDD, Or notify an exception
I am going to assume that by virtual memory you are referring to swap space (they are technically different concepts). I can think of two things:
The program checks to make sure that the allocation went well (ie in C there is a return code for malloc) and if it did not go well, then it will gracefully exit with a once-ubiquitous "Out of memory" Error message. Java and C++ have exceptions for the same purpose.
The program doesn't check because, really, who runs out of memory anymore? (This is a programmer thinking here.) I would bet that chances are there are many programs written out there that do not check to see if a call to malloc succeeded or not, and therefore they try to use a bad pointer and cause a memory access violation, causing the program to exit with a nice "This program has encountered a problem" message in windows, or a succinct "Segfault" message in Unix.
I'm not sure as to how Windows handles it, but on *nix systems, the kernel runs the OOM Killer program (more information can be found here http://linux-mm.org/OOM_Killer)

stack overflow method

In some operating system,for any process there is a stack and a heap.Both grows towards each other.There must be a guard band between them to check for overlapping.Can anyone give me some illustration about it.I want to write my own function for checking stack overflow error.
In a system like that, you would normally have a guard word or something similar at the top of the heap, something like 0xa55a or 0xdeadbeef.
Then, periodically, that guard word is checked to see if it's been corrupted. If so something has overwritten the memory.
Now this may not necessarily be a stack overflow, it may be a rogue memory write. But, in both those cases, something is seriously wrong so you may as well treat them the same.
Of course, more modern operating systems may take the approach of using the assistance of the hardware such as in the Intel chips. In those, you can set up a stack segment to a specific size and, if you try to write outside of there (using the stack selector), you'll get a trap raised.
The heap in that case would be using a different selector so as to be kept separate.
Many operating systems place a guard page (or similar techniques) between stack and heap to protect against such attack vectors. I haven't seen canaries (the method mentioned by paxdiablo) there yet, they're mostly used to guard against stack-internal overflows (aka to guard the return address).
Guard pages on Windows: http://msdn.microsoft.com/en-us/library/aa366549(VS.85).aspx
Linux had an interesting exploit based on this problem some time ago though: http://www.h-online.com/open/news/item/Root-privileges-through-Linux-kernel-bug-Update-1061563.html