From: Frank Tetzel <s1445051@mail.zih.tu-dresden.de>
To: gdb@sourceware.org
Subject: jit interface and jit reader
Date: Fri, 18 Jan 2019 10:50:00 -0000 [thread overview]
Message-ID: <20190118115004.1a51eefc@archvm> (raw)
[-- Attachment #1: Type: text/plain, Size: 870 bytes --]
Hi,
I have trouble getting GDB's jit interface to work. I'm trying to make
application using AsmJit [1] easier to debug by being able to break
when entering jitted code. As AsmJit is just an assembler returning a
function pointer to the generated code, I do not want to create an
object file for it. That is why I'm trying to use jit-reader, but the
symbol does not seem to show up in GDB and a pending breakpoint is
never hit.
What am I doing wrong? I attached two files: gdbjit.cpp is talking to
GDB via the jit interface. gdbjit-reader.c is the jit reader for GDB
which I compile to a shared object and load in GDB with jit-reader-load.
It does not implement unwind and get_frame_id. Do I need these
functions? unwind is called sometimes. Is there a minimal example
somewhere which implements jit reader?
Best regards,
Frank
[1] https://github.com/asmjit/asmjit
[-- Attachment #2: gdbjit.cpp --]
[-- Type: text/x-c++src, Size: 2029 bytes --]
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cstdint>
extern "C" {
typedef enum {
JIT_NOACTION = 0,
JIT_REGISTER_FN,
JIT_UNREGISTER_FN,
} jit_actions_t;
struct jit_code_entry {
struct jit_code_entry *next_entry;
struct jit_code_entry *prev_entry;
const char *symfile_addr;
uint64_t symfile_size;
};
struct jit_descriptor {
uint32_t version;
// This type should be jit_actions_t, but we use uint32_t
// to be explicit about the bitwidth.
uint32_t action_flag;
struct jit_code_entry *relevant_entry;
struct jit_code_entry *first_entry;
};
// GDB puts a breakpoint in this function.
void __attribute__((noinline)) __jit_debug_register_code() {}
// Make sure to specify the version statically, because the
// debugger may check the version before we can set it.
struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
} // extern "C"
void register_code(const char *name, uint64_t addr, uint64_t size){
puts("register_code called");
printf("name: %s; addr: %lu; size: %lu\n", name, addr, size);
uint64_t name_size = strlen(name)+1; // including null terminator
uint64_t symfile_size = name_size + 2*sizeof(uint64_t);
char *symfile = (char*)malloc(symfile_size);
char *ptr = symfile;
// begin address
*(uint64_t*)ptr = addr;
ptr += sizeof(uint64_t);
// end address
*(uint64_t*)ptr = addr + size;
ptr += sizeof(uint64_t);
// function/symbol name
(void)memcpy(ptr, name, name_size);
// create entry
jit_code_entry *n = new jit_code_entry; //FIXME: memory leak currently
n->next_entry = nullptr;
n->prev_entry = nullptr;
n->symfile_addr = symfile;
n->symfile_size = symfile_size;
// insert into linked list
jit_code_entry *entry = __jit_debug_descriptor.first_entry;
n->next_entry = entry;
if(entry){
entry->prev_entry = n;
}
__jit_debug_descriptor.first_entry = n;
// let GDB know about the new entry
__jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
__jit_debug_descriptor.relevant_entry = n;
puts("calling GDB");
__jit_debug_register_code();
}
[-- Attachment #3: gdbjit-reader.c --]
[-- Type: text/x-c++src, Size: 1752 bytes --]
#include <gdb/jit-reader.h>
#include <stdlib.h>
#include <stdio.h>
GDB_DECLARE_GPL_COMPATIBLE_READER
enum gdb_status read_debug_info(struct gdb_reader_funcs *self, struct gdb_symbol_callbacks *cb, void *memory, long memory_sz){
puts("reader read_debug_info called");
// get begin and end of code segment
GDB_CORE_ADDR begin = *(GDB_CORE_ADDR*)memory;
memory += sizeof(GDB_CORE_ADDR);
GDB_CORE_ADDR end = *(GDB_CORE_ADDR*)memory;
memory += sizeof(GDB_CORE_ADDR);
// get name of function, just a single one per file
const char *name = (const char*)memory;
printf("creating symbol %s at %lu - %lu (size=%lu)\n", name, begin, end, end - begin);
struct gdb_object *obj = cb->object_open(cb);
struct gdb_symtab *symtab = cb->symtab_open(cb, obj, NULL);
struct gdb_block *block = cb->block_open(cb, symtab, NULL, begin, end, name);
cb->symtab_close(cb, symtab);
cb->object_close(cb, obj);
return GDB_SUCCESS;
}
enum gdb_status unwind(struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cb){
puts("reader unwind called");
//TODO
return GDB_FAIL;
}
struct gdb_frame_id get_frame_id(struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cb){
puts("reader get_frame_id called");
//TODO
struct gdb_frame_id frame = {0, 0};
return frame;
}
void destroy(struct gdb_reader_funcs *self){
puts("reader destroy called");
free(self);
}
struct gdb_reader_funcs *gdb_init_reader(void){
puts("gdb_init_reader called");
struct gdb_reader_funcs *funcs = malloc(sizeof(struct gdb_reader_funcs));
funcs->reader_version = GDB_READER_INTERFACE_VERSION;
funcs->priv_data = NULL;
funcs->read = read_debug_info;
funcs->unwind = unwind;
funcs->get_frame_id = get_frame_id;
funcs->destroy = destroy;
return funcs;
}
next reply other threads:[~2019-01-18 10:50 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-18 10:50 Frank Tetzel [this message]
2019-01-21 2:54 ` How to set the same command for all the breakpoints in gdb? Peng Yu
2019-01-21 13:53 ` jit interface and jit reader Frank Tetzel
2019-01-22 11:21 ` Tony Simpson
2019-01-22 17:33 ` Frank Tetzel
2019-01-22 17:56 ` Tony Simpson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190118115004.1a51eefc@archvm \
--to=s1445051@mail.zih.tu-dresden.de \
--cc=gdb@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox