[interp] avoid leaking MonoMethodHeader data structure by freeing or avoiding it

This commit is contained in:
Bernhard Urban 2017-10-11 20:09:57 +02:00
Родитель d055f9e21f
Коммит acb5f68e3e
3 изменённых файлов: 33 добавлений и 23 удалений

Просмотреть файл

@ -91,6 +91,7 @@ typedef struct _InterpMethod
guint32 stack_size; guint32 stack_size;
guint32 vt_stack_size; guint32 vt_stack_size;
guint32 alloca_size; guint32 alloca_size;
unsigned int init_locals : 1;
unsigned short *code; unsigned short *code;
unsigned short *new_body_start; /* after all STINARG instrs */ unsigned short *new_body_start; /* after all STINARG instrs */
MonoPIFunc func; MonoPIFunc func;

Просмотреть файл

@ -229,13 +229,12 @@ ves_real_abort (int line, MonoMethod *mh,
const unsigned short *ip, stackval *stack, stackval *sp) const unsigned short *ip, stackval *stack, stackval *sp)
{ {
MonoError error; MonoError error;
fprintf (stderr, "Execution aborted in method: %s::%s\n", mh->klass->name, mh->name); MonoMethodHeader *header = mono_method_get_header_checked (mh, &error);
fprintf (stderr, "Line=%d IP=0x%04lx, Aborted execution\n", line,
ip-(const unsigned short *)mono_method_get_header_checked (mh, &error)->code);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
g_print ("0x%04x %02x\n",
ip-(const unsigned short *)mono_method_get_header_checked (mh, &error)->code, *ip);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */ mono_error_cleanup (&error); /* FIXME: don't swallow the error */
g_printerr ("Execution aborted in method: %s::%s\n", mh->klass->name, mh->name);
g_printerr ("Line=%d IP=0x%04lx, Aborted execution\n", line, ip-(const unsigned short *) header->code);
g_print ("0x%04x %02x\n", ip-(const unsigned short *) header->code, *ip);
mono_metadata_free_mh (header);
if (sp > stack) if (sp > stack)
printf ("\t[%ld] 0x%08x %0.5f\n", sp-stack, sp[-1].data.i, sp[-1].data.f); printf ("\t[%ld] 0x%08x %0.5f\n", sp-stack, sp[-1].data.i, sp[-1].data.f);
} }
@ -776,6 +775,7 @@ interp_walk_stack_with_ctx (MonoInternalStackWalk func, MonoContext *ctx, MonoUn
fi.il_offset = frame->ip - (const unsigned short *) hd->code; fi.il_offset = frame->ip - (const unsigned short *) hd->code;
if (!fi.method->wrapper_type) if (!fi.method->wrapper_type)
fi.managed = TRUE; fi.managed = TRUE;
mono_metadata_free_mh (hd);
} }
if (func (&fi, ctx, user_data)) if (func (&fi, ctx, user_data))
@ -1240,6 +1240,7 @@ dump_frame (InterpFrame *inv)
MonoDebugSourceLocation *minfo = mono_debug_lookup_method (method); MonoDebugSourceLocation *minfo = mono_debug_lookup_method (method);
source = mono_debug_method_lookup_location (minfo, codep); source = mono_debug_method_lookup_location (minfo, codep);
#endif #endif
mono_metadata_free_mh (hd);
} }
} }
args = dump_args (inv); args = dump_args (inv);
@ -4929,9 +4930,8 @@ array_constructed:
int len = sp [-1].data.i; int len = sp [-1].data.i;
sp [-1].data.p = alloca (len); sp [-1].data.p = alloca (len);
MonoMethodHeader *header = mono_method_get_header_checked (frame->imethod->method, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */ if (frame->imethod->init_locals)
if (header && header->init_locals)
memset (sp [-1].data.p, 0, len); memset (sp [-1].data.p, 0, len);
++ip; ++ip;
MINT_IN_BREAK; MINT_IN_BREAK;
@ -5103,8 +5103,6 @@ die_on_ex:
MonoExceptionClause *clause; MonoExceptionClause *clause;
GSList *old_list = finally_ips; GSList *old_list = finally_ips;
MonoMethod *method = frame->imethod->method; MonoMethod *method = frame->imethod->method;
MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
#if DEBUG_INTERP #if DEBUG_INTERP
if (tracing) if (tracing)
@ -5118,9 +5116,10 @@ die_on_ex:
if (endfinally_ip != NULL) if (endfinally_ip != NULL)
finally_ips = g_slist_prepend(finally_ips, (void *)endfinally_ip); finally_ips = g_slist_prepend(finally_ips, (void *)endfinally_ip);
for (i = 0; i < header->num_clauses; ++i) for (i = 0; i < rtm->num_clauses; ++i)
if (frame->ex_handler == &rtm->clauses [i]) if (frame->ex_handler == &rtm->clauses [i])
break; break;
while (i > 0) { while (i > 0) {
--i; --i;
clause = &rtm->clauses [i]; clause = &rtm->clauses [i];
@ -5159,16 +5158,14 @@ die_on_ex:
guint32 ip_offset; guint32 ip_offset;
MonoExceptionClause *clause; MonoExceptionClause *clause;
GSList *old_list = finally_ips; GSList *old_list = finally_ips;
MonoMethod *method = frame->imethod->method;
MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
#if DEBUG_INTERP #if DEBUG_INTERP
if (tracing) if (tracing)
g_print ("* Handle fault\n"); g_print ("* Handle fault\n");
#endif #endif
ip_offset = frame->ip - rtm->code; ip_offset = frame->ip - rtm->code;
for (i = 0; i < header->num_clauses; ++i) {
for (i = 0; i < rtm->num_clauses; ++i) {
clause = &rtm->clauses [i]; clause = &rtm->clauses [i];
if (clause->flags == MONO_EXCEPTION_CLAUSE_FAULT && MONO_OFFSET_IN_CLAUSE (clause, ip_offset)) { if (clause->flags == MONO_EXCEPTION_CLAUSE_FAULT && MONO_OFFSET_IN_CLAUSE (clause, ip_offset)) {
ip = rtm->code + clause->handler_offset; ip = rtm->code + clause->handler_offset;

Просмотреть файл

@ -1062,7 +1062,6 @@ no_intrinsic:
(target_method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) == 0 && (target_method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) == 0 &&
!(target_method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING)) { !(target_method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING)) {
int called_inited = mono_class_vtable (domain, target_method->klass)->initialized; int called_inited = mono_class_vtable (domain, target_method->klass)->initialized;
MonoMethodHeader *mheader = mono_method_get_header (target_method);
if (/*mono_metadata_signature_equal (method->signature, target_method->signature) */ method == target_method && *(td->ip + 5) == CEE_RET) { if (/*mono_metadata_signature_equal (method->signature, target_method->signature) */ method == target_method && *(td->ip + 5) == CEE_RET) {
int offset; int offset;
@ -1080,12 +1079,17 @@ no_intrinsic:
td->ip += 5; td->ip += 5;
return; return;
} else { } else {
MonoMethodHeader *mheader = mono_method_get_header (target_method);
/* mheader might not exist if this is a delegate invoc, etc */ /* mheader might not exist if this is a delegate invoc, etc */
gboolean has_vt_arg = FALSE; gboolean has_vt_arg = FALSE;
for (i = 0; i < csignature->param_count; i++) for (i = 0; i < csignature->param_count; i++)
has_vt_arg |= !mini_type_is_reference (csignature->params [i]); has_vt_arg |= !mini_type_is_reference (csignature->params [i]);
if (mheader && *mheader->code == CEE_RET && called_inited && !has_vt_arg) { gboolean empty_callee = mheader && *mheader->code == CEE_RET;
if (mheader)
mono_metadata_free_mh (mheader);
if (empty_callee && called_inited && !has_vt_arg) {
if (td->verbose_level) if (td->verbose_level)
g_print ("Inline (empty) call of %s.%s\n", target_method->klass->name, target_method->name); g_print ("Inline (empty) call of %s.%s\n", target_method->klass->name, target_method->name);
for (i = 0; i < csignature->param_count; i++) { for (i = 0; i < csignature->param_count; i++) {
@ -1336,7 +1340,7 @@ interp_save_debug_info (InterpMethod *rtm, MonoMethodHeader *header, TransformDa
} }
for (i = 0; i < dinfo->num_locals; i++) { for (i = 0; i < dinfo->num_locals; i++) {
MonoDebugVarInfo *var = &dinfo->locals [i]; MonoDebugVarInfo *var = &dinfo->locals [i];
var->type = header->locals [i]; var->type = mono_metadata_type_dup (NULL, header->locals [i]);
} }
for (i = 0; i < dinfo->num_line_numbers; i++) for (i = 0; i < dinfo->num_line_numbers; i++)
@ -1550,9 +1554,8 @@ emit_seq_point (TransformData *td, int il_offset, InterpBasicBlock *cbb, gboolea
} while (0) } while (0)
static void static void
generate (MonoMethod *method, InterpMethod *rtm, unsigned char *is_bb_start, MonoGenericContext *generic_context, MonoError *error) generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, unsigned char *is_bb_start, MonoGenericContext *generic_context, MonoError *error)
{ {
MonoMethodHeader *header = mono_method_get_header (method);
MonoMethodSignature *signature = mono_method_signature (method); MonoMethodSignature *signature = mono_method_signature (method);
MonoImage *image = method->klass->image; MonoImage *image = method->klass->image;
MonoDomain *domain = rtm->domain; MonoDomain *domain = rtm->domain;
@ -4140,6 +4143,7 @@ generate (MonoMethod *method, InterpMethod *rtm, unsigned char *is_bb_start, Mon
memcpy (rtm->code, td->new_code, (td->new_ip - td->new_code) * sizeof(gushort)); memcpy (rtm->code, td->new_code, (td->new_ip - td->new_code) * sizeof(gushort));
g_free (td->new_code); g_free (td->new_code);
rtm->new_body_start = rtm->code + body_start_offset; rtm->new_body_start = rtm->code + body_start_offset;
rtm->init_locals = header->init_locals;
rtm->num_clauses = header->num_clauses; rtm->num_clauses = header->num_clauses;
for (i = 0; i < header->num_clauses; i++) { for (i = 0; i < header->num_clauses; i++) {
MonoExceptionClause *c = rtm->clauses + i; MonoExceptionClause *c = rtm->clauses + i;
@ -4216,7 +4220,7 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context)
int i, align, size, offset; int i, align, size, offset;
MonoMethod *method = imethod->method; MonoMethod *method = imethod->method;
MonoImage *image = method->klass->image; MonoImage *image = method->klass->image;
MonoMethodHeader *header = mono_method_get_header (method); MonoMethodHeader *header = NULL;
MonoMethodSignature *signature = mono_method_signature (method); MonoMethodSignature *signature = mono_method_signature (method);
register const unsigned char *ip, *end; register const unsigned char *ip, *end;
const MonoOpcode *opcode; const MonoOpcode *opcode;
@ -4331,6 +4335,10 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context)
g_error ("TODO"); g_error ("TODO");
} }
} }
if (!header)
header = mono_method_get_header (method);
g_assert ((signature->param_count + signature->hasthis) < 1000); g_assert ((signature->param_count + signature->hasthis) < 1000);
g_assert (header->max_stack < 10000); g_assert (header->max_stack < 10000);
/* intern the strings in the method. */ /* intern the strings in the method. */
@ -4447,6 +4455,8 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context)
if (imethod->transformed) { if (imethod->transformed) {
mono_os_mutex_unlock(&calc_section); mono_os_mutex_unlock(&calc_section);
g_free (is_bb_start); g_free (is_bb_start);
if (header)
mono_metadata_free_mh (header);
MONO_PROFILER_RAISE (jit_done, (method, imethod->jinfo)); MONO_PROFILER_RAISE (jit_done, (method, imethod->jinfo));
return NULL; return NULL;
} }
@ -4503,7 +4513,9 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context)
g_assert (imethod->args_size < 10000); g_assert (imethod->args_size < 10000);
error_init (&error); error_init (&error);
generate (method, imethod, is_bb_start, generic_context, &error); generate (method, header, imethod, is_bb_start, generic_context, &error);
mono_metadata_free_mh (header);
if (!mono_error_ok (&error)) { if (!mono_error_ok (&error)) {
mono_os_mutex_unlock (&calc_section); mono_os_mutex_unlock (&calc_section);