Using ulimit To Limit Resources

I’ve learnt an important thing today. ulimit bash builtin allows users to limit various resources (e.g. memory usage, CPU time etc.) for all processes that are started from that shell.

This is a (long?) article which may interest linux / bash users, programmers and others who are willing to learn and discover.

I needed to limit a program’s stack usage, for example. To find out what the current limit was I did:

exit@Black-Feather:~$ ulimit -s
8192
exit@Black-Feather:~$ ulimit -Ss
8192
exit@Black-Feather:~$ ulimit -Hs
unlimited
exit@Black-Feather:~$

There are two types of limits: hard and soft. The -S and -H above stand for these, exactly. The hard limit can only be increased by root. That’s why if you don’t specify -S or -H you won’t be able to change it a second time, as it changes the hard limit as well.

exit@Black-Feather:~$ ulimit -s
8192
exit@Black-Feather:~$ ulimit -s 1024
exit@Black-Feather:~$ ulimit -s
1024
exit@Black-Feather:~$ ulimit -s 2048
bash: ulimit: stack size: cannot modify limit: Operation not permitted
exit@Black-Feather:~$ ulimit -s
1024
exit@Black-Feather:~$

You need to use -S to alter the “soft” limit:

exit@Black-Feather:~$ ulimit -s
8192
exit@Black-Feather:~$ ulimit -Ss 1024
exit@Black-Feather:~$ ulimit -s
1024
exit@Black-Feather:~$ #run some stuff with the set limit
exit@Black-Feather:~$ ulimit -Ss 4096
exit@Black-Feather:~$ ulimit -s
4096
exit@Black-Feather:~$

To see what are the current limits, you can do any of the following (depending which limits you want):

ulimit -a
ulimit -Sa
ulimit -Ha

As far as I can tell, ulimit -a is the same as ulimit -Sa.

If you’ve got a crazy recursion (my case) and want to know just how deep did it go, you can use gdb. Make sure you set the stack limit small enough to cause the program to segfault, and then:

exit@Black-Feather:~/prog/campion/7-pregatire/src/johnie/theirs$ ulimit -Ss 1024
exit@Black-Feather:~/prog/campion/7-pregatire/src/johnie/theirs$ gdb ./johnie.e
[…]
(gdb) r
Starting program: /home/exit/prog/campion/7-pregatire/src/johnie/theirs/johnie.e
Program received signal SIGSEGV, Segmentation fault.
0x080487ac in step (node=14156) at johnie8r-nocheck-release.cpp:91
91 step(old->n);
(gdb) bt -4
#32627 0x080487b4 in step (node=10974) at johnie8r-nocheck-release.cpp:91
#32628 0x080487b4 in step (node=6789) at johnie8r-nocheck-release.cpp:91
#32629 0x08048969 in euler (start=6789) at johnie8r-nocheck-release.cpp:122
#32630 0x08048a78 in main () at johnie8r-nocheck-release.cpp:145
(gdb)

Notice the bt -4 command. It displays the 4 outermost frames of the backtrace (see the gdb info page). You can easily tell from this information that the program recursed 32630 calls deep before hitting the stack limit.

For more info on ulimit see:

  • help ulimit (in a bash shell)
  • this page on the LQ Wiki

One Response to Using ulimit To Limit Resources

%d bloggers like this: