e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
c365542004-12-11Henrik Grubbström (Grubba) || $Id: main.c,v 1.216 2004/12/11 13:29:59 grubba Exp $
e576bb2002-10-11Martin Nilsson */
aedfb12002-10-09Martin Nilsson 
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
5740881998-01-01Fredrik Hübinette (Hubbe) #include "fdlib.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "backend.h" #include "module.h" #include "object.h" #include "lex.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h" #include "builtin_functions.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "array.h" #include "stralloc.h" #include "interpret.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "callback.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "signal_handler.h"
07513e1996-10-04Fredrik Hübinette (Hubbe) #include "threads.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "dynamic_load.h" #include "gc.h"
61e9a01998-01-25Fredrik Hübinette (Hubbe) #include "multiset.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "mapping.h"
5740881998-01-01Fredrik Hübinette (Hubbe) #include "cpp.h"
0808b21998-01-25Fredrik Hübinette (Hubbe) #include "main.h"
19aaeb1998-05-25Fredrik Hübinette (Hubbe) #include "operators.h"
ab56702001-04-30Martin Stjernholm #include "rbtree.h"
37775c2004-04-06Martin Nilsson #include "pike_security.h"
67f0b51999-09-26Henrik Grubbström (Grubba) #include "constants.h"
c37c7e1999-03-26Fredrik Hübinette (Hubbe) #include "version.h"
4b63c62001-12-14Martin Nilsson #include "program.h"
d5c61f2002-12-07Henrik Grubbström (Grubba) #include "pike_rusage.h"
d658ab2002-09-26Martin Stjernholm #include "module_support.h"
143d882003-11-14Martin Stjernholm #include "opcodes.h"
4b63c62001-12-14Martin Nilsson  #ifdef AUTO_BIGNUM #include "bignum.h" #endif
5740881998-01-01Fredrik Hübinette (Hubbe) 
d1913b2000-10-01Fredrik Hübinette (Hubbe) #if defined(__linux__) && defined(HAVE_DLOPEN) && defined(HAVE_DLFCN_H)
07eda22000-07-05Fredrik Hübinette (Hubbe) #include <dlfcn.h> #endif
cee5811999-12-05Henrik Grubbström (Grubba) #include "las.h"
834e022003-11-28Henrik Grubbström (Grubba) #ifdef HAVE_UNISTD_H
fde6ed2003-11-27Martin Stjernholm #include <unistd.h>
834e022003-11-28Henrik Grubbström (Grubba) #endif #ifdef HAVE_ERRNO_H
ac173e1997-11-02Henrik Grubbström (Grubba) #include <errno.h>
834e022003-11-28Henrik Grubbström (Grubba) #endif
ac173e1997-11-02Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef HAVE_LOCALE_H #include <locale.h> #endif
6930181996-02-25Fredrik Hübinette (Hubbe) 
6e37dc1996-06-21Fredrik Hübinette (Hubbe) #include "time_stuff.h"
6930181996-02-25Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> #endif
9debfa1999-08-11Fredrik Hübinette (Hubbe) #ifdef TRY_USE_MMX
895ced2003-10-25Martin Nilsson #ifdef HAVE_MMX_H
9debfa1999-08-11Fredrik Hübinette (Hubbe) #include <mmx.h>
895ced2003-10-25Martin Nilsson #else #include <asm/mmx.h> #endif
9debfa1999-08-11Fredrik Hübinette (Hubbe) int try_use_mmx; #endif
ff34a52001-05-31Henrik Grubbström (Grubba) /* Define this to trace the execution of main(). */ /* #define TRACE_MAIN */ #ifdef TRACE_MAIN #define TRACE(X) fprintf X #else /* !TRACE_MAIN */ #define TRACE(X) #endif /* TRACE_MAIN */
f8e5fe1997-01-18Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe) char *master_file;
e1195f1997-03-23Fredrik Hübinette (Hubbe) char **ARGV;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT int debug_options=0; PMOD_EXPORT int runtime_options=0; PMOD_EXPORT int d_flag=0; PMOD_EXPORT int c_flag=0; PMOD_EXPORT int default_t_flag=0; PMOD_EXPORT int a_flag=0; PMOD_EXPORT int l_flag=0; PMOD_EXPORT int p_flag=0;
ff34a52001-05-31Henrik Grubbström (Grubba) #if defined(YYDEBUG) || defined(PIKE_DEBUG)
943f851998-04-13Henrik Grubbström (Grubba) extern int yydebug;
ff34a52001-05-31Henrik Grubbström (Grubba) #endif /* YYDEBUG || PIKE_DEBUG */
3f1eeb1998-04-05Fredrik Hübinette (Hubbe) static long instructions_left;
bd182a2004-10-14Henrik Grubbström (Grubba) #define MASTER_COOKIE1 "(#*&)@(*&$" #define MASTER_COOKIE2 "Master Cookie:" #define MASTER_COOKIE MASTER_COOKIE1 MASTER_COOKIE2
c37c7e1999-03-26Fredrik Hübinette (Hubbe)  #ifndef MAXPATHLEN #define MAXPATHLEN 32768 #endif char master_location[MAXPATHLEN * 2] = MASTER_COOKIE;
3f1eeb1998-04-05Fredrik Hübinette (Hubbe) static void time_to_exit(struct callback *cb,void *tmp,void *ignored) { if(instructions_left-- < 0) { push_int(0); f_exit(1); } }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
0612442001-05-16Fredrik Hübinette (Hubbe) #ifdef PROFILING static unsigned int samples[8200]; long record; static void sample_stack(struct callback *cb,void *tmp,void *ignored) { long stack_size=( ((char *)&cb) - Pike_interpreter.stack_bottom) * STACK_DIRECTION; stack_size>>=10; stack_size++; if(stack_size<0) stack_size=0; if(stack_size >= (long)NELEM(samples)) stack_size=NELEM(samples)-1; samples[stack_size]++; #ifdef PIKE_DEBUG if(stack_size > record) { extern void gdb_break_on_stack_record(long); gdb_break_on_stack_record(stack_size); record=stack_size; } #endif } #ifdef PIKE_DEBUG void gdb_break_on_stack_record(long stack_size) { ; } #endif #endif
81b84e1996-12-03Fredrik Hübinette (Hubbe) static struct callback_list post_master_callbacks;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct callback *add_post_master_callback(callback_func call,
8f4f881996-06-20Fredrik Hübinette (Hubbe)  void *arg,
6e37dc1996-06-21Fredrik Hübinette (Hubbe)  callback_func free_func)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
6e37dc1996-06-21Fredrik Hübinette (Hubbe)  return add_to_callback(&post_master_callbacks, call, arg, free_func);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
61e9a01998-01-25Fredrik Hübinette (Hubbe) static struct callback_list exit_callbacks;
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT struct callback *add_exit_callback(callback_func call,
61e9a01998-01-25Fredrik Hübinette (Hubbe)  void *arg, callback_func free_func) { return add_to_callback(&exit_callbacks, call, arg, free_func); }
a999e71998-07-27Fredrik Hübinette (Hubbe) #ifdef __NT__
1c32fd2000-08-19Henrik Grubbström (Grubba) static void get_master_key(HKEY cat)
a999e71998-07-27Fredrik Hübinette (Hubbe) { HKEY k; char buffer[4096]; DWORD len=sizeof(buffer)-1,type=REG_SZ;
a5cd6a2001-09-24Henrik Grubbström (Grubba) 
a999e71998-07-27Fredrik Hübinette (Hubbe)  if(RegOpenKeyEx(cat,
387b042003-01-02Martin Nilsson  (LPCTSTR)("SOFTWARE\\Pike\\"
1f1f182001-03-10Henrik Grubbström (Grubba)  DEFINETOSTR(PIKE_MAJOR_VERSION) "."
50bf1e2004-09-16Martin Nilsson  DEFINETOSTR(PIKE_MINOR_VERSION) "." DEFINETOSTR(PIKE_BUILD_VERSION)),
a999e71998-07-27Fredrik Hübinette (Hubbe)  0,KEY_READ,&k)==ERROR_SUCCESS) { if(RegQueryValueEx(k, "PIKE_MASTER", 0, &type, buffer, &len)==ERROR_SUCCESS) {
21315b1999-05-07Fredrik Hübinette (Hubbe)  dmalloc_accept_leak( master_file=strdup(buffer) );
a999e71998-07-27Fredrik Hübinette (Hubbe)  } RegCloseKey(k); } } #endif /* __NT__ */
3189c92004-01-31Marcus Comstedt #ifdef __amigaos4__ #define timeval timeval_amigaos #include <exec/types.h> #include <utility/hooks.h> #include <dos/dosextens.h> #include <proto/dos.h> static SAVEDS LONG scan_amigaos_environment_func(struct Hook *REG(a0,hook), APTR REG(a2,userdata), struct ScanVarsMsg *REG(a1,msg)) { if(msg->sv_GDir[0] == '\0' || !strcmp(msg->sv_GDir, "ENV:")) { push_text(msg->sv_Name); push_constant_text("="); push_string(make_shared_binary_string(msg->sv_Var, msg->sv_VarLen)); f_add(3); } return 0; } static struct Hook scan_amigaos_environment_hook = { { NULL, NULL }, (ULONG (*)())scan_amigaos_environment_func, NULL, NULL }; #endif /* __amigsos4__ */
3c0c281998-01-26Fredrik Hübinette (Hubbe) int dbm_main(int argc, char **argv)
5267b71995-08-09Fredrik Hübinette (Hubbe) { JMP_BUF back;
a5cd6a2001-09-24Henrik Grubbström (Grubba)  int e, num;
5267b71995-08-09Fredrik Hübinette (Hubbe)  char *p; struct array *a;
85f59e1998-01-08Fredrik Hübinette (Hubbe) #ifdef DECLARE_ENVIRON extern char **environ; #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "dbm_main()\n"));
fde6ed2003-11-27Martin Stjernholm  init_rusage();
d9c7172001-03-23Henrik Grubbström (Grubba)  /* Attempt to make sure stderr is unbuffered. */ #ifdef HAVE_SETVBUF setvbuf(stderr, NULL, _IONBF, 0); #else /* !HAVE_SETVBUF */ #ifdef HAVE_SETBUF setbuf(stderr, NULL); #endif /* HAVE_SETBUF */ #endif /* HAVE_SETVBUF */
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Init CPU lib...\n"));
aad99b2001-03-28Fredrik Hübinette (Hubbe)  init_pike_cpulib();
d9c7172001-03-23Henrik Grubbström (Grubba) 
9debfa1999-08-11Fredrik Hübinette (Hubbe) #ifdef TRY_USE_MMX
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Init MMX...\n"));
9debfa1999-08-11Fredrik Hübinette (Hubbe)  try_use_mmx=mmx_ok(); #endif
bbc16c2000-08-29Mirar (Pontus Hagland) #ifdef OWN_GETHRTIME /* initialize our own gethrtime conversion /Mirar */
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Init gethrtime...\n"));
bbc16c2000-08-29Mirar (Pontus Hagland)  own_gethrtime_init(); #endif
9debfa1999-08-11Fredrik Hübinette (Hubbe) 
e1195f1997-03-23Fredrik Hübinette (Hubbe)  ARGV=argv;
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Main init...\n"));
5740881998-01-01Fredrik Hübinette (Hubbe)  fd_init();
aad99b2001-03-28Fredrik Hübinette (Hubbe)  { extern void init_mapping_blocks(void); extern void init_callable_blocks(void); extern void init_gc_frame_blocks(void); extern void init_pike_frame_blocks(void); extern void init_node_s_blocks(void); extern void init_object_blocks(void); extern void init_callback_blocks(void); init_mapping_blocks(); init_callable_blocks(); init_gc_frame_blocks(); init_pike_frame_blocks(); init_node_s_blocks(); init_object_blocks();
c365542004-12-11Henrik Grubbström (Grubba) #if !defined(DEBUG_MALLOC) || !defined(_REENTRANT)
a596292002-10-11Henrik Grubbström (Grubba)  /* This has already been done by initialize_dmalloc(). */
aad99b2001-03-28Fredrik Hübinette (Hubbe)  init_callback_blocks();
a596292002-10-11Henrik Grubbström (Grubba) #endif /* !DEBUG_MALLOC */
5b15bb2001-12-10Martin Stjernholm  init_multiset();
d8073b2002-01-27Martin Stjernholm  init_builtin_constants();
aad99b2001-03-28Fredrik Hübinette (Hubbe)  }
5740881998-01-01Fredrik Hübinette (Hubbe) 
cee5811999-12-05Henrik Grubbström (Grubba) #ifdef SHARED_NODES
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Init shared nodes...\n"));
a69c422000-12-01Henrik Grubbström (Grubba)  node_hash.table = malloc(sizeof(node *)*32831);
cee5811999-12-05Henrik Grubbström (Grubba)  if (!node_hash.table) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("Out of memory!\n");
cee5811999-12-05Henrik Grubbström (Grubba)  }
a69c422000-12-01Henrik Grubbström (Grubba)  MEMSET(node_hash.table, 0, sizeof(node *)*32831); node_hash.size = 32831;
cee5811999-12-05Henrik Grubbström (Grubba) #endif /* SHARED_NODES */
4bc94b2002-09-07Henrik Grubbström (Grubba) #ifdef HAVE_TZSET tzset(); #endif /* HAVE_TZSET */
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef HAVE_SETLOCALE
2cf1a11996-09-23Fredrik Hübinette (Hubbe) #ifdef LC_NUMERIC
06983f1996-09-22Fredrik Hübinette (Hubbe)  setlocale(LC_NUMERIC, "C");
2cf1a11996-09-23Fredrik Hübinette (Hubbe) #endif #ifdef LC_CTYPE
06983f1996-09-22Fredrik Hübinette (Hubbe)  setlocale(LC_CTYPE, "");
2cf1a11996-09-23Fredrik Hübinette (Hubbe) #endif #ifdef LC_TIME
06983f1996-09-22Fredrik Hübinette (Hubbe)  setlocale(LC_TIME, "C");
2cf1a11996-09-23Fredrik Hübinette (Hubbe) #endif #ifdef LC_COLLATE
06983f1996-09-22Fredrik Hübinette (Hubbe)  setlocale(LC_COLLATE, "");
2cf1a11996-09-23Fredrik Hübinette (Hubbe) #endif #ifdef LC_MESSAGES
06983f1996-09-22Fredrik Hübinette (Hubbe)  setlocale(LC_MESSAGES, "");
2cf1a11996-09-23Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
bf47e12000-04-06Henrik Grubbström (Grubba) 
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Init master...\n"));
5267b71995-08-09Fredrik Hübinette (Hubbe)  master_file = 0;
c37c7e1999-03-26Fredrik Hübinette (Hubbe) 
208f351998-05-12Henrik Grubbström (Grubba) #ifdef HAVE_GETENV
a999e71998-07-27Fredrik Hübinette (Hubbe)  if(getenv("PIKE_MASTER")) master_file = getenv("PIKE_MASTER");
208f351998-05-12Henrik Grubbström (Grubba) #endif
dc7cc91998-01-14Fredrik Hübinette (Hubbe) 
c37c7e1999-03-26Fredrik Hübinette (Hubbe)  if(master_location[CONSTANT_STRLEN(MASTER_COOKIE)]) master_file=master_location + CONSTANT_STRLEN(MASTER_COOKIE);
e37d792004-05-10Marcus Agehall #if defined(__NT__)
c37c7e1999-03-26Fredrik Hübinette (Hubbe)  if(!master_file) get_master_key(HKEY_CURRENT_USER); if(!master_file) get_master_key(HKEY_LOCAL_MACHINE); #endif if(!master_file) { sprintf(master_location,DEFAULT_MASTER, PIKE_MAJOR_VERSION, PIKE_MINOR_VERSION, PIKE_BUILD_VERSION); master_file=master_location; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Default master at \"%s\"...\n", master_file));
895ced2003-10-25Martin Nilsson 
5267b71995-08-09Fredrik Hübinette (Hubbe)  for(e=1; e<argc; e++) {
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Parse argument %d:\"%s\"...\n", e, argv[e]));
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(argv[e][0]=='-') { for(p=argv[e]+1; *p;) { switch(*p) { case 'D': add_predefine(p+1); p+=strlen(p); break; case 'm': if(p[1]) { master_file=p+1; p+=strlen(p); }else{ e++; if(e >= argc) { fprintf(stderr,"Missing argument to -m\n"); exit(1); } master_file=argv[e]; p+=strlen(p); } break;
9f243b1996-08-12Fredrik Hübinette (Hubbe)  case 's': if(!p[1]) { e++; if(e >= argc) { fprintf(stderr,"Missing argument to -s\n"); exit(1); } p=argv[e];
4908871998-08-10Fredrik Hübinette (Hubbe)  }else{ p++; if(*p=='s') { if(!p[1]) { e++; if(e >= argc) { fprintf(stderr,"Missing argument to -ss\n"); exit(1); } p=argv[e]; }else{ p++; } #ifdef _REENTRANT thread_stack_size=STRTOL(p,&p,0); #endif p+=strlen(p); break; }
9f243b1996-08-12Fredrik Hübinette (Hubbe)  }
7965d72001-01-24Fredrik Hübinette (Hubbe)  Pike_stack_size=STRTOL(p,&p,0);
9f243b1996-08-12Fredrik Hübinette (Hubbe)  p+=strlen(p);
7965d72001-01-24Fredrik Hübinette (Hubbe)  if(Pike_stack_size < 256)
9f243b1996-08-12Fredrik Hübinette (Hubbe)  { fprintf(stderr,"Stack size must at least be 256.\n"); exit(1); } break;
3f1eeb1998-04-05Fredrik Hübinette (Hubbe)  case 'q': if(!p[1]) { e++; if(e >= argc) { fprintf(stderr,"Missing argument to -q\n"); exit(1); } p=argv[e];
4908871998-08-10Fredrik Hübinette (Hubbe)  }else{ p++;
3f1eeb1998-04-05Fredrik Hübinette (Hubbe)  }
4908871998-08-10Fredrik Hübinette (Hubbe)  instructions_left=STRTOL(p,&p,0);
3f1eeb1998-04-05Fredrik Hübinette (Hubbe)  p+=strlen(p); add_to_callback(&evaluator_callbacks, time_to_exit, 0,0); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case 'd':
cd83521998-02-02Fredrik Hübinette (Hubbe)  more_d_flags: switch(p[1]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': d_flag+=STRTOL(p+1,&p,10); break;
943f851998-04-13Henrik Grubbström (Grubba)  case 'c': p++;
ff34a52001-05-31Henrik Grubbström (Grubba) #if defined(YYDEBUG) || defined(PIKE_DEBUG)
943f851998-04-13Henrik Grubbström (Grubba)  yydebug++;
ff34a52001-05-31Henrik Grubbström (Grubba) #endif /* YYDEBUG || PIKE_DEBUG */
943f851998-04-13Henrik Grubbström (Grubba)  break;
cd83521998-02-02Fredrik Hübinette (Hubbe)  case 's': debug_options|=DEBUG_SIGNALS; p++;
9b08a21998-03-31Fredrik Hübinette (Hubbe)  goto more_d_flags; case 't': debug_options|=NO_TAILRECURSION;
cd83521998-02-02Fredrik Hübinette (Hubbe)  p++;
9b08a21998-03-31Fredrik Hübinette (Hubbe)  goto more_d_flags;
cd83521998-02-02Fredrik Hübinette (Hubbe) 
382fea2003-04-13Martin Nilsson #ifdef DEBUG_MALLOC
7386972001-06-30Fredrik Hübinette (Hubbe)  case 'g': debug_options|=GC_RESET_DMALLOC; p++; goto more_d_flags;
382fea2003-04-13Martin Nilsson #endif
7386972001-06-30Fredrik Hübinette (Hubbe)  case 'p': debug_options|=NO_PEEP_OPTIMIZING; p++; goto more_d_flags;
01185d2003-04-01Martin Stjernholm  case 'T': debug_options |= ERRORCHECK_MUTEXES; p++; goto more_d_flags;
7d955e1999-12-13Henrik Grubbström (Grubba)  default: d_flag += (p[0] == 'd');
cee5811999-12-05Henrik Grubbström (Grubba)  p++;
7d955e1999-12-13Henrik Grubbström (Grubba)  } break;
cee5811999-12-05Henrik Grubbström (Grubba) 
7d955e1999-12-13Henrik Grubbström (Grubba)  case 'r':
17e1771999-12-13Per Hedbor  more_r_flags: switch(p[1]) {
7d955e1999-12-13Henrik Grubbström (Grubba)  case 't': runtime_options |= RUNTIME_CHECK_TYPES; p++;
17e1771999-12-13Per Hedbor  goto more_r_flags;
7d955e1999-12-13Henrik Grubbström (Grubba)  case 'T': runtime_options |= RUNTIME_STRICT_TYPES; p++;
17e1771999-12-13Per Hedbor  goto more_r_flags;
7d955e1999-12-13Henrik Grubbström (Grubba) 
17e1771999-12-13Per Hedbor  default: p++;
7d955e1999-12-13Henrik Grubbström (Grubba)  break;
cd83521998-02-02Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case 'a': if(p[1]>='0' && p[1]<='9') a_flag+=STRTOL(p+1,&p,10); else a_flag++,p++; break; case 't':
24d38f2004-03-17Martin Stjernholm  more_t_flags: switch (p[1]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': Pike_interpreter.trace_level+=STRTOL(p+1,&p,10); break; case 'g': gc_trace++; p++; goto more_t_flags; default: if (p[0] == 't') Pike_interpreter.trace_level++; p++; }
97ebb32003-01-09Henrik Grubbström (Grubba)  default_t_flag = Pike_interpreter.trace_level;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
06983f1996-09-22Fredrik Hübinette (Hubbe)  case 'p':
0612442001-05-16Fredrik Hübinette (Hubbe)  if(p[1]=='s') { #ifdef PROFILING add_to_callback(&evaluator_callbacks, sample_stack, 0,0); p+=strlen(p); #endif }else{ if(p[1]>='0' && p[1]<='9') p_flag+=STRTOL(p+1,&p,10); else p_flag++,p++; }
06983f1996-09-22Fredrik Hübinette (Hubbe)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case 'l': if(p[1]>='0' && p[1]<='9') l_flag+=STRTOL(p+1,&p,10); else l_flag++,p++; break; default:
4967071997-01-15Fredrik Hübinette (Hubbe)  p+=strlen(p);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } }else{ break; } }
01185d2003-04-01Martin Stjernholm #ifndef PIKE_MUTEX_ERRORCHECK if (debug_options & ERRORCHECK_MUTEXES) fputs ("Warning: -dT (error checking mutexes) not supported on this system.\n", stderr); #endif if (d_flag) debug_options |= ERRORCHECK_MUTEXES;
2a50961995-08-23Fredrik Hübinette (Hubbe) #if !defined(RLIMIT_NOFILE) && defined(RLIMIT_OFILE) #define RLIMIT_NOFILE RLIMIT_OFILE
e17dbc1995-08-11David Hedbor #endif
2a50961995-08-23Fredrik Hübinette (Hubbe) 
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Init C stack...\n"));
cd86322000-07-06Fredrik Hübinette (Hubbe)  Pike_interpreter.stack_top = (char *)&argv;
a9388a1998-09-02Henrik Grubbström (Grubba)  /* Adjust for anything already pushed on the stack. * We align on a 64 KB boundary. * Thus we at worst, lose 64 KB stack. * * We have to do it this way since some compilers don't like * & and | on pointers, and casting to an integer type is * too unsafe (consider 64-bit systems). */ #if STACK_DIRECTION < 0 /* Equvivalent with |= 0xffff */
d2361e2003-06-30Martin Stjernholm  Pike_interpreter.stack_top += ~(PTR_TO_INT(Pike_interpreter.stack_top)) & 0xffff;
a9388a1998-09-02Henrik Grubbström (Grubba) #else /* STACK_DIRECTION >= 0 */ /* Equvivalent with &= ~0xffff */
d2361e2003-06-30Martin Stjernholm  Pike_interpreter.stack_top -= PTR_TO_INT(Pike_interpreter.stack_top) & 0xffff;
a9388a1998-09-02Henrik Grubbström (Grubba) #endif /* STACK_DIRECTION < 0 */
0612442001-05-16Fredrik Hübinette (Hubbe) #ifdef PROFILING Pike_interpreter.stack_bottom=Pike_interpreter.stack_top; #endif
4908871998-08-10Fredrik Hübinette (Hubbe) #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK) { struct rlimit lim; if(!getrlimit(RLIMIT_STACK, &lim)) { #ifdef RLIM_INFINITY if(lim.rlim_cur == RLIM_INFINITY)
752e101999-04-30Fredrik Hübinette (Hubbe)  lim.rlim_cur=1024*1024*32;
4908871998-08-10Fredrik Hübinette (Hubbe) #endif
fcf0732000-03-28Fredrik Hübinette (Hubbe)  #ifdef Pike_INITIAL_STACK_SIZE if(lim.rlim_cur > Pike_INITIAL_STACK_SIZE) lim.rlim_cur=Pike_INITIAL_STACK_SIZE; #endif
d1913b2000-10-01Fredrik Hübinette (Hubbe) #if defined(__linux__) && defined(PIKE_THREADS) /* This is a really really *stupid* limit in glibc 2.x * which is not detectable since __pthread_initial_thread_bos * went static. On a stupidity-scale from 1-10, this rates a * solid 11. - Hubbe */ if(lim.rlim_cur > 2*1024*1024) lim.rlim_cur=2*1024*1024; #endif
91fbfd2001-04-11Henrik Grubbström (Grubba) #if defined(_AIX) && defined(__ia64) /* getrlimit() on AIX 5L/IA64 Beta 3 reports 32MB by default, * even though the stack is just 8MB. */ if (lim.rlim_cur > 8*1024*1024) { lim.rlim_cur = 8*1024*1024; } #endif /* _AIX && __ia64 */
f12b712001-03-25Henrik Grubbström (Grubba) #if STACK_DIRECTION < 0 Pike_interpreter.stack_top -= lim.rlim_cur; #else /* STACK_DIRECTION >= 0 */ Pike_interpreter.stack_top += lim.rlim_cur; #endif /* STACK_DIRECTION < 0 */
752e101999-04-30Fredrik Hübinette (Hubbe) 
9fb7302002-01-08Henrik Grubbström (Grubba) #if defined(__linux__) && defined(HAVE_DLOPEN) && defined(HAVE_DLFCN_H) && !defined(PPC)
07eda22000-07-05Fredrik Hübinette (Hubbe)  { char ** bos_location; void *handle;
d1913b2000-10-01Fredrik Hübinette (Hubbe)  /* damn this is ugly -Hubbe */
07eda22000-07-05Fredrik Hübinette (Hubbe)  if((handle=dlopen(0, RTLD_LAZY))) { bos_location=dlsym(handle,"__pthread_initial_thread_bos"); if(bos_location && *bos_location &&
0e7aa12000-08-05Fredrik Hübinette (Hubbe)  (*bos_location - Pike_interpreter.stack_top) *STACK_DIRECTION < 0)
d1913b2000-10-01Fredrik Hübinette (Hubbe)  {
0e7aa12000-08-05Fredrik Hübinette (Hubbe)  Pike_interpreter.stack_top=*bos_location;
d1913b2000-10-01Fredrik Hübinette (Hubbe)  }
e31ca22002-01-08Henrik Grubbström (Grubba)  dlclose(handle);
07eda22000-07-05Fredrik Hübinette (Hubbe)  } } #else
d1913b2000-10-01Fredrik Hübinette (Hubbe) #ifdef HAVE_PTHREAD_INITIAL_THREAD_BOS
752e101999-04-30Fredrik Hübinette (Hubbe)  { extern char * __pthread_initial_thread_bos; /* Linux glibc threads are limited to a 4 Mb stack * __pthread_initial_thread_bos is the actual limit */ if(__pthread_initial_thread_bos &&
cd86322000-07-06Fredrik Hübinette (Hubbe)  (__pthread_initial_thread_bos - Pike_interpreter.stack_top) *STACK_DIRECTION < 0)
d1913b2000-10-01Fredrik Hübinette (Hubbe)  {
cd86322000-07-06Fredrik Hübinette (Hubbe)  Pike_interpreter.stack_top=__pthread_initial_thread_bos;
d1913b2000-10-01Fredrik Hübinette (Hubbe)  }
752e101999-04-30Fredrik Hübinette (Hubbe)  }
d1913b2000-10-01Fredrik Hübinette (Hubbe) #endif /* HAVE_PTHREAD_INITIAL_THREAD_BOS */
9fb7302002-01-08Henrik Grubbström (Grubba) #endif /* __linux__ && HAVE_DLOPEN && HAVE_DLFCN_H && !PPC*/
d1913b2000-10-01Fredrik Hübinette (Hubbe) 
f12b712001-03-25Henrik Grubbström (Grubba) #if STACK_DIRECTION < 0 Pike_interpreter.stack_top += 8192 * sizeof(char *); #else /* STACK_DIRECTION >= 0 */ Pike_interpreter.stack_top -= 8192 * sizeof(char *); #endif /* STACK_DIRECTION < 0 */
a9388a1998-09-02Henrik Grubbström (Grubba)  #ifdef STACK_DEBUG fprintf(stderr, "1: C-stack: 0x%08p - 0x%08p, direction:%d\n",
cd86322000-07-06Fredrik Hübinette (Hubbe)  &argv, Pike_interpreter.stack_top, STACK_DIRECTION);
a9388a1998-09-02Henrik Grubbström (Grubba) #endif /* STACK_DEBUG */
4908871998-08-10Fredrik Hübinette (Hubbe)  } }
a9388a1998-09-02Henrik Grubbström (Grubba) #else /* !HAVE_GETRLIMIT || !RLIMIT_STACK */ /* 128 MB seems a bit extreme, most OS's seem to have their limit at ~8MB */
cd86322000-07-06Fredrik Hübinette (Hubbe)  Pike_interpreter.stack_top += STACK_DIRECTION * (1024*1024 * 8 - 8192 * sizeof(char *));
a9388a1998-09-02Henrik Grubbström (Grubba) #ifdef STACK_DEBUG fprintf(stderr, "2: C-stack: 0x%08p - 0x%08p, direction:%d\n",
cd86322000-07-06Fredrik Hübinette (Hubbe)  &argv, Pike_interpreter.stack_top, STACK_DIRECTION);
a9388a1998-09-02Henrik Grubbström (Grubba) #endif /* STACK_DEBUG */ #endif /* HAVE_GETRLIMIT && RLIMIT_STACK */
4908871998-08-10Fredrik Hübinette (Hubbe) 
1726312000-05-20Per Hedbor #if 0
2a50961995-08-23Fredrik Hübinette (Hubbe) #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { struct rlimit lim;
f90e541995-08-17Fredrik Hübinette (Hubbe)  long tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!getrlimit(RLIMIT_NOFILE, &lim)) {
5c8e891995-10-29Fredrik Hübinette (Hubbe) #ifdef RLIM_INFINITY if(lim.rlim_max == RLIM_INFINITY) lim.rlim_max=MAX_OPEN_FILEDESCRIPTORS; #endif
f90e541995-08-17Fredrik Hübinette (Hubbe)  tmp=MINIMUM(lim.rlim_max, MAX_OPEN_FILEDESCRIPTORS);
5267b71995-08-09Fredrik Hübinette (Hubbe)  lim.rlim_cur=tmp; setrlimit(RLIMIT_NOFILE, &lim); } }
1726312000-05-20Per Hedbor #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif
4081261998-04-23Fredrik Hübinette (Hubbe) 
ff34a52001-05-31Henrik Grubbström (Grubba)  TRACE((stderr, "Init time...\n"));
6e37dc1996-06-21Fredrik Hübinette (Hubbe)  GETTIMEOFDAY(&current_time);
2da1e22003-02-03Henrik Grubbström (Grubba)  TRACE((stderr, "Init threads...\n"));
96b0d62002-01-03Henrik Grubbström (Grubba)  low_th_init();
2da1e22003-02-03Henrik Grubbström (Grubba)  TRACE((stderr, "Init strings...\n"));
ff34a52001-05-31Henrik Grubbström (Grubba) 
378b2d1997-02-06Fredrik Hübinette (Hubbe)  init_shared_string_table();
2da1e22003-02-03Henrik Grubbström (Grubba)  TRACE((stderr, "Init interpreter...\n"));
378b2d1997-02-06Fredrik Hübinette (Hubbe)  init_interpreter();
2da1e22003-02-03Henrik Grubbström (Grubba)  TRACE((stderr, "Init types...\n"));
aee13c1998-05-25Henrik Grubbström (Grubba)  init_types();
2da1e22003-02-03Henrik Grubbström (Grubba) 
143d882003-11-14Martin Stjernholm  TRACE((stderr, "Init opcodes...\n"));
2da1e22003-02-03Henrik Grubbström (Grubba) 
143d882003-11-14Martin Stjernholm  init_opcodes();
2da1e22003-02-03Henrik Grubbström (Grubba)  TRACE((stderr, "Init programs...\n"));
4218011999-01-31Fredrik Hübinette (Hubbe)  init_program();
2da1e22003-02-03Henrik Grubbström (Grubba)  TRACE((stderr, "Init objects...\n"));
a5787d1999-03-03Fredrik Hübinette (Hubbe)  init_object();
a91ca01998-07-10Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(SETJMP(back)) {
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(throw_severity == THROW_EXIT) { num=throw_value.u.integer; }else{
667ec22003-07-22Martin Stjernholm  if (throw_value.type == T_OBJECT && throw_value.u.object->prog == master_load_error_program && !get_master()) { /* Report this specific error in a nice way. Since there's no * master it'd be reported with a raw error dump otherwise. */ struct generic_error_struct *err;
e8cbe42004-07-04Martin Nilsson  dynamic_buffer buf; dynbuf_string s; struct svalue t;
667ec22003-07-22Martin Stjernholm  *(Pike_sp++) = throw_value; dmalloc_touch_svalue(Pike_sp-1); throw_value.type=T_INT; err = (struct generic_error_struct *) get_storage (Pike_sp[-1].u.object, generic_error_program);
e8cbe42004-07-04Martin Nilsson  t.type = PIKE_T_STRING; t.u.string = err->error_message; init_buf(&buf); describe_svalue(&t,0,0); s=complex_free_buf(&buf);
9f6bfe2004-07-04Stephen R. van den Berg  fputs(s.str, stderr);
e8cbe42004-07-04Martin Nilsson  free(s.str);
667ec22003-07-22Martin Stjernholm  } else call_handle_error();
61e9a01998-01-25Fredrik Hübinette (Hubbe)  num=10; } }else{ back.severity=THROW_EXIT;
fe5eb01998-01-31Fredrik Hübinette (Hubbe) 
8964bd2004-10-11Henrik Grubbström (Grubba)  TRACE((stderr, "Init master cookie...\n"));
bd182a2004-10-14Henrik Grubbström (Grubba)  /* Avoid duplicate entries... */ push_constant_text(MASTER_COOKIE1); push_constant_text(MASTER_COOKIE2); f_add(2);
8964bd2004-10-11Henrik Grubbström (Grubba)  low_add_constant("__master_cookie", Pike_sp-1); pop_stack();
586dd32004-03-10Henrik Grubbström (Grubba)  TRACE((stderr, "Init modules...\n")); init_modules(); #ifdef TEST_MULTISET /* A C-level testsuite for the low level stuff in multisets. */ test_multiset(); #endif
09126b2001-12-19Martin Stjernholm  TRACE((stderr, "Init master...\n")); master(); call_callback(& post_master_callbacks, 0); free_callback_list(& post_master_callbacks); TRACE((stderr, "Call master->_main()...\n"));
fe5eb01998-01-31Fredrik Hübinette (Hubbe)  a=allocate_array_no_init(argc,0); for(num=0;num<argc;num++) { ITEM(a)[num].u.string=make_shared_string(argv[num]); ITEM(a)[num].type=T_STRING; }
2523ce2003-04-28Martin Stjernholm  a->type_field = BIT_STRING;
fe5eb01998-01-31Fredrik Hübinette (Hubbe)  push_array(a);
61e9a01998-01-25Fredrik Hübinette (Hubbe) 
092e542003-12-17Marcus Comstedt #ifdef __amigaos__
3189c92004-01-31Marcus Comstedt #ifdef __amigaos4__
52ce1d2004-09-26Marcus Comstedt  if(DOSBase->lib_Version >= 50) {
3189c92004-01-31Marcus Comstedt  struct svalue *mark = Pike_sp; IDOS->ScanVars(&scan_amigaos_environment_hook, GVF_BINARY_VAR|GVF_DONT_NULL_TERM, NULL); f_aggregate(Pike_sp-mark); } else #endif push_array(allocate_array_no_init(0,0));
092e542003-12-17Marcus Comstedt #else
fe5eb01998-01-31Fredrik Hübinette (Hubbe)  for(num=0;environ[num];num++); a=allocate_array_no_init(num,0); for(num=0;environ[num];num++) { ITEM(a)[num].u.string=make_shared_string(environ[num]); ITEM(a)[num].type=T_STRING; }
2523ce2003-04-28Martin Stjernholm  a->type_field = BIT_STRING;
fe5eb01998-01-31Fredrik Hübinette (Hubbe)  push_array(a);
092e542003-12-17Marcus Comstedt #endif
fe5eb01998-01-31Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  apply(master(),"_main",2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_stack();
61e9a01998-01-25Fredrik Hübinette (Hubbe)  num=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } UNSETJMP(back);
cfd36c2003-11-14Martin Stjernholm  TRACE((stderr, "Exit %d...\n", num));
ff34a52001-05-31Henrik Grubbström (Grubba) 
eb2fd52000-11-06Henrik Grubbström (Grubba)  pike_do_exit(num);
3c0c281998-01-26Fredrik Hübinette (Hubbe)  return num; /* avoid warning */
61e9a01998-01-25Fredrik Hübinette (Hubbe) }
3c0c281998-01-26Fredrik Hübinette (Hubbe) #undef ATTRIBUTE #define ATTRIBUTE(X)
eb2fd52000-11-06Henrik Grubbström (Grubba) DECLSPEC(noreturn) void pike_do_exit(int num) ATTRIBUTE((noreturn))
61e9a01998-01-25Fredrik Hübinette (Hubbe) {
d2361e2003-06-30Martin Stjernholm  call_callback(&exit_callbacks, NULL);
ecf1451998-03-21Fredrik Hübinette (Hubbe)  free_callback_list(&exit_callbacks);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  exit_modules();
2916001998-01-16Henrik Grubbström (Grubba) 
2043ba1998-02-10Fredrik Hübinette (Hubbe) #ifdef DEBUG_MALLOC
da41292002-11-25Martin Stjernholm  cleanup_memhdrs(); cleanup_debug_malloc();
2043ba1998-02-10Fredrik Hübinette (Hubbe) #endif
0612442001-05-16Fredrik Hübinette (Hubbe)  #ifdef PROFILING { int q; for(q=0;q<(long)NELEM(samples);q++) if(samples[q]) fprintf(stderr,"STACK WAS %4d Kb %12u times\n",q-1,samples[q]); } #endif
9a6d002001-06-26Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG /* For profiling */
143d882003-11-14Martin Stjernholm  exit_opcodes();
9a6d002001-06-26Fredrik Hübinette (Hubbe) #endif
0f65e12002-09-14Martin Stjernholm #ifdef INTERNAL_PROFILING fprintf (stderr, "Evaluator callback calls: %lu\n", evaluator_callback_calls); #ifdef PIKE_THREADS fprintf (stderr, "Thread yields: %lu\n", thread_yields); #endif fprintf (stderr, "Main thread summary:\n"); debug_print_rusage (stderr); #endif
61e9a01998-01-25Fredrik Hübinette (Hubbe)  exit(num);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
156fd51997-10-27Fredrik Hübinette (Hubbe) void low_init_main(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
6f3ad02001-07-02Martin Stjernholm  void init_iterators(void);
528fe12004-10-23Martin Nilsson  void init_facetgroup(void);
8650752001-06-25Henrik Grubbström (Grubba) 
f8bb982001-12-20Martin Stjernholm  init_cpp();
87f9082001-03-12Fredrik Hübinette (Hubbe)  init_backend();
4cdb802001-02-23Fredrik Hübinette (Hubbe)  init_iterators();
9b1f032000-10-09Fredrik Hübinette (Hubbe)  init_pike_searching();
f01a521999-08-14Fredrik Hübinette (Hubbe)  init_error();
7e97c31999-01-21Fredrik Hübinette (Hubbe)  init_pike_security();
378b2d1997-02-06Fredrik Hübinette (Hubbe)  th_init();
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  init_operators();
8650752001-06-25Henrik Grubbström (Grubba)  init_builtin();
5267b71995-08-09Fredrik Hübinette (Hubbe)  init_builtin_efuns();
cb22561995-10-11Fredrik Hübinette (Hubbe)  init_signals();
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  init_dynamic_load();
528fe12004-10-23Martin Nilsson  init_facetgroup();
5267b71995-08-09Fredrik Hübinette (Hubbe) }
378b2d1997-02-06Fredrik Hübinette (Hubbe) void exit_main(void)
156fd51997-10-27Fredrik Hübinette (Hubbe) {
b5c00b2003-03-30Martin Stjernholm #ifdef DO_PIKE_CLEANUP
75c0252004-03-16Martin Stjernholm  size_t count;
31a8682004-09-27Martin Stjernholm  if (exit_with_cleanup) { /* Destruct all remaining objects while we have a proper execution * environment. The downside is that the leak report below will * always report destructed objects. We use the gc in a special mode * for this to get a reasonably sane destruct order. */ gc_destruct_everything = 1; count = do_gc (NULL, 1); while (count) { size_t new_count = do_gc (NULL, 1); if (new_count >= count) { fprintf (stderr, "Some destroy function is creating new objects " "during final cleanup - can't exit cleanly.\n"); break; } count = new_count;
75c0252004-03-16Martin Stjernholm  }
31a8682004-09-27Martin Stjernholm  gc_destruct_everything = 0;
75c0252004-03-16Martin Stjernholm  }
826bd72003-04-02Martin Stjernholm  /* Unload dynamic modules before static ones. */ exit_dynamic_load();
b5c00b2003-03-30Martin Stjernholm #endif
156fd51997-10-27Fredrik Hübinette (Hubbe) } void init_main(void) { } void low_exit_main(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
5f06241999-04-11Fredrik Hübinette (Hubbe) #ifdef DO_PIKE_CLEANUP
727a4f2001-07-02Martin Stjernholm  void exit_iterators(void);
528fe12004-10-23Martin Nilsson  void exit_facetgroup(void);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
826bd72003-04-02Martin Stjernholm  /* Clear various global references. */
e37a3e1999-10-09Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM exit_auto_bignum(); #endif
9b1f032000-10-09Fredrik Hübinette (Hubbe)  exit_pike_searching();
a5787d1999-03-03Fredrik Hübinette (Hubbe)  exit_object();
cb22561995-10-11Fredrik Hübinette (Hubbe)  exit_signals();
8650752001-06-25Henrik Grubbström (Grubba)  exit_builtin();
5740881998-01-01Fredrik Hübinette (Hubbe)  exit_cpp();
5267b71995-08-09Fredrik Hübinette (Hubbe)  cleanup_interpret();
1c5b342003-03-26Martin Nilsson  exit_builtin_constants();
feef142002-05-14Martin Stjernholm  cleanup_module_support();
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  exit_operators();
c52c082001-03-28Henrik Grubbström (Grubba)  exit_iterators();
528fe12004-10-23Martin Nilsson  exit_facetgroup();
5267b71995-08-09Fredrik Hübinette (Hubbe)  cleanup_program();
61e9a01998-01-25Fredrik Hübinette (Hubbe)  cleanup_compiler();
8310c61999-03-19Fredrik Hübinette (Hubbe)  cleanup_error();
c2be512001-03-21Fredrik Hübinette (Hubbe)  exit_backend();
a12b8c2003-03-30Martin Stjernholm  cleanup_gc(); cleanup_pike_types();
06983f1996-09-22Fredrik Hübinette (Hubbe) 
826bd72003-04-02Martin Stjernholm  /* This zaps Pike_interpreter.thread_state among other things, so
6ff38a2004-04-03Martin Stjernholm  * THREADS_ALLOW/DISALLOW are NOPs beyond this point. */
826bd72003-04-02Martin Stjernholm  th_cleanup();
cee5811999-12-05Henrik Grubbström (Grubba) #ifdef SHARED_NODES free(node_hash.table); #endif /* SHARED_NODES */
1ab7c61999-04-08Fredrik Hübinette (Hubbe)  exit_pike_security();
f545211998-01-27Fredrik Hübinette (Hubbe)  free_svalue(& throw_value); throw_value.type=T_INT;
b5c00b2003-03-30Martin Stjernholm 
f65d102004-03-16Martin Stjernholm  do_gc(NULL, 1);
06983f1996-09-22Fredrik Hübinette (Hubbe) 
31a8682004-09-27Martin Stjernholm  if (exit_with_cleanup)
61e9a01998-01-25Fredrik Hübinette (Hubbe)  {
31a8682004-09-27Martin Stjernholm  int leak_found = 0;
56ac102000-03-29Fredrik Hübinette (Hubbe) #ifdef _REENTRANT if(count_pike_threads()>1) { fprintf(stderr,"Byte counting aborted, because all threads have not exited properly.\n");
31a8682004-09-27Martin Stjernholm  exit_with_cleanup = 0;
56ac102000-03-29Fredrik Hübinette (Hubbe)  return; } #endif
75c0252004-03-16Martin Stjernholm #ifdef DEBUG_MALLOC
25479a2000-03-07Fredrik Hübinette (Hubbe)  search_all_memheaders_for_references();
75c0252004-03-16Martin Stjernholm #endif /* The use of markers below only works after a gc run where it * hasn't freed anything. Since we've destructed all objects in * exit_main, nothing should be left after the run above, so only * one more run is necessary. */ gc_keep_markers = 1; do_gc (NULL, 1);
61e9a01998-01-25Fredrik Hübinette (Hubbe) 
5272b22004-09-22Martin Stjernholm #define STATIC_ARRAYS {&empty_array, &weak_empty_array}
f65d102004-03-16Martin Stjernholm  #define REPORT_LINKED_LIST_LEAKS(TYPE, START, STATICS, T_TYPE, NAME) do { \
a12b8c2003-03-30Martin Stjernholm  struct TYPE *x; \
cd451f2004-03-15Martin Stjernholm  for (x = START; x; x = x->next) { \
a12b8c2003-03-30Martin Stjernholm  struct marker *m = find_marker (x); \ if (!m) { \
75c0252004-03-16Martin Stjernholm  DO_IF_DEBUG ( \ fprintf (stderr, "Didn't find gc marker as expected for:\n"); \ describe_something (x, T_TYPE, 2, 2, 0, NULL); \ ); \
a12b8c2003-03-30Martin Stjernholm  } \
f65d102004-03-16Martin Stjernholm  else { \ int is_static = 0; \ static const struct TYPE *statics[] = STATICS; \ ptrdiff_t i; /* Use signed type to avoid warnings from gcc. */ \ for (i = 0; i < (ptrdiff_t) NELEM (statics); i++) \ if (x == statics[i]) \ is_static = 1; \ if (x->refs != m->refs + is_static) { \
31a8682004-09-27Martin Stjernholm  if (!leak_found) { \ fputs ("Leak(s) found at exit:\n", stderr); \ leak_found = 1; \ } \ fprintf (stderr, NAME " got %d unaccounted references: ", \
75c0252004-03-16Martin Stjernholm  x->refs - (m->refs + is_static)); \
31a8682004-09-27Martin Stjernholm  print_short_svalue (stderr, (union anything *) &x, T_TYPE); \ fputc ('\n', stderr); \
ed97a62004-09-30Martin Stjernholm  DO_IF_DMALLOC (debug_malloc_dump_references (x, 0, 1, 0)); \
f65d102004-03-16Martin Stjernholm  } \
a12b8c2003-03-30Martin Stjernholm  } \ } \ } while (0)
f65d102004-03-16Martin Stjernholm  REPORT_LINKED_LIST_LEAKS (array, first_array, STATIC_ARRAYS, T_ARRAY, "Array"); REPORT_LINKED_LIST_LEAKS (multiset, first_multiset, {}, T_MULTISET, "Multiset"); REPORT_LINKED_LIST_LEAKS (mapping, first_mapping, {}, T_MAPPING, "Mapping"); REPORT_LINKED_LIST_LEAKS (program, first_program, {}, T_PROGRAM, "Program"); REPORT_LINKED_LIST_LEAKS (object, first_object, {}, T_OBJECT, "Object");
a12b8c2003-03-30Martin Stjernholm  #undef REPORT_LINKED_LIST_LEAKS /* Just remove the extra external refs reported above and do * another gc so that we don't report the blocks again in the low * level dmalloc reports. */
f3501d2004-09-30Martin Stjernholm #if 1 /* It can be a good idea to disable this to leave the blocks * around to be reported by an external memchecker like valgrind. * Ideally we should only free the svalues inside these things but * leave the blocks themselves. */
f65d102004-03-16Martin Stjernholm #define ZAP_LINKED_LIST_LEAKS(TYPE, START, STATICS) do { \
ed97a62004-09-30Martin Stjernholm  struct TYPE *x, *next; \ for (x = START; x; x = next) { \
a12b8c2003-03-30Martin Stjernholm  struct marker *m = find_marker (x); \
ed97a62004-09-30Martin Stjernholm  next = x->next; \
f65d102004-03-16Martin Stjernholm  if (m) { \ int is_static = 0; \ static const struct TYPE *statics[] = STATICS; \ ptrdiff_t i; /* Use signed type to avoid warnings from gcc. */ \
ed97a62004-09-30Martin Stjernholm  INT32 refs; \
f65d102004-03-16Martin Stjernholm  for (i = 0; i < (ptrdiff_t) NELEM (statics); i++) \ if (x == statics[i]) \ is_static = 1; \
ed97a62004-09-30Martin Stjernholm  refs = x->refs; \ while (refs > m->refs + is_static) { \
31a8682004-09-27Martin Stjernholm  DO_IF_DEBUG (m->flags |= GC_CLEANUP_FREED); \
a12b8c2003-03-30Martin Stjernholm  PIKE_CONCAT(free_, TYPE) (x); \
ed97a62004-09-30Martin Stjernholm  refs--; \
4fab5f2004-04-18Martin Stjernholm  } \
f65d102004-03-16Martin Stjernholm  } \
a12b8c2003-03-30Martin Stjernholm  } \ } while (0)
f65d102004-03-16Martin Stjernholm  ZAP_LINKED_LIST_LEAKS (array, first_array, STATIC_ARRAYS); ZAP_LINKED_LIST_LEAKS (multiset, first_multiset, {}); ZAP_LINKED_LIST_LEAKS (mapping, first_mapping, {}); ZAP_LINKED_LIST_LEAKS (program, first_program, {}); ZAP_LINKED_LIST_LEAKS (object, first_object, {});
a12b8c2003-03-30Martin Stjernholm  #undef ZAP_LINKED_LIST_LEAKS
31a8682004-09-27Martin Stjernholm #ifdef PIKE_DEBUG
a12b8c2003-03-30Martin Stjernholm  /* If we stumble on the real refs whose refcounts we've zapped * above we should try to handle it gracefully. */ gc_external_refs_zapped = 1;
f3501d2004-09-30Martin Stjernholm #endif
31a8682004-09-27Martin Stjernholm #endif
a12b8c2003-03-30Martin Stjernholm  do_gc (NULL, 1);
61e9a01998-01-25Fredrik Hübinette (Hubbe) 
4fab5f2004-04-18Martin Stjernholm  gc_keep_markers = 0; exit_gc();
75c0252004-03-16Martin Stjernholm #ifdef DEBUG_MALLOC
61e9a01998-01-25Fredrik Hübinette (Hubbe)  {
a12b8c2003-03-30Martin Stjernholm  INT32 num, size; count_memory_in_pike_types(&num, &size); if (num) fprintf(stderr, "Types left: %d (%d bytes)\n", num, size); describe_all_types();
61e9a01998-01-25Fredrik Hübinette (Hubbe)  }
75c0252004-03-16Martin Stjernholm #endif
61e9a01998-01-25Fredrik Hübinette (Hubbe)  }
5b7b061999-04-08Fredrik Hübinette (Hubbe) 
b5c00b2003-03-30Martin Stjernholm  destruct_objects_to_destruct_cb();
a12b8c2003-03-30Martin Stjernholm 
826bd72003-04-02Martin Stjernholm  /* Now there are no arrays/objects/programs/anything left. */
b660c81999-03-01Fredrik Hübinette (Hubbe)  really_clean_up_interpret();
5f06241999-04-11Fredrik Hübinette (Hubbe) 
5b7b061999-04-08Fredrik Hübinette (Hubbe)  cleanup_callbacks(); free_all_callable_blocks(); exit_destroy_called_mark_hash();
f6f3842000-03-07Fredrik Hübinette (Hubbe) 
61daf72001-03-29Henrik Grubbström (Grubba)  cleanup_pike_type_table(); cleanup_shared_string_table();
da667d2000-09-28Henrik Grubbström (Grubba)  free_dynamic_load();
22ef9c2000-09-30Martin Stjernholm  first_mapping=0;
4be46f2000-03-07Fredrik Hübinette (Hubbe)  free_all_mapping_blocks();
22ef9c2000-09-30Martin Stjernholm  first_object=0;
648a1a2000-06-22Fredrik Hübinette (Hubbe)  free_all_object_blocks();
2d4a382001-05-13Fredrik Hübinette (Hubbe)  first_program=0;
f3c7152001-04-14Fredrik Hübinette (Hubbe)  free_all_program_blocks();
5b15bb2001-12-10Martin Stjernholm  exit_multiset(); #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) }