Skip to content
Snippets Groups Projects
Commit 4e54d362 authored by ebensza's avatar ebensza Committed by Gerrit Code Review
Browse files

Merge "Fixed memory leaks in usage stats, JSON attribute parsing and ttcn2json (artf786863)"

parents 36c80a18 bdbe2b36
No related branches found
No related tags found
No related merge requests found
...@@ -194,32 +194,28 @@ UsageData::~UsageData() { ...@@ -194,32 +194,28 @@ UsageData::~UsageData() {
} }
struct thread_data {
std::string msg;
Sender* sndr;
};
void UsageData::sendDataThreaded(std::string msg, Sender* sender) { pthread_t UsageData::sendDataThreaded(std::string msg, thread_data* data) {
thread_data* data = new thread_data; // will be deleted by sendData data->msg = "id="+ id + "&host=" + host + "&platform=" + platform +
data->msg = "id="+ id + "&host=" + host + "&platform=" + platform + "&gccv=" + C_COMPILER_VERSION + "&titanv=" + PRODUCT_NUMBER + "&msg="+ msg + "\r"; "&gccv=" + C_COMPILER_VERSION + "&titanv=" + PRODUCT_NUMBER + "&msg="+ msg + "\r";
data->sndr = sender;
pthread_t thread; pthread_t thread;
pthread_create(&thread, NULL, sendData, data); pthread_create(&thread, NULL, sendData, data);
return thread;
} }
void* UsageData::sendData(void* m) { void* UsageData::sendData(void* m) {
// make sure the thread is cancelable if the main thread finishes first
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
thread_data* my_data; thread_data* my_data;
my_data = (thread_data*)m; my_data = (thread_data*)m;
if(my_data->sndr) { if(my_data->sndr) {
my_data->sndr->send(my_data->msg.c_str()); my_data->sndr->send(my_data->msg.c_str());
delete my_data->sndr;
} }
// delete the data after use
delete my_data;
return NULL; return NULL;
} }
......
...@@ -61,6 +61,10 @@ public: ...@@ -61,6 +61,10 @@ public:
void send(const char*); void send(const char*);
}; };
struct thread_data {
std::string msg;
Sender* sndr;
};
class UsageData { class UsageData {
public: public:
...@@ -69,7 +73,7 @@ public: ...@@ -69,7 +73,7 @@ public:
static UsageData instance; // Guaranteed to be destroyed. static UsageData instance; // Guaranteed to be destroyed.
return instance; // Instantiated on first use. return instance; // Instantiated on first use.
} }
static void sendDataThreaded(std::string msg, Sender* sender); static pthread_t sendDataThreaded(std::string msg, thread_data* data);
private: private:
......
...@@ -1152,6 +1152,11 @@ int main(int argc, char *argv[]) ...@@ -1152,6 +1152,11 @@ int main(int argc, char *argv[])
unsigned int error_count = Error_Context::get_error_count(); unsigned int error_count = Error_Context::get_error_count();
if (error_count > 0) ret_val = EXIT_FAILURE; if (error_count > 0) ret_val = EXIT_FAILURE;
#ifdef USAGE_STATS
pthread_t stats_thread = 0;
thread_data* stats_data = NULL;
#endif
if (parse_only || semantic_check_only) { if (parse_only || semantic_check_only) {
// print detailed statistics // print detailed statistics
Error_Context::print_error_statistics(); Error_Context::print_error_statistics();
...@@ -1184,8 +1189,9 @@ int main(int argc, char *argv[]) ...@@ -1184,8 +1189,9 @@ int main(int argc, char *argv[])
} }
} }
HttpSender *sender = new HttpSender; stats_data = new thread_data;
UsageData::getInstance().sendDataThreaded(stream.str(), sender); stats_data->sndr = new HttpSender;
stats_thread = UsageData::getInstance().sendDataThreaded(stream.str(), stats_data);
#endif #endif
if (ttcn2json) { if (ttcn2json) {
NOTIFY("Generating JSON schema..."); NOTIFY("Generating JSON schema...");
...@@ -1233,5 +1239,19 @@ int main(int argc, char *argv[]) ...@@ -1233,5 +1239,19 @@ int main(int argc, char *argv[])
// dbgnew.hh already does it: check_mem_leak(argv[0]); // dbgnew.hh already does it: check_mem_leak(argv[0]);
#ifdef USAGE_STATS
if (stats_thread != 0) {
// cancel the usage stats thread if it hasn't finished yet
pthread_cancel(stats_thread);
pthread_join(stats_thread, NULL);
}
if (stats_data != NULL) {
if (stats_data->sndr != NULL) {
delete stats_data->sndr;
}
delete stats_data;
}
#endif
return ret_val; return ret_val;
} }
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
void JsonSchemaExtension::init(const char* p_key, const char* p_value) void JsonSchemaExtension::init(char* p_key, char* p_value)
{ {
key = mcopystr(p_key); key = p_key;
value = mcopystr(p_value); value = p_value;
} }
JsonSchemaExtension::~JsonSchemaExtension() JsonSchemaExtension::~JsonSchemaExtension()
......
...@@ -18,13 +18,13 @@ ...@@ -18,13 +18,13 @@
class JsonSchemaExtension { class JsonSchemaExtension {
private: private:
void init(const char* p_key, const char* p_value); void init(char* p_key, char* p_value);
public: public:
char* key; char* key;
char* value; char* value;
JsonSchemaExtension(const char* p_key, const char* p_value) { init(p_key, p_value); } JsonSchemaExtension(char* p_key, char* p_value) { init(p_key, p_value); }
JsonSchemaExtension(const JsonSchemaExtension& x) { init(x.key, x.value); } JsonSchemaExtension(const JsonSchemaExtension& x) { init(mcopystr(x.key), mcopystr(x.value)); }
~JsonSchemaExtension(); ~JsonSchemaExtension();
}; };
......
...@@ -715,7 +715,9 @@ namespace Ttcn { ...@@ -715,7 +715,9 @@ namespace Ttcn {
regex_str = TTCN_pattern_to_regexp(utf8str.c_str(), true); regex_str = TTCN_pattern_to_regexp(utf8str.c_str(), true);
} }
return convert_to_json_string(regex_str); char* json_str = convert_to_json_string(regex_str);
Free(regex_str);
return json_str;
} }
} // namespace Ttcn } // namespace Ttcn
......
...@@ -349,8 +349,9 @@ void Module_List::print_version() ...@@ -349,8 +349,9 @@ void Module_List::print_version()
"--------------------\n", stderr); "--------------------\n", stderr);
} }
void Module_List::send_versions() {
#ifdef USAGE_STATS #ifdef USAGE_STATS
void Module_List::send_usage_stats(pthread_t& thread, thread_data*& data)
{
std::set<ModuleVersion> versions; std::set<ModuleVersion> versions;
for (TTCN_Module *list_iter = list_head; list_iter != NULL; for (TTCN_Module *list_iter = list_head; list_iter != NULL;
list_iter = list_iter->list_next) { list_iter = list_iter->list_next) {
...@@ -371,11 +372,26 @@ void Module_List::send_versions() { ...@@ -371,11 +372,26 @@ void Module_List::send_versions() {
} }
} }
HttpSender* sender = new HttpSender; data = new thread_data;
UsageData::getInstance().sendDataThreaded(stream.str().c_str(), sender); data->sndr = new HttpSender;
#endif thread = UsageData::getInstance().sendDataThreaded(stream.str().c_str(), data);
}
void Module_List::clean_up_usage_stats(pthread_t thread, thread_data* data)
{
if (thread != 0) {
// cancel the usage stats thread if it hasn't finished yet
pthread_cancel(thread);
pthread_join(thread, NULL);
}
if (data != NULL) {
if (data->sndr != NULL) {
delete data->sndr;
}
delete data;
}
} }
#endif // USAGE_STATS
void Module_List::list_testcases() void Module_List::list_testcases()
{ {
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
#include <stdio.h> #include <stdio.h>
#include "Types.h" #include "Types.h"
#ifdef USAGE_STATS
#include <pthread.h>
#endif
class Text_Buf; class Text_Buf;
class TTCN_Module; class TTCN_Module;
...@@ -30,6 +33,9 @@ class Module_Param; ...@@ -30,6 +33,9 @@ class Module_Param;
class Module_Param_Name; class Module_Param_Name;
class ModuleVersion; class ModuleVersion;
struct namespace_t; struct namespace_t;
#ifdef USAGE_STATS
struct thread_data;
#endif
typedef void (*genericfunc_t)(void); typedef void (*genericfunc_t)(void);
...@@ -64,7 +70,11 @@ public: ...@@ -64,7 +70,11 @@ public:
static void execute_all_testcases(const char *module_name); static void execute_all_testcases(const char *module_name);
static void print_version(); static void print_version();
static void send_versions();
#ifdef USAGE_STATS
static void send_usage_stats(pthread_t& thread, thread_data*& data);
static void clean_up_usage_stats(pthread_t thread, thread_data* data);
#endif
static void list_testcases(); static void list_testcases();
static void push_version(Text_Buf& text_buf); static void push_version(Text_Buf& text_buf);
......
...@@ -447,12 +447,18 @@ int TTCN_Runtime::hc_main(const char *local_addr, const char *MC_addr, ...@@ -447,12 +447,18 @@ int TTCN_Runtime::hc_main(const char *local_addr, const char *MC_addr,
TTCN_Logger::log_HC_start(get_host_name()); TTCN_Logger::log_HC_start(get_host_name());
TTCN_Logger::write_logger_settings(); TTCN_Logger::write_logger_settings();
TTCN_Snapshot::check_fd_setsize(); TTCN_Snapshot::check_fd_setsize();
#ifdef USAGE_STATS
pthread_t stats_thread = 0;
thread_data* stats_data = NULL;
#endif
try { try {
if (local_addr != NULL) if (local_addr != NULL)
TTCN_Communication::set_local_address(local_addr); TTCN_Communication::set_local_address(local_addr);
TTCN_Communication::set_mc_address(MC_addr, MC_port); TTCN_Communication::set_mc_address(MC_addr, MC_port);
TTCN_Communication::connect_mc(); TTCN_Communication::connect_mc();
Module_List::send_versions(); #ifdef USAGE_STATS
Module_List::send_usage_stats(stats_thread, stats_data);
#endif
executor_state = HC_IDLE; executor_state = HC_IDLE;
TTCN_Communication::send_version(); TTCN_Communication::send_version();
initialize_component_process_tables(); initialize_component_process_tables();
...@@ -477,6 +483,10 @@ int TTCN_Runtime::hc_main(const char *local_addr, const char *MC_addr, ...@@ -477,6 +483,10 @@ int TTCN_Runtime::hc_main(const char *local_addr, const char *MC_addr,
TTCN_Logger::log_executor_runtime( TTCN_Logger::log_executor_runtime(
API::ExecutorRuntime_reason::host__controller__finished); API::ExecutorRuntime_reason::host__controller__finished);
#ifdef USAGE_STATS
Module_List::clean_up_usage_stats(stats_thread, stats_data);
#endif
return ret_val; return ret_val;
} }
......
...@@ -293,6 +293,11 @@ runs on Shell_CT ...@@ -293,6 +293,11 @@ runs on Shell_CT
pl_success:=false; pl_success:=false;
} }
}//select }//select
vl_pattern := "*(Memory leak at)*";
if (regexp(v_ASP_PResult.stderr,vl_pattern,0) != "") {
log("Memory leak detected during command execution.");
pl_success := false;
}
} else { } else {
log("The result code(", v_ASP_PResult.code, ") is not the expected(", vl_expectedCode, ")"); log("The result code(", v_ASP_PResult.code, ") is not the expected(", vl_expectedCode, ")");
pl_success:=false; pl_success:=false;
......
...@@ -235,6 +235,11 @@ runs on Shell_CT ...@@ -235,6 +235,11 @@ runs on Shell_CT
pl_success:=false; pl_success:=false;
} }
}//select }//select
vl_pattern := "*(Memory leak at)*";
if (regexp(v_ASP_PResult.stderr,vl_pattern,0) != "") {
log("Memory leak detected during command execution.");
pl_success := false;
}
} else { } else {
log("The result code(", v_ASP_PResult.code, ") is not the expected(", vl_expectedCode, ")"); log("The result code(", v_ASP_PResult.code, ") is not the expected(", vl_expectedCode, ")");
pl_success:=false; pl_success:=false;
......
...@@ -223,6 +223,11 @@ runs on Shell_CT ...@@ -223,6 +223,11 @@ runs on Shell_CT
pl_success:=false; pl_success:=false;
} }
}//select }//select
vl_pattern := "*(Memory leak at)*";
if (regexp(v_ASP_PResult.stderr,vl_pattern,0) != "") {
log("Memory leak detected during command execution.");
pl_success := false;
}
} else { } else {
log("The result code(", v_ASP_PResult.code, ") is not the expected(", vl_expectedCode, ")"); log("The result code(", v_ASP_PResult.code, ") is not the expected(", vl_expectedCode, ")");
pl_success:=false; pl_success:=false;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment