+/* Call SNIFFER from UNWINDER. If it succeeded set UNWINDER for
+ THIS_FRAME and return 1. Otherwise the function keeps THIS_FRAME
+ unchanged and returns 0. */
+
+static int
+frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache,
+ const struct frame_unwind *unwinder)
+{
+ int res = 0;
+
+ frame_prepare_for_sniffer (this_frame, unwinder);
+
+ TRY
+ {
+ res = unwinder->sniffer (unwinder, this_frame, this_cache);
+ }
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ /* Catch all exceptions, caused by either interrupt or error.
+ Reset *THIS_CACHE. */
+ *this_cache = NULL;
+ if (ex.error == NOT_AVAILABLE_ERROR)
+ {
+ /* This usually means that not even the PC is available,
+ thus most unwinders aren't able to determine if they're
+ the best fit. Keep trying. Fallback prologue unwinders
+ should always accept the frame. */
+ frame_cleanup_after_sniffer (this_frame);
+ return 0;
+ }
+ throw_exception (ex);
+ }
+ END_CATCH
+
+ if (res)
+ return 1;
+ else
+ {
+ /* Don't set *THIS_CACHE to NULL here, because sniffer has to do
+ so. */
+ frame_cleanup_after_sniffer (this_frame);
+ return 0;
+ }
+ gdb_assert_not_reached ("frame_unwind_try_unwinder");
+}
+
+/* Iterate through sniffers for THIS_FRAME frame until one returns with an
+ unwinder implementation. THIS_FRAME->UNWIND must be NULL, it will get set
+ by this function. Possibly initialize THIS_CACHE. */
+
+void