From 543bbc0585c51ed941171659e4abb4dc870ff56a Mon Sep 17 00:00:00 2001 From: Alex Lin Date: Thu, 25 Feb 2016 08:56:04 -0600 Subject: [PATCH] Add option to validate pointer addresses in variable server clients Added a flag called validate_address to each variable server thread. When activated each pointer address will be tested to see if it is in memory the memory manager is tracking. If it is then everything proceeds normally. If it does not, then an error return value is returned for the value of this variable. refs #193 --- include/trick/VariableServerThread.hh | 22 ++++++------ .../MemoryManager/MemoryManager_ref_dim.cpp | 1 + .../VariableServer/VariableServerThread.cpp | 2 +- .../VariableServerThread_commands.cpp | 10 +++--- .../VariableServerThread_copy_sim_data.cpp | 35 ++++++++++++------- .../VariableServerThread_restart.cpp | 4 --- .../VariableServer/var_server_ext.cpp | 15 +++++--- 7 files changed, 50 insertions(+), 39 deletions(-) diff --git a/include/trick/VariableServerThread.hh b/include/trick/VariableServerThread.hh index 9f78c2bb..da10e285 100644 --- a/include/trick/VariableServerThread.hh +++ b/include/trick/VariableServerThread.hh @@ -170,6 +170,14 @@ namespace Trick { */ int var_exit() ; + /** + @brief @userdesc Turns on validating addresses before they are referenced + @par Python Usage: + @code trick.var_validate_address() @endcode + @return always 0 + */ + int var_validate_address(bool on_off) ; + /** @brief @userdesc Command to instruct the variable server to output debug information. @par Python Usage: @@ -205,14 +213,6 @@ namespace Trick { */ int var_binary_nonames() ; - /** - @brief @userdesc Command to look up bad references - @par Python Usage: - @code trick.var_retry_bad_ref() @endcode - @return always 0 - */ - int var_retry_bad_ref() ; - /** @brief @userdesc Command to tell the server when to copy data - VS_COPY_ASYNC = copies data asynchronously. (default) @@ -470,6 +470,9 @@ namespace Trick { /** Toggle to indicate var_exit commanded.\n */ bool exit_cmd ; /**< trick_io(**) */ + /** Set to true to validate all addresses before copying.\n */ + bool validate_address ; /**< trick_io(**) */ + /** The mutex to protect variable output buffers when copying variable values to them from Trick memory.\n */ pthread_mutex_t copy_mutex ; /**< trick_io(**) */ @@ -512,9 +515,6 @@ namespace Trick { /** Toggle to tell variable server to send data multicast or point to point.\n */ bool multicast ; /**< trick_io(**) */ - /** Toggle to look up bad refs.\n */ - bool retry_bad_ref ; /**< trick_io(**) */ - /** Flag to indicate the connection has been made\n */ bool connection_accepted ; /**< trick_io(**) */ diff --git a/trick_source/sim_services/MemoryManager/MemoryManager_ref_dim.cpp b/trick_source/sim_services/MemoryManager/MemoryManager_ref_dim.cpp index 71be4c0b..800975c3 100644 --- a/trick_source/sim_services/MemoryManager/MemoryManager_ref_dim.cpp +++ b/trick_source/sim_services/MemoryManager/MemoryManager_ref_dim.cpp @@ -51,6 +51,7 @@ int Trick::MemoryManager::ref_dim( REF2* R, V_DATA* V) { } else { + R->pointer_present = 1 ; if ( R->create_add_path ) { ADDRESS_NODE * address_node ; diff --git a/trick_source/sim_services/VariableServer/VariableServerThread.cpp b/trick_source/sim_services/VariableServer/VariableServerThread.cpp index 309b32b7..bfa7b859 100644 --- a/trick_source/sim_services/VariableServer/VariableServerThread.cpp +++ b/trick_source/sim_services/VariableServer/VariableServerThread.cpp @@ -24,11 +24,11 @@ Trick::VariableServerThread::VariableServerThread(TCDevice * in_listen_dev) : binary_data = false; multicast = false; byteswap = false ; - retry_bad_ref = false ; pause_cmd = false ; exit_cmd = false ; + validate_address = true ; send_stdio = false ; update_rate = 0.1 ; diff --git a/trick_source/sim_services/VariableServer/VariableServerThread_commands.cpp b/trick_source/sim_services/VariableServer/VariableServerThread_commands.cpp index 182b0324..56955d1c 100644 --- a/trick_source/sim_services/VariableServer/VariableServerThread_commands.cpp +++ b/trick_source/sim_services/VariableServer/VariableServerThread_commands.cpp @@ -186,6 +186,11 @@ int Trick::VariableServerThread::var_exit() { return(0) ; } +int Trick::VariableServerThread::var_validate_address(bool on_off) { + validate_address = on_off ; + return(0) ; +} + int Trick::VariableServerThread::var_debug(int level) { debug = level ; return(0) ; @@ -207,11 +212,6 @@ int Trick::VariableServerThread::var_binary_nonames() { return(0) ; } -int Trick::VariableServerThread::var_retry_bad_ref() { - retry_bad_ref = 1 ; - return(0) ; -} - int Trick::VariableServerThread::var_set_copy_mode(int mode) { if ( mode >= VS_COPY_ASYNC and mode <= VS_COPY_TOP_OF_FRAME ) { copy_mode = (VS_COPY_MODE)mode ; diff --git a/trick_source/sim_services/VariableServer/VariableServerThread_copy_sim_data.cpp b/trick_source/sim_services/VariableServer/VariableServerThread_copy_sim_data.cpp index 294bab11..bde8dfbc 100644 --- a/trick_source/sim_services/VariableServer/VariableServerThread_copy_sim_data.cpp +++ b/trick_source/sim_services/VariableServer/VariableServerThread_copy_sim_data.cpp @@ -15,7 +15,7 @@ int Trick::VariableServerThread::copy_sim_data() { return 0 ; } - if ( pthread_mutex_trylock(©_mutex) == 0 ) { + if ( pthread_mutex_trylock(©_mutex) == 0 ) { // Get the simulation time we start this copy time = (double)exec_get_time_tics() / exec_get_time_tic_value() ; @@ -24,29 +24,39 @@ int Trick::VariableServerThread::copy_sim_data() { curr_var = vars[ii] ; // if this variable is unresolved, try to resolve it - if ( retry_bad_ref ) { - if (curr_var->ref->address == &bad_ref_int) { - REF2 *new_ref = ref_attributes(const_cast(curr_var->ref->reference)); - if (new_ref != NULL) { - curr_var->ref = new_ref; - } + if (curr_var->ref->address == &bad_ref_int) { + REF2 *new_ref = ref_attributes(const_cast(curr_var->ref->reference)); + if (new_ref != NULL) { + curr_var->ref = new_ref; } } // if there's a pointer somewhere in the address path, follow it in case pointer changed if ( curr_var->ref->pointer_present == 1 ) { curr_var->address = follow_address_path(curr_var->ref) ; - if ( curr_var->address == NULL ) { + if ( (curr_var->address == NULL) ) { std::string save_name(curr_var->ref->reference) ; - if ( curr_var->ref->attr) { - free(curr_var->ref->attr) ; - } free(curr_var->ref) ; curr_var->ref = make_error_ref(save_name) ; curr_var->address = curr_var->ref->address ; + } else if ( validate_address ) { + // The address is not NULL. + // If validate_address is on, check the memory manager if the address falls into + // any of the memory blocks it knows of. Don't do this if we have a std::string or + // wstring type, or we already are pointing to a bad ref. + if ( (curr_var->string_type != TRICK_STRING) and + (curr_var->string_type != TRICK_WSTRING) and + (curr_var->ref->address != &bad_ref_int) and + (get_alloc_info_of(curr_var->address) == NULL) ) { + std::string save_name(curr_var->ref->reference) ; + free(curr_var->ref) ; + curr_var->ref = make_error_ref(save_name) ; + curr_var->address = curr_var->ref->address ; + } } else { curr_var->ref->address = curr_var->address ; } + } // if this variable is a string we need to get the raw character string out of it. @@ -76,11 +86,10 @@ int Trick::VariableServerThread::copy_sim_data() { curr_var->size = wcslen((wchar_t *)curr_var->address) * sizeof(wchar_t); } } + memcpy( curr_var->buffer_in , curr_var->address , curr_var->size ) ; } - retry_bad_ref = false ; - // Indicate that sim data has been written and is now ready in the buffer_in's of the vars variable list. var_data_staged = true; packets_copied++ ; diff --git a/trick_source/sim_services/VariableServer/VariableServerThread_restart.cpp b/trick_source/sim_services/VariableServer/VariableServerThread_restart.cpp index 8379611f..1e96b5bf 100644 --- a/trick_source/sim_services/VariableServer/VariableServerThread_restart.cpp +++ b/trick_source/sim_services/VariableServer/VariableServerThread_restart.cpp @@ -29,10 +29,6 @@ void Trick::VariableServerThread::restart() { // Set the pause state of this thread back to its "pre-checkpoint reload" state. pause_cmd = saved_pause_cmd ; - // Set retry_bad_ref so that variables in this varible server thread will - // be re-resolved to the newly re-created memory objects. - var_retry_bad_ref(); - // Allow data copying to continue. pthread_mutex_unlock(©_mutex); diff --git a/trick_source/sim_services/VariableServer/var_server_ext.cpp b/trick_source/sim_services/VariableServer/var_server_ext.cpp index 4a8dc42c..abbed8f7 100644 --- a/trick_source/sim_services/VariableServer/var_server_ext.cpp +++ b/trick_source/sim_services/VariableServer/var_server_ext.cpp @@ -114,6 +114,15 @@ int var_exit() { return(0) ; } +int var_validate_address(int on_off) { + Trick::VariableServerThread * vst ; + vst = get_vst() ; + if (vst != NULL ) { + vst->var_validate_address((bool)on_off) ; + } + return(0) ; +} + int var_debug(int level) { Trick::VariableServerThread * vst ; vst = get_vst() ; @@ -142,11 +151,7 @@ int var_binary() { } int var_retry_bad_ref() { - Trick::VariableServerThread * vst ; - vst = get_vst() ; - if (vst != NULL ) { - vst->var_retry_bad_ref() ; - } + message_publish(MSG_WARNING,"var_retry_bad_ref has been deprecated\n") ; return(0) ; }