Index: runtime/vm/dart_api_impl.cc |
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc |
index 74117cc890c7626dfab5cecd7e978bde797cb284..53a650da1c86c2b1104cea09578c84dae59b14da 100644 |
--- a/runtime/vm/dart_api_impl.cc |
+++ b/runtime/vm/dart_api_impl.cc |
@@ -15,6 +15,7 @@ |
#include "vm/dart_api_message.h" |
#include "vm/dart_api_state.h" |
#include "vm/dart_entry.h" |
+#include "vm/debugger.h" |
#include "vm/debuginfo.h" |
#include "vm/exceptions.h" |
#include "vm/flags.h" |
@@ -375,19 +376,95 @@ DART_EXPORT Dart_Handle Dart_ErrorGetException(Dart_Handle handle) { |
} |
-DART_EXPORT Dart_Handle Dart_ErrorGetStacktrace(Dart_Handle handle) { |
+DART_EXPORT Dart_Handle Dart_ErrorGetStacktrace( |
+ Dart_Handle handle, |
+ Dart_ExceptionStackTrace *trace) { |
Isolate* isolate = Isolate::Current(); |
DARTSCOPE(isolate); |
const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
if (obj.IsUnhandledException()) { |
const UnhandledException& error = UnhandledException::Cast(obj); |
- return Api::NewHandle(isolate, error.stacktrace()); |
+ Stacktrace& dart_stacktrace = Stacktrace::Handle(isolate); |
+ dart_stacktrace ^= error.stacktrace(); |
+ if (dart_stacktrace.IsNull()) { |
+ *trace = NULL; |
+ } else { |
+ ExceptionStackTrace* cpp_stacktrace = |
+ dart_stacktrace.BuildExceptionStackTrace(); |
+ *trace = reinterpret_cast<Dart_ExceptionStackTrace>(cpp_stacktrace); |
+ } |
+ return Api::Success(); |
} else if (obj.IsError()) { |
return Api::NewError("This error is not an unhandled exception error."); |
} else { |
return Api::NewError("Can only get stacktraces from error handles."); |
} |
} |
+DART_EXPORT Dart_Handle Dart_CurrentStacktrace( |
+ Dart_ExceptionStackTrace *trace) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ ExceptionStackTrace* cpp_stacktrace = |
+ isolate->debugger()->BuildExceptionStackTrace(); |
+ *trace = reinterpret_cast<Dart_ExceptionStackTrace>(cpp_stacktrace); |
+ return Api::Success(); |
+} |
+ |
+ |
+DART_EXPORT Dart_Handle Dart_StacktraceLength(Dart_ExceptionStackTrace trace, |
+ intptr_t* length) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ if (trace == NULL) { |
+ return Api::NewError("%s expects argument 'trace' to be non-null.", |
+ CURRENT_FUNC); |
+ } |
+ ExceptionStackTrace *stack_trace = |
+ reinterpret_cast<ExceptionStackTrace*>(trace); |
+ if (length == NULL) { |
+ return Api::NewError("%s expects argument 'length' to be non-null.", |
+ CURRENT_FUNC); |
+ } |
+ *length = stack_trace->Length(); |
+ return Api::Success(); |
+} |
+ |
+ |
+DART_EXPORT Dart_Handle Dart_StacktraceFrameInfo( |
+ Dart_ExceptionStackTrace trace, |
+ intptr_t frame_index, |
+ Dart_Handle* function_name, |
+ Dart_Handle* script_url, |
+ intptr_t* line_number, |
+ intptr_t* col_number) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ if (trace == NULL) { |
+ return Api::NewError("%s expects argument 'trace' to be non-null.", |
+ CURRENT_FUNC); |
+ } |
+ ExceptionStackTrace *stack_trace = |
+ reinterpret_cast<ExceptionStackTrace*>(trace); |
+ if (frame_index < 0 || frame_index >= stack_trace->Length()) { |
+ return Api::NewError( |
+ "%s: frame index was out of bounds (%" Pd ")", |
+ CURRENT_FUNC, frame_index); |
+ } |
+ ExceptionStackFrame *frame = stack_trace->FrameAt(frame_index); |
+ if (function_name != NULL) { |
+ *function_name = Api::NewHandle(isolate, frame->function_name()); |
+ } |
+ if (script_url != NULL) { |
+ *script_url = Api::NewHandle(isolate, frame->script_uri()); |
+ } |
+ if (line_number != NULL) { |
+ *line_number = frame->line_number(); |
+ } |
+ if (col_number != NULL) { |
+ *col_number = frame->column_number(); |
+ } |
+ return Api::Success(); |
+} |
// TODO(turnidge): This clones Api::NewError. I need to use va_copy to |