Пример #1
0
/*******************************************************************************
Process a (file system) pathname (a file, directory or "other").
*******************************************************************************/
void process_path(char *pathname, regex_t *extregexpptr, int recursiondepth) {
	struct stat	statinfo;

	if (recursiondepth == 0) {
		trim_trailing_slashes(pathname);
	}

	if (!regularfileflag && !directoryflag && !otherobjectflag) {
		fprintf(stderr, "No output target types requested for '%s'!\n",pathname);
		returncode = 1;
		return;
	}

	if (lstat(pathname, &statinfo) == -1) {
		fprintf(stderr, "process_path: Cannot access '%s'\n", pathname);
		returncode = 1;
		return;
	}

	if (S_ISREG(statinfo.st_mode)) {
		if (regularfileflag) {
			process_object(pathname, extregexpptr);
		}
	} else if (S_ISDIR(statinfo.st_mode)) {
		if (directoryflag) {
			process_object(pathname, extregexpptr);
		}
		if (recursiondepth == 0 || (recursiveflag && recursiondepth <= maxrecursiondepth)) {
			process_directory(pathname, extregexpptr, recursiondepth);
		}
	} else if (otherobjectflag) {
		process_object(pathname, extregexpptr);
	}
}
Пример #2
0
static int loop(struct walker *walker)
{
	struct object_list *elem;

	while (process_queue) {
		struct object *obj = process_queue->item;
		elem = process_queue;
		process_queue = elem->next;
		free(elem);
		if (!process_queue)
			process_queue_end = &process_queue;

		/* If we are not scanning this object, we placed it in
		 * the queue because we needed to fetch it first.
		 */
		if (! (obj->flags & TO_SCAN)) {
			if (walker->fetch(walker, obj->sha1)) {
				report_missing(obj);
				return -1;
			}
		}
		if (!obj->type)
			parse_object(obj->sha1);
		if (process_object(walker, obj))
			return -1;
	}
	return 0;
}
Пример #3
0
int main () {

  by_reference();
  std::cout << std::endl;

  by_value_copy();
  std::cout << std::endl;

  by_value_move();
  std::cout << std::endl;

  by_value_temp_move();
  std::cout << std::endl;

  by_value_temp_move_rvo();
  std::cout << std::endl;

  some_method_by_reference(A(S(std::string("cool string"))));
  std::cout << std::endl;

  some_method_by_reference(B(S(std::string("cool string"))));
  std::cout << std::endl;

  emplace_into_vector();
  std::cout << std::endl;

  process_object(B(get_string()));
  std::cout << std::endl;

  return 0;
}
Пример #4
0
static void process_value(json_value* value, int depth)
{
        int j;
        if (value == NULL) {
                return;
        }
        if (value->type != json_object) {
                print_depth_shift(depth);
        }
        
        DEBUG("PROCESSBALUE\n");
        
        switch (value->type) {
                case json_none:
                        DEBUG("none\n");
                        break;
                case json_object:
                        process_object(value, depth+1);
                        break;
                case json_array:
                        process_array(value, depth+1);
                        break;
                case json_integer:
                        DEBUG("int: %ld\n", value->u.integer);
                        break;
                case json_double:
                        DEBUG("double: %f\n", value->u.dbl);
                        break;
                case json_string:
                        DEBUG("string: %s\n", value->u.string.ptr);
                        break;
                case json_boolean:
                        DEBUG("bool: %d\n", value->u.boolean);
                        break;
				case json_null:
						DEBUG("JSON parse NULL\n");
					break;
        }
}
Пример #5
0
void start_job(File_t *object)
{
	check_connection();
	pid_t p;
	if (n_jobs == parallel_max)
	{
		wait_for_job();
	}
	p = fork();
	if (p < 0)
	{
		Error("fork failed");
	}
	else if (p == 0)
	{
		bool status = process_object(object);
		if (!status) {
			*connection_broken = 1;
		}
		exit(1);
	}
	++n_jobs;
}
Пример #6
0
static void
reload (an_object_file_ptr pobj, string path)
{
    string old_name = pobj->name;
    unsigned old_name_index = pobj->name_ndx;
    int fd;

    unread_sections (pobj);
    unread_obj (pobj, FALSE);
    BZERO (pobj, sizeof(an_object_file));
    pobj->other_name = old_name;
    pobj->other_name_ndx = old_name_index;
    pobj->name = path;
    pobj->name_ndx = string_find_offset(path);

    /* copied from pass1 */
    fd = open_file (path, TRUE, FALSE, 0);
    if (!use_mmap)
        pobj->access_method = AM_READ;
    pobj->ftype = read_headers (pobj, fd, FALSE);
    LD_ASSERT (pobj->ftype == FT_OBJ, thisfile,
               "incorrect file type from back end");

    add_object (pobj);
    msg(ER_DEFAULT /* ER_VERBOSE */ , ERN_LOAD_OBJ, num_objects_linked, pobj->name);
    if (bsdmap)
        printf("%s\n", pobj->other_name);
    process_object (pobj);
    if (optsym[OPTSYM_MDEPEND].num)
        update_make_depend (pobj->other_name);
    unread_sections (pobj);
    close (fd);
    delay_load = DL_DEFAULT;
    if (hides != HS_IGNORE) {
        hides = HS_DEFAULT;
    }
} /* reload */
/*
 * Get the linkmap from the dynlinker.  Try to load kernel modules
 * from all objects in the linkmap.
 */
void
rumpuser_dl_bootstrap(rump_modinit_fn domodinit,
	rump_symload_fn symload, rump_compload_fn compload)
{
	struct link_map *map, *origmap, *mainmap;
	void *mainhandle;
	int error;

	mainhandle = dlopen(NULL, RTLD_NOW);
	if (dlinfo(mainhandle, RTLD_DI_LINKMAP, &mainmap) == -1) {
		fprintf(stderr, "warning: rumpuser module bootstrap "
		    "failed: %s\n", dlerror());
		return;
	}
	origmap = mainmap;

	/*
	 * Process last->first because that's the most probable
	 * order for dependencies
	 */
	for (; origmap->l_next; origmap = origmap->l_next)
		continue;

	/*
	 * Build symbol table to hand to the rump kernel.  Do this by
	 * iterating over all rump libraries and collecting symbol
	 * addresses and relocation info.
	 */
	error = 0;
	for (map = origmap; map && !error; map = map->l_prev) {
		if (strstr(map->l_name, "librump") != NULL || map == mainmap)
			error = getsymbols(map, map == mainmap);
	}

	if (error == 0) {
		void *trimmedsym, *trimmedstr;

		/*
		 * Allocate optimum-sized memory for storing tables
		 * and feed to kernel.  If memory allocation fails,
		 * just give the ones with extra context (although
		 * I'm pretty sure we'll die moments later due to
		 * memory running out).
		 */
		if ((trimmedsym = malloc(symtaboff)) != NULL) {
			memcpy(trimmedsym, symtab, symtaboff);
		} else {
			trimmedsym = symtab;
			symtab = NULL;
		}
		if ((trimmedstr = malloc(strtaboff)) != NULL) {
			memcpy(trimmedstr, strtab, strtaboff);
		} else {
			trimmedstr = strtab;
			strtab = NULL;
		}
		symload(trimmedsym, symtaboff, trimmedstr, strtaboff);
	}
	free(symtab);
	free(strtab);

	/*
	 * Next, load modules and components.
	 *
	 * Simply loop through all objects, ones unrelated to rump kernels
	 * will not contain link_set_rump_components (well, not including
	 * "sabotage", but that needs to be solved at another level anyway).
	 */
	for (map = origmap; map; map = map->l_prev) {
		void *handle;

		if (map == mainmap) {
			handle = mainhandle;
		} else {
			handle = dlopen(map->l_name, RTLD_LAZY);
			if (handle == NULL)
				continue;
		}
		process_object(handle, domodinit, compload);
		if (map != mainmap)
			dlclose(handle);
	}
}
Пример #8
0
int main(int argc, char **argv)
{
   char config_file_path[256];
   opt_filename = NULL;
   opt_url = NULL;
   fetch_all = false;
   test_mode = false;
   verbose = false;
   opt_insecure = false;
   used_insecure = false;

   strcpy(config_file_path, "/etc/openrail.conf");
   word usage = false;
   int c;
   while ((c = getopt (argc, argv, ":c:u:f:tpih")) != -1)
      switch (c)
      {
      case 'c':
         strcpy(config_file_path, optarg);
         break;
      case 'u':
         if(!opt_filename) opt_url = optarg;
         break;
      case 'f':
         if(!opt_url) opt_filename = optarg;
         break;
      case 'a':
         fetch_all = true;
         break;
      case 't':
         test_mode = true;
         break;
      case 'p':
         verbose = true;
         break;
      case 'i':
         opt_insecure = true;
         break;
      case 'h':
         usage = true;
         break;
      case ':':
         break;
      case '?':
      default:
         usage = true;
      break;
      }

   char * config_fail;
   if((config_fail = load_config(config_file_path)))
   {
      printf("Failed to read config file \"%s\":  %s\n", config_file_path, config_fail);
      usage = true;
   }

   if(usage) 
   {
      printf("%s %s  Usage: %s [-c /path/to/config/file.conf] [-u <url> | -f <path> | -a] [-t | -r] [-p][-i]\n", NAME, BUILD, argv[0]);
      printf(
             "-c <file>  Path to config file.\n"
             "Data source:\n"
             "default    Fetch latest update.\n"
             "-u <url>   Fetch from specified URL.\n"
             "-f <file>  Use specified file.  (Must already be decompressed.)\n"
             "Actions:\n"
             "default    Apply data to database.\n"
             "-t         Report datestamp on download or file, do not apply to database.\n"
             "Options:\n"
             "-i         Insecure.  Circumvent certificate checks if necessary.\n"
             "-p         Print activity as well as logging.\n"
             );
      exit(1);
   }

   char zs[1024];

   start_time = time(NULL);

   debug = *conf[conf_debug];
  
   _log_init(debug?"/tmp/tscdb.log":"/var/log/garner/tscdb.log", (debug?1:(verbose?4:0)));
   
   _log(GENERAL, "");
   _log(GENERAL, "%s %s", NAME, BUILD);
   
   // Enable core dumps
   struct rlimit limit;
   if(!getrlimit(RLIMIT_CORE, &limit))
   {
      limit.rlim_cur = RLIM_INFINITY;
      setrlimit(RLIMIT_CORE, &limit);
   }
   
   int i;
   for(i = 0; i < MATCHES; i++)
   {
      if(regcomp(&match[i], match_strings[i], REG_ICASE + REG_EXTENDED))
      {
         sprintf(zs, "Failed to compile regex match %d", i);
         _log(MAJOR, zs);
      }
   }
   
   // Initialise database
   if(db_init(conf[conf_db_server], conf[conf_db_user], conf[conf_db_password], conf[conf_db_name])) exit(1);

   {
      word e;
      if((e=database_upgrade(cifdb)))
      {
         _log(CRITICAL, "Error %d in upgrade_database().  Aborting.", e);
         exit(1);
      }
   }

   run = 1;
   tiploc_ignored = false;

   // Zero the stats
   {
      word i;
      for(i = 0; i < MAXStats; i++) { stats[i] = 0; }
   }

   if(fetch_file())
   {
      if(opt_url || opt_filename)
      {
         _log(GENERAL, "Failed to find data.");
         exit(1);
      }
      {
         char report[256];
         _log(GENERAL, "Failed to fetch file.");
         
         sprintf(report, "Failed to collect timetable update after %lld attempts.", stats[Fetches]);
         email_alert(NAME, BUILD, "Timetable Update Failure Report", report);
      }
      exit(1);
   }

   char in_q = 0;
   char b_depth = 0;

   size_t ibuf = 0;
   size_t iobj = 0;
   size_t buf_end;

   // Determine applicable update
   {
      MYSQL_RES * result0;
      MYSQL_ROW row0;
      last_update_id[0] = '\0';
      if(!db_query("SELECT MAX(id) FROM updates_processed"))
      {
         result0 = db_store_result();
         if((row0 = mysql_fetch_row(result0)))
         {
            strcpy(last_update_id, row0[0]);
         }
         mysql_free_result(result0);
      }
   }

   if(last_update_id[0] == '\0')
   {
      _log(CRITICAL, "Failed to determine last update id from database.");
      exit(1);
   }


   if(test_mode)
   {
   }
   else
   {
      char c, pc;
      pc = 0;
      // Run through the file splitting off each JSON object and passing it on for processing.

      // DB may have dropped out due to long delay
      (void) db_connect();
      if(db_start_transaction()) _log(CRITICAL, "Failed to initiate database transaction.");
      while((buf_end = fread(buffer, 1, MAX_BUF, fp_result)) && run && !db_errored)
      {
         for(ibuf = 0; ibuf < buf_end && run && !db_errored; ibuf++)
         {
            c = buffer[ibuf];
            if(c != '\r' && c != '\n') 
            {
               obj[iobj++] = c;
               if(iobj >= MAX_OBJ)
               {
                  _log(CRITICAL, "Object buffer overflow!");
                  exit(1);
               }
               if(c == '"' && pc != '\\') in_q = ! in_q;
               if(!in_q && c == '{') b_depth++;
               if(!in_q && c == '}' && b_depth-- && !b_depth)
               {
                  obj[iobj] = '\0';
                  process_object(obj);
                  iobj = 0;
               }
            }
            pc = c;
         }
      }
      fclose(fp_result);
      if(db_errored)
      {
         _log(CRITICAL, "Update rolled back due to database error.");
         (void) db_rollback_transaction();
      }
      else
      {
         _log(GENERAL, "Committing database updates...");
         if(db_commit_transaction())
         {
            _log(CRITICAL, "Database commit failed.");
         }
         else
         {
            _log(GENERAL, "Committed.");
         }
      }
   }

#define REPORT_SIZE 16384
   char report[REPORT_SIZE];
   report[0] = '\0';

   _log(GENERAL, "");
   _log(GENERAL, "End of run:");

   if(used_insecure)
   {
      strcat(report, "*** Warning: Insecure download used.\n");
      _log(GENERAL, "*** Warning: Insecure download used.");
   }

   sprintf(zs, "             Elapsed time: %ld minutes", (time(NULL) - start_time + 30) / 60);
   _log(GENERAL, zs);
   strcat(report, zs); strcat(report, "\n");
   if(test_mode)
   {
      sprintf(zs, "Test mode.  No database changes made.");
      _log(GENERAL, zs);
      strcat(report, zs); strcat(report, "\n");
      exit(0);
   }

   for(i=0; i<MAXStats; i++)
   {
      sprintf(zs, "%25s: %s", stats_category[i], commas_q(stats[i]));
      if(i == DBError && stats[i]) strcat(zs, " ****************");
      _log(GENERAL, zs);
      strcat(report, zs);
      strcat(report, "\n");
   }

   db_disconnect();

   email_alert(NAME, BUILD, "Timetable Update Report", report);

   exit(0);
}
Пример #9
0
void ModelObject::read_obj(const char * filename)
{
    int vert_id = 1;
    std::string temp;
    std::string obj_line;
    std::ifstream obj_file (filename);

    if (obj_file.is_open()) {
        while (getline(obj_file, obj_line)) {
            if (obj_line[0] == 'v') {
                std::istringstream vert_string (obj_line);
                coord * new_coord = new coord;

                new_coord->id = vert_id;

                for (int i = 0; i < 4; i++) {
                    if (getline(vert_string, temp, ' ')) {
                        if (i == 1) {
                            new_coord->x = (float)atof(temp.c_str());
                        }
                        else if (i == 2) {
                            new_coord->y = (float)atof(temp.c_str());
                        }
                        else if (i == 3) {
                            new_coord->z = (float)atof(temp.c_str());
                        }
                    }
                }

                object->vertices.push_back(new_coord);
                object->vert_count++;
                vert_id++;
            }
            else if (obj_line[0] == 'f') {
                object->face_count++;

                std::istringstream face_string (obj_line);
                face * new_face = new face;
                int coord_id;

                getline(face_string, temp, ' ');

                while (getline(face_string, temp, ' '))
                {
                    coord_id = (int)atoi(temp.c_str());

                    new_face->coords.push_back(object->vertices[coord_id - 1]);
                }

                object->faces.push_back(new_face);

            }
            else if (obj_line[0] == 'o' && object->obj_name == 0) {
                std::string name_string (obj_line);

                if (name_string.length() > 2) {
                    object->obj_name = new char[name_string.length() - 1];
                    
                    for (int i = 2; i < name_string.length(); i++)
                        object->obj_name[i - 2] = name_string[i];
                }
            }
        }
        obj_file.close();

        process_object();
    }
}
Пример #10
0
/*
 * process_class - process a class
 * HEAP_CACHE_ATTRINFO structure
 *    return: error status
 *    class_oid(in): the class OID
 *    hfid(in): the class HFID 
 *    max_space_to_process(in): maximum space to process
 *    instance_lock_timeout(in): the lock timeout for instances
 *    space_to_process(in, out): space to process
 *    last_processed_oid(in, out): last processed oid
 *    total_objects(in, out): count the processed class objects
 *    failed_objects(in, out): count the failed class objects
 *    modified_objects(in, out): count the modified class objects
 *    big_objects(in, out): count the big class objects
 */
static int
process_class (THREAD_ENTRY * thread_p, OID * class_oid, HFID * hfid,
	       int max_space_to_process, int *instance_lock_timeout,
	       int *space_to_process, OID * last_processed_oid,
	       int *total_objects, int *failed_objects,
	       int *modified_objects, int *big_objects)
{
  int nobjects, nfetched, i, j;
  OID last_oid, prev_oid;
  LOCK null_lock = NULL_LOCK;
  LOCK oid_lock = X_LOCK;
  LC_COPYAREA *fetch_area = NULL;	/* Area where objects are received */
  struct lc_copyarea_manyobjs *mobjs;	/* Describe multiple objects in area */
  struct lc_copyarea_oneobj *obj;	/* Describe on object in area        */
  RECDES recdes;
  HEAP_CACHE_ATTRINFO attr_info;
  HEAP_SCANCACHE upd_scancache;
  int ret = NO_ERROR, object_processed;

  int nfailed_instances = 0;

  if (class_oid == NULL || hfid == NULL || space_to_process == NULL ||
      *space_to_process <= 0 || *space_to_process > max_space_to_process ||
      last_processed_oid == NULL || total_objects == NULL ||
      failed_objects == NULL || modified_objects == NULL ||
      big_objects == NULL || *total_objects < 0 || *failed_objects < 0)
    {
      return ER_FAILED;
    }

  nobjects = 0;
  nfetched = -1;

  ret =
    heap_scancache_start_modify (thread_p, &upd_scancache, hfid, class_oid,
				 SINGLE_ROW_UPDATE);
  if (ret != NO_ERROR)
    {
      return ER_FAILED;
    }

  ret = heap_attrinfo_start (thread_p, class_oid, -1, NULL, &attr_info);
  if (ret != NO_ERROR)
    {
      heap_scancache_end_modify (thread_p, &upd_scancache);
      return ER_FAILED;
    }

  COPY_OID (&last_oid, last_processed_oid);
  COPY_OID (&prev_oid, last_processed_oid);

  while (nobjects != nfetched)
    {
      ret = xlocator_lock_and_fetch_all (thread_p, hfid, &oid_lock,
					 instance_lock_timeout, class_oid,
					 &null_lock, &nobjects, &nfetched,
					 &nfailed_instances, &last_oid,
					 &fetch_area);

      if (ret == NO_ERROR)
	{
	  (*total_objects) += nfailed_instances;
	  (*failed_objects) += nfailed_instances;

	  if (fetch_area != NULL)
	    {
	      mobjs = LC_MANYOBJS_PTR_IN_COPYAREA (fetch_area);
	      obj = LC_START_ONEOBJ_PTR_IN_COPYAREA (mobjs);

	      for (i = 0; i < mobjs->num_objs; i++)
		{
		  if (obj->length > *space_to_process)
		    {
		      if (*space_to_process == max_space_to_process)
			{
			  (*total_objects)++;
			  (*big_objects)++;
			  lock_unlock_object (thread_p, &obj->oid, class_oid,
					      oid_lock, true);
			}
		      else
			{
			  *space_to_process = 0;
			  COPY_OID (last_processed_oid, &prev_oid);

			  for (j = i; j < mobjs->num_objs; j++)
			    {
			      lock_unlock_object (thread_p, &obj->oid,
						  class_oid, oid_lock, true);
			      obj = LC_NEXT_ONEOBJ_PTR_IN_COPYAREA (obj);
			    }

			  if (fetch_area)
			    {
			      locator_free_copy_area (fetch_area);
			    }
			  goto end;
			}
		    }
		  else
		    {
		      *space_to_process -= obj->length;

		      (*total_objects)++;
		      LC_RECDES_TO_GET_ONEOBJ (fetch_area, obj, &recdes);

		      if (desc_disk_to_attr_info
			  (thread_p, &obj->oid, &recdes,
			   &attr_info) == NO_ERROR)
			{
			  object_processed = process_object
			    (thread_p, &upd_scancache, &attr_info, &obj->oid);

			  if (object_processed != 1)
			    {
			      lock_unlock_object (thread_p, &obj->oid,
						  class_oid, oid_lock, true);

			      if (object_processed == -1)
				{
				  (*failed_objects)++;
				}
			    }
			  else
			    {
			      (*modified_objects)++;
			    }
			}
		      else
			{
			  (*failed_objects)++;
			}
		    }

		  COPY_OID (&prev_oid, &obj->oid);
		  obj = LC_NEXT_ONEOBJ_PTR_IN_COPYAREA (obj);
		}

	      if (fetch_area)
		{
		  locator_free_copy_area (fetch_area);
		}
	    }
	  else
	    {
	      /* No more objects */
	      break;
	    }
	}
      else
	{
	  ret = ER_FAILED;
	  break;
	}
    }

  COPY_OID (last_processed_oid, &last_oid);

end:

  heap_attrinfo_end (thread_p, &attr_info);
  heap_scancache_end_modify (thread_p, &upd_scancache);

  return ret;
}
Пример #11
0
static void process_workitems(MVMThreadContext *tc, MVMHeapSnapshotState *ss) {
    while (ss->num_workitems > 0) {
        MVMHeapSnapshotWorkItem item = pop_workitem(tc, ss);

        /* We take our own working copy of the collectable info, since the
         * collectables array can grow and be reallocated. */
        MVMHeapSnapshotCollectable col;
        set_ref_from(tc, ss, item.col_idx);
        col = ss->hs->collectables[item.col_idx];
        col.kind = item.kind;

        switch (item.kind) {
            case MVM_SNAPSHOT_COL_KIND_OBJECT:
            case MVM_SNAPSHOT_COL_KIND_TYPE_OBJECT:
                process_object(tc, ss, &col, (MVMObject *)item.target);
                break;
            case MVM_SNAPSHOT_COL_KIND_STABLE: {
                MVMuint16 i;
                MVMSTable *st = (MVMSTable *)item.target;
                process_collectable(tc, ss, &col, (MVMCollectable *)st);
                set_type_index(tc, ss, &col, st);

                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                    (MVMCollectable *)st->method_cache, "Method cache");

                for (i = 0; i < st->type_check_cache_length; i++)
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->type_check_cache[i], "Type cache entry");

                if (st->container_spec && st->container_spec->gc_mark_data) {
                    st->container_spec->gc_mark_data(tc, st, ss->gcwl);
                    process_gc_worklist(tc, ss, "Container spec data item");
                }

                if (st->boolification_spec)
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->boolification_spec->method,
                        "Boolification method");

                if (st->invocation_spec) {
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->invocation_spec->class_handle,
                        "Invocation spec class handle");
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->invocation_spec->attr_name,
                        "Invocation spec attribute name");
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->invocation_spec->invocation_handler,
                        "Invocation spec invocation handler");
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->invocation_spec->md_class_handle,
                        "Invocation spec class handle (multi)");
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->invocation_spec->md_cache_attr_name,
                        "Invocation spec cache attribute name (multi)");
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->invocation_spec->md_valid_attr_name,
                        "Invocation spec valid attribute name (multi)");
                }

                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                    (MVMCollectable *)st->WHO, "WHO");
                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                    (MVMCollectable *)st->WHAT, "WHAT");
                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                    (MVMCollectable *)st->HOW, "HOW");
                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                    (MVMCollectable *)st->HOW_sc, "HOW serialization context");
                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                    (MVMCollectable *)st->method_cache_sc,
                    "Method cache serialization context");

                if (st->mode_flags & MVM_PARAMETRIC_TYPE) {
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->paramet.ric.parameterizer,
                        "Parametric type parameterizer");
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->paramet.ric.lookup,
                        "Parametric type intern table");
                }
                else if (st->mode_flags & MVM_PARAMETERIZED_TYPE) {
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->paramet.erized.parametric_type,
                        "Parameterized type's parametric type");
                    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                        (MVMCollectable *)st->paramet.erized.parameters,
                        "Parameterized type's parameters");
                }

                if (st->REPR->gc_mark_repr_data) {
                    st->REPR->gc_mark_repr_data(tc, st, ss->gcwl);
                    process_gc_worklist(tc, ss, "REPR data item");
                }
                break;
            }
            case MVM_SNAPSHOT_COL_KIND_FRAME: {
                MVMFrame *frame = (MVMFrame *)item.target;
                col.collectable_size = sizeof(MVMFrame);
                set_static_frame_index(tc, ss, &col, frame->static_info);

                if (frame->caller && !MVM_FRAME_IS_ON_CALLSTACK(tc, frame))
                    add_reference_const_cstr(tc, ss, "Caller",
                        get_frame_idx(tc, ss, frame->caller));
                if (frame->outer)
                    add_reference_const_cstr(tc, ss, "Outer",
                        get_frame_idx(tc, ss, frame->outer));

                MVM_gc_root_add_frame_registers_to_worklist(tc, ss->gcwl, frame);
                process_gc_worklist(tc, ss, "Register");
                if (frame->work)
                    col.unmanaged_size += frame->allocd_work;

                if (frame->env) {
                    MVMuint16  i, count;
                    MVMuint16 *type_map;
                    MVMuint16  name_count = frame->static_info->body.num_lexicals;
                    MVMLexicalRegistry **names = frame->static_info->body.lexical_names_list;
                    if (frame->spesh_cand && frame->spesh_log_idx == -1 && frame->spesh_cand->lexical_types) {
                        type_map = frame->spesh_cand->lexical_types;
                        count    = frame->spesh_cand->num_lexicals;
                    }
                    else {
                        type_map = frame->static_info->body.lexical_types;
                        count    = frame->static_info->body.num_lexicals;
                    }
                    for (i = 0; i < count; i++) {
                        if (type_map[i] == MVM_reg_str || type_map[i] == MVM_reg_obj) {
                            if (i < name_count)
                                MVM_profile_heap_add_collectable_rel_vm_str(tc, ss,
                                    (MVMCollectable *)frame->env[i].o, names[i]->key);
                            else
                                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                                    (MVMCollectable *)frame->env[i].o, "Lexical (inlined)");
                        }
                    }
                    col.unmanaged_size += frame->allocd_env;
                }

                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                    (MVMCollectable *)frame->code_ref, "Code reference");
                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                    (MVMCollectable *)frame->static_info, "Static frame");
                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                    (MVMCollectable *)frame->dynlex_cache_name,
                    "Dynamic lexical cache name");

                if (frame->special_return_data && frame->mark_special_return_data) {
                    frame->mark_special_return_data(tc, frame, ss->gcwl);
                    process_gc_worklist(tc, ss, "Special return data");
                }

                if (frame->continuation_tags) {
                    MVMContinuationTag *tag = frame->continuation_tags;
                    while (tag) {
                        MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
                            (MVMCollectable *)tag->tag, "Continuation tag");
                        col.unmanaged_size += sizeof(MVMContinuationTag);
                        tag = tag->next;
                    }
                }

                break;
            }
            case MVM_SNAPSHOT_COL_KIND_PERM_ROOTS:
                MVM_gc_root_add_permanents_to_worklist(tc, NULL, ss);
                break;
            case MVM_SNAPSHOT_COL_KIND_INSTANCE_ROOTS:
                MVM_gc_root_add_instance_roots_to_worklist(tc, NULL, ss);
                break;
            case MVM_SNAPSHOT_COL_KIND_CSTACK_ROOTS:
                MVM_gc_root_add_temps_to_worklist((MVMThreadContext *)item.target, NULL, ss);
                break;
            case MVM_SNAPSHOT_COL_KIND_THREAD_ROOTS: {
                MVMThreadContext *thread_tc = (MVMThreadContext *)item.target;
                MVM_gc_root_add_tc_roots_to_worklist(thread_tc, NULL, ss);
                if (thread_tc->cur_frame && !MVM_FRAME_IS_ON_CALLSTACK(thread_tc, tc->cur_frame))
                    add_reference_const_cstr(tc, ss, "Current frame",
                        get_frame_idx(tc, ss, thread_tc->cur_frame));
                 break;
            }
            case MVM_SNAPSHOT_COL_KIND_ROOT: {
                MVMThread *cur_thread;

                add_reference_const_cstr(tc, ss, "Permanent Roots",
                    push_workitem(tc, ss, MVM_SNAPSHOT_COL_KIND_PERM_ROOTS, NULL));
                add_reference_const_cstr(tc, ss, "VM Instance Roots",
                    push_workitem(tc, ss, MVM_SNAPSHOT_COL_KIND_INSTANCE_ROOTS, NULL));

                cur_thread = tc->instance->threads;
                while (cur_thread) {
                    if (cur_thread->body.tc) {
                        add_reference_const_cstr(tc, ss, "C Stack Roots",
                            push_workitem(tc, ss,
                                MVM_SNAPSHOT_COL_KIND_CSTACK_ROOTS,
                                cur_thread->body.tc));
                        add_reference_const_cstr(tc, ss, "Thread Roots",
                            push_workitem(tc, ss,
                                MVM_SNAPSHOT_COL_KIND_THREAD_ROOTS,
                                cur_thread->body.tc));
                        add_reference_const_cstr(tc, ss, "Inter-generational Roots",
                            push_workitem(tc, ss,
                                MVM_SNAPSHOT_COL_KIND_INTERGEN_ROOTS,
                                cur_thread->body.tc));
                        add_reference_const_cstr(tc, ss, "Thread Call Stack Roots",
                            push_workitem(tc, ss,
                                MVM_SNAPSHOT_COL_KIND_CALLSTACK_ROOTS,
                                cur_thread->body.tc));
                    }
                    cur_thread = cur_thread->body.next;
                }

                break;
            }
            case MVM_SNAPSHOT_COL_KIND_INTERGEN_ROOTS: {
                MVMThreadContext *thread_tc = (MVMThreadContext *)item.target;
                MVM_gc_root_add_gen2s_to_snapshot(thread_tc, ss);
                break;
            }
            case MVM_SNAPSHOT_COL_KIND_CALLSTACK_ROOTS: {
                MVMThreadContext *thread_tc = (MVMThreadContext *)item.target;
                if (thread_tc->cur_frame && MVM_FRAME_IS_ON_CALLSTACK(tc, thread_tc->cur_frame)) {
                    MVMFrame *cur_frame = thread_tc->cur_frame;
                    MVMint32 idx = 0;
                    while (cur_frame && MVM_FRAME_IS_ON_CALLSTACK(tc, cur_frame)) {
                        add_reference_idx(tc, ss, idx,
                            push_workitem(tc, ss, MVM_SNAPSHOT_COL_KIND_FRAME,
                                (MVMCollectable *)cur_frame));
                        idx++;
                        cur_frame = cur_frame->caller;
                    }
                }
                break;
            }
            default:
                MVM_panic(1, "Unknown heap snapshot worklist item kind %d", item.kind);
        }

        /* Store updated collectable info into array. Note that num_refs was
         * updated "at a distance". */
        col.num_refs = ss->hs->collectables[item.col_idx].num_refs;
        ss->hs->collectables[item.col_idx] = col;
    }
}
Пример #12
0
/*
 * Get the linkmap from the dynlinker.  Try to load kernel modules
 * from all objects in the linkmap.
 */
void
rumpuser_dl_bootstrap(rump_modinit_fn domodinit,
	rump_symload_fn symload, rump_compload_fn compload)
{
	struct link_map *map, *origmap, *mainmap;
	void *mainhandle;
	int error;

	mainhandle = dlopen(NULL, RTLD_NOW);
	/* Will be null if statically linked so just return */
	if (mainhandle == NULL)
		return;
	if (dlinfo(mainhandle, RTLD_DI_LINKMAP, &mainmap) == -1) {
		fprintf(stderr, "warning: rumpuser module bootstrap "
		    "failed: %s\n", dlerror());
		return;
	}
	origmap = mainmap;

	/*
	 * Use a heuristic to determine if we are static linked.
	 * A dynamically linked binary should always have at least
	 * two objects: itself and ld.so.
	 *
	 * In a statically linked binary with glibc the linkmap
	 * contains some "info" that leads to a segfault.  Since we
	 * can't really do anything useful in here without ld.so, just
	 * simply bail and let the symbol references in librump do the
	 * right things.
	 */
	if (origmap->l_next == NULL && origmap->l_prev == NULL) {
		dlclose(mainhandle);
		return;
	}

	/*
	 * Process last->first because that's the most probable
	 * order for dependencies
	 */
	for (; origmap->l_next; origmap = origmap->l_next)
		continue;

	/*
	 * Build symbol table to hand to the rump kernel.  Do this by
	 * iterating over all rump libraries and collecting symbol
	 * addresses and relocation info.
	 */
	error = 0;
	for (map = origmap; map && !error; map = map->l_prev) {
		if (strstr(map->l_name, "librump") != NULL || map == mainmap)
			error = getsymbols(map, map == mainmap);
	}

	if (error == 0) {
		void *trimmedsym, *trimmedstr;

		/*
		 * Allocate optimum-sized memory for storing tables
		 * and feed to kernel.  If memory allocation fails,
		 * just give the ones with extra context (although
		 * I'm pretty sure we'll die moments later due to
		 * memory running out).
		 */
		if ((trimmedsym = malloc(symtaboff)) != NULL) {
			memcpy(trimmedsym, symtab, symtaboff);
		} else {
			trimmedsym = symtab;
			symtab = NULL;
		}
		if ((trimmedstr = malloc(strtaboff)) != NULL) {
			memcpy(trimmedstr, strtab, strtaboff);
		} else {
			trimmedstr = strtab;
			strtab = NULL;
		}
		symload(trimmedsym, symtaboff, trimmedstr, strtaboff);
	}
	free(symtab);
	free(strtab);

	/*
	 * Next, load modules and components.
	 *
	 * Simply loop through all objects, ones unrelated to rump kernels
	 * will not contain link_set_rump_components (well, not including
	 * "sabotage", but that needs to be solved at another level anyway).
	 */
	for (map = origmap; map; map = map->l_prev) {
		void *handle;

		if (map == mainmap) {
			handle = mainhandle;
		} else {
			handle = dlopen(map->l_name, RTLD_LAZY);
			if (handle == NULL)
				continue;
		}
		process_object(handle, domodinit, compload);
		if (map != mainmap)
			dlclose(handle);
	}
}