ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi there,
I'm trying to restrict the data and stack segments used by a program.
I tried to use setrlimit, but it doesn't seem to have any effect on the program. Isn't it supposed to kill the program as soon as the data or stack segment size exceeds a certain value (that I set using setrlimit)?
Here's the C code I used:
Personally I've never used setrlimit(), but from the man page I understand that setrlimit(RLIMIT_DATA, ...) does not send a signal when the process reaches its data-limit. Only RLIMIT_STACK should cause termination of your program with a segfault when it exceeds the stack limit.
If you tried to exceed the stacksize, and your program does not get terminated, maybe the call setrlimit(RLIMIT_STACK, ... ) didn't succeed for some reason. Try checking the return-value of setrlimit() to find out if the call really succeeds.
Note that if the process does not run as root, could be a reason for setrlimit() to fail.
When you declare char ch[10000] locally (function parameter, or non-static local variable declared inside a function), the space for this (10000 bytes) is allocated on the stack. So mem space for local var's can exceed the stack limit, but not the data limit. Exceeding stack limit will terminate the process automatically with a SIGXFSZ signal.
The data limit limits memory dynamically allocated on the heap. In this case malloc() will fail if it exceeds the data limit and return a NULL pointer. Checking for this condition is always a good idea (as you already know I suppose). E.g.:
This leaves the cases of declaring a global or static variable. I'm not sure about this. I don't know where exactly these var's are stored (heap? or even code space?).
A wild guess about this is that memory for these kind of var's get allocated when the process first starts, so before a limit is set.... But, as I said this is a wild guess, and I have yet to try these things to find out.
If you do find out, I would appreciate it if you could post it here.
Thanks for your reply! I really appreciate your help..
Now, when I try this code I expected to get a message "aborted", but it isn't the case.. It doesn't work..
I've found out that RLIMIT_DATA only effect sbrk() and brk() calls, and that malloc() of recent versions of glibc (or is it the kernel?) don't call brk() anymore to do the allocation.... That explains why it doesn't work.
A solution could be to RLIMIT_AS instead of RLIMIT_DATA.
You may have overseen this RLIMIT_AS (as I first did), because, on my system (debian sarge) it is not mentioned in the man-page, but it is in de info-doc's of glibc.
RLIMIT_AS limit all memory, including globals, statics, malloc's, and I think even code and environment memory (but probably not local var's as thay are on the stack). So there may be some calculation needed to determine what the actual limit value should be.
As far as I understand the mechanics behind all this, it does work a little awkward. E.g. when malloc-ing 1 byte it aborts with a limit of 1212415, but it succeeds with a limit of 1212416 (on my system). And when I set the limit to 10000000 (ten million), I can malloc 8000000 bytes (eight million) succesfully, but it aborts on 9000000 (nine million).
You may want to play with the numbers to find out how it works. If you find something interesting, please post it here. TIA.
Example:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <sys/resource.h>
#include <unistd.h>
int main()
{
char *str;
struct rlimit myrlimit;
getrlimit(RLIMIT_DATA, &myrlimit);
myrlimit.rlim_cur = 10000000;
setrlimit(RLIMIT_AS, &myrlimit);
str = (char *) malloc(8000000); /* 9000000 fails on my system */
if (str == NULL) {
abort(); /* abort() prints "Aborted" to stderr itself. */
}
return 0;
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.