Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Support reports on demand #12

Closed
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
API: Export a hu_report() function for requesting reports on demand
The tool currently only produces reports on a clean exit from the
analyzed program, which is not always achievable (daemons, programs
crashing, etc.). An "on demand" report requested from within the
application itself has proven useful in debugging scenarios, e.g. by
attaching a debugger to the analyzed program and then just call a
routine from there for producing a `heapusage` report.

This way, extend `heapusage` with a public API, currently only having a
`hu_report()` function for generating a `heapusage` report as done from
`log_summary()`. The new API files are `huapi.h` and `huapi.cpp`. The
header file first gets installed in the standard include dir so other SW
modules can use it. The source file is added to the library's link step.

The `log_summary()` call for generating the report from `hu_report()` is
wrapped by a new `log_summary_safe()` function, so that `heapusage`
analysis is temporarily disabled when actually calling `log_summary()`,
otherwise `log_summary()` itself, which does memory allocations, would
interfere with the analysis. This problem didn't exist before, because
`log_summary()` was only being called from the exit handler, which also
disables the analysis before calling `log_summary()`.

Also add an internal global `log_message()` function, useful for logging
generic messages into the `heapusage` log.

Update `README.md` with this new usage possibility.

Signed-off-by: Ricardo Silva <[email protected]>
rjpdasilva committed May 24, 2024

Verified

This commit was signed with the committer’s verified signature.
rjpdasilva Ricardo Silva
commit 4acca12450a50772b32a82389766922d2c0e7e4a
7 changes: 5 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -23,9 +23,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Library
add_library(heapusage SHARED src/humain.cpp src/hulog.cpp src/humalloc.cpp)
add_library(heapusage SHARED src/humain.cpp src/hulog.cpp src/humalloc.cpp src/huapi.cpp)
set_target_properties(heapusage PROPERTIES PUBLIC_HEADER "src/huapi.h")
target_compile_features(heapusage PRIVATE cxx_variadic_templates)
install(TARGETS heapusage LIBRARY DESTINATION lib)
install(TARGETS heapusage
LIBRARY DESTINATION lib
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
target_link_libraries(heapusage pthread dl)

# Dependency backward-cpp providing more detailed stacktraces on Linux, when
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -136,6 +136,12 @@ Examples:
heapusage -t all -m 0 ./ex002
analyze heap allocations of any size with all tools.

Programs being ran with Heapusage can themselves also request reports from
Heapusage, while the program is running, by using the `hu_report()` public API
function. For doing so, they must include the `huapi.h` public header file, link
with the Heapusage shared library itself and call `hu_report()` when wanted.
Still, this only works if the program is running through the `heapusage` tool.

Output Format
=============
Example output:
22 changes: 22 additions & 0 deletions src/huapi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* huapi.cpp
*
* Copyright (C) 2017-2021 Kristofer Berggren
* All rights reserved.
*
* heapusage is distributed under the BSD 3-Clause license, see LICENSE for details.
*
*/


/* ----------- Includes ------------------------------------------ */
#include "hulog.h"


/* ----------- Global Functions ---------------------------------- */

extern "C" void hu_report()
{
log_message("hu_report: Request Log Summary\n");
log_summary_safe();
}
27 changes: 27 additions & 0 deletions src/huapi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* huapi.h
*
* Copyright (C) 2021 Kristofer Berggren
* All rights reserved.
*
* heapusage is distributed under the BSD 3-Clause license, see LICENSE for details.
*
*/

#ifndef _HUAPI_H_
#define _HUAPI_H_


/* ----------- Global Function Prototypes ------------------------ */

#ifdef __cplusplus
extern "C" {
#endif

void hu_report(void);

#ifdef __cplusplus
}
#endif

#endif /* _HUAPI_H_ */
36 changes: 36 additions & 0 deletions src/hulog.cpp
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>

#include <map>
#include <set>
@@ -385,6 +386,30 @@ void hu_sig_handler(int sig, siginfo_t* si, void* /*ucontext*/)
exit(EXIT_FAILURE);
}

void log_message(const char *format, ...)
{
va_list args;

FILE *f = NULL;
if (hu_log_file)
{
f = fopen(hu_log_file, "a");
}

if (!f)
{
return;
}

fprintf(f, "==%d== MESSAGE: ", pid);

va_start(args, format);
vfprintf(f, format, args);
va_end(args);

fclose(f);
}

void log_summary()
{
FILE *f = NULL;
@@ -465,6 +490,17 @@ void log_summary()
fclose(f);
}

void log_summary_safe()
{
hu_set_bypass(true);
log_enable(0);

log_summary();

log_enable(1);
hu_set_bypass(false);
}

void hu_log_remove_freed_allocation(void* ptr)
{
if (!hu_log_free)
2 changes: 2 additions & 0 deletions src/hulog.h
Original file line number Diff line number Diff line change
@@ -24,5 +24,7 @@ void log_enable(int flag);
void log_event(int event, void* ptr, size_t size);
void log_invalid_access(void* ptr);
void hu_sig_handler(int sig, siginfo_t* si, void* /*ucontext*/);
void log_message(const char *format, ...);
void log_summary();
void log_summary_safe();
void hu_log_remove_freed_allocation(void* ptr);