This is the mail archive of the guile@cygnus.com mailing list for the guile project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
I wrote a little program to see what ways there are to get the top of the stack on a system. Here is my code so far (the #defines at the top must be hacked by hand). Does anyone know of any other ways of potentially getting something above the first stack frame? I recall someone mentioning that glibc 2.x had a function like this, what is it called? Once I get a lot of tests, I will package this up to be a completely automated shell script (a configure script, really) and ship it out for a lot of people to run on many different systems. So far it seems like environ is the most promising candidate for finding (close enough to) the top of the stack on many systems, this works on sparc-sun-solaris, sparc-sun-sunos, and i386-unknown-linux-gnulibc1, I'd expect it to work with anything that uses glibc, and any BSD-derived or SVR4-derived system, actually. I can specifically check on NetBSD/i386, Irix, HP-UX, AIX and Digital Unix but not right now. Anyway, if you have more start-of-stack ideas, send them my way. ------------------ #define HAVE_GETCONTEXT 1 #define HAVE_SIGSTACK 1 #define HAVE_ENVIRON 1 #include <stdlib.h> #if HAVE_SIGSTACK #include <signal.h> #endif #if HAVE_GETCONTEXT #include <ucontext.h> #endif #include <errno.h> #if HAVE_ENVIRON extern char **environ; #endif static int stack_compare(void *addr1, void *addr2, int down_p) { if (down_p) { return (unsigned long)addr1 > (unsigned long)addr2; } else { return (unsigned long)addr1 < (unsigned long)addr2; } } static unsigned long do_test(char **argv, char **envp, int *p_outer_var, void *gcp) { int inner_var; int down_p; #if HAVE_SIGSTACK struct sigstack oss; #endif #if HAVE_GETCONTEXT ucontext_t uc; #endif #if HAVE_SIGSTACK sigstack(NULL, &oss); #endif #if HAVE_GETCONTEXT getcontext(&uc); #endif printf("Address of outer stack frame variable: 0x%x\n", p_outer_var); printf("Address of inner stack frame variable: 0x%x\n", &inner_var); printf("Address pointed to by argv: 0x%x\n", argv); printf("Address pointed to by envp: 0x%x\n", envp); #if HAVE_ENVIRON printf("Address pointed to by environ: 0x%x\n", environ); printf("Address of environ: 0x%x\n", &environ); #endif printf("Address of errno: 0x%x\n", &errno); #if HAVE_SIGSTACK printf("Signal stack pointer from sigstack: 0x%x\n", oss.ss_sp); #endif #if HAVE_GETCONTEXT printf("Current stack pointer from getcontext: 0x%x\n", uc.uc_stack.ss_sp); printf("Stack pointer in main from getcontext: 0x%x\n", gcp); #endif puts(""); #if HAVE_GETCONTEXT if (uc.uc_stack.ss_sp=gcp) { puts("getcontext returns constant stack pointerer."); } #endif down_p=(unsigned long)p_outer_var > (unsigned long)(&inner_var); if (down_p) { puts("Stack grows down."); } else { puts("Stack grows up."); } if (stack_compare(argv, p_outer_var, down_p)) { puts("argv area is ahead of first stack frame."); } if (stack_compare(envp, p_outer_var, down_p)) { puts("envp area is ahead of first stack frame."); } #if HAVE_ENVIRON if (stack_compare(environ, p_outer_var, down_p)) { puts("environ is ahead of first stack frame."); } if (stack_compare(&environ, p_outer_var, down_p)) { puts("address of environ is ahead of first stack frame."); } #endif if (stack_compare(&errno, p_outer_var, down_p)) { puts("address of errno is ahead of first stack frame."); } #if HAVE_SIGSTACK if (stack_compare(oss.ss_sp, p_outer_var, down_p)) { puts("sigstack stack pounsigned longer is ahead of first stack frame."); } #endif #if HAVE_GETCONTEXT if (stack_compare(uc.uc_stack.ss_sp, p_outer_var, down_p)) { puts("getcontext stack pounsigned longer is ahead of first stack frame."); } #endif } int main (unsigned long argc, char **argv, char **envp) { int outer_var; #if HAVE_GETCONTEXT ucontext_t uc; getcontext(&uc); #endif do_test(argv, envp, &outer_var, #if HAVE_GETCONTEXT uc.uc_stack.ss_sp #else NULL #endif ); }