Beispiel #1
0
void HeapScan()
{
	ListElement* current = NULL;
	Log(LOG_INFO, Messages_get(101), state.current_size);
	while (ListNextElement(&heap, &current))
	{
		storageElement* s = (storageElement*)(current->content);
		Log(LOG_INFO, Messages_get(102), s->size, s->line, s->file, s->ptr);
		Log(LOG_INFO, Messages_get(103), (10 > s->size) ? s->size : 10, s->ptr);
	}
	Log(LOG_INFO, Messages_get(104));
}
Beispiel #2
0
/**
 * Log a message.  If possible, all messages should be indexed by message number, and
 * the use of the format string should be minimized or negated altogether.  If format is
 * provided, the message number is only used as a message label.
 * @param log_level the log level of the message
 * @param msgno the id of the message to use if the format string is NULL
 * @param aFormat the printf format string to be used if the message id does not exist
 * @param ... the printf inserts
 */
void Log(int log_level, int msgno, char* format, ...)
{
	char* temp = NULL;
	static char msg_buf[512];

	if (log_level >= trace_settings.trace_level)
	{
		va_list args;

		if (format == NULL && (temp = Messages_get(msgno, log_level)) != NULL)
			format = temp;

		va_start(args, format);
		vsnprintf(msg_buf, sizeof(msg_buf), format, args);

		Log_trace(log_level, msg_buf);
		va_end(args);
	}

	/*if (log_level >= LOG_ERROR)
	{
		char* filename = NULL;
		Log_recordFFDC(&msg_buf[7]);
	}

	if (log_level == LOG_FATAL)
		exit(-1);*/
}
Beispiel #3
0
static char* Log_formatTraceEntry(traceEntry* cur_entry)
{
	struct tm *timeinfo;
	int buf_pos = 31;

#if defined(GETTIMEOFDAY)
	timeinfo = localtime(&cur_entry->ts.tv_sec);
#else
	timeinfo = localtime(&cur_entry->ts.time);
#endif
	strftime(&msg_buf[7], 80, "%Y%m%d %H%M%S ", timeinfo);
#if defined(GETTIMEOFDAY)
	sprintf(&msg_buf[22], ".%.3lu ", cur_entry->ts.tv_usec / 1000L);
#else
	sprintf(&msg_buf[22], ".%.3hu ", cur_entry->ts.millitm);
#endif
	buf_pos = 27;

	sprintf(msg_buf, "(%.4d)", cur_entry->sametime_count);
	msg_buf[6] = ' ';

	if (cur_entry->has_rc == 2)
		strncpy(&msg_buf[buf_pos], cur_entry->name, sizeof(msg_buf)-buf_pos);
	else
	{
		char* format = Messages_get(cur_entry->number, cur_entry->level);
		if (cur_entry->has_rc == 1)
			snprintf(&msg_buf[buf_pos], sizeof(msg_buf)-buf_pos, format, cur_entry->thread_id,
					cur_entry->depth, "", cur_entry->depth, cur_entry->name, cur_entry->line, cur_entry->rc);
		else
			snprintf(&msg_buf[buf_pos], sizeof(msg_buf)-buf_pos, format, cur_entry->thread_id,
					cur_entry->depth, "", cur_entry->depth, cur_entry->name, cur_entry->line);
	}
	return msg_buf;
}
Beispiel #4
0
/**
 * Log a message.  If possible, all messages should be indexed by message number, and
 * the use of the format string should be minimized or negated altogether.  If format is
 * provided, the message number is only used as a message label.
 * @param log_level the log level of the message
 * @param msgno the id of the message to use if the format string is NULL
 * @param aFormat the printf format string to be used if the message id does not exist
 * @param ... the printf inserts
 */
void Log(int log_level, int msgno, char* format, ...)
{
	if (log_level >= trace_settings.trace_level)
	{
		char* temp = NULL;
		static char msg_buf[512];
		va_list args;

		/* we're using a static character buffer, so we need to make sure only one thread uses it at a time */
		Thread_lock_mutex(log_mutex); 
		if (format == NULL && (temp = Messages_get(msgno, log_level)) != NULL)
			format = temp;

		va_start(args, format);
		vsnprintf(msg_buf, sizeof(msg_buf), format, args);

		Log_trace(log_level, msg_buf);
		va_end(args);
		Thread_unlock_mutex(log_mutex); 
	}

	/*if (log_level >= LOG_ERROR)
	{
		char* filename = NULL;
		Log_recordFFDC(&msg_buf[7]);
	}
	*/
}
Beispiel #5
0
void Heap_terminate()
{
	Log(LOG_INFO, "Maximum heap use was %d bytes\n", state.max_size);
	if (state.current_size > 0)
	{
		Log(LOG_ERROR, Messages_get(106));
		HeapScan();
	}
}
Beispiel #6
0
void myfree(char* file, int line, void* p)
{
	ListElement* e = ListFindItem(&heap, p, ptrCompare);
	if (e == NULL)
		Log(LOG_ERROR, Messages_get(99), file, line);
	else
	{
		storageElement* s = (storageElement*)(heap.current->content);
		//Log(LOG_DEBUG, "Freeing %d bytes in heap at file %s line %d, heap use now %d bytes\n", s->size, file, line, state.current_size);
		free(s->file);
		state.current_size -= s->size;
		ListRemoveCurrentItem(&heap);
	}
	free(p);
}
Beispiel #7
0
void *myrealloc(char* file, int line, void* p, size_t size)
{
	void* rc = NULL;
	ListElement* e = ListFindItem(&heap, p, ptrCompare);
	if (e == NULL)
		Log(LOG_ERROR, Messages_get(100), file, line);
	else
	{
		storageElement* s = (storageElement*)(heap.current->content);
		state.current_size += size - s->size;
		if (state.current_size > state.max_size)
			state.max_size = state.current_size;
		rc = s->ptr = realloc(s->ptr, size);
		s->size = size;
		s->file = realloc(s->file, strlen(file)+1);
		strcpy(s->file, file);
		s->line = line;
	}
	return rc;
}
Beispiel #8
0
/**
 * Record First Failure Data Capture information for problem determination.
 * @param symptoms - a symptom string to write along with the rest of the info
 * @return FFDC filename
 */
char* Broker_recordFFDC(char* symptoms)
{
	static char filename[160];
	struct tm *timeinfo;
#if defined(GETTIMEOFDAY)
	struct timeval ts;
#else
	struct timeb ts;
#endif
	FILE* file = NULL;
	char* ptr = filename;
	int mem_leak = 0;

	filename[0] = '\0';
	if (BrokerState.ffdc_location && strcmp(BrokerState.ffdc_location, "off") == 0)
	{
		if (segv_flag)
			printf("%s\n", Messages_get(48, LOG_WARNING));
		else
			Log(LOG_WARNING, 48, NULL);
		goto exit;
	}

	if (BrokerState.ffdc_location)
		strcpy(filename, BrokerState.ffdc_location);
	else if (BrokerState.persistence_location)
		strcpy(filename, BrokerState.persistence_location);
    ptr += strlen(filename);

#if defined(GETTIMEOFDAY)
	gettimeofday(&ts, NULL);
	timeinfo = localtime(&ts.tv_sec);
#else
	ftime(&ts);
	timeinfo = localtime(&ts.time);
#endif

	strftime(ptr, 80, "FFDC.CWNAN.%Y%m%d.%H%M%S.", timeinfo);
#if defined(GETTIMEOFDAY)
	sprintf(&ptr[26], ".%.3ld.dmp", ts.tv_usec / 1000L);
#else
	sprintf(&ptr[26], ".%.3u.dmp", ts.millitm);
#endif

	if ((file = fopen(filename, "wb")) != NULL)
	{
		fprintf(file, "========== Start FFDC ==========\n");
		fprintf(file, "Filename  :- %s\n", filename);
		fprintf(file, "Product   :- %s\n", PRODUCT_NAME);
		fprintf(file, "Version   :- %s\n", 	BrokerState.version);
		fprintf(file, "Build     :- %s\n", 	BrokerState.timestamp);	
		fprintf(file, "Date/Time :- %s", asctime(timeinfo));
		fprintf(file, "Reason    :- %s\n\n", symptoms);
		/* potential additions:
		 * os info (uname, getWindowsVersion)
		 * environment variables
		 */
		fclose(file);
	}

	StackTrace_dumpStack(filename);
	if (strstr(symptoms, "memory leak"))
	{
		if ((file = fopen(filename, "ab")) != NULL)
		{
			Heap_scan(file);
			fclose(file);
		}
		mem_leak = 1;
	}
	else
	{
		Log_dumpTrace(filename);
		Broker_dumpHeap(filename);
	}
	if ((file = fopen(filename, "ab")) != NULL)
	{
		fprintf(file, "========== End FFDC ==========\n");
		fclose(file);
	}
	if (segv_flag || mem_leak)
		printf("First Failure Data Capture (FFDC) information written to file %s\n", filename);

exit:
	return filename;
}
Beispiel #9
0
/**
 * Main broker startup function
 * @param argc number of elements of argv
 * @param argv command line strings
 * @return system return code
 */
int main(int argc, char* argv[])
{
	int rc = 0;
#define BUILD_TIMESTAMP __DATE__ " " __TIME__ /* __TIMESTAMP__ */
#define BROKER_VERSION "1.2.0.12" /* __VERSION__ */
#define PRODUCT_NAME "MQTT Daemon for Devices"

	static char* broker_version_eye = NULL;
	static char* broker_timestamp_eye = NULL;

	FUNC_ENTRY_NOLOG;
	broker_timestamp_eye = "AMQTDD_Timestamp " BUILD_TIMESTAMP;
	broker_version_eye = "AMQTDD_Version " BROKER_VERSION;
	BrokerState.version = BROKER_VERSION;
	BrokerState.timestamp = BUILD_TIMESTAMP;
	
	srand(time(NULL));

	Heap_initialize();
	Log_initialize();

	Log(LOG_INFO, 9999, PRODUCT_NAME);
	Log(LOG_INFO, 9998, "Part of Project Mosquitto in Eclipse\n("
                      "http://projects.eclipse.org/projects/technology.mosquitto)");
	getopts(argc, argv);

	if (Messages_initialize(&BrokerState) != 0)
		goto no_messages;

	Log(LOG_INFO, 53, NULL, BrokerState.version, BrokerState.timestamp);
	Log(LOG_INFO, 54, "%s %s", Messages_get(54, LOG_INFO), "" 
#if !defined(NO_BRIDGE)
	" bridge"
#endif
#if defined(MQTTMP)
	" MQTTMP"
#endif
#if defined(MQTTS)
	" MQTTS"
#endif
	);

	if ((rc = Broker_startup()) == 0)
	{
		SubscriptionEngines_setRetained(BrokerState.se, "$SYS/broker/version", 0,
			BrokerState.version, strlen(BrokerState.version));
		SubscriptionEngines_setRetained(BrokerState.se, "$SYS/broker/timestamp", 0,
					BrokerState.timestamp, strlen(BrokerState.timestamp));
		while (BrokerState.state == BROKER_RUNNING)
		{
			Protocol_timeslice();
			#if !defined(NO_BRIDGE)
				Bridge_timeslice(&BrokerState.bridge);
			#endif
		}
		Log(LOG_INFO, 46, NULL);
		#if !defined(NO_BRIDGE)
			Bridge_stop(&BrokerState.bridge);
		#endif
		while (BrokerState.state == BROKER_STOPPING)
		{
			Protocol_timeslice();
			#if !defined(NO_BRIDGE)
				Bridge_timeslice(&BrokerState.bridge);
			#endif
		}
	}
	Broker_shutdown(rc);

	Log(LOG_INFO, 47, NULL);

no_messages:
	Messages_terminate();
	Log_terminate();
	Heap_terminate();

	/*FUNC_EXIT_NOLOG(rc); would anyone ever see this? */
	return rc;
}
Beispiel #10
0
/**
 * Log a message.  If possible, all messages should be indexed by message number, and
 * the use of the format string should be minimized or negated altogether.  If format is
 * provided, the message number is only used as a message label.
 * @param log_level the log level of the message
 * @param msgno the id of the message to use if the format string is NULL
 * @param aFormat the printf format string to be used if the message id does not exist
 * @param ... the printf inserts
 */
void Log(int log_level, int msgno, char* format, ...)
{
	int islogmsg = 1;
	char* temp = NULL;
	static char msg_buf[256];

	if (log_level < LOG_CONFIG)
		islogmsg = 0;

#if defined(HIGH_PERFORMANCE)
	if (!islogmsg)
#else
	if (!islogmsg && log_level < trace_settings.trace_level)
#endif
		return;

	if (islogmsg &&	log_level < trace_settings.log_level)
		return;

	if (format == NULL && (temp = Messages_get(msgno, log_level)) != NULL)
		format = temp;

	if (!islogmsg)
	{
		static char trace_msg_buf[256];
		va_list args;

		va_start(args, format);
		vsnprintf(trace_msg_buf, sizeof(trace_msg_buf), format, args);
		Log_trace(log_level, trace_msg_buf);
		va_end(args);
		return;
	}

	if (Log_recurse_flag == 0)
	{
		struct tm *timeinfo;
		char level_char = ' ';
		int buf_pos = 31;
		va_list args;

#if defined(GETTIMEOFDAY)
		gettimeofday(&ts, NULL);
		timeinfo = localtime(&ts.tv_sec);
#else
		ftime(&ts);
		timeinfo = localtime(&ts.time);
#endif
		strftime(&msg_buf[7], 80, "%Y%m%d %H%M%S ", timeinfo);
#if defined(GETTIMEOFDAY)
		sprintf(&msg_buf[22], ".%.3lu ", ts.tv_usec / 1000L);
#else
		sprintf(&msg_buf[22], ".%.3hu ", ts.millitm);
#endif
		buf_pos = 27;

#if defined(GETTIMEOFDAY)
		if (ts.tv_sec == last_ts.tv_sec && ts.tv_usec == last_ts.tv_usec)
#else
		if (ts.time == last_ts.time && ts.millitm == last_ts.millitm)
#endif
			++sametime_count; /* this message has the same timestamp as the last, so increase the sequence no */
		else
		{
			sametime_count = 0;
			last_ts = ts;
		}
		sprintf(msg_buf, "(%.4d)", sametime_count);
		msg_buf[6] = ' ';

		level_char = "     CDIAWESF"[log_level];
		sprintf(&msg_buf[buf_pos], "%s%.4d%c ", MSG_PREFIX, msgno, level_char);
		buf_pos += 11;

		va_start(args, format);
		vsnprintf(&msg_buf[buf_pos], sizeof(msg_buf)-buf_pos, format, args);
		va_end(args);

		if (log_level >= LOG_ERROR)
		{
			char* filename = NULL;
			Log_recurse_flag = 1;
			filename = Broker_recordFFDC(&msg_buf[7]);
			Log_recurse_flag = 0;
			snprintf(&msg_buf[buf_pos], sizeof(msg_buf)-buf_pos, Messages_get(13, LOG_WARN), filename);
		}

		addToBuffer(log_buffer, msg_buf);
#if !defined(WIN32)
		if (trace_settings.isdaemon)
		{
			static char priorities[] = { 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 1, 0};
			syslog(priorities[log_level], "%s", &msg_buf[22]);
		}
		else
		{
#endif
			printf("%s\n", &msg_buf[7]);
			fflush(stdout);
#if !defined(WIN32)
		}
#endif
		if (Log_publishFlag)
		{
			#define MAX_LOG_TOPIC_NAME_LEN 25
			static char topic_buf[MAX_LOG_TOPIC_NAME_LEN];
			sprintf(topic_buf, "$SYS/broker/log/%c/%.4d", level_char, msgno);
			Log_recurse_flag = 1;
			Log_Publish(topic_buf, &msg_buf[7]);
			Log_recurse_flag = 0;
		}
	}

	if (log_level == LOG_FATAL)
		exit(-1);
}