mirror of
https://github.com/Hizenberg469/Memory-Leak-Detector.git
synced 2026-04-19 17:52:26 +03:00
Implementation finished
This commit is contained in:
@@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 17)
|
|||||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_C_EXTENSIONS OFF)
|
set(CMAKE_C_EXTENSIONS OFF)
|
||||||
|
|
||||||
set(MLD_LIB libmld)
|
set(MLD_LIB mld)
|
||||||
set(TEST_APP test_app)
|
set(TEST_APP test_app)
|
||||||
|
|
||||||
set(HEADER_DIR ${CMAKE_SOURCE_DIR}/include)
|
set(HEADER_DIR ${CMAKE_SOURCE_DIR}/include)
|
||||||
|
|||||||
37
app/app.c
37
app/app.c
@@ -29,7 +29,7 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
/*Step 1 : Initialize a new structure database */
|
/*Step 1 : Initialize a new structure database */
|
||||||
struct_db_t* struct_db = calloc(1, sizeof(struct_db_t));
|
struct_db_t* struct_db = calloc(1, sizeof(struct_db_t));
|
||||||
//mld_init_primitive_data_types_support(struct_db);
|
mld_init_primitive_data_types_support(struct_db);
|
||||||
|
|
||||||
/*Step 2 : Create structure record for structure emp_t*/
|
/*Step 2 : Create structure record for structure emp_t*/
|
||||||
static field_info_t emp_fields[] = {
|
static field_info_t emp_fields[] = {
|
||||||
@@ -57,29 +57,30 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
///*Working with object database*/
|
/*Working with object database*/
|
||||||
///*Step 1 : Initialize a new Object database */
|
/*Step 1 : Initialize a new Object database */
|
||||||
//object_db_t* object_db = calloc(1, sizeof(object_db_t));
|
object_db_t* object_db = calloc(1, sizeof(object_db_t));
|
||||||
//object_db->struct_db = struct_db;
|
object_db->struct_db = struct_db;
|
||||||
|
|
||||||
///*Step 2 : Create some sample objects, equivalent to standard
|
/*Step 2 : Create some sample objects, equivalent to standard
|
||||||
// * calloc(1, sizeof(student_t))*/
|
* calloc(1, sizeof(student_t))*/
|
||||||
//student_t* abhishek = xcalloc(object_db, "student_t", 1);
|
student_t* abhishek = xcalloc(object_db, "student_t", 1);
|
||||||
//mld_set_dynamic_object_as_root(object_db, abhishek);
|
mld_set_dynamic_object_as_root(object_db, abhishek);
|
||||||
|
|
||||||
//student_t* shivani = xcalloc(object_db, "student_t", 1);
|
student_t* shivani = xcalloc(object_db, "student_t", 1);
|
||||||
//strncpy(shivani->stud_name, "shivani", strlen("shivani"));
|
strncpy(shivani->stud_name, "shivani", strlen("shivani"));
|
||||||
////abhishek->best_colleage = shivani;
|
//abhishek->best_colleage = shivani;
|
||||||
|
|
||||||
//emp_t* joseph = xcalloc(object_db, "emp_t", 2);
|
emp_t* joseph = xcalloc(object_db, "emp_t", 2);
|
||||||
//mld_set_dynamic_object_as_root(object_db, joseph);
|
//mld_set_dynamic_object_as_root(object_db, joseph);
|
||||||
//joseph->p = xcalloc(object_db, "int", 1);
|
joseph->p = xcalloc(object_db, "int", 1);
|
||||||
|
joseph->p = NULL;
|
||||||
|
|
||||||
//print_object_db(object_db);
|
print_object_db(object_db);
|
||||||
|
|
||||||
//run_mld_algorithm(object_db);
|
run_mld_algorithm(object_db);
|
||||||
//printf("Leaked Objects : \n");
|
printf("Leaked Objects : \n");
|
||||||
//report_leaked_objects(object_db);
|
report_leaked_objects(object_db);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -204,6 +204,15 @@ xcalloc(object_db_t* object_db, char* struct_name, int units);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****API to calloc the object******/
|
||||||
|
|
||||||
|
|
||||||
|
/*****API to calloc the object******/
|
||||||
|
|
||||||
|
void
|
||||||
|
xfree(object_db_t* object_db, void* ptr);
|
||||||
|
|
||||||
|
|
||||||
/*****API to calloc the object******/
|
/*****API to calloc the object******/
|
||||||
|
|
||||||
|
|
||||||
@@ -211,16 +220,35 @@ xcalloc(object_db_t* object_db, char* struct_name, int units);
|
|||||||
/*****APIs to register root objects******/
|
/*****APIs to register root objects******/
|
||||||
|
|
||||||
void
|
void
|
||||||
mld_register_root_object(object_db_t* object_db,
|
mld_register_global_object_as_root(object_db_t* object_db,
|
||||||
void* objptr,
|
void* objptr,
|
||||||
char* struct_name,
|
char* struct_name,
|
||||||
unsigned int units);
|
unsigned int units);
|
||||||
|
|
||||||
void
|
void
|
||||||
set_mld_object_as_global_root(object_db_t* object_db, void* obj_ptr);
|
mld_set_dynamic_object_as_root(object_db_t* object_db, void* obj_ptr);
|
||||||
|
|
||||||
/*****APIs to register root objects******/
|
/*****APIs to register root objects******/
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************APIs' to implement MLD algorithm*************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
report_leaked_objects(object_db_t* object_db);
|
||||||
|
|
||||||
|
/*********************************************APIs' to implement MLD algorithm*************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/********Adding support for primitive data type********/
|
||||||
|
|
||||||
|
void
|
||||||
|
run_mld_algorithm(object_db_t* object_db);
|
||||||
|
|
||||||
|
void
|
||||||
|
mld_init_primitive_data_types_support(struct_db_t* struct_db);
|
||||||
|
|
||||||
|
/********Adding support for primitive data type********/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Declaration for OBJECT DATABASE
|
* Declaration for OBJECT DATABASE
|
||||||
*/
|
*/
|
||||||
|
|||||||
422
src/mld.c
422
src/mld.c
@@ -4,6 +4,7 @@
|
|||||||
#include "css.h"
|
#include "css.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
char* DATA_TYPE[] = { "UINT8", "UINT32", "INT32",
|
char* DATA_TYPE[] = { "UINT8", "UINT32", "INT32",
|
||||||
"CHAR", "OBJ_PTR", "VOID_PTR", "FLOAT",
|
"CHAR", "OBJ_PTR", "VOID_PTR", "FLOAT",
|
||||||
@@ -87,13 +88,16 @@ add_structure_to_struct_db(struct_db_t* struct_db, struct_db_rec_t* struct_rec)
|
|||||||
/******Function to lookup the structure record in structure db******/
|
/******Function to lookup the structure record in structure db******/
|
||||||
|
|
||||||
/*return pointer of struct_db_rec_t on success, NULL on failure from some reason*/
|
/*return pointer of struct_db_rec_t on success, NULL on failure from some reason*/
|
||||||
static struct_db_rec_t*
|
struct_db_rec_t*
|
||||||
struct_db_look_up(struct_db_t* struct_db, char* struct_name) {
|
struct_db_look_up(struct_db_t* struct_db, char* struct_name) {
|
||||||
|
|
||||||
if (!struct_db || !struct_name)
|
if (!struct_db || !struct_name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
struct_db_rec_t* struct_rec = struct_db->head;
|
struct_db_rec_t* struct_rec = struct_db->head;
|
||||||
|
|
||||||
|
if (!struct_rec)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
unsigned int sz_db = struct_db->count;
|
unsigned int sz_db = struct_db->count;
|
||||||
|
|
||||||
@@ -138,7 +142,7 @@ object_db_look_up(object_db_t* object_db,
|
|||||||
while (i < sz_db) {
|
while (i < sz_db) {
|
||||||
|
|
||||||
if (head->ptr == ptr) {
|
if (head->ptr == ptr) {
|
||||||
desired_obj = head->ptr;
|
desired_obj = head;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,4 +153,416 @@ object_db_look_up(object_db_t* object_db,
|
|||||||
|
|
||||||
return desired_obj;
|
return desired_obj;
|
||||||
}
|
}
|
||||||
/******Function to lookup the object record in object db******/
|
/******Function to lookup the object record in object db******/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******Function to add object to OBJECT DB*******/
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_object_to_object_db(object_db_t* object_db,
|
||||||
|
void* ptr,
|
||||||
|
int units,
|
||||||
|
struct_db_rec_t* struct_rec,
|
||||||
|
mld_boolean_t is_root) {
|
||||||
|
|
||||||
|
object_db_rec_t* obj_rec = object_db_look_up(object_db, ptr);
|
||||||
|
|
||||||
|
/**Don't add some object twice**/
|
||||||
|
assert(!obj_rec);
|
||||||
|
|
||||||
|
obj_rec = calloc(1, sizeof(object_db_rec_t));
|
||||||
|
|
||||||
|
obj_rec->next = NULL;
|
||||||
|
obj_rec->ptr = ptr;
|
||||||
|
obj_rec->units = units;
|
||||||
|
obj_rec->struct_rec = struct_rec;
|
||||||
|
obj_rec->is_visited = MLD_FALSE;
|
||||||
|
obj_rec->is_root = is_root;
|
||||||
|
|
||||||
|
object_db_rec_t* head = object_db->head;
|
||||||
|
|
||||||
|
if (!head) {
|
||||||
|
object_db->head = obj_rec;
|
||||||
|
obj_rec->next = NULL;
|
||||||
|
object_db->count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
obj_rec->next = head;
|
||||||
|
object_db->head = obj_rec;
|
||||||
|
object_db->count++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
xcalloc(object_db_t* object_db,
|
||||||
|
char* struct_name,
|
||||||
|
int units) {
|
||||||
|
|
||||||
|
struct_db_rec_t* struct_rec = struct_db_look_up(object_db->struct_db, struct_name);
|
||||||
|
assert(struct_rec);
|
||||||
|
void* ptr = calloc(units, struct_rec->ds_size);
|
||||||
|
add_object_to_object_db(object_db, ptr, units,
|
||||||
|
struct_rec, MLD_FALSE);
|
||||||
|
/*xcalloc by default set the object as non-root*/
|
||||||
|
return ptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******Function to add object to OBJECT DB*******/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******Function to delete object record from object db******/
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
delete_object_record_from_object_db(object_db_t* object_db,
|
||||||
|
object_db_rec_t* object_rec) {
|
||||||
|
|
||||||
|
assert(object_rec);
|
||||||
|
|
||||||
|
object_db_rec_t* head = object_db->head;
|
||||||
|
if (head == object_rec) {
|
||||||
|
object_db->head = object_rec->next;
|
||||||
|
free(object_rec);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_db_rec_t* prev = head;
|
||||||
|
head = head->next;
|
||||||
|
|
||||||
|
while (head) {
|
||||||
|
if (head != object_rec) {
|
||||||
|
prev = head;
|
||||||
|
head = head->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev->next = head->next;
|
||||||
|
head->next = NULL;
|
||||||
|
free(head);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
xfree(object_db_t* object_db, void* ptr) {
|
||||||
|
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
object_db_rec_t* object_rec =
|
||||||
|
object_db_look_up(object_db, ptr);
|
||||||
|
|
||||||
|
assert(object_rec);
|
||||||
|
assert(object_rec->ptr);
|
||||||
|
free(object_rec->ptr);
|
||||||
|
object_rec->ptr = NULL;
|
||||||
|
|
||||||
|
/*Delete object record from object db*/
|
||||||
|
delete_object_record_from_object_db(object_db, object_rec);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******Function to delete object record from object db******/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****Printing functions for dumping object db****/
|
||||||
|
|
||||||
|
void
|
||||||
|
print_object_rec(object_db_rec_t* obj_rec, int i) {
|
||||||
|
|
||||||
|
if (!obj_rec)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf(ANSI_COLOR_MAGENTA "|-------------------------------------------------------------------------------------------------------------|\n"ANSI_COLOR_RESET);
|
||||||
|
printf(ANSI_COLOR_YELLOW "|%-3d ptr = %-10p | next = %-10p | units = %-4d | struct_name = %-10s | is_root = %s |\n"ANSI_COLOR_RESET,
|
||||||
|
i, obj_rec->ptr, obj_rec->next, obj_rec->units, obj_rec->struct_rec->struct_name, obj_rec->is_root == MLD_TRUE? "TRUE " : "FALSE");
|
||||||
|
printf(ANSI_COLOR_MAGENTA "|-------------------------------------------------------------------------------------------------------------|\n"ANSI_COLOR_RESET);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_object_db(object_db_t* object_db) {
|
||||||
|
|
||||||
|
|
||||||
|
object_db_rec_t* object_rec = object_db->head;
|
||||||
|
unsigned int i = 0;
|
||||||
|
printf(ANSI_COLOR_CYAN "Printing OBJECT DATABASE\n" ANSI_COLOR_RESET);
|
||||||
|
for (; object_rec; object_rec = object_rec->next) {
|
||||||
|
print_object_rec(object_rec, i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/****Printing functions for dumping object db****/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****APIs to register root objects******/
|
||||||
|
|
||||||
|
/***
|
||||||
|
|
||||||
|
This API is used to register global object of certain as root object, which are global in scope.
|
||||||
|
Object is not initialized by xcalloc() function.
|
||||||
|
|
||||||
|
***/
|
||||||
|
|
||||||
|
void
|
||||||
|
mld_register_global_object_as_root(object_db_t* object_db,
|
||||||
|
void* objptr,
|
||||||
|
char* struct_name,
|
||||||
|
unsigned int units) {
|
||||||
|
|
||||||
|
struct_db_rec_t* req_struct_rec = struct_db_look_up(object_db->struct_db, struct_name);
|
||||||
|
|
||||||
|
assert(req_struct_rec);
|
||||||
|
|
||||||
|
/*Create a new object record and add it to object database with it being a root object*/
|
||||||
|
add_object_to_object_db(object_db, objptr, units, req_struct_rec, MLD_TRUE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mld_set_dynamic_object_as_root(object_db_t* object_db, void* obj_ptr) {
|
||||||
|
|
||||||
|
|
||||||
|
object_db_rec_t* req_obj_rec = object_db_look_up(object_db, obj_ptr);
|
||||||
|
|
||||||
|
assert(req_obj_rec != NULL);
|
||||||
|
|
||||||
|
|
||||||
|
req_obj_rec->is_root = MLD_TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****APIs to register root objects******/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************APIs' to implement MLD algorithm***************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
static object_db_rec_t*
|
||||||
|
get_next_root_object(object_db_t* object_db, object_db_rec_t* last_root_object) {
|
||||||
|
|
||||||
|
object_db_rec_t* cur_obj_rec = last_root_object ? last_root_object->next : object_db->head;
|
||||||
|
|
||||||
|
//assert(cur_obj_rec);
|
||||||
|
|
||||||
|
while (cur_obj_rec) {
|
||||||
|
|
||||||
|
if (cur_obj_rec->is_root == MLD_TRUE)
|
||||||
|
return cur_obj_rec;
|
||||||
|
|
||||||
|
cur_obj_rec = cur_obj_rec->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_mld_algorithm(object_db_t* object_db) {
|
||||||
|
|
||||||
|
object_db_rec_t* cur_obj = object_db->head;
|
||||||
|
|
||||||
|
while (cur_obj) {
|
||||||
|
cur_obj->is_visited = MLD_FALSE;
|
||||||
|
cur_obj = cur_obj->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//DFS algorithm to explore the Graphically oriented object set...
|
||||||
|
static void
|
||||||
|
mld_explore_object_recursively(object_db_t* object_db,
|
||||||
|
object_db_rec_t* parent_obj_rec) {
|
||||||
|
|
||||||
|
unsigned int i, n_fields;
|
||||||
|
char* parent_obj_ptr = NULL,
|
||||||
|
* child_obj_offset = NULL;
|
||||||
|
void* child_object_address = NULL;
|
||||||
|
field_info_t* field_info = NULL;
|
||||||
|
|
||||||
|
object_db_rec_t* child_object_rec = NULL;
|
||||||
|
struct_db_rec_t* parent_struct_rec = parent_obj_rec->struct_rec;
|
||||||
|
|
||||||
|
/*Parent object must have already visited*/
|
||||||
|
|
||||||
|
assert(parent_obj_rec->is_visited == MLD_TRUE);
|
||||||
|
|
||||||
|
if (parent_struct_rec->n_fields == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < parent_obj_rec->units; i++) {
|
||||||
|
|
||||||
|
parent_obj_ptr = (char*)(parent_obj_rec->ptr) + (i * parent_struct_rec->ds_size);
|
||||||
|
|
||||||
|
for (n_fields = 0; n_fields < parent_struct_rec->n_fields; n_fields++) {
|
||||||
|
|
||||||
|
field_info = &parent_struct_rec->fields[n_fields];
|
||||||
|
|
||||||
|
/*Only need to handle void* and obj_ptr*/
|
||||||
|
switch (field_info->dtype) {
|
||||||
|
case UINT8:
|
||||||
|
case UINT32:
|
||||||
|
case INT32:
|
||||||
|
case CHAR:
|
||||||
|
case FLOAT:
|
||||||
|
case DOUBLE:
|
||||||
|
case OBJ_STRUCT:
|
||||||
|
break;
|
||||||
|
case VOID_PTR:
|
||||||
|
case OBJ_PTR:
|
||||||
|
default:
|
||||||
|
|
||||||
|
|
||||||
|
/*child_obj_offset is the memory location inside parent object
|
||||||
|
where address of next level object is stored*/
|
||||||
|
|
||||||
|
child_obj_offset = parent_obj_ptr + field_info->offset;
|
||||||
|
memcpy(&child_object_address, child_obj_offset, sizeof(void*));
|
||||||
|
|
||||||
|
/*child_obj_address now stores the address of the next object in the graph.
|
||||||
|
It could be NULL, Handle that as well*/
|
||||||
|
|
||||||
|
if (!child_object_address)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
child_object_rec = object_db_look_up(object_db, child_object_address);
|
||||||
|
|
||||||
|
assert(child_object_rec);
|
||||||
|
|
||||||
|
/*Since it's a valid child object of the given parent object,
|
||||||
|
explore it with leisure for memory leak*/
|
||||||
|
if (child_object_rec->is_visited == MLD_FALSE) {
|
||||||
|
child_object_rec->is_visited = MLD_TRUE;
|
||||||
|
if (field_info->dtype != VOID_PTR)/*Explore next object only when it is not a VOID_PTR*/
|
||||||
|
mld_explore_object_recursively(object_db, child_object_rec);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue; /*Do nothing, explore next child object*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Public API to run MLD Algorithm **/
|
||||||
|
void
|
||||||
|
run_mld_algorithm(object_db_t* object_db) {
|
||||||
|
|
||||||
|
//Necessary initialisation...
|
||||||
|
init_mld_algorithm(object_db);
|
||||||
|
|
||||||
|
//Get the first root object...
|
||||||
|
object_db_rec_t* root_obj = get_next_root_object(object_db, NULL);
|
||||||
|
|
||||||
|
while (root_obj) {
|
||||||
|
if (root_obj->is_visited == MLD_TRUE) {
|
||||||
|
//Exploration from this node object is already done...
|
||||||
|
root_obj = get_next_root_object(object_db, root_obj);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
root_obj->is_visited = MLD_TRUE;
|
||||||
|
|
||||||
|
mld_explore_object_recursively(object_db, root_obj);
|
||||||
|
|
||||||
|
root_obj = get_next_root_object(object_db, root_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mld_dump_object_rec_detail(object_db_rec_t* obj_rec) {
|
||||||
|
|
||||||
|
int n_fields = obj_rec->struct_rec->n_fields;
|
||||||
|
|
||||||
|
field_info_t* field = NULL;
|
||||||
|
|
||||||
|
int units = obj_rec->units, obj_index = 0,
|
||||||
|
field_index = 0;
|
||||||
|
|
||||||
|
for (; obj_index < units; obj_index++) {
|
||||||
|
char* current_object_ptr = (char*)(obj_rec->ptr) +
|
||||||
|
(obj_index * obj_rec->struct_rec->ds_size);
|
||||||
|
|
||||||
|
for (field_index = 0; field_index < n_fields; field_index++) {
|
||||||
|
|
||||||
|
field = &obj_rec->struct_rec->fields[field_index];
|
||||||
|
|
||||||
|
switch (field->dtype) {
|
||||||
|
case UINT8:
|
||||||
|
case INT32:
|
||||||
|
case UINT32:
|
||||||
|
printf("%s[%d]->%s = %d\n", obj_rec->struct_rec->struct_name, obj_index, field->fname, *(int*)(current_object_ptr + field->offset));
|
||||||
|
break;
|
||||||
|
case CHAR:
|
||||||
|
printf("%s[%d]->%s = %s\n", obj_rec->struct_rec->struct_name, obj_index, field->fname, (char*)(current_object_ptr + field->offset));
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
printf("%s[%d]->%s = %f\n", obj_rec->struct_rec->struct_name, obj_index, field->fname, *(float*)(current_object_ptr + field->offset));
|
||||||
|
break;
|
||||||
|
case DOUBLE:
|
||||||
|
printf("%s[%d]->%s = %f\n", obj_rec->struct_rec->struct_name, obj_index, field->fname, *(double*)(current_object_ptr + field->offset));
|
||||||
|
break;
|
||||||
|
case OBJ_PTR:
|
||||||
|
printf("%s[%d]->%s = %p\n", obj_rec->struct_rec->struct_name, obj_index, field->fname, (void*)*(int*)(current_object_ptr + field->offset));
|
||||||
|
break;
|
||||||
|
case OBJ_STRUCT:
|
||||||
|
/*Later*/
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
report_leaked_objects(object_db_t* object_db) {
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
object_db_rec_t* head;
|
||||||
|
|
||||||
|
printf("Dumping Leaked Objects\n");
|
||||||
|
|
||||||
|
for (head = object_db->head; head; head = head->next) {
|
||||||
|
if (head->is_visited == MLD_FALSE) {
|
||||||
|
print_object_rec(head, i++);
|
||||||
|
mld_dump_object_rec_detail(head);
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************APIs' to implement MLD algorithm***************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/********Adding support for primitive data type********/
|
||||||
|
|
||||||
|
void
|
||||||
|
mld_init_primitive_data_types_support(struct_db_t* struct_db) {
|
||||||
|
|
||||||
|
REG_STRUCT(struct_db, int, 0);
|
||||||
|
REG_STRUCT(struct_db, float, 0);
|
||||||
|
REG_STRUCT(struct_db, double, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/********Adding support for primitive data type********/
|
||||||
|
|||||||
Reference in New Issue
Block a user