Skip to content

Commit

Permalink
Changed os_dump_core_live() to return the path to the memory dump file.
Browse files Browse the repository at this point in the history
  • Loading branch information
ivankyluk committed Jan 22, 2025
1 parent 5e38538 commit eddb5c8
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 6 deletions.
3 changes: 3 additions & 0 deletions api/docs/release.dox
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ changes:
- The size of #dr_mcontext_t on 32-bit Arm has been increased by 4 so that
the struct can be pushed onto the 8-byte aligned stack without additional
padding. The offset of the field "simd" has changed.
- Added new fields elf_path and elf_path_size to dr_memory_dump_spec_t. When
dr_create_memory_dump() returns true and elf_path is not NULL, elf_path will be
written with the path to the memory dump file.

Further non-compatibility-affecting changes include:
- Added support for reading a single drmemtrace trace file from stdin
Expand Down
10 changes: 10 additions & 0 deletions core/lib/dr_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,16 @@ typedef struct _dr_memory_dump_spec_t {
* in bytes, of ldmp_path.
*/
size_t ldmp_path_size;
/**
* This field only applies to DR_MEMORY_DUMP_ELF. This is an optional output
* field that, if non-NULL, will be written with the path to the created file.
*/
char *elf_path;
/**
* This field only applies to DR_MEMORY_DUMP_ELF. This is the maximum size,
* in bytes, of elf_path.
*/
size_t elf_path_size;
} dr_memory_dump_spec_t;

DR_API
Expand Down
3 changes: 2 additions & 1 deletion core/lib/instrument.c
Original file line number Diff line number Diff line change
Expand Up @@ -2533,7 +2533,8 @@ dr_create_memory_dump(dr_memory_dump_spec_t *spec)
#elif defined(LINUX) && \
((defined(X64) && defined(X86)) || (defined(AARCH64) && !defined(ANDROID64)))
if (TEST(DR_MEMORY_DUMP_ELF, spec->flags)) {
return os_dump_core_live(get_thread_private_dcontext());
return os_dump_core_live(get_thread_private_dcontext(), spec->elf_path,
spec->elf_path_size);
}
#endif
return false;
Expand Down
9 changes: 6 additions & 3 deletions core/unix/coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ write_fpregset_note(DR_PARAM_IN dcontext_t *dcontext, DR_PARAM_IN priv_mcontext_
* false otherwise.
*/
static bool
os_dump_core_internal(dcontext_t *dcontext)
os_dump_core_internal(dcontext_t *dcontext, char *path DR_PARAM_OUT, size_t path_sz)
{
priv_mcontext_t mc;
if (!dr_get_mcontext_priv(dcontext, NULL, &mc))
Expand Down Expand Up @@ -477,6 +477,9 @@ os_dump_core_internal(dcontext_t *dcontext)
SYSLOG_INTERNAL_ERROR("Unable to open the core dump file.");
return false;
}
if (path != NULL) {
d_r_strncpy(path, dump_core_file_name, path_sz);
}
// We use two types of program headers. NOTE is used to store prstatus
// structure and floating point registers. LOAD is used to specify loadable
// segments. All but one section (shstrtab which stores section names)
Expand Down Expand Up @@ -650,7 +653,7 @@ os_dump_core_internal(dcontext_t *dcontext)
* Returns true if a core dump file is written, false otherwise.
*/
bool
os_dump_core_live(dcontext_t *dcontext)
os_dump_core_live(dcontext_t *dcontext, char *path DR_PARAM_OUT, size_t path_sz)
{
#ifdef DR_HOST_NOT_TARGET
// Memory dump is supported only when the host and the target are the same.
Expand All @@ -671,7 +674,7 @@ os_dump_core_live(dcontext_t *dcontext)
}

// TODO i#7046: Add support to save register values for all threads.
const bool ret = os_dump_core_internal(dcontext);
const bool ret = os_dump_core_internal(dcontext, path, path_sz);

end_synch_with_all_threads(threads, num_threads,
/*resume=*/true);
Expand Down
2 changes: 1 addition & 1 deletion core/unix/os_exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ os_get_app_tls_base(dcontext_t *dcontext, reg_id_t seg);
* mode (a process mixing 64-bit and 32-bit code) is not supported.
*/
bool
os_dump_core_live(dcontext_t *dcontext);
os_dump_core_live(dcontext_t *dcontext, char *path DR_PARAM_OUT, size_t path_sz);
#endif

#if defined(AARCHXX) || defined(RISCV64)
Expand Down
28 changes: 27 additions & 1 deletion suite/tests/client-interface/memory_dump_test.dll.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@
#endif

#define NUDGE_ARG_DUMP_MEMORY 1
#define MAX_PATH_SIZE 200

static bool saw_thread_init_event = false;
static client_id_t client_id = 0;
static thread_id_t thread_id = 0;
static char path[MAX_PATH_SIZE];

static void
event_nudge(void *drcontext, uint64 arg)
Expand All @@ -53,9 +55,33 @@ event_nudge(void *drcontext, uint64 arg)
spec.flags = DR_MEMORY_DUMP_LDMP;
#else
spec.flags = DR_MEMORY_DUMP_ELF;
spec.elf_path = (char *)&path;
spec.elf_path_size = MAX_PATH_SIZE;
#endif
if (!dr_create_memory_dump(&spec))
if (!dr_create_memory_dump(&spec)) {
dr_fprintf(STDERR, "Error: failed to create memory dump.\n");
return;
}

file_t memory_dump_file = dr_open_file(path, DR_FILE_READ);
if (memory_dump_file < 0) {
dr_fprintf(STDERR, "Error: failed to read memory dump file: %s.\n", path);
return;
}

uint64 file_size;
if (!dr_file_size(memory_dump_file, &file_size)) {
dr_fprintf(STDERR,
"Error: failed to read the size of the memory dump file: %s.\n",
path);
dr_close_file(memory_dump_file);
return;
}

if (file_size == 0)
dr_fprintf(STDERR, "Error: memory dump file %s is empty.\n", path);

dr_close_file(memory_dump_file);
return;
}
dr_fprintf(STDERR, "Error: unexpected nudge event!\n");
Expand Down

0 comments on commit eddb5c8

Please sign in to comment.