tracetools.cpp
Go to the documentation of this file.
00001 // Copyright (c) 2016, 2017 - for information on the respective 
00002 // copyright owner see the NOTICE file and/or the repository 
00003 // https://github.com/bosch-robotics-cr/tracetools.git
00004 //
00005 // Licensed under the Apache License, Version 2.0 (the "License");
00006 // you may not use this file except in compliance with the License.
00007 // You may obtain a copy of the License at
00008 //
00009 //     http://www.apache.org/licenses/LICENSE-2.0
00010 //
00011 // Unless required by applicable law or agreed to in writing, software
00012 // distributed under the License is distributed on an "AS IS" BASIS,
00013 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 // See the License for the specific language governing permissions and
00015 // limitations under the License.
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         // check if we need to truncate, because name is usually not unique
00051         // and we need the procname to disambiguate
00052         if (strlen(name) > 10) {
00053                 oss.str(fqn.substr(0, 8));
00054                 // let prctl truncate the rest
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         // check if we just got a pointer
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 /*void cb_call(const void* ptr_ref, const void* data, const
00102  uint64_t trace_id) {
00103  tracepoint(roscpp, ptr_call, ptr_ref, data, trace_id);
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                         // add full backtrace (excepting ourselves and our immediate
00258                         // caller)
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 }


tracetools
Author(s): Ingo Luetkebohle
autogenerated on Thu Jun 6 2019 20:31:53