GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
assertions.cpp
1 /**
2  * Copyright (c) 2009 Carnegie Mellon University.
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an "AS
13  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14  * express or implied. See the License for the specific language
15  * governing permissions and limitations under the License.
16  *
17  * For more about this software visit:
18  *
19  * http://www.graphlab.ml.cmu.edu
20  *
21  */
22 
23 
24 #include <execinfo.h>
25 #include <iostream>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <cxxabi.h>
31 #include <graphlab/parallel/pthread_tools.hpp>
32 #include <graphlab/rpc/get_last_dc_procid.hpp>
33 
34 
35 /** Code from http://mykospark.net/2009/09/runtime-backtrace-in-c-with-name-demangling/ */
36 std::string demangle(const char* symbol) {
37  size_t size;
38  int status;
39  char temp[1024];
40  char* demangled;
41  //first, try to demangle a c++ name
42  if (1 == sscanf(symbol, "%*[^(]%*[^_]%127[^)+]", temp)) {
43  if (NULL != (demangled = abi::__cxa_demangle(temp, NULL, &size, &status))) {
44  std::string result(demangled);
45  free(demangled);
46  return result;
47  }
48  }
49  //if that didn't work, try to get a regular c symbol
50  if (1 == sscanf(symbol, "%127s", temp)) {
51  return temp;
52  }
53 
54  //if all else fails, just return the symbol
55  return symbol;
56 }
57 
58 
59 static graphlab::mutex back_trace_file_lock;
60 static size_t write_count = 0;
61 static bool write_error = 0;
62 /* Obtain a backtrace and print it to ofile. */
63 void __print_back_trace() {
64  void *array[1024];
65  size_t size, i;
66  char **strings;
67 
68 
69  back_trace_file_lock.lock();
70 
71  if (write_error) {
72  back_trace_file_lock.unlock();
73  return;
74  }
75  char filename[1024];
76  sprintf(filename, "backtrace.%d", int(graphlab::dc_impl::get_last_dc_procid()));
77 
78  FILE* ofile = NULL;
79  if (write_count == 0) {
80  ofile = fopen(filename, "w");
81  }
82  else {
83  ofile = fopen(filename, "a");
84  }
85  // if unable to open the file for output
86  if (ofile == NULL) {
87  // print an error, set the error flag so we don't ever print it again
88  fprintf(stderr, "Unable to open output backtrace file.\n");
89  write_error = 1;
90  back_trace_file_lock.unlock();
91  return;
92  }
93  ++write_count;
94 
95  size = backtrace(array, 1024);
96  strings = backtrace_symbols(array, size);
97 
98  fprintf(ofile, "Pointers\n");
99  fprintf(ofile, "------------\n");
100  for (i = 0; i < size; ++i) {
101  fprintf(ofile, "%p\n", array[i]);
102  }
103 
104 
105  fprintf(ofile, "Raw\n");
106  fprintf(ofile, "------------\n");
107  for (i = 0; i < size; ++i) {
108  fprintf(ofile, "%s\n", strings[i]);
109  }
110  fprintf(ofile, "\nDemangled\n");
111  fprintf(ofile, "------------\n");
112 
113  for (i = 0; i < size; ++i) {
114  std::string ret = demangle(strings[i]);
115  fprintf(ofile, "%s\n", ret.c_str());
116  }
117  free(strings);
118 
119  fprintf(ofile, "\n\n\n\n\n\n\n\n\n\n\n\n\n");
120 
121  fclose(ofile);
122  back_trace_file_lock.unlock();
123 }
124