1254661Semaste/* $NetBSD: unwind.c,v 1.1 2012/05/26 22:02:29 christos Exp $ */ 2254661Semaste 3254661Semaste/*- 4254661Semaste * Copyright (c) 2012 The NetBSD Foundation, Inc. 5254661Semaste * All rights reserved. 6254661Semaste * 7254661Semaste * This code is derived from software contributed to The NetBSD Foundation 8254661Semaste * by Christos Zoulas. 9254661Semaste * 10254661Semaste * Redistribution and use in source and binary forms, with or without 11254661Semaste * modification, are permitted provided that the following conditions 12254661Semaste * are met: 13254661Semaste * 1. Redistributions of source code must retain the above copyright 14254661Semaste * notice, this list of conditions and the following disclaimer. 15254661Semaste * 2. Redistributions in binary form must reproduce the above copyright 16254661Semaste * notice, this list of conditions and the following disclaimer in the 17254661Semaste * documentation and/or other materials provided with the distribution. 18254661Semaste * 19254661Semaste * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20254661Semaste * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21254661Semaste * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22254661Semaste * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23254661Semaste * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24254661Semaste * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25254661Semaste * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26254661Semaste * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27254661Semaste * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28254661Semaste * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29254661Semaste * POSSIBILITY OF SUCH DAMAGE. 30254661Semaste */ 31254661Semaste#include <sys/cdefs.h> 32254661Semaste#include <sys/types.h> 33254661Semaste#include <stdio.h> 34254661Semaste 35254661Semaste#include "unwind.h" 36254661Semaste#include "execinfo.h" 37254661Semaste 38254661Semastestruct tracer_context { 39254661Semaste void **arr; 40254661Semaste size_t len; 41254661Semaste size_t n; 42254661Semaste}; 43254661Semaste 44254661Semastestatic _Unwind_Reason_Code 45254661Semastetracer(struct _Unwind_Context *ctx, void *arg) 46254661Semaste{ 47254661Semaste struct tracer_context *t = arg; 48254661Semaste if (t->n == (size_t)~0) { 49254661Semaste /* Skip backtrace frame */ 50254661Semaste t->n = 0; 51254661Semaste return 0; 52254661Semaste } 53254661Semaste if (t->n < t->len) 54254661Semaste t->arr[t->n++] = _Unwind_GetIP(ctx); 55254661Semaste return 0; 56254661Semaste} 57254661Semaste 58254661Semastesize_t 59254661Semastebacktrace(void **arr, size_t len) 60254661Semaste{ 61254661Semaste struct tracer_context ctx; 62254661Semaste 63254661Semaste ctx.arr = arr; 64254661Semaste ctx.len = len; 65254661Semaste ctx.n = (size_t)~0; 66254661Semaste 67254661Semaste _Unwind_Backtrace(tracer, &ctx); 68254661Semaste if (ctx.n != (size_t)~0 && ctx.n > 0) 69254661Semaste ctx.arr[--ctx.n] = NULL; /* Skip frame below __start */ 70254661Semaste 71254661Semaste return ctx.n; 72254661Semaste} 73