Add option to validate pointer addresses in variable server clients

Back ported validate_address fix from trunk.

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
This commit is contained in:
Alex Lin 2016-02-25 10:08:07 -06:00
parent 352ec7d821
commit 6ef4517335
7 changed files with 47 additions and 38 deletions

View File

@ -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 ;

View File

@ -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)
@ -465,6 +465,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(**) */
@ -504,9 +507,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(**) */

View File

@ -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 = false ;
send_stdio = false ;
update_rate = 0.1 ;

View File

@ -168,6 +168,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) ;
@ -189,11 +194,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 ;

View File

@ -14,18 +14,16 @@ int Trick::VariableServerThread::copy_sim_data() {
return 0 ;
}
if ( pthread_mutex_trylock(&copy_mutex) == 0 ) {
if ( pthread_mutex_trylock(&copy_mutex) == 0 ) {
for ( ii = 0 ; ii < vars.size() ; ii++ ) {
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<char*>(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<char*>(curr_var->ref->reference));
if (new_ref != NULL) {
curr_var->ref = new_ref;
}
}
@ -34,12 +32,23 @@ int Trick::VariableServerThread::copy_sim_data() {
curr_var->address = follow_address_path(curr_var->ref) ;
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 ;
}
@ -75,8 +84,6 @@ int Trick::VariableServerThread::copy_sim_data() {
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++ ;

View File

@ -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(&copy_mutex);

View File

@ -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) ;
}