stacktrace.c revision 07630cea1f3a845c09309f197ac7c4f11edd3b62
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <dwarf.h>
#include "formats-util.h"
#include "macro.h"
#include "string-util.h"
#include "util.h"
#include "stacktrace.h"
#define FRAMES_MAX 64
#define THREADS_MAX 64
struct stack_context {
FILE *f;
unsigned n_thread;
unsigned n_frame;
};
struct stack_context *c = userdata;
bool is_activation;
assert(c);
if (c->n_frame >= FRAMES_MAX)
return DWARF_CB_ABORT;
return DWARF_CB_ABORT;
if (module) {
int n;
if (cudie) {
Dwarf_Attribute *a, space;
if (!a)
if (a)
symbol = dwarf_formstring(a);
if (!symbol)
symbol = dwarf_diename(s);
if (symbol)
break;
}
}
}
if (!symbol)
}
fprintf(c->f, "#%-2u 0x%016" PRIx64 " %s (%s)\n", c->n_frame, (uint64_t) pc, strna(symbol), strna(fname));
c->n_frame ++;
return DWARF_CB_OK;
}
struct stack_context *c = userdata;
assert(c);
if (c->n_thread >= THREADS_MAX)
return DWARF_CB_ABORT;
if (c->n_thread != 0)
fputc('\n', c->f);
c->n_frame = 0;
return DWARF_CB_ABORT;
c->n_thread ++;
return DWARF_CB_OK;
}
static const Dwfl_Callbacks callbacks = {
};
struct stack_context c = {};
int r;
return -errno;
if (!c.f)
return -ENOMEM;
if (!c.elf) {
r = -EINVAL;
goto finish;
}
if (!c.dwfl) {
r = -EINVAL;
goto finish;
}
r = -EINVAL;
goto finish;
}
r = -EINVAL;
goto finish;
}
r = -EINVAL;
goto finish;
}
r = -EINVAL;
goto finish;
}
c.f = safe_fclose(c.f);
r = 0;
if (c.dwfl)
if (c.elf)
safe_fclose(c.f);
return r;
}