00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <tracetools/tracetools.h>
00019 #ifdef WITH_LTTNG
00020 #include "tp_call.h"
00021 #endif
00022 #include <execinfo.h>
00023 #include <sstream>
00024 #include <sys/prctl.h>
00025
00026 namespace ros {
00027 namespace trace {
00028
00029 bool compile_status() throw () {
00030 #ifdef WITH_LTTNG
00031 return true;
00032 #else
00033 return false;
00034 #endif
00035 }
00036 void task_init(const char* name, const char* owner) {
00037 #ifdef WITH_LTTNG
00038 std::ostringstream oss;
00039 oss << name << "_";
00040 if (owner != NULL && strlen(owner) > 0) {
00041 oss << owner;
00042 } else {
00043 char thread_name[256];
00044 prctl(PR_GET_NAME, thread_name, NULL, NULL, NULL);
00045 oss << thread_name;
00046 }
00047 std::string fqn(oss.str());
00048 tracepoint(roscpp, task_start, fqn.c_str());
00049
00050
00051
00052 if (strlen(name) > 10) {
00053 oss.str(fqn.substr(0, 8));
00054
00055 oss << "_" << fqn.substr(strlen(name));
00056 fqn = oss.str();
00057 }
00058 prctl(PR_SET_NAME, fqn.c_str(), NULL, NULL, NULL);
00059 #endif
00060 }
00061 void node_init(const char* node_name, unsigned int roscpp_version) {
00062 #ifdef WITH_LTTNG
00063 tracepoint(roscpp, init_node, node_name, roscpp_version);
00064 prctl(PR_SET_NAME, node_name, NULL, NULL, NULL);
00065 #endif
00066 }
00067 void call_start(const void* ptr_ref, const void* data,
00068 const uint64_t trace_id) {
00069 #ifdef WITH_LTTNG
00070 tracepoint(roscpp, callback_start, ptr_ref, data, trace_id);
00071 #endif
00072 }
00073 void call_end(const void* ptr_ref, const void* data, const uint64_t trace_id) {
00074 #ifdef WITH_LTTNG
00075 tracepoint(roscpp, callback_end, ptr_ref, data, trace_id);
00076 #endif
00077 }
00078
00079 void message_processed(const char* message_name, const void* callback_ref,
00080 const uint32_t receipt_time_sec, const uint32_t receipt_time_nsec) {
00081 #ifdef WITH_LTTNG
00082 tracepoint(roscpp, message_processed, message_name, callback_ref,
00083 receipt_time_sec, receipt_time_nsec);
00084 #endif
00085 }
00086
00087
00088 void fn_name_info(const void* const_ptr, const void* ptr) {
00089 #ifdef WITH_LTTNG
00090 void* func_ptr = const_cast<void*>(const_ptr);
00091 char** symbols = backtrace_symbols(&func_ptr, 1);
00092
00093 if (symbols[0][0] == '[') {
00094 tracepoint(roscpp, ptr_name_info, impl::get_backtrace().c_str(), ptr);
00095 } else {
00096 tracepoint(roscpp, ptr_name_info, symbols[0], ptr);
00097 }
00098 free(symbols);
00099 #endif
00100 }
00101
00102
00103
00104
00105
00106
00107 void timer_added(const void* fun_ptr, const char* type_info, int period_sec,
00108 int period_nsec) {
00109 #ifdef WITH_LTTNG
00110 tracepoint(roscpp, timer_added, fun_ptr,
00111 impl::get_symbol(const_cast<void*>(fun_ptr)).c_str(), type_info,
00112 period_sec, period_nsec);
00113 #endif
00114 }
00115
00116 void timer_scheduled(const void* callback_ref, const void* timer_ref) {
00117 #ifdef WITH_LTTNG
00118 tracepoint(roscpp, timer_scheduled, callback_ref, timer_ref);
00119 #endif
00120 }
00121
00122 void time_sleep(const void* callback_ref, int sleep_sec, int sleep_nsec) {
00123 #ifdef WITH_LTTNG
00124 tracepoint(roscpp, time_sleep, callback_ref, sleep_sec, sleep_nsec);
00125 #endif
00126 }
00127
00128 void link_step(const char* element_name, const void* caller_ref,
00129 const void* in_data_ref, const void* out_data_ref,
00130 const uint64_t trace_id) {
00131 #ifdef WITH_LTTNG
00132 #ifdef NO_LINK_BACKTRACES
00133 tracepoint(roscpp, trace_link, element_name, user_name,
00134 in_data_ref, out_data_ref, trace_id, NULL);
00135 #else
00136 tracepoint(roscpp, trace_link, element_name, typeid(caller_ref).name(),
00137 caller_ref, in_data_ref, out_data_ref, trace_id,
00138 impl::get_backtrace().c_str());
00139 #endif
00140 #endif
00141 }
00142
00143 void new_connection(const char* local_hostport_arg,
00144 const char* remote_hostport_arg, const void* channel_ref_arg,
00145 const char* channel_type_arg, const char* name_arg,
00146 const char* data_type_arg) {
00147 #ifdef WITH_LTTNG
00148 tracepoint(roscpp, new_connection, local_hostport_arg, remote_hostport_arg,
00149 channel_ref_arg, channel_type_arg, name_arg, data_type_arg);
00150 #endif
00151 }
00152 void publisher_link_handle_message(const void* channel_ref_arg,
00153 const void* buffer_ref_arg) {
00154 #ifdef WITH_LTTNG
00155 tracepoint(roscpp, publisher_link_handle_message, channel_ref_arg,
00156 buffer_ref_arg);
00157 #endif
00158 }
00159
00160 void publisher_message_queued(const char* topic_arg,
00161 const void* buffer_ref_arg) {
00162 #ifdef WITH_LTTNG
00163 tracepoint(roscpp, publisher_message_queued, topic_arg, buffer_ref_arg);
00164 #endif
00165 }
00166 void publisher_message_queued(const std::string& topic_arg,
00167 const void* buffer_ref_arg) {
00168 #ifdef WITH_LTTNG
00169 tracepoint(roscpp, publisher_message_queued, topic_arg.c_str(),
00170 buffer_ref_arg);
00171 #endif
00172 }
00173 void subscriber_link_message_write(const void* message_ref_arg,
00174 const void* channel_ref_arg) {
00175 #ifdef WITH_LTTNG
00176 tracepoint(roscpp, subscriber_link_message_write, message_ref_arg,
00177 channel_ref_arg);
00178 #endif
00179 }
00180 void subscriber_link_message_dropped(const void* message_ref_arg) {
00181 #ifdef WITH_LTTNG
00182 tracepoint(roscpp, subscriber_link_message_dropped, message_ref_arg);
00183 #endif
00184 }
00185
00186 void subscription_message_queued(const char* topic_arg,
00187 const void* buffer_ref_arg, const void* queue_ref_arg,
00188 const void* callback_ref_arg, const void* message_ref_arg,
00189 int receipt_time_sec_arg, int receipt_time_nsec_arg) {
00190 #ifdef WITH_LTTNG
00191 tracepoint(roscpp, subscription_message_queued, topic_arg, buffer_ref_arg,
00192 queue_ref_arg, callback_ref_arg, message_ref_arg,
00193 receipt_time_sec_arg, receipt_time_nsec_arg);
00194 #endif
00195 }
00196 void subscription_message_dropped(const char* topic_arg,
00197 const void* buffer_ref_arg,
00198 const void* queue_ref_arg,
00199 const void* callback_ref_arg,
00200 const void* message_ref_arg,
00201 int receipt_time_sec_arg,
00202 int receipt_time_nsec_arg)
00203 {
00204 #ifdef WITH_LTTNG
00205 tracepoint(roscpp, subscription_message_dropped, topic_arg, buffer_ref_arg,
00206 queue_ref_arg, callback_ref_arg, message_ref_arg,
00207 receipt_time_sec_arg, receipt_time_nsec_arg);
00208 #endif
00209 }
00210 void subscriber_callback_added(const void* queue_ref_arg,
00211 const void* callback_ref_arg, const char* type_info_arg,
00212 const char* data_type_arg, const char* source_name_arg,
00213 int queue_size_arg) {
00214 #ifdef WITH_LTTNG
00215 tracepoint(roscpp, subscriber_callback_added, queue_ref_arg,
00216 callback_ref_arg, type_info_arg, data_type_arg, source_name_arg,
00217 queue_size_arg);
00218 #endif
00219 }
00220
00221 void subscriber_call_start(const std::string& topic, const void* queue_ref,
00222 const void* callback_ref, const void* message_ref, int receipt_time_sec,
00223 int receipt_time_nsec) {
00224 #ifdef WITH_LTTNG
00225 tracepoint(roscpp, subscriber_callback_start, topic.c_str(), 0, queue_ref,
00226 callback_ref, message_ref, receipt_time_sec, receipt_time_nsec);
00227 #endif
00228 }
00229 void subscriber_call_end(const std::string& topic, const void* queue_ref,
00230 const void* callback_ref, const void* message_ref, int receipt_time_sec,
00231 int receipt_time_nsec) {
00232 #ifdef WITH_LTTNG
00233 tracepoint(roscpp, subscriber_callback_end, topic.c_str(), 0, queue_ref,
00234 callback_ref, message_ref, receipt_time_sec, receipt_time_nsec);
00235 #endif
00236 }
00237
00238 void queue_delay(const char* queue_name, const void* ptr_ref, const void* data,
00239 const uint32_t entry_time_sec, const uint32_t entry_time_nsec) {
00240 #ifdef WITH_LTTNG
00241 tracepoint(roscpp, queue_delay, queue_name, ptr_ref, data, entry_time_sec,
00242 entry_time_nsec);
00243 #endif
00244 }
00245
00246 namespace impl {
00247 std::string get_backtrace(int index) {
00248 #ifdef WITH_LTTNG
00249 const int bufsize = 50;
00250 void* bt_buffer[bufsize];
00251 int size = backtrace(bt_buffer, bufsize);
00252 char** symbols = backtrace_symbols(bt_buffer, size);
00253
00254 std::ostringstream oss;
00255 if (index < size) {
00256 if (index < 0) {
00257
00258
00259 for (int i = 2; i < size; ++i) {
00260 oss << symbols[i] << "|";
00261 }
00262 } else {
00263 oss << symbols[index];
00264 }
00265 } else
00266 oss << "Invalid index " << index << " requested, only have " << size
00267 << " backtrace entries";
00268
00269 free(symbols);
00270
00271 return oss.str();
00272 #else
00273 return "";
00274 #endif
00275 }
00276
00277 std::string get_symbol(void* funptr) {
00278 #ifdef WITH_LTTNG
00279 char** symbols = backtrace_symbols(&funptr, 1);
00280 std::string result(symbols[0]);
00281 free(symbols);
00282 return result;
00283 #else
00284 return "";
00285 #endif
00286 }
00287 std::string getCallbackInfo(const void* func_ptr, const char* name) {
00288 #ifdef WITH_LTTNG
00289 void* funptr = const_cast<void*>(func_ptr);
00290 char** symbols = backtrace_symbols(&funptr, 1);
00291 std::string result(symbols[0]);
00292 free(symbols);
00293 return name + std::string(" ") + result;
00294 #else
00295 return "";
00296 #endif
00297 }
00298 }
00299
00300
00301 }
00302 }