diff --git a/src/memory-analyzer/gdb_api.cpp b/src/memory-analyzer/gdb_api.cpp index e487933f90..3b001a0196 100644 --- a/src/memory-analyzer/gdb_api.cpp +++ b/src/memory-analyzer/gdb_api.cpp @@ -24,6 +24,7 @@ Author: Malte Mues #include #include +#include #include #include @@ -56,6 +57,47 @@ gdb_apit::~gdb_apit() wait(NULL); } +size_t gdb_apit::query_malloc_size(const std::string &pointer_expr) +{ +#ifdef __linux__ + write_to_gdb("-var-create tmp * malloc_usable_size(" + pointer_expr + ")"); +#elif __APPLE__ + write_to_gdb("-var-create tmp * malloc_size(" + pointer_expr + ")"); +#else + // Under non-linux/OSX system we simple return 1, i.e. as if the \p + // pointer_expr was not dynamically allocated. + return 1; +#endif + + if(!was_command_accepted()) + { + return 1; + } + + write_to_gdb("-var-evaluate-expression tmp"); + gdb_output_recordt record = get_most_recent_record("^done", true); + + write_to_gdb("-var-delete tmp"); + check_command_accepted(); + + const auto it = record.find("value"); + CHECK_RETURN(it != record.end()); + + const std::string value = it->second; + + INVARIANT( + value.back() != '"' || + (value.length() >= 2 && value[value.length() - 2] == '\\'), + "quotes should have been stripped off from value"); + INVARIANT(value.back() != '\n', "value should not end in a newline"); + + const auto result = string2optional_size_t(value); + if(result.has_value()) + return *result; + else + return 1; +} + void gdb_apit::create_gdb_process() { PRECONDITION(gdb_state == gdb_statet::NOT_CREATED); diff --git a/src/memory-analyzer/gdb_api.h b/src/memory-analyzer/gdb_api.h index 1312bebe6f..05f7991370 100644 --- a/src/memory-analyzer/gdb_api.h +++ b/src/memory-analyzer/gdb_api.h @@ -90,6 +90,17 @@ public: } }; + /// Get the allocated size estimate for a pointer by evaluating + /// `malloc_usable_size'. The function returns the number of usable bytes in + /// the block pointed to by the pointer to a block of memory allocated by + /// `malloc' or a related function. The value may be greater than the + /// requested size of the allocation because of alignment and minimum size + /// constraints. + /// \param pointer_expr: expression with a pointer name + /// \return 1 if the pointer was not allocated with malloc otherwise return + /// the result of calling `malloc_usable_size' + size_t query_malloc_size(const std::string &pointer_expr); + /// Create a new gdb process for analysing the binary indicated by the member /// variable `binary` void create_gdb_process();