gcl-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gcl-devel] Sparc mprotect bug


From: Camm Maguire
Subject: [Gcl-devel] Sparc mprotect bug
Date: Fri, 20 Feb 2009 14:17:41 -0500
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux)

Greetings!  GCL has a runtime check for SGC functionality.  This is
because it can vary from kernel to kernel and machine to machine,
though it is not supposed to.  For example, hppa routinely disables
the SGC garbage collecting routine when building applications that use
it, notably ACL2.

I've just confirmed that current Debian sid sparc has an unreliable
mprotect at high addresses only, crashing the acl2 build.  Apart from
filing a bug, is the best approach to expand the runtime check as
follows: 

=============================================================================
static int
memprotect_test_int(char *b1,unsigned long n) {

  char b2[PAGESIZE];
  struct sigaction sa,sao,saob;

  if (memprotect_result!=memprotect_none)
    return memprotect_result!=memprotect_success;
  if (atexit(memprotect_print)) {
    fprintf(stderr,"Cannot setup memprotect_print on exit\n");
    exit(-1);
  }

  memset(b1,32,n);
  memset(b2,0,sizeof(b2));
  memprotect_test_address=(void *)(((unsigned long)b1+PAGESIZE-1) & 
~(PAGESIZE-1));
  if (mprotect(memprotect_test_address,PAGESIZE,PROT_READ_EXEC)) {
    memprotect_result=memprotect_cannot_protect;
    return -1;
  }
  sa.sa_sigaction=(void *)memprotect_handler_test;
  sa.sa_flags=MPROTECT_ACTION_FLAGS;
  if (sigaction(SIGSEGV,&sa,&sao)) {
    memprotect_result=memprotect_sigaction;
    return -1;
  }
  if (sigaction(SIGBUS,&sa,&saob)) {
    sigaction(SIGSEGV,&sao,NULL);
    memprotect_result=memprotect_sigaction;
    return -1;
  }
  memprotect_result=memprotect_bad_return;
  memset(memprotect_test_address,0,PAGESIZE);
  if (memprotect_result==memprotect_bad_return)
    memprotect_result=memprotect_no_signal;
  if (memprotect_result!=memprotect_none) {
    sigaction(SIGSEGV,&sao,NULL);
    sigaction(SIGBUS,&saob,NULL);
    return -1;
  }
  if (memcmp(memprotect_test_address,b2,PAGESIZE)) {
    memprotect_result=memprotect_no_restart;
    sigaction(SIGSEGV,&sao,NULL);
    sigaction(SIGBUS,&saob,NULL);
    return -1;
  }
  memprotect_result=memprotect_success;
  sigaction(SIGSEGV,&sao,NULL);
  sigaction(SIGBUS,&saob,NULL);
  return 0;

}

static int
memprotect_test(void) {

  char b1[2*PAGESIZE],j;

  if ((j=memprotect_test_int(b1,sizeof(b1))))
    return j;

  if ((unsigned long)(rb_start-heap_end)<2*PAGESIZE)
    fprintf(stderr,"Warning: not checking SGC at heap end\n");
  else {
    memprotect_result=memprotect_none;
    memprotect_handler_invocations=0;
    if ((j=memprotect_test_int(heap_end,2*PAGESIZE)))
      return j;
  }

  /*SPARC has trouble with mprotect at high addresses*/
  if ((unsigned long)(core_end-rb_pointer)<2*PAGESIZE) {
    fprintf(stderr,"Warning: not checking SGC at rb_pointer\n");
    return 0;
  }
  memprotect_result=memprotect_none;
  memprotect_handler_invocations=0;
  return memprotect_test_int(rb_pointer,2*PAGESIZE);

}
=============================================================================

The alternative of course is to remove the ability in the
sparc-linux.h file, which then needs reupdating once the problem is
fixed.  


Take care,
-- 
Camm Maguire                                        address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




reply via email to

[Prev in Thread] Current Thread [Next in Thread]