some logger changes
This commit is contained in:
@@ -46,6 +46,7 @@ add_library(hiload SHARED
|
|||||||
src/files.c
|
src/files.c
|
||||||
src/memory.c
|
src/memory.c
|
||||||
src/string/string.c
|
src/string/string.c
|
||||||
|
src/logger/logger.c
|
||||||
src/filewatcher/filewatcher.c
|
src/filewatcher/filewatcher.c
|
||||||
src/filewatcher/filewatch.c
|
src/filewatcher/filewatch.c
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef HILOAD_H_
|
#ifndef HILOAD_H_
|
||||||
#define HILOAD_H_
|
#define HILOAD_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -8,14 +9,6 @@ extern "C" {
|
|||||||
// Allows using -fvisibility=hidden by default, decreasing visible symbols
|
// Allows using -fvisibility=hidden by default, decreasing visible symbols
|
||||||
#pragma GCC visibility push(default)
|
#pragma GCC visibility push(default)
|
||||||
|
|
||||||
// Return codes for reload_module
|
|
||||||
typedef enum {
|
|
||||||
HI_RELOAD_SUCCESS = 0,
|
|
||||||
HI_RELOAD_NOT_FOUND,
|
|
||||||
HI_RELOAD_CLOSE_ERROR,
|
|
||||||
HI_RELOAD_OPEN_ERROR
|
|
||||||
} ReloadResult;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialiez the module. Must be called before anything else
|
* Initialiez the module. Must be called before anything else
|
||||||
*/
|
*/
|
||||||
@@ -34,8 +27,12 @@ void hi_print_loaded_modules(void);
|
|||||||
/**
|
/**
|
||||||
* Reload shared library if it has changed since last reload or init was called
|
* Reload shared library if it has changed since last reload or init was called
|
||||||
*/
|
*/
|
||||||
ReloadResult hi_reload_solib(const char *module_name);
|
HiloadResult hi_reload_solib(const char *module_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload all watched modules
|
||||||
|
*/
|
||||||
|
HiloadResult hi_reload();
|
||||||
|
|
||||||
|
|
||||||
#pragma GCC visibility pop
|
#pragma GCC visibility pop
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "array/array.h"
|
#include "array/array.h"
|
||||||
|
#include "array/sc_array.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "filewatch.h"
|
#include "filewatch.h"
|
||||||
#include "filewatch_context.h"
|
#include "filewatch_context.h"
|
||||||
@@ -85,8 +86,8 @@ static hiFileEvent file_event_create(const struct inotify_event *inevent,
|
|||||||
size_t fullpath_size = parent_name_size + event_path_size;
|
size_t fullpath_size = parent_name_size + event_path_size;
|
||||||
if (fullpath_size > BUFSIZE - 1) {
|
if (fullpath_size > BUFSIZE - 1) {
|
||||||
sc_log_error("Pathname length over %u, please compile with smaller "
|
sc_log_error("Pathname length over %u, please compile with smaller "
|
||||||
"paths. Event discarded for %s\n.", BUFSIZE - 1,
|
"paths. Event discarded for %s\n.",
|
||||||
inevent->name);
|
BUFSIZE - 1, inevent->name);
|
||||||
return NULL_EVENT;
|
return NULL_EVENT;
|
||||||
}
|
}
|
||||||
#undef BUFSIZE
|
#undef BUFSIZE
|
||||||
@@ -124,7 +125,8 @@ static hiFileEvent file_event_create(const struct inotify_event *inevent,
|
|||||||
return NULL_EVENT;
|
return NULL_EVENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.pathname = watched_file;
|
// Use params path pointer, because that's what user has control over.
|
||||||
|
event.pathname = params->path;
|
||||||
|
|
||||||
// Event matched and we're watching for it
|
// Event matched and we're watching for it
|
||||||
return event;
|
return event;
|
||||||
@@ -137,14 +139,16 @@ static hiFileEvent file_event_create(const struct inotify_event *inevent,
|
|||||||
return NULL_EVENT;
|
return NULL_EVENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
hiFileEvent hi_file_event_pop(hiFileWatcher *ctx) {
|
hiFileEvent hi_file_event_pop(hiFileWatcher *fw) {
|
||||||
mtx_lock(&ctx->mutex);
|
mtx_lock(&fw->mutex);
|
||||||
hiFileEvent *last = &sc_array_last(&ctx->events);
|
|
||||||
hiFileEvent e = *last;
|
|
||||||
|
|
||||||
sc_array_del_last(&ctx->events);
|
hiFileEvent e = NULL_EVENT;
|
||||||
|
if (sc_array_size(&fw->events) > 0) {
|
||||||
|
e = sc_array_last(&fw->events);
|
||||||
|
sc_array_del_last(&fw->events);
|
||||||
|
}
|
||||||
|
|
||||||
mtx_unlock(&ctx->mutex);
|
mtx_unlock(&fw->mutex);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,13 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* File event watcher using inotify.
|
* File event watcher using inotify.
|
||||||
|
*
|
||||||
|
* Paths are stored as absolute, and this doesn't handle symlinks in watched
|
||||||
|
* files. So if you have e.g. a symlink 'my-proj' to your project folder in
|
||||||
|
* '/workspace/code/my-proj' paths might exist from either side and they are
|
||||||
|
* not interpreted as equal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File Event produced by FileWatcher.
|
* File Event produced by FileWatcher.
|
||||||
*
|
*
|
||||||
|
|||||||
153
src/hiload.c
153
src/hiload.c
@@ -1,9 +1,8 @@
|
|||||||
#include "hiload/hiload.h"
|
#include "hiload/hiload.h"
|
||||||
|
|
||||||
#include "array/sc_array.h"
|
#include "array/array.h"
|
||||||
#include "filewatcher/filewatcher.h"
|
#include "filewatcher/filewatcher.h"
|
||||||
#include "logger/logger.h"
|
#include "logger/logger.h"
|
||||||
#include "logger/sc_log.h"
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "string/string.h"
|
#include "string/string.h"
|
||||||
#include "symbols.h"
|
#include "symbols.h"
|
||||||
@@ -25,6 +24,7 @@ typedef struct {
|
|||||||
struct sc_array_ptr handles; // Array of library handles
|
struct sc_array_ptr handles; // Array of library handles
|
||||||
struct sc_array_uptr addresses; // Array of library base addresses
|
struct sc_array_uptr addresses; // Array of library base addresses
|
||||||
struct sc_array_syms symbols; // Symbol info for modules
|
struct sc_array_syms symbols; // Symbol info for modules
|
||||||
|
bool dirty[256]; // Flag for when module needs to be changed
|
||||||
size_t count; // Number of modules
|
size_t count; // Number of modules
|
||||||
} ModuleInfos;
|
} ModuleInfos;
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size,
|
|||||||
const char *modname = info->dlpi_name;
|
const char *modname = info->dlpi_name;
|
||||||
sc_array_add(&mod_infos->names, strdup(modname));
|
sc_array_add(&mod_infos->names, strdup(modname));
|
||||||
|
|
||||||
sc_log_info("Processing: '%s'\n", info->dlpi_name);
|
log_info("Processing: '%s'\n", info->dlpi_name);
|
||||||
|
|
||||||
// Try to get the handle
|
// Try to get the handle
|
||||||
void *handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD);
|
void *handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD);
|
||||||
@@ -56,11 +56,11 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size,
|
|||||||
|
|
||||||
sc_array_add(&mod_infos->handles, handle);
|
sc_array_add(&mod_infos->handles, handle);
|
||||||
sc_array_add(&mod_infos->addresses, info->dlpi_addr);
|
sc_array_add(&mod_infos->addresses, info->dlpi_addr);
|
||||||
sc_log_debug(" size: %u\n", size);
|
log_debug_v(" size: %u\n", size);
|
||||||
sc_log_debug(" handle: %p\n", sc_array_last(&mod_infos->handles));
|
log_debug_v(" handle: %p\n", sc_array_last(&mod_infos->handles));
|
||||||
sc_log_debug(" dlpi_addr: %p\n", info->dlpi_addr);
|
log_debug_v(" dlpi_addr: %p\n", info->dlpi_addr);
|
||||||
sc_log_debug(" dlpi_tls_modid: %zu\n", info->dlpi_tls_modid);
|
log_debug_v(" dlpi_tls_modid: %zu\n", info->dlpi_tls_modid);
|
||||||
sc_log_debug(" dlpi_tls_data: %p\n", info->dlpi_tls_data);
|
log_debug_v(" dlpi_tls_data: %p\n", info->dlpi_tls_data);
|
||||||
|
|
||||||
Dl_info dl_info = {0};
|
Dl_info dl_info = {0};
|
||||||
if (dladdr((void *)sc_array_last(&mod_infos->addresses), &dl_info)) {
|
if (dladdr((void *)sc_array_last(&mod_infos->addresses), &dl_info)) {
|
||||||
@@ -78,14 +78,14 @@ static int gather_module_infos_callback(struct dl_phdr_info *info, size_t size,
|
|||||||
}
|
}
|
||||||
if (!HILOADRES(hi_file_watcher_add(context.filewatcher, filename,
|
if (!HILOADRES(hi_file_watcher_add(context.filewatcher, filename,
|
||||||
HI_FILE_ALL_EVENTS))) {
|
HI_FILE_ALL_EVENTS))) {
|
||||||
sc_log_error("Failed to set filewatcher for: '%s'\n", filename);
|
log_error("Failed to set filewatcher for: '%s'\n", filename);
|
||||||
} else {
|
} else {
|
||||||
sc_log_info("Watching file: %s\n", filename);
|
log_info("Watching file: %s\n", filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sc_log_error("Couldn't load dlinfo for %s: %s\n",
|
log_error("Couldn't load dlinfo for %s: %s\n",
|
||||||
(sc_array_last(&mod_infos->names)), dlerror());
|
(sc_array_last(&mod_infos->names)), dlerror());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,137 +131,60 @@ static ModuleInfos *gather_module_infos(void) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ReloadResult reload_solib(ModuleInfos *modules, const char *filename,
|
i32 get_module_index(const char *path, HiloadContext *ctx) {
|
||||||
void **updated_handle) {
|
|
||||||
if (!modules || !filename) {
|
|
||||||
return HI_RELOAD_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the module by filename
|
for (size_t i = 0; i < ctx->loaded_modules->count; i++) {
|
||||||
int found = 0;
|
const char *name = sc_array_at(&ctx->loaded_modules->names, i);
|
||||||
size_t index = 0;
|
if (strcmp(name, path) == 0) {
|
||||||
|
return i;
|
||||||
for (size_t i = 0; i < modules->count; i++) {
|
|
||||||
// Check if this is the module we're looking for
|
|
||||||
const char *pathname = sc_array_at(&modules->names, i);
|
|
||||||
|
|
||||||
if (hi_path_has_filename(pathname, filename)) {
|
|
||||||
found = 1;
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
if (!found) {
|
|
||||||
return HI_RELOAD_NOT_FOUND;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the full path
|
HiloadResult hi_reload() {
|
||||||
const char *fullpath = sc_array_at(&modules->names, index);
|
|
||||||
if (!fullpath) {
|
hiFileEvent event = hi_file_event_pop(context.filewatcher);
|
||||||
return HI_RELOAD_OPEN_ERROR;
|
while (event.type != HI_FILE_NONE) {
|
||||||
|
log_debug("Event pop: %s – %s\n", event.pathname,
|
||||||
|
hi_file_watch_type_to_str(event.type));
|
||||||
|
|
||||||
|
i32 index = get_module_index(event.pathname, &context);
|
||||||
|
if (index < 0) {
|
||||||
|
log_warn("Watched module: %s not found.\n", event.pathname);
|
||||||
|
}
|
||||||
|
event = hi_file_event_pop(context.filewatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the old handle
|
return HILOAD_OK;
|
||||||
void *handle = sc_array_at(&modules->handles, index);
|
|
||||||
if (handle) {
|
|
||||||
if (dlclose(handle) != 0) {
|
|
||||||
return HI_RELOAD_CLOSE_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the module with RTLD_NOW
|
|
||||||
void *new_handle = dlopen(fullpath, RTLD_LAZY);
|
|
||||||
if (!new_handle) {
|
|
||||||
sc_log_error("Error reloading module: %s\n", dlerror());
|
|
||||||
return HI_RELOAD_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_handle != handle) {
|
|
||||||
sc_log_info("%s: changed\n", fullpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the handle in our structure
|
|
||||||
modules->handles.elems[index] = new_handle;
|
|
||||||
|
|
||||||
// If the caller wants the new handle, provide it
|
|
||||||
if (updated_handle) {
|
|
||||||
*updated_handle = new_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return HI_RELOAD_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReloadResult hi_reload_solib(const char *module_name) {
|
|
||||||
|
|
||||||
void *new_handle = NULL;
|
|
||||||
ReloadResult result =
|
|
||||||
reload_solib(context.loaded_modules, module_name, &new_handle);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hi_print_loaded_modules(void) {
|
|
||||||
|
|
||||||
sc_log_info("Loaded module info:\n");
|
|
||||||
sc_log_info("-------------------\n");
|
|
||||||
|
|
||||||
const ModuleInfos *mod_infos = context.loaded_modules;
|
|
||||||
if (!mod_infos) {
|
|
||||||
sc_log_error("No module information available.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log_info("Found %zu loaded modules:\n", mod_infos->count);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < mod_infos->count; i++) {
|
|
||||||
|
|
||||||
sc_log_info("'%s'\n", sc_array_at(&mod_infos->names, i));
|
|
||||||
sc_log_info(" handle: %p\n", sc_array_at(&mod_infos->handles, i));
|
|
||||||
sc_log_info(" address: %p\n", sc_array_at(&mod_infos->addresses, i));
|
|
||||||
|
|
||||||
// If we have loaded symbols, print those
|
|
||||||
if (sc_array_size(&mod_infos->symbols) > 0) {
|
|
||||||
const SymbolInfos *symbols = &sc_array_at(&mod_infos->symbols, i);
|
|
||||||
if (symbols) {
|
|
||||||
for (size_t j = 0; j < sc_array_size(&symbols->names); j++) {
|
|
||||||
const void *addr = sc_array_at(&symbols->addresses, j);
|
|
||||||
const char *name = sc_array_at(&symbols->names, j);
|
|
||||||
sc_log_info(" %p: %s\n", addr, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log_info("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int hi_init(unsigned n, const char **enabled_modules) {
|
int hi_init(unsigned n, const char **enabled_modules) {
|
||||||
|
|
||||||
if (sc_log_init() != 0) {
|
if (log_init() != 0) {
|
||||||
fprintf(stderr, "Failed to init logger.\n");
|
fprintf(stderr, "Failed to init logger.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
sc_log_set_level("DEBUG");
|
log_set_level("DEBUG");
|
||||||
sc_log_set_thread_name("Main");
|
log_set_thread_name("Main");
|
||||||
|
|
||||||
// Start the filewatcher
|
// Start the filewatcher
|
||||||
context.filewatcher = hi_file_watcher_create();
|
context.filewatcher = hi_file_watcher_create();
|
||||||
|
|
||||||
for (unsigned i = 0; i < n; i++) {
|
for (unsigned i = 0; i < n; i++) {
|
||||||
const char *module_name = enabled_modules[i];
|
const char *module_name = enabled_modules[i];
|
||||||
sc_log_info("Enabling module: '%s'\n", module_name);
|
log_info("Enabling module: '%s'\n", module_name);
|
||||||
sc_array_add(&context.enabled_modules, module_name);
|
sc_array_add(&context.enabled_modules, module_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_memory_maps_self(&context.memory_regions) != HILOAD_OK) {
|
if (read_memory_maps_self(&context.memory_regions) != HILOAD_OK) {
|
||||||
sc_log_error("Could not populate program memory maps.\n");
|
log_error("Could not populate program memory maps.\n");
|
||||||
return HILOAD_FAIL;
|
return HILOAD_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleInfos *infos = gather_module_infos();
|
ModuleInfos *infos = gather_module_infos();
|
||||||
if (!infos) {
|
if (!infos) {
|
||||||
sc_log_error("Failed to gather module infos.\n");
|
log_error("Failed to gather module infos.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,14 +194,12 @@ int hi_init(unsigned n, const char **enabled_modules) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
context.loaded_modules = infos;
|
context.loaded_modules = infos;
|
||||||
hi_print_loaded_modules();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hi_deinit() {
|
void hi_deinit() {
|
||||||
module_infos_free(context.loaded_modules);
|
module_infos_free(context.loaded_modules);
|
||||||
hi_file_watcher_destroy(context.filewatcher);
|
hi_file_watcher_destroy(context.filewatcher);
|
||||||
sc_log_term();
|
log_term();
|
||||||
memset(&context, 0, sizeof(context));
|
memset(&context, 0, sizeof(context));
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/logger/logger.c
Normal file
13
src/logger/logger.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
|
_Atomic bool hiload_verbose_log = false;
|
||||||
|
|
||||||
|
void log_set_verbose(bool value) {
|
||||||
|
atomic_store_explicit(&hiload_verbose_log, value, memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool log_get_verbose() {
|
||||||
|
return atomic_load_explicit(&hiload_verbose_log, memory_order_relaxed);
|
||||||
|
}
|
||||||
@@ -3,4 +3,26 @@
|
|||||||
|
|
||||||
#include "logger/sc_log.h"
|
#include "logger/sc_log.h"
|
||||||
|
|
||||||
|
|
||||||
|
void log_set_verbose(bool value);
|
||||||
|
bool log_get_verbose();
|
||||||
|
|
||||||
|
#define log_init() (sc_log_init())
|
||||||
|
#define log_set_level(level) (sc_log_set_level((level)))
|
||||||
|
#define log_set_thread_name(name) (sc_log_set_thread_name((name)))
|
||||||
|
#define log_term() (sc_log_term())
|
||||||
|
#define log_debug(...) (sc_log_debug(__VA_ARGS__))
|
||||||
|
#define log_info(...) (sc_log_info(__VA_ARGS__))
|
||||||
|
#define log_warn(...) (sc_log_warn(__VA_ARGS__))
|
||||||
|
#define log_error(...) (sc_log_error(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define log_debug_v(...) do { if (log_get_verbose()) { \
|
||||||
|
log_debug(__VA_ARGS__); } } while(0)
|
||||||
|
#define log_info_v(...) do { if (log_get_verbose()) { \
|
||||||
|
log_info(__VA_ARGS__); } } while(0)
|
||||||
|
#define log_warn_v(...) do { if (log_get_verbose()) { \
|
||||||
|
log_warn(__VA_ARGS__); } } while(0)
|
||||||
|
#define log_error_v(...) do { if (log_get_verbose()) { \
|
||||||
|
log_error(__VA_ARGS__); } } while(0)
|
||||||
|
|
||||||
#endif // LOGGER_H_
|
#endif // LOGGER_H_
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ HiloadResult read_memory_maps_self(struct sc_array_memreg *regions) {
|
|||||||
if (!maps_str)
|
if (!maps_str)
|
||||||
return HILOAD_FAIL;
|
return HILOAD_FAIL;
|
||||||
|
|
||||||
sc_log_debug("/proc/self/maps:\n%s", maps_str);
|
log_debug_v("/proc/self/maps:\n%s", maps_str);
|
||||||
|
|
||||||
char *strptr = maps_str;
|
char *strptr = maps_str;
|
||||||
|
|
||||||
@@ -47,10 +47,10 @@ HiloadResult read_memory_maps_self(struct sc_array_memreg *regions) {
|
|||||||
while (line) {
|
while (line) {
|
||||||
MemoryRegion reg = {0};
|
MemoryRegion reg = {0};
|
||||||
|
|
||||||
|
char pathname[256];
|
||||||
char perm_str[5];
|
char perm_str[5];
|
||||||
u32 dev_major;
|
u32 dev_major;
|
||||||
u32 dev_minor;
|
u32 dev_minor;
|
||||||
char pathname[256];
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Format example from the file:
|
// Format example from the file:
|
||||||
|
|||||||
@@ -2,24 +2,27 @@
|
|||||||
|
|
||||||
#include "../../include/hiload/hiload.h"
|
#include "../../include/hiload/hiload.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#define ARRLEN(A) (sizeof((A)) / (sizeof((A)[0])))
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
const char *reloadable_modules[] = {"", "libmini.so"};
|
const char *reloadable_modules[] = {"", "libmini.so"};
|
||||||
hi_init(2, reloadable_modules);
|
hi_init(ARRLEN(reloadable_modules), reloadable_modules);
|
||||||
|
|
||||||
int modified = -1;
|
int modified = -1;
|
||||||
while (modified != 0) {
|
while (modified != 0) {
|
||||||
|
|
||||||
printf("==========================\n");
|
// printf("==========================\n");
|
||||||
printf("main address: %p\n", main);
|
// printf("main address: %p\n", main);
|
||||||
printf("minimal_lib::getNewValue address: %p\n", minimal_lib::getNewValue);
|
// printf("minimal_lib::getNewValue address: %p\n", minimal_lib::getNewValue);
|
||||||
printf("minimal_lib::otherValue address: %p\n", &minimal_lib::otherValue);
|
// printf("minimal_lib::otherValue address: %p\n", &minimal_lib::otherValue);
|
||||||
printf("==========================\n");
|
// printf("==========================\n");
|
||||||
printf("");
|
// printf("");
|
||||||
|
|
||||||
modified = minimal_lib::getNewValue(5);
|
modified = minimal_lib::getNewValue(5);
|
||||||
printf("getModified(5): %d\n", modified);
|
printf("getModified(5): %d\n", modified);
|
||||||
@@ -27,10 +30,9 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
printf("otherValue: %d\n", minimal_lib::otherValue++);
|
printf("otherValue: %d\n", minimal_lib::otherValue++);
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (hi_reload_solib("libmini.so") != HI_RELOAD_SUCCESS) {
|
if (hi_reload() != HILOAD_OK) {
|
||||||
fprintf(stderr, "Failed to load solib\n");
|
fprintf(stderr, "Failed to load modules\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user