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

Re: clisp 1997-05-03 for IRIX6.2



Nathan Sidwell <nathan@bristol.st.com> writes:

> has anybody successfully built the 1997-05-03 sources on IRIX 6.2
> it fails for me when loading up all the modules during loading of
> compiler.lsp. the error reported is
> 
> *** - handle_fault error1 !
> SIGSEGV cannot be cured. Fault address = 0x20000000.
> Segmentation fault - core dumped
> make: *** [interpreted.mem] Error 139
> 
> this occurs when compiling with gcc or with SGI cc.

Thank you for the precise report. It enabled me to reproduce it,
and Marcus Daniels found the bug.
It is a bug in the generational GC: When the last object in a heap
happens to end exactly at a hardware page boundary, a certain
malloc'ed array is accessed with an out-of-range index, thus causing
realloc() to dump core a little later.

Please apply the following patch (which also fixes another GC bug)
and recompile.

*** clisp/src/spvw.d.bak	Sun May  4 16:58:02 1997
--- clisp/src/spvw.d	Thu Jun  5 23:52:19 1997
***************
*** 1911,1921 ****
  
  #ifdef SPVW_PAGES
  
! #if !defined(VIRTUAL_MEMORY) || defined(BROKEN_MALLOC)
  # Jede Page enthält einen Header für die AVL-Baum-Verwaltung.
  # Das erlaubt es, daß die AVL-Baum-Verwaltung selbst keine malloc-Aufrufe
  # tätigen muß.
! #else # defined(VIRTUAL_MEMORY) && !defined(BROKEN_MALLOC)
  # Bei Virtual Memory ist es schlecht, wenn die GC alle Seiten anfassen muß.
  # Daher sei die AVL-Baum-Verwaltung separat.
  #define AVL_SEPARATE
--- 1911,1921 ----
  
  #ifdef SPVW_PAGES
  
! #ifndef VIRTUAL_MEMORY
  # Jede Page enthält einen Header für die AVL-Baum-Verwaltung.
  # Das erlaubt es, daß die AVL-Baum-Verwaltung selbst keine malloc-Aufrufe
  # tätigen muß.
! #else # VIRTUAL_MEMORY
  # Bei Virtual Memory ist es schlecht, wenn die GC alle Seiten anfassen muß.
  # Daher sei die AVL-Baum-Verwaltung separat.
  #define AVL_SEPARATE
***************
*** 4779,4785 ****
            if (physpage_count==0)
              { xfree(heap->physpages); heap->physpages = NULL; }
              else
!             { heap->physpages = (physpage_state*) xrealloc(heap->physpages,physpage_count*sizeof(physpage_state));
                if (!(heap->physpages==NULL))
                  { # Wenn wir fertig sind, wird sowohl Cache als auch Speicherinhalt
                    # gültig sein:
--- 4779,4785 ----
            if (physpage_count==0)
              { xfree(heap->physpages); heap->physpages = NULL; }
              else
!             { heap->physpages = (physpage_state*) xrealloc(heap->physpages,(physpage_count+1)*sizeof(physpage_state));
                if (!(heap->physpages==NULL))
                  { # Wenn wir fertig sind, wird sowohl Cache als auch Speicherinhalt
                    # gültig sein:
***************
*** 5323,5329 ****
                      ) >> physpageshift;
                    var physpage_state* physpages = NULL;
                    if (physpagecount > 0)
!                     physpages = (physpage_state*) malloc(physpagecount*sizeof(physpage_state));
                    if (!(physpages==NULL))
                      { var uintL i;
                        for (i=0; i<physpagecount; i++)
--- 5323,5329 ----
                      ) >> physpageshift;
                    var physpage_state* physpages = NULL;
                    if (physpagecount > 0)
!                     physpages = (physpage_state*) malloc((physpagecount+1)*sizeof(physpage_state));
                    if (!(physpages==NULL))
                      { var uintL i;
                        for (i=0; i<physpagecount; i++)
***************
*** 5979,5984 ****
--- 5979,6001 ----
  #define SORT_LESS(key1,key2)  ((key1) < (key2))
  #include "sort.c"
  
+ # Liste von Pages, die freizugeben sind, sobald die Aktualisierung
+ # abgeschlossen ist:
+   local var Page* delayed_pages = NULL;
+ # Einfügen einer Page in diese Liste:
+   #define free_page_later(page)  \
+     { (page)->page_gcpriv.next = delayed_pages; delayed_pages = page; }
+ # Freigeben aller Pages in der Liste:
+   #define free_delayed_pages()  \
+     { var Page* page = delayed_pages;                     \
+       until (page==NULL)                                  \
+         { var Page* next = (Page*)page->page_gcpriv.next; \
+           free_page(page);                                \
+           page = next;                                    \
+         }                                                 \
+       delayed_pages = NULL;                               \
+     }
+ 
  # Kompaktierung einer Page durch Umfüllen in andere Pages derselben Art:
    #ifdef SPVW_PURE
    local void gc_compact_from_varobject_page (Heap* heapptr, Page* page, uintL heapnr);
***************
*** 6151,6157 ****
                   { # Page freigeben:
                     if (page->m_length > min_page_size_brutto)
                       # Übergroße Page
!                      { free_page(page); } # ans Betriebssystem zurückgeben
                       else
                       # Normalgroße Page
                       { # wieder initialisieren (page->page_room bleibt gleich!):
--- 6168,6174 ----
                   { # Page freigeben:
                     if (page->m_length > min_page_size_brutto)
                       # Übergroße Page
!                      { free_page_later(page); } # später ans Betriebssystem zurückgeben
                       else
                       # Normalgroße Page
                       { # wieder initialisieren (page->page_room bleibt gleich!):
***************
*** 6250,6255 ****
--- 6267,6273 ----
            );
        for_each_cons_heap(heap, { heap->lastused = dummy_lastused; } );
        recalc_space(TRUE);
+       free_delayed_pages();
        free_some_unused_pages();
        CHECK_AVL_CONSISTENCY();
        CHECK_GC_CONSISTENCY();


> The notes for IRIX 6.2 say that cc cannot compile in 64 bit mode

Actually, only "cc 6.2" cannot. SGI "cc 7.0" compiles CLISP like a
charm.

                           Bruno