Skip to content

Instantly share code, notes, and snippets.

@timholy
Created June 23, 2013 13:48
Show Gist options
  • Save timholy/5845088 to your computer and use it in GitHub Desktop.
Save timholy/5845088 to your computer and use it in GitHub Desktop.
Calling libunwind on Linux This is modified from https://gist.github.com/blakejohnson/5831456 Only "make test3" was tested (the rest may require extra things to be installed) You need an installation of Julia. The Makefile assumes this is in /home/yourusername/src/.
all: test test2 test3
JULIADIR = $(HOME)/src/julia
JULIALIB = $(JULIADIR)/usr/lib
OPENBLASDIR = $(JULIADIR)/deps/openblas-develop
UNWINDDIR = $(JULIADIR)/deps/libunwind-1.1
# LDFLAGS = -Wl,-no_compact_unwind
LDFLAGS =
CC = gcc
test: unwind.c
$(CC) -g -DAPPLEBLAS -framework vecLib -lblas $(LDFLAGS) unwind.c -o test
LDFLAGS += -Wl,-rpath,$(JULIALIB)
test2: unwind.c
$(CC) -g -I$(OPENBLASDIR) -L$(JULIALIB) -lopenblas $(LDFLAGS) unwind.c -o test2
test3: unwind.c
$(CC) -g -DFORTRANBLAS -I$(OPENBLASDIR) -I$(UNWINDDIR)/include -L$(JULIALIB) $(LDFLAGS) unwind.c -o test3 -lunwind -lopenblas
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <signal.h>
#include <sys/time.h>
#define UNW_LOCAL_ONLY
#include "libunwind.h"
typedef ptrdiff_t ptrint_t;
#ifdef APPLEBLAS
#include <Accelerate/Accelerate.h>
#else
#ifdef FORTRANBLAS
extern void daxpy_(
ptrdiff_t *n,
double *da,
double *dx,
ptrdiff_t *incx,
double *dy,
ptrdiff_t *incy
);
#else
#include "cblas.h"
#endif
#endif
struct itimerval timerprof;
static u_int64_t usecprof = 500;
int running;
int samples;
size_t rec_backtrace(size_t maxsize)
{
unw_cursor_t cursor; unw_context_t uc;
unw_word_t ip, offset;
size_t n=0;
char fname[64];
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
while (unw_step(&cursor) > 0 && n < maxsize) {
if (unw_get_reg(&cursor, UNW_REG_IP, &ip) < 0) {
break;
}
fname[0] = '\0';
unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);
printf("%p: (%s + 0x%x)\n", (void *)ip, fname, (unsigned int)offset);
}
printf("\n");
return n;
}
static void sprofile_bt(int dummy) {
if (running) {
printf("Sample %d\n", samples);
rec_backtrace(10);
if (samples-- > 0) {
timerprof.it_value.tv_usec = usecprof;
setitimer(ITIMER_REAL, &timerprof, 0);
}
}
}
int start_timer(void)
{
timerprof.it_interval.tv_sec = 0;
timerprof.it_interval.tv_usec = 0;
timerprof.it_value.tv_sec = 0;
timerprof.it_value.tv_usec = usecprof;
if (setitimer(ITIMER_REAL, &timerprof, 0) == -1)
return -3;
running = 1;
samples = 10;
signal(SIGALRM, sprofile_bt);
return 0;
}
void stop_timer(void)
{
running = 0;
}
int blas_op(int a, double *x, double *y) {
#ifdef FORTRANBLAS
long n = 1000;
double da = (double)a;
long incx = 1, incy = 1;
daxpy_(&n, &da, x, &incx, y, &incy);
#else
cblas_daxpy(1000, (double)a, x, 1, y, 1);
#endif
return y[0];
}
void fill_xy(double *x, double *y, int n) {
int ct;
for (ct=0; ct < n; ct++) {
x[ct] = (double)rand() / (double)RAND_MAX;
y[ct] = (double)rand() / (double)RAND_MAX;
}
}
int main(void) {
int a = 2;
int b;
double x[1000], y[1000];
int ct;
fill_xy(x, y, 1000);
start_timer();
for (ct = 0; ct < 10000; ct++)
b = blas_op(a, x, y);
stop_timer();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment