Beispiel #1
0
void Write_UserDefined_Labels(FILE * pcf_fd)
{
    unsigned i, j, max_types = Extrae_Vector_Count (&defined_user_event_types);
    for (i = 0; i < max_types; i++)
    {
        event_type_t * evt = Extrae_Vector_Get (&defined_user_event_types, i);
        unsigned max_values = Extrae_Vector_Count (&evt->event_values);
        fprintf (pcf_fd, "%s\n", TYPE_LABEL);
        fprintf (pcf_fd, "0    %d    %s\n", evt->event_type.type, evt->event_type.label);
        if (max_values>0)
        {
            fprintf (pcf_fd, "%s\n", VALUES_LABEL);
            for (j = 0; j < max_values; j++)
            {
                value_t * values = Extrae_Vector_Get (&evt->event_values, j);
                fprintf (pcf_fd, "%d      %s\n", values->value, values->label);
            }
        }
        LET_SPACES (pcf_fd);
    }
}
static int paraver_build_multi_event (struct fdz_fitxer fdz, paraver_rec_t ** current,
	PRVFileSet_t * fset, unsigned long long *num_events)
{
#define MAX_EVENT_COUNT_IN_MULTI_EVENT	1024
	unsigned int events[MAX_EVENT_COUNT_IN_MULTI_EVENT];
	UINT64 values[MAX_EVENT_COUNT_IN_MULTI_EVENT];
	int prev_cpu, prev_ptask, prev_task, prev_thread;
	unsigned long long prev_time;
	paraver_rec_t *cur;
	UINT64 CallerAddresses[MAX_CALLERS];
	unsigned nevents = 0;

	// Here we store the caller addresses for a reference to a dynamic mem object
	// Set to 0 initially
	memset (CallerAddresses, 0, sizeof(CallerAddresses));

	cur = *current;

	prev_cpu = cur->cpu;
	prev_ptask = cur->ptask;
	prev_task = cur->task;
	prev_thread = cur->thread;
	prev_time = cur->time;

	while (cur != NULL)
	{
	/* Merge multiple events if they are in the same cpu, task, thread and time */
		if (prev_cpu == cur->cpu && prev_ptask == cur->ptask &&
		prev_task == cur->task && prev_thread == cur->thread &&
		prev_time == cur->time && cur->type == 2 &&
		nevents < MAX_EVENT_COUNT_IN_MULTI_EVENT)
		{
			/* Copy the value by default... we'll change it if needed */
			values[nevents] = cur->value;
			events[nevents] = cur->event;

#if defined(DEBUG)
			fprintf (stderr, "mpi2prv: paraver_build_multi_event %d:%d:%d <%d,%llu> @ %llu\n",
			  prev_ptask, prev_task, prev_thread, events[nevents], values[nevents], prev_time);
#endif

			if (cur->event == MPI_GLOBAL_OP_COMM)
				values[nevents] = (UINT64)alies_comunicador ((int) cur->value, cur->ptask, cur->task);
#if defined(HAVE_BFD)
			else
			{
				if (cur->event == USRFUNC_EV || cur->event == USRFUNC_LINE_EV ||
				  (cur->event >= CALLER_EV && cur->event < CALLER_EV + MAX_CALLERS) || 
				  (cur->event >= CALLER_LINE_EV && cur->event < CALLER_LINE_EV + MAX_CALLERS) ||
				  (cur->event >= SAMPLING_EV && cur->event < SAMPLING_EV + MAX_CALLERS) ||
				  (cur->event >= SAMPLING_LINE_EV && cur->event < SAMPLING_LINE_EV + MAX_CALLERS) ||
				  cur->event == OMPFUNC_EV || cur->event == OMPFUNC_LINE_EV ||
				  cur->event == TASKFUNC_EV || cur->event == TASKFUNC_LINE_EV ||
				  cur->event == TASKFUNC_INST_EV || cur->event == TASKFUNC_INST_LINE_EV ||
				  cur->event == PTHREAD_FUNC_EV || cur->event == PTHREAD_FUNC_LINE_EV ||
				  cur->event == CUDAFUNC_EV || cur->event == CUDAFUNC_LINE_EV)
				{
					values[nevents] = paraver_translate_bfd_event (cur->ptask,
					  cur->task, cur->event, cur->value);
				}

				if (cur->event == FILE_NAME_EV)
				{
					/* Unify the file identifiers. Each task stored local identifiers for the open files,
                                         * and after the first merge phase, we shared all the ids and we change them now 
                                         * for a global id, so that each file pathname has an unique id */
					values[nevents] = Unify_File_Id(cur->ptask, cur->task, cur->value);
				}

				if (cur->event >= SAMPLING_ADDRESS_ALLOCATED_OBJECT_CALLER_EV &&
				    cur->event < SAMPLING_ADDRESS_ALLOCATED_OBJECT_CALLER_EV+MAX_CALLERS)
				{
					CallerAddresses[cur->event-SAMPLING_ADDRESS_ALLOCATED_OBJECT_CALLER_EV] =
					  cur->value;
				}

				if (cur->event == SAMPLING_ADDRESS_ALLOCATED_OBJECT_EV)
				{
					values[nevents] = Address2Info_Translate_MemReference (cur->ptask,
					  cur->task, cur->value, MEM_REFERENCE_DYNAMIC,
					  CallerAddresses);

					// Set to 0 again after emitting the information
					memset (CallerAddresses, 0, sizeof(CallerAddresses));
				}
				else if (cur->event == SAMPLING_ADDRESS_STATIC_OBJECT_EV)
				{
					values[nevents] = Address2Info_Translate_MemReference (cur->ptask,
					  cur->task, cur->value, MEM_REFERENCE_STATIC, NULL);
					events[nevents]  = SAMPLING_ADDRESS_ALLOCATED_OBJECT_EV;

					// Set to 0 again after emitting the information
					memset (CallerAddresses, 0, sizeof(CallerAddresses));
				}

				if (Extrae_Vector_Count (&RegisteredCodeLocationTypes) > 0)
				{
					unsigned u;
					unsigned umax = Extrae_Vector_Count (&RegisteredCodeLocationTypes);
					for (u = 0; u < umax; u++)
					{
						Extrae_Addr2Type_t *element = 
							Extrae_Vector_Get (&RegisteredCodeLocationTypes, u);

						if (element->FunctionType == cur->event ||
						    element->LineType == cur->event)
							values[nevents] = paraver_translate_bfd_event (cur->ptask,
							  cur->task, cur->event, cur->value);
					}
				}

				if (get_option_merge_EmitLibraryEvents())
				{
					if (cur->event == USRFUNC_EV ||
					  (cur->event >= CALLER_EV && cur->event < CALLER_EV + MAX_CALLERS) || 
					  (cur->event >= SAMPLING_EV && cur->event < SAMPLING_EV + MAX_CALLERS) ||
					  cur->event == OMPFUNC_EV || cur->event == TASKFUNC_INST_EV ||
					  cur->event == PTHREAD_FUNC_EV || cur->event == CUDAFUNC_EV)
					{
						if (cur->value == UNRESOLVED_ID+1 || cur->value == NOT_FOUND_ID+1)
						{
							nevents++;
							events[nevents] = LIBRARY_EV;
							values[nevents] = Address2Info_GetLibraryID (cur->ptask, cur->task, cur->value);
						}
					}
					else
					{
						if (Extrae_Vector_Count (&RegisteredCodeLocationTypes) > 0)
						{
							unsigned u;
							unsigned umax = Extrae_Vector_Count (&RegisteredCodeLocationTypes);
							for (u = 0; u < umax; u++)
							{
								Extrae_Addr2Type_t *element = 
									Extrae_Vector_Get (&RegisteredCodeLocationTypes, u);
	
								if (element->FunctionType == cur->event || element->LineType == cur->event)
									if (cur->value == UNRESOLVED_ID+1 || cur->value == NOT_FOUND_ID+1)
									{
										nevents++;
										events[nevents] = LIBRARY_EV;
										values[nevents] = Address2Info_GetLibraryID (cur->ptask, cur->task, cur->value);
									}
							}
						}
					}
				}
			}
#endif

			/* These events don't go into final tracefile */
			if (!(cur->event >= SAMPLING_ADDRESS_ALLOCATED_OBJECT_CALLER_EV &&
			    cur->event < SAMPLING_ADDRESS_ALLOCATED_OBJECT_CALLER_EV+MAX_CALLERS))
				nevents++;
		}
		else
			break;

		/* Keep searching ... */
		cur = GetNextParaver_Rec (fset);
	}

	paraver_multi_event (fdz, prev_cpu, prev_ptask, prev_task, prev_thread,
	  prev_time, nevents, events, values);

	*current = cur;
	if (num_events != NULL)
		*num_events = nevents;
	return 0;
#undef MAX_EVENT_COUNT_IN_MULTI_EVENT
}
static UINT64 paraver_translate_bfd_event (unsigned ptask, unsigned task,
	unsigned eventtype, UINT64 eventvalue)
{
	if (eventtype == USRFUNC_EV)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2UF_FUNCTION, get_option_merge_UniqueCallerID());
	else if (eventtype == USRFUNC_LINE_EV)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2UF_LINE, get_option_merge_UniqueCallerID());
	else if (eventtype >= CALLER_EV && eventtype < CALLER_EV + MAX_CALLERS)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2MPI_FUNCTION, get_option_merge_UniqueCallerID());
	else if (eventtype >= CALLER_LINE_EV && eventtype < CALLER_LINE_EV + MAX_CALLERS)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2MPI_LINE, get_option_merge_UniqueCallerID());
	else if (eventtype >= SAMPLING_EV && eventtype < SAMPLING_EV + MAX_CALLERS)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2SAMPLE_FUNCTION, get_option_merge_UniqueCallerID());
	else if (eventtype >= SAMPLING_LINE_EV && eventtype < SAMPLING_LINE_EV + MAX_CALLERS)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2SAMPLE_LINE, get_option_merge_UniqueCallerID());
	else if (eventtype == OMPFUNC_EV || eventtype == TASKFUNC_INST_EV || eventtype == TASKFUNC_EV)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2OMP_FUNCTION, get_option_merge_UniqueCallerID());
	else if (eventtype == OMPFUNC_LINE_EV || eventtype == TASKFUNC_INST_LINE_EV || eventtype == TASKFUNC_LINE_EV)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2OMP_LINE, get_option_merge_UniqueCallerID());
	else if (eventtype == PTHREAD_FUNC_EV)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2OMP_FUNCTION, get_option_merge_UniqueCallerID());
	else if (eventtype == PTHREAD_FUNC_LINE_EV)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2OMP_LINE, get_option_merge_UniqueCallerID());
	else if (eventtype == CUDAFUNC_EV)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2CUDA_FUNCTION, get_option_merge_UniqueCallerID());
	else if (eventtype == CUDAFUNC_LINE_EV)
		return Address2Info_Translate (ptask, task, 
		  eventvalue, ADDR2CUDA_LINE, get_option_merge_UniqueCallerID());
	else
	{
		if (Extrae_Vector_Count (&RegisteredCodeLocationTypes) > 0)
		{
			unsigned u;
			unsigned umax = Extrae_Vector_Count (&RegisteredCodeLocationTypes);
			for (u = 0; u < umax; u++)
			{
				Extrae_Addr2Type_t *element = 
					Extrae_Vector_Get (&RegisteredCodeLocationTypes, u);

				if (element->FunctionType == eventtype)
					return Address2Info_Translate (ptask, task, 
					  eventvalue, element->FunctionType_lbl, get_option_merge_UniqueCallerID());
				else if (element->LineType == eventtype)
					return Address2Info_Translate (ptask, task, 
					  eventvalue, element->LineType_lbl, get_option_merge_UniqueCallerID());
			}
		}
	}

	return eventvalue;
}
Beispiel #4
0
/******************************************************************************
 *** Labels_loadSYMfile
 ******************************************************************************/
void Labels_loadSYMfile (int taskid, int allobjects, unsigned ptask,
	unsigned task, char *name, int report)
{
#ifndef HAVE_BFD
	static int shown_BFD_missing = FALSE;
#endif
	static int Labels_loadSYMfile_init = FALSE;
	FILE *FD;
	char LINE[1024], Type;
	unsigned function_count = 0, hwc_count = 0, other_count = 0;

	if (!Labels_loadSYMfile_init)
	{
		Extrae_Vector_Init (&defined_user_event_types);
        Extrae_Vector_Init (&defined_basic_block_labels);
		Labels_loadSYMfile_init = TRUE;
	}
	event_type_t * last_event_type_used = NULL;

	if (!name)
		return;

	if (strlen(name) == 0)
		return;

	if (!file_exists(name))
		return;

	FD = (FILE *) fopen (name, "r");
	if (FD == NULL)
	{
		fprintf (stderr, "mpi2prv: WARNING: Task %d Can\'t open symbols file %s\n", taskid, name);
		return;
	}

	while (!feof (FD))
	{
		int args_assigned;

		if (fgets (LINE, 1024, FD) == NULL)
			break;

		args_assigned = sscanf (LINE, "%c %[^\n]", &Type, LINE);

		if (args_assigned == 2)
		{
			switch (Type)
			{
				case 'B':
					{
						unsigned long start, end, offset;
						char module[1024];
						int res = sscanf (LINE, "0 \"%lx-%lx %lx %[^\n\"]\"", &start, &end, &offset, module);
						if (res == 4)
						{
#ifdef HAVE_BFD
							ObjectTable_AddBinaryObject (allobjects, ptask, task, start, end, offset, module);
#else
							if (!shown_BFD_missing)
								fprintf (stdout, "mpi2prv: Ignoring symbols from the application execution because mpi2prv does not support BFD\n");
							shown_BFD_missing = TRUE;
							UNREFERENCED_PARAMETER(allobjects);
							UNREFERENCED_PARAMETER(ptask);
							UNREFERENCED_PARAMETER(task);
#endif
						}
						else
							fprintf (stderr, PACKAGE_NAME": Error! Invalid line ('%s') in %s\n", LINE, name);
					}
					break;

				case 'O':
				case 'U':
				case 'P':
					{
#ifdef HAVE_BFD
						/* Example of line: U 0x100016d4 fA mpi_test.c 0 */
						char fname[1024], modname[1024];
						int line;
						int type;
						int res;
						UINT64 address;

						res = sscanf (LINE, "%lx \"%[^\"]\" \"%[^\"]\" %d", &address, fname, modname, &line);
						if (res != 4)
							fprintf (stderr, PACKAGE_NAME": Error! Invalid line ('%s') in %s\n", LINE, name);

						if (!get_option_merge_UniqueCallerID())
						{
							if (Type == 'O')
								type = OTHER_FUNCTION_TYPE;
							else if (Type == 'U')
								type = USER_FUNCTION_TYPE;
							else /* if (Type == 'P') */
								type = OUTLINED_OPENMP_TYPE;
						}
						else
							type = UNIQUE_TYPE;

						Address2Info_AddSymbol (address, type, fname, modname, line);
						function_count++;
#endif /* HAVE_BFD */
					}
					break;

				case 'H':
					{
						int res, eventcode;
						char hwc_description[1024];

						res = sscanf (LINE, "%d \"%[^\"]\"", &eventcode, hwc_description);
						if (res != 2)
							fprintf (stderr, PACKAGE_NAME": Error! Invalid line ('%s') in %s\n", LINE, name);

						Labels_AddHWCounter_Code_Description (eventcode, hwc_description);
						hwc_count++;
					}
					break;

				case 'c':
				case 'C':
					{
						int res, eventcode;
						char code_description[1024];

						res = sscanf (LINE, "%d \"%[^\"]\"", &eventcode, code_description);
						if (res != 2)
							fprintf (stderr, PACKAGE_NAME": Error! Invalid line ('%s') in %s\n", LINE, name);

						Labels_Add_CodeLocation_Label (eventcode,
							Type=='C'?CODELOCATION_FUNCTION:CODELOCATION_FILELINE,
							code_description);
						other_count++;
					}
					break;

                case 'd':
                    {
                        int res, eventvalue;
                        char value_description[1024];
                        value_t * evt_value = NULL;
                        unsigned i, max = Extrae_Vector_Count (&last_event_type_used->event_values);

                        res = sscanf (LINE, "%d \"%[^\"]\"", &eventvalue, value_description);
                        if (res != 2)
                            fprintf (stderr, PACKAGE_NAME": Error! Invalid line ('%s') in %s\n", LINE, name);
                        
                        for (i = 0; i < max; i++)
                        {
                            value_t * evt = Extrae_Vector_Get (&last_event_type_used->event_values, i);
                            if(evt->value == eventvalue)
                            {
                                if(strcmp(evt->label, value_description))
                                {
                                    fprintf(stderr, PACKAGE_NAME"(%s,%d): Warning! Ignoring duplicate definition \"%s\" for value type %d,%d!\n",__FILE__, __LINE__, value_description,last_event_type_used->event_type.type, eventvalue);
                                }
                                evt_value = evt;
                                break;
                            }
                        }
                        if (!evt_value)
                        {
                            evt_value = (value_t*) malloc (sizeof (value_t));
                            if (evt_value == NULL)
                            {
                                fprintf (stderr, PACKAGE_NAME"(%s,%d): Fatal error! Cannot allocate memory to store the 'd' symbol in TRACE.sym file\n", __FILE__, __LINE__);
                                exit(-1);
                            }
                            evt_value->value = eventvalue;
                            strcpy(evt_value->label, value_description);
                            Extrae_Vector_Append (&last_event_type_used->event_values, evt_value);
                            other_count++;
                        }
                    }
                    break;
                case 'D':
                    {
                        int res, eventcode;
                        char code_description[1024];
                        unsigned i, max = Extrae_Vector_Count (&defined_user_event_types);
                        event_type_t * evt_type = NULL;

                        res = sscanf (LINE, "%d \"%[^\"]\"", &eventcode, code_description);
                        if (res != 2)
                            fprintf (stderr, PACKAGE_NAME": Error! Invalid line ('%s') in %s\n", LINE, name);

                        for (i = 0; i < max; i++)
                        {
                            event_type_t * evt = Extrae_Vector_Get (&defined_user_event_types, i);
                            if (evt->event_type.type == eventcode)
                            {
                                if(strcmp(evt->event_type.label, code_description))
                                {
                                    fprintf(stderr, PACKAGE_NAME"(%s,%d): Warning! Ignoring duplicate definition \"%s\" for type %d!\n", __FILE__, __LINE__, code_description, eventcode);
                                }
                                evt_type = evt;
                                break;
                            }
                        }

                        if (!evt_type)
                        {
                            evt_type = (event_type_t*)  malloc (sizeof (event_type_t));
                            if (evt_type == NULL)
                            {
                                fprintf (stderr, "Extrae (%s,%d): Fatal error! Cannot allocate memory to store the 'D' symbol in TRACE.sym file\n", __FILE__, __LINE__);
                                exit(-1);
                            }
                            evt_type->event_type.type = eventcode;
                            strcpy(evt_type->event_type.label, code_description);
                            Extrae_Vector_Init(&evt_type->event_values);
    
                            Extrae_Vector_Append(&defined_user_event_types, evt_type);
                            other_count++;
                        }
                        last_event_type_used = evt_type;
                    }
                    break;

                case 'b': // BasicBlocks symbol
                    {
                        int res, eventvalue;
                        char bb_description[1024];
                        unsigned i, max = Extrae_Vector_Count (&defined_basic_block_labels);
                        event_type_t * evt_type = NULL;
                        value_t * evt_value = NULL;

                        res = sscanf (LINE, "%d \"%[^\"]\"", &eventvalue, bb_description);
                        if (res != 2)
                            fprintf (stderr, PACKAGE_NAME": Error! Invalid line ('%s') in %s\n", LINE, name);
                        if (max==0){
                            evt_type = (event_type_t*)  malloc (sizeof (event_type_t));
                            if (evt_type == NULL)
                            {
                                fprintf (stderr, "Extrae (%s,%d): Fatal error! Cannot allocate memory to store the 'B' symbol in TRACE.sym file\n", __FILE__, __LINE__);
                                exit(-1);
                            }
                            evt_type->event_type.type = USRFUNC_EV_BB;
                            strcpy(evt_type->event_type.label, "BASIC_BLOCKS");
                            Extrae_Vector_Init(&evt_type->event_values);
                            Extrae_Vector_Append(&defined_basic_block_labels, evt_type);
                        } else 
                        {
                            evt_type = Extrae_Vector_Get (&defined_basic_block_labels, 0); // There is only one event type in the vector
                        }

                        max = Extrae_Vector_Count (&evt_type->event_values);

                        for(i = 0; i < max; i++)
                        {
                            value_t * evt = Extrae_Vector_Get (&evt_type->event_values, i);
                            if(evt->value == eventvalue)
                            {
                                if(strcmp(evt->label, bb_description))
                                {
                                    fprintf(stderr, "Extrae (%s,%d): Warning! Ignoring duplicate definition \"%s\" for value type %d,%d!\n",__FILE__, __LINE__, bb_description,evt_type->event_type.type, eventvalue);
                                }
                                evt_value = evt;
                                break;
                            }
                        }

                        if (!evt_value)
                        {
                            evt_value = (value_t*) malloc (sizeof (value_t));
                            if (evt_value == NULL)
                            {
                                fprintf (stderr, "Extrae (%s,%d): Fatal error! Cannot allocate memory to store the 'B' symbol in TRACE.sym file\n", __FILE__, __LINE__);
                                exit(-1);
                            }
                            evt_value->value = eventvalue;
                            strcpy(evt_value->label, bb_description);
                            Extrae_Vector_Append (&evt_type->event_values, evt_value);
                            other_count++;
                        }
                    }
                    break;
				default:
					fprintf (stderr, PACKAGE_NAME" mpi2prv: Error! Task %d found unexpected line in symbol file '%s'\n", taskid, LINE);
					break;
			}
		}
	}

	if (taskid == 0 && report)
	{
		fprintf (stdout, "mpi2prv: A total of %u symbols were imported from %s file\n", function_count+hwc_count+other_count, name);
		fprintf (stdout, "mpi2prv: %u function symbols imported\n", function_count);
		fprintf (stdout, "mpi2prv: %u HWC counter descriptions imported\n", hwc_count);
	}

	fclose (FD);
}
int main (int argc, char *argv[])
{
	int i;
	int a = 1;
	int b = 2;
	int c = 3;

	for (i = 0; i < N; i++)
		vec[i] = i;

	UNREFERENCED_PARAMETER(argc);
	UNREFERENCED_PARAMETER(argv);
	
	Extrae_Vector_Init (&v);
	Extrae_Vector_Init (&v2);

	Extrae_Vector_Append (&v, &a);
	Extrae_Vector_Append (&v, &b);
	Extrae_Vector_Append (&v, &c);
	Extrae_Vector_Append (&v, &d);
	Extrae_Vector_Append (&v, &e);

	assert (Extrae_Vector_Count(&v) == 5);
	assert (Extrae_Vector_Count(&v2) == 0);

	assert (Extrae_Vector_Get(&v,0) == &a);
	assert ((*(int*) Extrae_Vector_Get(&v,0)) == a);

	assert (Extrae_Vector_Get(&v,1) == &b);
	assert ((*(int*) Extrae_Vector_Get(&v,1)) == b);

	assert (Extrae_Vector_Get(&v,2) == &c);
	assert ((*(int*) Extrae_Vector_Get(&v,2)) == c);

	assert (Extrae_Vector_Get(&v,3) == &d);
	assert ((*(int*) Extrae_Vector_Get(&v,3)) == d);

	assert (Extrae_Vector_Get(&v,4) == &e);
	assert ((*(int*) Extrae_Vector_Get(&v,4)) == e);

	Extrae_Vector_Destroy (&v);
	assert (Extrae_Vector_Count(&v) == 0);

	for (i = 0; i < N; i++)
		Extrae_Vector_Append (&v2, &vec[i]);

	assert (Extrae_Vector_Count(&v2) == N);

	for (i = 0; i < N; i++)
	{
		assert (Extrae_Vector_Get(&v2,i) == &vec[i]);
		assert ((*(int*) Extrae_Vector_Get(&v2,i)) == vec[i]);
	}

	Extrae_Vector_Destroy (&v2);
	assert (Extrae_Vector_Count(&v2) == 0);

	return 0;
}