{
const int SystemDiagnosticsStackDepth = 3;
- if (skipFrames + SystemDiagnosticsStackDepth < 0 || !get_frame_info(skipFrames + SystemDiagnosticsStackDepth, needFileInfo, out MethodBase? method, out int ilOffset, out int nativeOffset, out string? fileName, out int line, out int column))
+ if (skipFrames + SystemDiagnosticsStackDepth < 0)
+ return;
+
+ MethodBase? method = null;
+ string? fileName = null;
+ bool success = GetFrameInfo(skipFrames + SystemDiagnosticsStackDepth, needFileInfo,
+ ObjectHandleOnStack.Create (ref method), ObjectHandleOnStack.Create (ref fileName),
+ out int ilOffset, out int nativeOffset, out int line, out int column);
+ if (!success)
return;
_method = method;
#pragma warning restore IDE0060
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool get_frame_info(int skipFrames, bool needFileInfo,
- out MethodBase method, out int ilOffset, out int nativeOffset, out string file, out int line, out int column);
-
+ private static extern bool GetFrameInfo(int skipFrames, bool needFileInfo,
+ ObjectHandleOnStack out_method, ObjectHandleOnStack out_file,
+ out int ilOffset, out int nativeOffset, out int line, out int column);
}
}
public partial class StackTrace
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern MonoStackFrame[] get_trace(Exception e, int skipFrames, bool needFileInfo);
+ internal static extern void GetTrace(ObjectHandleOnStack ex, ObjectHandleOnStack res, int skipFrames, bool needFileInfo);
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "StackFrame.GetMethod is getting compared to null but nothing else on it is touched.")]
private void InitializeForException(Exception e, int skipFrames, bool needFileInfo)
{
- MonoStackFrame[] frames = get_trace(e, skipFrames, needFileInfo);
- _numOfFrames = frames.Length;
+ MonoStackFrame[]? frames = null;
+ GetTrace (ObjectHandleOnStack.Create (ref e), ObjectHandleOnStack.Create (ref frames), skipFrames, needFileInfo);
+ _numOfFrames = frames!.Length;
int foreignFrames;
MonoStackFrame[]? foreignExceptions = e.foreignExceptionsFrames;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
using System.Diagnostics.Tracing;
namespace System
if (_traceIPs != null)
{
- stackFrames = Diagnostics.StackTrace.get_trace(this, 0, true);
+ Exception self = this;
+ MonoStackFrame[]? frames = null;
+ Diagnostics.StackTrace.GetTrace (ObjectHandleOnStack.Create (ref self), ObjectHandleOnStack.Create (ref frames), 0, true);
+ stackFrames = frames!;
if (stackFrames.Length > 0)
stackFrames[stackFrames.Length - 1].isLastFrameFromForeignException = true;
ICALL_EXPORT MonoBoolean ves_icall_System_Reflection_LoaderAllocatorScout_Destroy (gpointer native);
+ICALL_EXPORT void ves_icall_System_Diagnostics_StackTrace_GetTrace (MonoObjectHandleOnStack ex_handle, MonoObjectHandleOnStack res, int skip_frames, MonoBoolean need_file_info);
+
+ICALL_EXPORT MonoBoolean ves_icall_System_Diagnostics_StackFrame_GetFrameInfo (gint32 skip, MonoBoolean need_file_info,
+ MonoObjectHandleOnStack out_method, MonoObjectHandleOnStack file,
+ gint32 *iloffset, gint32 *native_offset,
+ gint32 *line, gint32 *column);
+
#endif // __MONO_METADATA_ICALL_DECL_H__
NOHANDLES(ICALL(DEBUGR_2, "IsLogging", ves_icall_System_Diagnostics_Debugger_IsLogging))
NOHANDLES(ICALL(DEBUGR_3, "Log_icall", ves_icall_System_Diagnostics_Debugger_Log))
+ICALL_TYPE(STACKFRAME, "System.Diagnostics.StackFrame", STACKFRAME_1)
+NOHANDLES(ICALL(STACKFRAME_1, "GetFrameInfo", ves_icall_System_Diagnostics_StackFrame_GetFrameInfo))
+
+ICALL_TYPE(STACKTRACE, "System.Diagnostics.StackTrace", STACKTRACE_1)
+NOHANDLES(ICALL(STACKTRACE_1, "GetTrace", ves_icall_System_Diagnostics_StackTrace_GetTrace))
+
ICALL_TYPE(EVENTPIPE, "System.Diagnostics.Tracing.EventPipeInternal", EVENTPIPE_1)
HANDLES(EVENTPIPE_1, "CreateProvider", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_CreateProvider, gconstpointer, 3, (MonoString, gpointer, gpointer))
NOHANDLES(ICALL(EVENTPIPE_2, "DefineEvent", ves_icall_System_Diagnostics_Tracing_EventPipeInternal_DefineEvent))
return mono_cpu_limit ();
}
+void
+ves_icall_System_Diagnostics_StackTrace_GetTrace (MonoObjectHandleOnStack ex_handle, MonoObjectHandleOnStack res, int skip_frames, MonoBoolean need_file_info)
+{
+ MonoArray *trace = mono_get_runtime_callbacks ()->get_trace ((MonoException*)*ex_handle, skip_frames, need_file_info);
+ HANDLE_ON_STACK_SET (res, trace);
+}
+
+MonoBoolean
+ves_icall_System_Diagnostics_StackFrame_GetFrameInfo (gint32 skip, MonoBoolean need_file_info,
+ MonoObjectHandleOnStack out_method, MonoObjectHandleOnStack out_file,
+ gint32 *iloffset, gint32 *native_offset,
+ gint32 *line, gint32 *column)
+{
+ MonoMethod *method = NULL;
+ MonoDebugSourceLocation *location;
+ ERROR_DECL (error);
+
+ gboolean res = mono_get_runtime_callbacks ()->get_frame_info (skip, &method, &location, iloffset, native_offset);
+ if (!res)
+ return FALSE;
+
+ if (location)
+ *iloffset = location->il_offset;
+ else
+ *iloffset = 0;
+
+ if (need_file_info) {
+ if (location) {
+ MonoString *filename = mono_string_new_checked (location->source_file, error);
+ if (!is_ok (error)) {
+ mono_error_set_pending_exception (error);
+ return FALSE;
+ }
+ HANDLE_ON_STACK_SET (out_file, filename);
+ *line = location->row;
+ *column = location->column;
+ } else {
+ *line = *column = 0;
+ }
+ }
+
+ mono_debug_free_source_location (location);
+
+ MonoReflectionMethod *rm = mono_method_get_object_checked (method, NULL, error);
+ if (!is_ok (error)) {
+ mono_error_set_pending_exception (error);
+ return FALSE;
+ }
+ HANDLE_ON_STACK_SET (out_method, rm);
+
+ return TRUE;
+}
+
// Generate wrappers.
#define ICALL_TYPE(id,name,first) /* nothing */
#include <mono/metadata/threads-types.h>
#include <mono/metadata/handle.h>
#include <mono/metadata/abi-details.h>
+#include <mono/metadata/mono-debug.h>
#include "mono/utils/mono-compiler.h"
#include "mono/utils/mono-error.h"
#include "mono/utils/mono-error-internals.h"
void (*interp_jit_info_foreach)(InterpJitInfoFunc func, gpointer user_data);
gboolean (*interp_sufficient_stack)(gsize size);
void (*init_class) (MonoClass *klass);
+ MonoArray *(*get_trace) (MonoException *exc, gint32 skip, MonoBoolean need_file_info);
+ MonoBoolean (*get_frame_info) (gint32 skip, MonoMethod **out_method,
+ MonoDebugSourceLocation **out_location,
+ gint32 *iloffset, gint32 *native_offset);
} MonoRuntimeCallbacks;
typedef gboolean (*MonoInternalStackWalk) (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data);
return captured_has_traces || otherwise_has_traces;
}
-MonoArray *
-ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info)
+MonoArray*
+mono_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info)
{
ERROR_DECL (error);
MonoArray *res;
}
MonoBoolean
-ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
- MonoReflectionMethod **method,
- gint32 *iloffset, gint32 *native_offset,
- MonoString **file, gint32 *line, gint32 *column)
+mono_get_frame_info (gint32 skip,
+ MonoMethod **out_method,
+ MonoDebugSourceLocation **out_location,
+ gint32 *iloffset, gint32 *native_offset)
{
- ERROR_DECL (error);
MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
MonoLMF *lmf = mono_get_lmf ();
MonoJitInfo *ji = NULL;
*native_offset = GPTRDIFF_TO_INT32 (frame_ip - (guint8*)ji->code_start);
} else {
mono_arch_flush_register_windows ();
- MONO_INIT_CONTEXT_FROM_FUNC (&ctx, ves_icall_get_frame_info);
+ MONO_INIT_CONTEXT_FROM_FUNC (&ctx, mono_get_frame_info);
unwinder_init (&unwinder);
}
}
- MonoReflectionMethod *rm = mono_method_get_object_checked (actual_method, NULL, error);
- if (!is_ok (error)) {
- mono_error_set_pending_exception (error);
- return FALSE;
- }
- mono_gc_wbarrier_generic_store_internal (method, (MonoObject*) rm);
+ *out_method = actual_method;
if (il_offset != -1) {
location = mono_debug_lookup_source_location_by_il (jmethod, il_offset, NULL);
} else {
location = mono_debug_lookup_source_location (jmethod, *native_offset, NULL);
}
- if (location)
- *iloffset = location->il_offset;
- else
- *iloffset = 0;
-
- if (need_file_info) {
- if (location) {
- MonoString *filename = mono_string_new_checked (location->source_file, error);
- if (!is_ok (error)) {
- mono_error_set_pending_exception (error);
- return FALSE;
- }
- mono_gc_wbarrier_generic_store_internal (file, (MonoObject*)filename);
- *line = location->row;
- *column = location->column;
- } else {
- *file = NULL;
- *line = *column = 0;
- }
- }
- mono_debug_free_source_location (location);
+ *out_location = location;
return TRUE;
}
callbacks.get_jit_stats = get_jit_stats;
callbacks.get_exception_stats = get_exception_stats;
callbacks.init_class = init_class;
+ callbacks.get_trace = mono_get_trace;
+ callbacks.get_frame_info = mono_get_frame_info;
mono_install_callbacks (&callbacks);
static void
register_icalls (void)
{
- mono_add_internal_call_internal ("System.Diagnostics.StackFrame::get_frame_info",
- ves_icall_get_frame_info);
- mono_add_internal_call_internal ("System.Diagnostics.StackTrace::get_trace",
- ves_icall_get_trace);
- mono_add_internal_call_internal ("Mono.Runtime::mono_runtime_install_handlers",
- mono_runtime_install_handlers);
-
/*
* It's important that we pass `TRUE` as the last argument here, as
* it causes the JIT to omit a wrapper for these icalls. If the JIT
gpointer mono_get_throw_corlib_exception (void);
gpointer mono_get_throw_exception_addr (void);
gpointer mono_get_rethrow_preserve_exception_addr (void);
-ICALL_EXPORT
-MonoArray *ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info);
-
-ICALL_EXPORT
-MonoBoolean ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
- MonoReflectionMethod **method,
- gint32 *iloffset, gint32 *native_offset,
- MonoString **file, gint32 *line, gint32 *column);
+MonoArray* mono_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info);
+MonoBoolean mono_get_frame_info (gint32 skip, MonoMethod **out_method,
+ MonoDebugSourceLocation **out_location,
+ gint32 *iloffset, gint32 *native_offset);
void mono_set_cast_details (MonoClass *from, MonoClass *to);
void mono_decompose_typechecks (MonoCompile *cfg);