int main(int argc, char *argv[]) { time_t now; call.dialin = 1; strcpy(call.num[0], "41"); strcpy(call.num[1], argc > 1 ? argv[1] : "1234567"); strcpy(call.alias[0], ""); strcpy(call.alias[1], ""); strcpy(call.area[0], "Hbgtn"); strcpy(call.area[1], "Wien"); time(&now); call.connect = now; call.pay = 1.23; procinfo(2, &call, CONNECT); return 0; }
/* Determines which function the control flow entered/left * and prints the trace message. */ static int print_trace(void *addr, char const *dir) { static unsigned depth_limit; static int depth_limited = -1, be_async = -1, entries_only = -1; static int indent = -1, log_fname = -1; char const *env, *colon, *fname, *funame; int is_entry, success; /* Read $TRACY_MAXDEPTH if we haven't. */ if (depth_limited < 0) { if ((env = getenv("TRACY_MAXDEPTH")) && env[0]) { depth_limit = atoi(env); depth_limited = 1; } else depth_limited = 0; } /* Have we reached the limit? */ if (depth_limited && Callstack_depth >= depth_limit) return 1; #ifndef __ARMEL__ { void *addrs[3]; /* * In the frame: * [0] this function, * [1] the instrumentation function, * [2] the function we're interested in. * * On ARM backtrace() is unreliable, so use $addr directly. * On x86 we can't avoid this call. */ if (backtrace(addrs, 3) < 3) return 1; addr = addrs[2]; } #endif /* ! __ARMEL__ */ /* In async mode create a temporary file where we can write symbol * addresses the program encounters on function calls enters. */ if (be_async < 0) { be_async = (env = getenv("TRACY_ASYNC")) && env[0] == '1'; if (be_async) { static char tmpfname[] = "/tmp/tracy.XXXXXX"; if ((Async_fd = mkstemp(tmpfname)) < 0) { LOGIT("mkstemp: %m"); be_async = 0; } else { unlink(tmpfname); atexit(resolve_backlog); } } } /* be_async? */ /* Log only function entries? */ is_entry = dir[0] == 'E'; if (entries_only < 0) entries_only = (env = getenv("TRACY_LOG_ENTRIES_ONLY")) && env[0] == '1'; if (entries_only) dir = ""; /* Get how much to indent $fname:$funame. */ if (indent < 0) indent = (env = getenv("TRACY_LOG_INDENT")) ? atoi(env) : 0; /* Write the async file if necessary. */ if (Async_fd >= 0) { /* resolve_backlog() will resolve $addr when we exit. */ if (!entries_only || is_entry) LOGIT("%s%s[%u]%*s[%p]", procinfo(), dir, Callstack_depth, 1 + indent*Callstack_depth, " ", addr); if (is_entry) /* Try not to bloat the file, it'll have * lots of identical entries anyway. */ write(Async_fd, &addr, sizeof(addr)); return 1; } /* Resolve $addr. */ if ((success = addr2name(&fname, &funame, addr)) < 0) /* Omitted from output, don't count it in $Callstack_depth. */ return 0; /* Don't log LEAVE:s if $entries_only. */ if (entries_only && !is_entry) return 1; /* Print or omit the "<$fname>:" in front of $funame? */ if (log_fname < 0) log_fname = (env = getenv("TRACY_LOG_FNAME")) ? env[0] == '1' : 1; if (log_fname) colon = ":"; else fname = colon = ""; /* Log the damn thing. */ if (success) LOGIT("%s%s[%u]%*s%s%s%s()", procinfo(), dir, Callstack_depth, 1 + indent*Callstack_depth, " ", fname, colon, funame); else LOGIT("%s%s[%u]%*s%s%s[%p]", procinfo(), dir, Callstack_depth, 1 + indent*Callstack_depth, " ", fname, colon, addr); /* We've logged something. */ return 1; } /* print_trace */