Skip to content

Commit 9d78aa1

Browse files
mkokryashkinigormunkin
authored andcommitted
sysprof: enrich symtab on a new trace or a proto
This commit adds functionality introduced in 0847e71 ('memprof: enrich symtab when meeting new prototype') and 0243fb7 ('memprof: enrich symtab when new trace is compiled') for sysprof. Both the proto and the trace symtab extensions cannot be run from the sysprof's signal handler, so it is required to prevent sysprof from dumping anything in its signal handler during the process to keep the event stream intact. That is achieved by setting the sysprof's internal state to `SPS_IDLE`. Follows up tarantool/tarantool#781 Reviewed-by: Sergey Kaplun <skaplun@tarantool.org> Reviewed-by: Igor Munkin <imun@tarantool.org> Signed-off-by: Igor Munkin <imun@tarantool.org>
1 parent 8c07173 commit 9d78aa1

File tree

7 files changed

+106
-14
lines changed

7 files changed

+106
-14
lines changed

src/Makefile.dep.original

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
5959
lj_bcread.o: lj_bcread.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
6060
lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_bc.h \
6161
lj_ctype.h lj_cdata.h lualib.h lj_lex.h lj_bcdump.h lj_state.h \
62-
lj_strfmt.h lj_memprof.h lj_wbuf.h
62+
lj_strfmt.h lj_memprof.h lj_wbuf.h lmisclib.h lj_sysprof.h lj_jit.h \
63+
lj_ir.h
6364
lj_bcwrite.o: lj_bcwrite.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
6465
lj_gc.h lj_buf.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h \
6566
lj_ir.h lj_strfmt.h lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
@@ -175,7 +176,8 @@ lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
175176
lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
176177
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \
177178
lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \
178-
lj_vm.h lj_vmevent.h lj_memprof.h lj_wbuf.h
179+
lj_vm.h lj_vmevent.h lj_memprof.h lj_wbuf.h lmisclib.h lj_sysprof.h \
180+
lj_jit.h lj_ir.h
179181
lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
180182
lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \
181183
lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h \
@@ -208,16 +210,17 @@ lj_strscan.o: lj_strscan.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
208210
lj_symtab.o: lj_symtab.c lj_symtab.h lj_wbuf.h lj_def.h lua.h luaconf.h \
209211
lj_obj.h lj_arch.h
210212
lj_sysprof.o: lj_sysprof.c lj_arch.h lua.h luaconf.h lj_sysprof.h \
211-
lj_obj.h lj_def.h lmisclib.h lj_debug.h lj_dispatch.h lj_bc.h lj_jit.h \
212-
lj_ir.h lj_frame.h lj_trace.h lj_traceerr.h lj_wbuf.h lj_profile_timer.h \
213+
lj_jit.h lj_obj.h lj_def.h lj_ir.h lmisclib.h lj_debug.h lj_dispatch.h \
214+
lj_bc.h lj_frame.h lj_trace.h lj_traceerr.h lj_wbuf.h lj_profile_timer.h \
213215
lj_symtab.h
214216
lj_tab.o: lj_tab.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
215217
lj_err.h lj_errmsg.h lj_tab.h
216218
lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
217219
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \
218220
lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \
219221
lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \
220-
lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h lj_memprof.h lj_wbuf.h
222+
lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h lj_memprof.h lj_wbuf.h \
223+
lmisclib.h lj_sysprof.h
221224
lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
222225
lj_gc.h lj_udata.h
223226
lj_utils_leb128.o: lj_utils_leb128.c lj_utils.h lj_def.h lua.h luaconf.h

src/lj_bcread.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
#if LJ_HASMEMPROF
2626
#include "lj_memprof.h"
2727
#endif
28+
#if LJ_HASSYSPROF
29+
#include "lj_sysprof.h"
30+
#endif
2831

2932
/* Reuse some lexer fields for our own purposes. */
3033
#define bcread_flags(ls) ls->level
@@ -390,6 +393,10 @@ GCproto *lj_bcread_proto(LexState *ls)
390393
lj_memprof_add_proto(pt);
391394
#endif
392395

396+
#if LJ_HASSYSPROF
397+
lj_sysprof_add_proto(pt);
398+
#endif
399+
393400
return pt;
394401
}
395402

src/lj_parse.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
#if LJ_HASMEMPROF
3131
#include "lj_memprof.h"
3232
#endif
33+
#if LJ_HASSYSPROF
34+
#include "lj_sysprof.h"
35+
#endif
3336

3437
/* -- Parser structures and definitions ----------------------------------- */
3538

@@ -1598,6 +1601,9 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
15981601
#if LJ_HASMEMPROF
15991602
lj_memprof_add_proto(pt);
16001603
#endif
1604+
#if LJ_HASSYSPROF
1605+
lj_sysprof_add_proto(pt);
1606+
#endif
16011607

16021608
L->top--; /* Pop table of constants. */
16031609
ls->vtop = fs->vbase; /* Reset variable stack. */

src/lj_sysprof.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ static void stream_guest(struct sysprof *sp, uint32_t vmstate)
236236
static void stream_host(struct sysprof *sp, uint32_t vmstate)
237237
{
238238
struct lua_State *L = gco2th(gcref(sp->g->cur_L));
239-
lj_symtab_dump_newc(&sp->lib_adds, &sp->out, LJP_SYMTAB_EVENT, L);
239+
lj_symtab_dump_newc(&sp->lib_adds, &sp->out, LJP_SYMTAB_CFUNC_EVENT, L);
240240
lj_wbuf_addbyte(&sp->out, (uint8_t)vmstate);
241241
stream_backtrace_host(sp);
242242
}
@@ -494,6 +494,40 @@ int lj_sysprof_report(struct luam_Sysprof_Counters *counters)
494494
return PROFILE_SUCCESS;
495495
}
496496

497+
void lj_sysprof_add_proto(const struct GCproto *pt)
498+
{
499+
struct sysprof *sp = &sysprof;
500+
501+
if (sp->state != SPS_PROFILE)
502+
return;
503+
504+
/*
505+
** XXX: Avoid sampling during the symtab extension. That shouldn't have any
506+
** significant effect on profile precision, but if it does, it's better to
507+
** implement an async-safe queue for the symtab events.
508+
*/
509+
sp->state = SPS_IDLE;
510+
lj_wbuf_addbyte(&sp->out, LJP_SYMTAB_LFUNC_EVENT);
511+
lj_symtab_dump_proto(&sp->out, pt);
512+
sp->state = SPS_PROFILE;
513+
}
514+
515+
#if LJ_HASJIT
516+
void lj_sysprof_add_trace(const struct GCtrace *tr)
517+
{
518+
struct sysprof *sp = &sysprof;
519+
520+
if (sp->state != SPS_PROFILE)
521+
return;
522+
523+
/* See the comment about the sysprof state above. */
524+
sp->state = SPS_IDLE;
525+
lj_wbuf_addbyte(&sp->out, LJP_SYMTAB_TRACE_EVENT);
526+
lj_symtab_dump_trace(&sp->out, tr);
527+
sp->state = SPS_PROFILE;
528+
}
529+
#endif /* LJ_HASJIT */
530+
497531
#else /* LJ_HASSYSPROF */
498532

499533
int lj_sysprof_configure(const struct luam_Sysprof_Config *config)
@@ -520,4 +554,16 @@ int lj_sysprof_report(struct luam_Sysprof_Counters *counters)
520554
return PROFILE_ERRUSE;
521555
}
522556

557+
void lj_sysprof_add_proto(const struct GCproto *pt)
558+
{
559+
UNUSED(pt);
560+
}
561+
562+
#if LJ_HASJIT
563+
void lj_sysprof_add_trace(const struct GCtrace *tr)
564+
{
565+
UNUSED(tr);
566+
}
567+
#endif /* LJ_HASJIT */
568+
523569
#endif /* LJ_HASSYSPROF */

src/lj_sysprof.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
#ifndef _LJ_SYSPROF_H
1616
#define _LJ_SYSPROF_H
1717

18+
#if LJ_HASJIT
19+
#include "lj_jit.h"
20+
#endif
1821
#include "lj_obj.h"
1922
#include "lmisclib.h"
2023

21-
#define LJP_FORMAT_VERSION 0x1
24+
#define LJP_FORMAT_VERSION 0x2
2225

2326
/*
2427
** Event stream format:
@@ -80,9 +83,13 @@
8083
#define LJP_FRAME_LUA_LAST 0x80
8184
#define LJP_FRAME_HOST_LAST NULL
8285

83-
#define LJP_SYMTAB_EVENT ((uint8_t)10)
86+
#define LJP_SYMTAB_LFUNC_EVENT ((uint8_t)10)
87+
#define LJP_SYMTAB_CFUNC_EVENT ((uint8_t)11)
88+
#define LJP_SYMTAB_TRACE_EVENT ((uint8_t)12)
8489
#define LJP_EPILOGUE_BYTE 0x80
8590

91+
LJ_STATIC_ASSERT(LJ_VMST__MAX <= LJP_SYMTAB_LFUNC_EVENT);
92+
8693
int lj_sysprof_configure(const struct luam_Sysprof_Config *config);
8794

8895
int lj_sysprof_start(lua_State *L, const struct luam_Sysprof_Options *opt);
@@ -91,4 +98,10 @@ int lj_sysprof_stop(lua_State *L);
9198

9299
int lj_sysprof_report(struct luam_Sysprof_Counters *counters);
93100

101+
void lj_sysprof_add_proto(const struct GCproto *pt);
102+
103+
#if LJ_HASJIT
104+
void lj_sysprof_add_trace(const struct GCtrace *tr);
105+
#endif /* LJ_HASJIT */
106+
94107
#endif

src/lj_trace.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
#if LJ_HASMEMPROF
3434
#include "lj_memprof.h"
3535
#endif
36+
#if LJ_HASSYSPROF
37+
#include "lj_sysprof.h"
38+
#endif
3639

3740
/* -- Error handling ------------------------------------------------------ */
3841

@@ -171,6 +174,10 @@ static void trace_save(jit_State *J, GCtrace *T)
171174
#if LJ_HASMEMPROF
172175
lj_memprof_add_trace(T);
173176
#endif
177+
178+
#if LJ_HASSYSPROF
179+
lj_sysprof_add_trace(T);
180+
#endif
174181
}
175182

176183
void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T)

tools/sysprof/parse.lua

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ local symtab = require "utils.symtab"
66
local string_format = string.format
77

88
local LJP_MAGIC = "ljp"
9-
local LJP_CURRENT_VERSION = 1
9+
local LJP_CURRENT_VERSION = 2
1010

1111
local M = {}
1212

@@ -33,7 +33,9 @@ M.FRAME = {
3333
}
3434

3535
local STREAM_END = 0x80
36-
local SYMTAB_EVENT = 10
36+
local SYMTAB_LFUNC_EVENT = 10
37+
local SYMTAB_CFUNC_EVENT = 11
38+
local SYMTAB_TRACE_EVENT = 12
3739

3840
local function new_event()
3941
return {
@@ -128,8 +130,16 @@ local function parse_trace(reader, event, symbols)
128130
-- parse_lua_callchain(reader, event)
129131
end
130132

131-
local function parse_symtab(reader, symbols)
132-
symtab.parse_sym_cfunc(reader, symbols)
133+
local function parse_symtab(reader, symbols, vmstate)
134+
if vmstate == SYMTAB_LFUNC_EVENT then
135+
symtab.parse_sym_lfunc(reader, symbols)
136+
elseif vmstate == SYMTAB_CFUNC_EVENT then
137+
symtab.parse_sym_cfunc(reader, symbols)
138+
elseif vmstate == SYMTAB_TRACE_EVENT then
139+
symtab.parse_sym_trace(reader, symbols)
140+
else
141+
error("Unknown symtab event")
142+
end
133143
end
134144

135145
local event_parsers = {
@@ -152,8 +162,8 @@ local function parse_event(reader, events, symbols)
152162
if vmstate == STREAM_END then
153163
-- TODO: samples & overruns
154164
return false
155-
elseif vmstate == SYMTAB_EVENT then
156-
parse_symtab(reader, symbols)
165+
elseif SYMTAB_LFUNC_EVENT <= vmstate and vmstate <= SYMTAB_TRACE_EVENT then
166+
parse_symtab(reader, symbols, vmstate)
157167
return true
158168
end
159169

0 commit comments

Comments
 (0)