The ups and downs of strlcpy()
The ups and downs of strlcpy()
Posted Jul 23, 2012 13:21 UTC (Mon) by Cyberax (✭ supporter ✭, #52523)In reply to: The ups and downs of strlcpy() by nix
Parent article: The ups and downs of strlcpy()
Posted Jul 24, 2012 17:16 UTC (Tue)
by nix (subscriber, #2304)
[Link] (23 responses)
Posted Jul 24, 2012 18:16 UTC (Tue)
by renox (guest, #23785)
[Link] (3 responses)
I wonder why the GCC developpers chose this default behaviour, x86-64 isn't register starved like x86-32.
Posted Jul 24, 2012 23:19 UTC (Tue)
by nix (subscriber, #2304)
[Link] (2 responses)
Posted Jul 25, 2012 15:11 UTC (Wed)
by paulj (subscriber, #341)
[Link] (1 responses)
Posted Jul 25, 2012 17:17 UTC (Wed)
by nix (subscriber, #2304)
[Link]
Posted Jul 24, 2012 19:48 UTC (Tue)
by Cyberax (✭ supporter ✭, #52523)
[Link] (1 responses)
Posted Jul 29, 2012 15:34 UTC (Sun)
by pbonzini (subscriber, #60935)
[Link]
Posted Jul 24, 2012 20:37 UTC (Tue)
by foom (subscriber, #14868)
[Link] (16 responses)
So, no, it's not hard to produce a backtrace. You just call the function.
Posted Jul 24, 2012 23:10 UTC (Tue)
by nix (subscriber, #2304)
[Link] (15 responses)
(I must have been unlucky with backtrace(). It's never been willing to do more than coredump for me without frame pointers. Mind you I haven't tried it for years because I was so sure it was broken :) time to try it out in my next debugging blitz.)
Posted Jul 25, 2012 2:19 UTC (Wed)
by quotemstr (subscriber, #45331)
[Link] (12 responses)
If you run your system in a sane configuration, the kernel should have swap somewhere it can use to evict the pages it'll need to hardfault the pages from the unwind section. It might be slow, but it'll work. If you run overcommit, there's no such guarantee, but if you run overcommit, why the hell are you complaining about OOM behavior?
Posted Jul 25, 2012 13:45 UTC (Wed)
by nix (subscriber, #2304)
[Link] (11 responses)
If you are in overcommit state 2 with an overcommit ratio of 0, you may be right, but neither of these are the default -- and even then, I don't believe Linux reserves swap pages for every in-memory page, like Solaris does (a good thing too, it's fantastically annoying as even very-much-not-OOM systems can find fork() failing because there's not enough swap to back every page that might get dirtied in the new address space, even if it's only going to exec() and throw them all away).
Posted Jul 27, 2012 19:44 UTC (Fri)
by quotemstr (subscriber, #45331)
[Link] (10 responses)
OOM happens when you're out of commit. If you're doing it right, you paid for the commit for the pages you'll need when you loaded the image, so making the backtrace tables resident should still be possible.
> a good thing too, it's fantastically annoying as even very-much-not-OOM systems can find fork() failing because there's not enough swap to back every page that might get dirtied in the new address space, even if it's only going to exec() and throw them all away
I disagree: strict commit accounting makes a system more predictable in practice. If you find fork failing, you should either add more swap (which won't actually get used, as you note, except in the worst case) or change your program to use vfork or posix_spawn instead, both of which don't have the intrinsic commit-accounting problems of fork.
Posted Jul 28, 2012 10:41 UTC (Sat)
by nix (subscriber, #2304)
[Link] (9 responses)
Your former proposal betrays your single-user roots. Your latter proposal betrays your ignorance of what makes fork()/exec() better than the Windows model in the first place. Neither is at all times practical: the latter in particular is absolutely crackpot.
Thank goodness I can turn overcommit off on my own systems.
Posted Jul 28, 2012 10:43 UTC (Sat)
by nix (subscriber, #2304)
[Link] (3 responses)
Needless to say the thought of rewriting (then X)Emacs's ferociously complex subprocess-handling infrastructure to use posix_spawn() never crossed my mind. (I tried vfork(), but that was clearly out of the question.)
Posted Jul 31, 2012 1:30 UTC (Tue)
by khc (guest, #45209)
[Link] (1 responses)
Posted Jul 31, 2012 23:38 UTC (Tue)
by nix (subscriber, #2304)
[Link]
Posted Aug 1, 2012 15:53 UTC (Wed)
by quotemstr (subscriber, #45331)
[Link]
Posted Jul 29, 2012 2:18 UTC (Sun)
by foom (subscriber, #14868)
[Link] (3 responses)
It would be pretty cool if you could spawn an empty process in a stopped state, and then poke at it from the parent for a bit (open up new file descriptors/etc) before causing it to exec a real subprocess.
Doing things that way would avoid all the memory accounting issues, the performance issue of copying the page table for no good reason, and the significant complication of not actually being allowed to do anything that's not async-signal-handler-safe between fork() and exec(). (And nearly nothing actually falls into that category!)
Posted Jul 29, 2012 13:26 UTC (Sun)
by nix (subscriber, #2304)
[Link] (2 responses)
Posted Jul 30, 2012 1:51 UTC (Mon)
by foom (subscriber, #14868)
[Link] (1 responses)
Posted Jul 30, 2012 8:46 UTC (Mon)
by nix (subscriber, #2304)
[Link]
Posted Aug 1, 2012 15:50 UTC (Wed)
by quotemstr (subscriber, #45331)
[Link]
That's a rare edge case these days, like it or not. If you do regularly use such a system, it's the administrator's job to make sure system resources are adequate. The kernel is there to accurately account for system resources, not work around your sysadmin's snobbery.
> This despite the fact that vfork() cannot do many of the things you do between a fork() and exec()
Such as?
> hence the appallingly insane complexity of the interface
I don't think the interface is particularly complex. It's less complex than pthreads, certainly.
> the latter in particular is absolutely crackpot.
Do you really need to make it personal?
> Thank goodness I can turn overcommit off on my own systems
I think you mean "on".
Posted Jul 25, 2012 15:40 UTC (Wed)
by mmorrow (guest, #83845)
[Link] (1 responses)
Posted Jul 25, 2012 15:55 UTC (Wed)
by mmorrow (guest, #83845)
[Link]
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
If you find fork failing, you should either add more swap (which won't actually get used, as you note, except in the worst case) or change your program to use vfork or posix_spawn instead, both of which don't have the intrinsic commit-accounting problems of fork.
Right. So I'm a mere user on a system with 250 users. fork() is failing in my Emacs so I can't start a shell (Emacs is much bigger than a shell). And your proposal for fixing this awful user interface failure is either to beg the sysadmin to add swap (I did, he said no, of course turning overcommit off was out of the question as this machine was running a database, never mind that it was a test instance that nobody was using, also it was 'like Solaris does it' and he liked Solaris) or spend time hacking at Emacs and every other program that uses fork()/exec() -- i.e. nearly everything in Unix -- so it no longer does?! This despite the fact that vfork() cannot do many of the things you do between a fork() and exec(), and posix_spawn() cannot do any of them unless the developer of posix_spawn() thought of it, hence the appallingly insane complexity of the interface? And this on a machine with almost no memory left? And this when I'm supposed to be getting something else done?
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
It would be pretty cool if you could spawn an empty process in a stopped state, and then poke at it from the parent for a bit (open up new file descriptors/etc) before causing it to exec a real subprocess.
You can do that with PTRACE_O_TRACEFORK or PTRACE_O_TRACEEXEC, but as with anything involving ptrace() there are so many tentacles that virtually any alternative is preferable.
The ups and downs of strlcpy()
The ups and downs of strlcpy()
The ups and downs of strlcpy()
Backtracing on x86_64 is actually quite reasonable. Here are two methods:
The ups and downs of strlcpy()
#if defined(USE_BACKTRACE)
/*
-DUSE_BACKTRACE -rdynamic
(-rdynamic for backtrace_symbols)
*/
#include <execinfo.h>
void print_trace(void)
{
const size_t n = 10
void *array[n];
size_t size = backtrace(array,n);
char **strings = backtrace_symbols(array,size);
for(size_t i = 0; i < size; i++)
fprintf(stderr,"%s\n",strings[i]);
free(strings);
}
#elif defined(USE_LIBUNWIND)
/*
-DUSE_LIBUNWIND -lunwind-x86_64
*/
#include <libunwind.h>
void print_trace(void)
{
unw_cursor_t cur;
unw_context_t cxt;
unw_getcontext(&cxt);
unw_init_local(&cur,&cxt);
while(unw_step(&cur) > 0)
{
unw_word_t off, pc;
char fname[64] = {[0] = '\0'};
unw_get_reg(&cur,UNW_REG_IP,&pc);
unw_get_proc_name(&cur,fname,sizeof(fname),&off);
printf("%p: (%s+0x%x) [%p]\n",pc,fname,off,pc);
}
}
#endif
The ups and downs of strlcpy()
9c9
< const size_t n = 10
---
> const size_t n = 10;