Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* jit interface and jit reader
@ 2019-01-18 10:50 Frank Tetzel
  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
  0 siblings, 2 replies; 6+ messages in thread
From: Frank Tetzel @ 2019-01-18 10:50 UTC (permalink / raw)
  To: gdb

[-- 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;
}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* How to set the same command for all the breakpoints in gdb?
  2019-01-18 10:50 jit interface and jit reader Frank Tetzel
@ 2019-01-21  2:54 ` Peng Yu
  2019-01-21 13:53 ` jit interface and jit reader Frank Tetzel
  1 sibling, 0 replies; 6+ messages in thread
From: Peng Yu @ 2019-01-21  2:54 UTC (permalink / raw)
  To: gdb

gdb manual says the following. But I want to set the same command for
all breakpoints and I don't want to know the number of all the
breakpoints. Is there a syntax to specify all the breakpoints? Thanks.

*Some GDB commands accept a range of breakpoints on which to operate.
A breakpoint range is either a single breakpoint number, like `5', or
two such numbers, in increasing order, separated by a hyphen, like
`5-7'. When a breakpoint range is given to a command, all breakpoint
in that range are operated on.*

-- 
Regards,
Peng


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: jit interface and jit reader
  2019-01-18 10:50 jit interface and jit reader Frank Tetzel
  2019-01-21  2:54 ` How to set the same command for all the breakpoints in gdb? Peng Yu
@ 2019-01-21 13:53 ` Frank Tetzel
  2019-01-22 11:21   ` Tony Simpson
  1 sibling, 1 reply; 6+ messages in thread
From: Frank Tetzel @ 2019-01-21 13:53 UTC (permalink / raw)
  To: gdb

> 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?
> 
> [1] https://github.com/asmjit/asmjit


I looked at GDB's source code a bit and found a minimal example in
testsuite/gdb.base/jit{host.c,reader.c}.

The problem is also visible there: I can follow the indirect call into
the generated code. In TUI-mode, the instructions belonging to the
function have the correct symbol+offset. backtrace shows the function
name as well.

But, I cannot set a breakpoint with the function name. Nor can I use
the command disassemble, only the disassemble view in TUI works.

How can I register the address range as a proper function?

Best regards,
Frank


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: jit interface and jit reader
  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
  0 siblings, 1 reply; 6+ messages in thread
From: Tony Simpson @ 2019-01-22 11:21 UTC (permalink / raw)
  To: Frank Tetzel; +Cc: gdb

Hi Frank,

I think I ran into the same problem a couple of years ago. I fixed my
problem here
https://github.com/tonysimpson/binutils-gdb/commits/jit-interface-fixes.

I've forgotten the details but I remember I got it working with my patch -
here is the commit message for 3c0e5d45f727d5ef98b681103954820c8fbbd700
Fixes:
  * Named blocks not appearing as functions - can't break on functions;
  * Pending breakpoints on JIT'd code not being resolved;
  * GDB goes into an infinit loop with more than one JIT block in a
     symtab;
  * Unwinder function not being called.

Hope this helps. Best Regards,

Tony

On Mon, 21 Jan 2019 at 13:53, Frank Tetzel <s1445051@mail.zih.tu-dresden.de>
wrote:

> > 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?
> >
> > [1] https://github.com/asmjit/asmjit
>
>
> I looked at GDB's source code a bit and found a minimal example in
> testsuite/gdb.base/jit{host.c,reader.c}.
>
> The problem is also visible there: I can follow the indirect call into
> the generated code. In TUI-mode, the instructions belonging to the
> function have the correct symbol+offset. backtrace shows the function
> name as well.
>
> But, I cannot set a breakpoint with the function name. Nor can I use
> the command disassemble, only the disassemble view in TUI works.
>
> How can I register the address range as a proper function?
>
> Best regards,
> Frank
>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: jit interface and jit reader
  2019-01-22 11:21   ` Tony Simpson
@ 2019-01-22 17:33     ` Frank Tetzel
  2019-01-22 17:56       ` Tony Simpson
  0 siblings, 1 reply; 6+ messages in thread
From: Frank Tetzel @ 2019-01-22 17:33 UTC (permalink / raw)
  To: Tony Simpson; +Cc: gdb

> I think I ran into the same problem a couple of years ago. I fixed my
> problem here
> https://github.com/tonysimpson/binutils-gdb/commits/jit-interface-fixes.
> 
> I've forgotten the details but I remember I got it working with my
> patch - here is the commit message for
> 3c0e5d45f727d5ef98b681103954820c8fbbd700 Fixes:
>   * Named blocks not appearing as functions - can't break on
> functions;
>   * Pending breakpoints on JIT'd code not being resolved;
>   * GDB goes into an infinit loop with more than one JIT block in a
>      symtab;
>   * Unwinder function not being called.
> 
> Hope this helps. Best Regards,

Hi Tony,

thank you very much. Your patch is still working nearly unchanged. I
just checked for gdb 8.2.1 (dict_create_linear_expandable() takes an
argument now, "language").

Breakpoints are working now, even pending ones. The disassemble command
still does not work. But I haven't checked all the changes you did,
e.g., multiple blocks.

Did you try to upstream your changes?

Best regards,
Frank


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: jit interface and jit reader
  2019-01-22 17:33     ` Frank Tetzel
@ 2019-01-22 17:56       ` Tony Simpson
  0 siblings, 0 replies; 6+ messages in thread
From: Tony Simpson @ 2019-01-22 17:56 UTC (permalink / raw)
  To: Frank Tetzel; +Cc: gdb

Hi Frank,

I'm glad it was useful. Regarding upstreaming I don't remember why but I
gave up. One of the commits on that branch adds some tests which might be
useful for getting it upstreamed.

I'm happy to help if you need it to get things upstreamed.

Kind  regards,

Tony

On Tue, 22 Jan 2019 at 17:32, Frank Tetzel <s1445051@mail.zih.tu-dresden.de>
wrote:

> > I think I ran into the same problem a couple of years ago. I fixed my
> > problem here
> > https://github.com/tonysimpson/binutils-gdb/commits/jit-interface-fixes.
> >
> > I've forgotten the details but I remember I got it working with my
> > patch - here is the commit message for
> > 3c0e5d45f727d5ef98b681103954820c8fbbd700 Fixes:
> >   * Named blocks not appearing as functions - can't break on
> > functions;
> >   * Pending breakpoints on JIT'd code not being resolved;
> >   * GDB goes into an infinit loop with more than one JIT block in a
> >      symtab;
> >   * Unwinder function not being called.
> >
> > Hope this helps. Best Regards,
>
> Hi Tony,
>
> thank you very much. Your patch is still working nearly unchanged. I
> just checked for gdb 8.2.1 (dict_create_linear_expandable() takes an
> argument now, "language").
>
> Breakpoints are working now, even pending ones. The disassemble command
> still does not work. But I haven't checked all the changes you did,
> e.g., multiple blocks.
>
> Did you try to upstream your changes?
>
> Best regards,
> Frank
>


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-01-22 17:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-18 10:50 jit interface and jit reader Frank Tetzel
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox