* [PATCH] gdb/jit: fix jit-reader linetable integrity
@ 2024-12-21 8:30 Yang Liu
2024-12-22 2:12 ` Simon Marchi
0 siblings, 1 reply; 7+ messages in thread
From: Yang Liu @ 2024-12-21 8:30 UTC (permalink / raw)
To: gdb-patches; +Cc: tom, simon.marchi, Yang Liu
The custom linetable functionality in GDB's JIT Interface has been broken
since commit 1acc9dca423f78e44553928f0de839b618c13766.
In that commit, linetables were made independent from the objfile, which
requires objfile->section_offsets to be initialized. However, section_offsets
were never initialized in objfiles generated by GDB's JIT Interface
with custom jit-readers, leading to GDB crashes when stepping into JITed code
blocks with the following command already executed:
jit-reader-load libmygdbjitreader.so
This patch fixes the issue by initializing the minimum section_offsets required
for linetable parsing procedures.
---
gdb/jit.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gdb/jit.c b/gdb/jit.c
index 77d41bf86ba..7027c84b5bf 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -665,6 +665,8 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb,
objfile *objfile = objfile::make (nullptr, current_program_space,
objfile_name.c_str (), OBJF_NOT_FILENAME);
+ objfile->section_offsets.assign (1, 0);
+ objfile->sect_index_text = 0;
objfile->per_bfd->gdbarch = priv_data->gdbarch;
for (gdb_symtab &symtab : obj->symtabs)
--
2.42.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] gdb/jit: fix jit-reader linetable integrity
2024-12-21 8:30 [PATCH] gdb/jit: fix jit-reader linetable integrity Yang Liu
@ 2024-12-22 2:12 ` Simon Marchi
0 siblings, 0 replies; 7+ messages in thread
From: Simon Marchi @ 2024-12-22 2:12 UTC (permalink / raw)
To: Yang Liu, gdb-patches; +Cc: tom
On 2024-12-21 03:30, Yang Liu wrote:
> The custom linetable functionality in GDB's JIT Interface has been broken
> since commit 1acc9dca423f78e44553928f0de839b618c13766.
>
> In that commit, linetables were made independent from the objfile, which
> requires objfile->section_offsets to be initialized. However, section_offsets
> were never initialized in objfiles generated by GDB's JIT Interface
> with custom jit-readers, leading to GDB crashes when stepping into JITed code
> blocks with the following command already executed:
>
> jit-reader-load libmygdbjitreader.so
>
> This patch fixes the issue by initializing the minimum section_offsets required
> for linetable parsing procedures.
I can imagine how the problem can manifest, but do you have a
reproducer? I tried stepping with the binary of test
gdb.base/jit-reader.exp, but I couldn't get it to crash. Ideally, this
fix should come with a test to demonstrate the problem and the fix.
> ---
> gdb/jit.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/gdb/jit.c b/gdb/jit.c
> index 77d41bf86ba..7027c84b5bf 100644
> --- a/gdb/jit.c
> +++ b/gdb/jit.c
> @@ -665,6 +665,8 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb,
>
> objfile *objfile = objfile::make (nullptr, current_program_space,
> objfile_name.c_str (), OBJF_NOT_FILENAME);
> + objfile->section_offsets.assign (1, 0);
I would suggest using push_back instead of assign. Everybody knows
push_back, whereas I had to look up what assign does, I guess I'm not
the only one.
Simon
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] gdb/jit: fix jit-reader linetable integrity
@ 2024-12-22 11:46 liuyang22
2024-12-22 14:22 ` Simon Marchi
0 siblings, 1 reply; 7+ messages in thread
From: liuyang22 @ 2024-12-22 11:46 UTC (permalink / raw)
To: gdb-patches, Simon Marchi; +Cc: tom
[-- Attachment #1: Type: text/plain, Size: 6215 bytes --]
On Dec 22, 2024 10:12, Simon Marchi<simon.marchi@polymtl.ca> wrote:
> On 2024-12-21 03:30, Yang Liu wrote:
> > The custom linetable functionality in GDB's JIT Interface has been broken
> > since commit 1acc9dca423f78e44553928f0de839b618c13766.
> >
> > In that commit, linetables were made independent from the objfile, which
> > requires objfile->section_offsets to be initialized. However, section_offsets
> > were never initialized in objfiles generated by GDB's JIT Interface
> > with custom jit-readers, leading to GDB crashes when stepping into JITed code
> > blocks with the following command already executed:
> >
> > jit-reader-load libmygdbjitreader.so
> >
> > This patch fixes the issue by initializing the minimum section_offsets required
> > for linetable parsing procedures.
>
> I can imagine how the problem can manifest, but do you have a
> reproducer? I tried stepping with the binary of test
> gdb.base/jit-reader.exp, but I couldn't get it to crash. Ideally, this
> fix should come with a test to demonstrate the problem and the fix.
>
Hi Simon,
Thanks for the review!
Below is a reproducer, but I have no idea how GDB testsuite works, is it possible
to put this in?
// Compile with:
gcc -ggdb -o jit jit.c
gcc -shared -fPIC -o libmyreader.so reader.c
// Run with:
gdb --args ./jit
(gdb) jit-reader-load /path/to/libmyreader.so
(gdb) b jit.c:90
(gdb) step <-- GDB crashes here
// Source files:
// jit.h ------------------------------
#include <stdio.h>
#include <stdint.h>
#include <gdb/jit-reader.h>
typedef struct {
char filename[32];
FILE* file;
GDB_CORE_ADDR start;
GDB_CORE_ADDR end;
size_t nlines;
struct gdb_line_mapping lines[3];
} gdbjit_block_t;
// jit.c ------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include "jit.h"
enum {
GDBJIT_NOACTION = 0,
GDBJIT_REGISTER,
GDBJIT_UNREGISTER
};
typedef struct gdbjit_code_entry_s {
struct gdbjit_code_entry_s* next_entry;
struct gdbjit_code_entry_s* prev_entry;
const char* symfile_addr;
uint64_t symfile_size;
} gdbjit_code_entry_t;
typedef struct gdbjit_descriptor_s {
uint32_t version;
uint32_t action_flag;
gdbjit_code_entry_t* relevant_entry;
gdbjit_code_entry_t* first_entry;
} gdbjit_descriptor_t;
void __attribute__((noinline, visibility("default"))) __jit_debug_register_code()
{
asm volatile("" ::: "memory");
};
__attribute__((visibility("default")))
gdbjit_descriptor_t __jit_debug_descriptor = { 1, GDBJIT_NOACTION, NULL, NULL };
static void gdbjit_block_ready(GDB_CORE_ADDR start, GDB_CORE_ADDR end) {
gdbjit_block_t* block = (gdbjit_block_t*)calloc(sizeof(gdbjit_block_t), 1);
strcpy(block->filename, "/tmp/mygdbjit-XXXXXX.S");
int fd = mkstemps(block->filename, 2);
block->file = fdopen(fd, "w");
block->start = start;
block->end = end;
fprintf(block->file, "mov eax, edi\nadd eax, esi\nret\n");
fclose(block->file);
block->nlines = 3;
block->lines[0].pc = start;
block->lines[0].line = 1;
block->lines[1].pc = start + 2;
block->lines[1].line = 2;
block->lines[2].pc = start + 4;
block->lines[2].line = 3;
gdbjit_code_entry_t* entry = (gdbjit_code_entry_t*)malloc(sizeof(gdbjit_code_entry_t));
entry->symfile_addr = (const char*)block;
entry->symfile_size = sizeof(gdbjit_block_t);
if (__jit_debug_descriptor.first_entry) {
__jit_debug_descriptor.relevant_entry->next_entry = entry;
entry->prev_entry = __jit_debug_descriptor.relevant_entry;
} else {
__jit_debug_descriptor.first_entry = entry;
}
__jit_debug_descriptor.relevant_entry = entry;
__jit_debug_descriptor.action_flag = GDBJIT_REGISTER;
__jit_debug_register_code();
}
typedef int (*func_ptr)(int, int);
int main() {
unsigned char code[] = {
0x89, 0xF8, // mov eax, edi
0x01, 0xF0, // add eax, esi
0xC3 // ret
};
void *mem = mmap(NULL, sizeof(code), PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (mem == MAP_FAILED) {
perror("mmap");
return EXIT_FAILURE;
}
memcpy(mem, code, sizeof(code));
gdbjit_block_ready((GDB_CORE_ADDR)mem, (GDB_CORE_ADDR)mem + sizeof(code));
func_ptr add = (func_ptr)mem;
int a = 5, b = 7;
int result = add(a, b);
printf("Result of %d + %d = %d\n", a, b, result);
munmap(mem, sizeof(code));
return 0;
}
// reader.c ------------------------------
#include "jit.h"
#include <stdio.h>
static enum gdb_status read_debug_info(struct gdb_reader_funcs* self,
struct gdb_symbol_callbacks* cbs, void* memory, long memory_sz)
{
gdbjit_block_t* block = (gdbjit_block_t*)memory;
struct gdb_object* object = cbs->object_open(cbs);
struct gdb_symtab* symtab = cbs->symtab_open(cbs, object, block->filename);
cbs->block_open(cbs, symtab, NULL, block->start, block->end, "(block)");
cbs->line_mapping_add(cbs, symtab, block->nlines, block->lines);
cbs->symtab_close(cbs, symtab);
cbs->object_close(cbs, object);
return GDB_SUCCESS;
}
enum gdb_status unwind_frame(struct gdb_reader_funcs* self, struct gdb_unwind_callbacks* cbs)
{
return GDB_SUCCESS;
}
struct gdb_frame_id get_frame_id(struct gdb_reader_funcs* self, struct gdb_unwind_callbacks* cbs)
{
struct gdb_frame_id frame = {0xdeadbeef, 0};
return frame;
}
void destroy_reader(struct gdb_reader_funcs* self) {}
__attribute__((visibility("default"))) struct gdb_reader_funcs* gdb_init_reader(void)
{
static struct gdb_reader_funcs funcs = {GDB_READER_INTERFACE_VERSION, NULL,
read_debug_info, unwind_frame, get_frame_id, destroy_reader};
return &funcs;
}
__attribute__((visibility("default"))) int plugin_is_GPL_compatible (void)
{
return 0;
}
> > ---
> > gdb/jit.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/gdb/jit.c b/gdb/jit.c
> > index 77d41bf86ba..7027c84b5bf 100644
> > --- a/gdb/jit.c
> > +++ b/gdb/jit.c
> > @@ -665,6 +665,8 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb,
> >
> > objfile *objfile = objfile::make (nullptr, current_program_space,
> > objfile_name.c_str (), OBJF_NOT_FILENAME);
> > + objfile->section_offsets.assign (1, 0);
>
> I would suggest using push_back instead of assign. Everybody knows
> push_back, whereas I had to look up what assign does, I guess I'm not
> the only one.
>
Thank you for the advice, I will address this in V2.
Reagrds,
Yang Liu
> Simon
[-- Attachment #2: Type: text/html, Size: 17772 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] gdb/jit: fix jit-reader linetable integrity
2024-12-22 11:46 liuyang22
@ 2024-12-22 14:22 ` Simon Marchi
2024-12-22 16:38 ` Yang Liu
0 siblings, 1 reply; 7+ messages in thread
From: Simon Marchi @ 2024-12-22 14:22 UTC (permalink / raw)
To: liuyang22, gdb-patches; +Cc: tom
On 2024-12-22 06:46, liuyang22 wrote:
> On Dec 22, 2024 10:12, Simon Marchi<simon.marchi@polymtl.ca> wrote:
>> On 2024-12-21 03:30, Yang Liu wrote:
>> > The custom linetable functionality in GDB's JIT Interface has been broken
>> > since commit 1acc9dca423f78e44553928f0de839b618c13766.
>> >
>> > In that commit, linetables were made independent from the objfile, which
>> > requires objfile->section_offsets to be initialized. However, section_offsets
>> > were never initialized in objfiles generated by GDB's JIT Interface
>> > with custom jit-readers, leading to GDB crashes when stepping into JITed code
>> > blocks with the following command already executed:
>> >
>> > jit-reader-load libmygdbjitreader.so
>> >
>> > This patch fixes the issue by initializing the minimum section_offsets required
>> > for linetable parsing procedures.
>>
>> I can imagine how the problem can manifest, but do you have a
>> reproducer? I tried stepping with the binary of test
>> gdb.base/jit-reader.exp, but I couldn't get it to crash. Ideally, this
>> fix should come with a test to demonstrate the problem and the fix.
>>
>
> Hi Simon,
>
> Thanks for the review!
>
> Below is a reproducer, but I have no idea how GDB testsuite works, is it possible
> to put this in?
Thanks for the quick response. It should be fairly easy to turn this
into a test. I'll give it a shot if I find a bit of free time during
the holidays.
Simon
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] gdb/jit: fix jit-reader linetable integrity
2024-12-22 14:22 ` Simon Marchi
@ 2024-12-22 16:38 ` Yang Liu
0 siblings, 0 replies; 7+ messages in thread
From: Yang Liu @ 2024-12-22 16:38 UTC (permalink / raw)
To: Simon Marchi, gdb-patches; +Cc: tom
On 2024/12/22 22:22, Simon Marchi wrote:
> On 2024-12-22 06:46, liuyang22 wrote:
>> On Dec 22, 2024 10:12, Simon Marchi<simon.marchi@polymtl.ca> wrote:
> Thanks for the quick response. It should be fairly easy to turn this
> into a test. I'll give it a shot if I find a bit of free time during
> the holidays.
Thank you! That would be great. I've sent v2. Have a great holiday!
Regards,
Yang Liu
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] gdb/jit: fix jit-reader linetable integrity
@ 2024-12-22 16:31 Yang Liu
2024-12-22 16:34 ` Yang Liu
0 siblings, 1 reply; 7+ messages in thread
From: Yang Liu @ 2024-12-22 16:31 UTC (permalink / raw)
To: gdb-patches; +Cc: tom, simon.marchi, Yang Liu
The custom linetable functionality in GDB's JIT Interface has been broken
since commit 1acc9dca423f78e44553928f0de839b618c13766.
In that commit, linetables were made independent from the objfile, which
requires objfile->section_offsets to be initialized. However, section_offsets
were never initialized in objfiles generated by GDB's JIT Interface
with custom jit-readers, leading to GDB crashes when stepping into JITed code
blocks with the following command already executed:
jit-reader-load libmygdbjitreader.so
This patch fixes the issue by initializing the minimum section_offsets required
for linetable parsing procedures.
---
gdb/jit.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gdb/jit.c b/gdb/jit.c
index 77d41bf86ba..21c17c145c9 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -665,6 +665,8 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb,
objfile *objfile = objfile::make (nullptr, current_program_space,
objfile_name.c_str (), OBJF_NOT_FILENAME);
+ objfile->section_offsets.push_back (0);
+ objfile->sect_index_text = 0;
objfile->per_bfd->gdbarch = priv_data->gdbarch;
for (gdb_symtab &symtab : obj->symtabs)
--
2.42.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] gdb/jit: fix jit-reader linetable integrity
2024-12-22 16:31 Yang Liu
@ 2024-12-22 16:34 ` Yang Liu
0 siblings, 0 replies; 7+ messages in thread
From: Yang Liu @ 2024-12-22 16:34 UTC (permalink / raw)
To: gdb-patches; +Cc: tom, simon.marchi
Sorry, forgot to put a v2 in the title, please ignore this one.
On 2024/12/23 00:31, Yang Liu wrote:
> The custom linetable functionality in GDB's JIT Interface has been broken
> since commit 1acc9dca423f78e44553928f0de839b618c13766.
>
> In that commit, linetables were made independent from the objfile, which
> requires objfile->section_offsets to be initialized. However, section_offsets
> were never initialized in objfiles generated by GDB's JIT Interface
> with custom jit-readers, leading to GDB crashes when stepping into JITed code
> blocks with the following command already executed:
>
> jit-reader-load libmygdbjitreader.so
>
> This patch fixes the issue by initializing the minimum section_offsets required
> for linetable parsing procedures.
> ---
> gdb/jit.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/gdb/jit.c b/gdb/jit.c
> index 77d41bf86ba..21c17c145c9 100644
> --- a/gdb/jit.c
> +++ b/gdb/jit.c
> @@ -665,6 +665,8 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb,
>
> objfile *objfile = objfile::make (nullptr, current_program_space,
> objfile_name.c_str (), OBJF_NOT_FILENAME);
> + objfile->section_offsets.push_back (0);
> + objfile->sect_index_text = 0;
> objfile->per_bfd->gdbarch = priv_data->gdbarch;
>
> for (gdb_symtab &symtab : obj->symtabs)
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-12-22 16:39 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-12-21 8:30 [PATCH] gdb/jit: fix jit-reader linetable integrity Yang Liu
2024-12-22 2:12 ` Simon Marchi
2024-12-22 11:46 liuyang22
2024-12-22 14:22 ` Simon Marchi
2024-12-22 16:38 ` Yang Liu
2024-12-22 16:31 Yang Liu
2024-12-22 16:34 ` Yang Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox