Skip to content

Commit 87ed61a

Browse files
jacquelinekayJackie Kay
authored andcommitted
malloc_hook exception
1 parent 6f4aa78 commit 87ed61a

File tree

7 files changed

+41
-50
lines changed

7 files changed

+41
-50
lines changed

pendulum_control/include/pendulum_control/pendulum_controller.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class PendulumController
6464

6565
/// Calculate new command based on new sensor state and PID controller properties.
6666
// \param[in] msg Received sensor message.
67-
void on_sensor_message(const pendulum_msgs::msg::JointState::SharedPtr msg)
67+
void on_sensor_message(pendulum_msgs::msg::JointState::ConstSharedPtr msg)
6868
{
6969
++messages_received;
7070

@@ -96,10 +96,10 @@ class PendulumController
9696
message_ready_ = true;
9797
}
9898

99-
void on_pendulum_setpoint(const pendulum_msgs::msg::JointCommand::SharedPtr msg)
99+
void on_pendulum_setpoint(pendulum_msgs::msg::JointCommand::ConstSharedPtr msg)
100100
{
101101
set_command(msg->position);
102-
std::cout << "Pendulum set to: " << msg->position << std::endl;
102+
printf("Pendulum set to: %f\n", msg->position);
103103
}
104104

105105
/// Retrieve the command calculated from the last sensor message.

pendulum_control/include/pendulum_control/pendulum_motor.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class PendulumMotor
7777

7878
// Initialize a separate high-priority thread to run the physics update loop.
7979
pthread_attr_init(&thread_attr_);
80-
struct sched_param thread_param;
80+
sched_param thread_param;
8181
thread_param.sched_priority = 90;
8282
pthread_attr_setschedparam(&thread_attr_, &thread_param);
8383
pthread_attr_setschedpolicy(&thread_attr_, SCHED_RR);
@@ -87,7 +87,7 @@ class PendulumMotor
8787

8888
/// Update the position of motor based on the command.
8989
// \param[in] msg Received command.
90-
void on_command_message(const pendulum_msgs::msg::JointCommand::SharedPtr msg)
90+
void on_command_message(pendulum_msgs::msg::JointCommand::ConstSharedPtr msg)
9191
{
9292
++messages_received;
9393
// Assume direct, instantaneous position control
@@ -108,7 +108,7 @@ class PendulumMotor
108108

109109
/// Return the next sensor message calculated by the physics engine.
110110
// \return The sensor message
111-
const pendulum_msgs::msg::JointState::SharedPtr get_next_sensor_message() const
111+
pendulum_msgs::msg::JointState::SharedPtr get_next_sensor_message() const
112112
{
113113
return sensor_message_;
114114
}
@@ -221,7 +221,7 @@ class PendulumMotor
221221
std::chrono::nanoseconds publish_period_;
222222

223223
// Physics should update most frequently, in separate RT thread
224-
struct timespec physics_update_timespec_;
224+
timespec physics_update_timespec_;
225225
double dt_;
226226

227227
// Physical qualities of the pendulum

pendulum_control/include/pendulum_control/rtt_executor.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class RttExecutor : public executor::Executor
4444
: executor::Executor(ms), running(false)
4545
{
4646
rttest_ready = rttest_running();
47+
memset(&start_time_, 0, sizeof(timespec));
4748
}
4849

4950
/// Default destructor
@@ -65,7 +66,7 @@ class RttExecutor : public executor::Executor
6566

6667
/// Retrieve the results measured by rttest
6768
// \param[in] output A struct containing performance statistics.
68-
void get_rtt_results(struct rttest_results & output) const
69+
void get_rtt_results(rttest_results & output) const
6970
{
7071
output = results;
7172
}
@@ -78,7 +79,7 @@ class RttExecutor : public executor::Executor
7879
msg->max_latency = results.max_latency;
7980
msg->minor_pagefaults = results.minor_pagefaults;
8081
msg->major_pagefaults = results.major_pagefaults;
81-
struct timespec curtime;
82+
timespec curtime;
8283
clock_gettime(CLOCK_MONOTONIC, &curtime);
8384
msg->stamp.sec = curtime.tv_sec;
8485
msg->stamp.nanosec = curtime.tv_nsec;
@@ -141,7 +142,7 @@ class RttExecutor : public executor::Executor
141142
}
142143

143144
// For storing accumulated performance statistics.
144-
struct rttest_results results;
145+
rttest_results results;
145146
// True if the executor is spinning.
146147
bool running;
147148
// True if rttest has initialized and hasn't been stopped yet.
@@ -151,7 +152,7 @@ class RttExecutor : public executor::Executor
151152

152153
protected:
153154
// Absolute timestamp at which the first data point was collected in rttest.
154-
struct timespec start_time_;
155+
timespec start_time_;
155156

156157
private:
157158
RCLCPP_DISABLE_COPY(RttExecutor);

pendulum_control/scripts/pendulum_launch.bash

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,15 @@ logger_pid=$!
55

66
# run pendulum demo indefinitely
77
pendulum_demo__rmw_opensplice_cpp -i 0 &
8-
#pendulum_demo__rmw_opensplice_cpp -i 0
98
demo_pid=$!
109

1110
# Initialize system stress
1211
stress -c 2 -i 2 --timeout 18000000000 &
1312
stress_pid=$!
14-
# Publish new command messages every 3 minutes
15-
# Run for 5 hours (5*60/3 = 100 iterations)
16-
# run for 1 hr: 60/3 = 20 iterations
17-
1813
for i in {1..100}; do
1914
sleep 3m
2015
pendulum_teleop__rmw_opensplice_cpp $i
2116
done
2217

2318
# Kill backgrounded processes on exit
2419
kill -9 $logger_pid $demo_pid $stress_pid
25-
#kill -9 $logger_pid

pendulum_control/src/pendulum_demo.cpp

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@
3232
#include "pendulum_control/pendulum_motor.hpp"
3333
#include "pendulum_control/rtt_executor.hpp"
3434

35+
36+
static bool running = false;
37+
3538
// Initialize a malloc hook so we can show that no mallocs are made during real-time execution
3639

3740
/// Declare a function pointer into which we will store the default malloc.
38-
static void *(*prev_malloc_hook)(size_t, const void *);
41+
static void * (* prev_malloc_hook)(size_t, const void *);
3942

4043
// Use pragma to ignore a warning for using __malloc_hook, which is deprecated (but still awesome).
4144
#pragma GCC diagnostic push
@@ -51,28 +54,20 @@ static void *(*prev_malloc_hook)(size_t, const void *);
5154
static void * testing_malloc(size_t size, const void * caller)
5255
{
5356
(void)caller;
57+
/*
5458
// Maximum depth we are willing to traverse into the stack trace.
5559
static const int MAX_DEPTH = 2;
5660
// Instantiate a buffer to store the traced symbols.
5761
void * backtrace_buffer[MAX_DEPTH];
62+
*/
63+
if (running) {
64+
throw std::runtime_error("Called malloc during realtime execution phase!");
65+
}
66+
5867
// Set the malloc implementation to the default malloc hook so that we can call it implicitly
5968
// to initialize a string, otherwise this function will loop infinitely.
6069
__malloc_hook = prev_malloc_hook;
61-
// Backtrace and get the depth of the stack that we traversed.
62-
int stack_depth = backtrace(backtrace_buffer, MAX_DEPTH);
63-
// Format the symbols as human-readable strings if possible.
64-
char ** function_names = backtrace_symbols(backtrace_buffer, stack_depth);
65-
// The 0th level of the stack is not very useful; try printing the 1st level.
66-
if (stack_depth > 1) {
67-
printf("malloc(%u) called from %s [%p]\n",
68-
(unsigned)size, function_names[1], backtrace_buffer[1]);
69-
} else {
70-
// If the first level was unavailable, default to the 0th level.
71-
printf("malloc(%u) called from %s [%p]\n",
72-
(unsigned)size, function_names[0], backtrace_buffer[0]);
73-
}
74-
// Release the string that was allocated for printing.
75-
free(function_names);
70+
7671
// Execute the requested malloc.
7772
void * mem = malloc(size);
7873
// Set the malloc hook back to this function, so that we can intercept future mallocs.
@@ -177,7 +172,7 @@ int main(int argc, char * argv[])
177172

178173
// Create a lambda function to invoke the motor callback when a command is received.
179174
auto motor_subscribe_callback =
180-
[&pendulum_motor](const pendulum_msgs::msg::JointCommand::SharedPtr msg) -> void
175+
[&pendulum_motor](pendulum_msgs::msg::JointCommand::ConstSharedPtr msg) -> void
181176
{
182177
pendulum_motor->on_command_message(msg);
183178
};
@@ -190,7 +185,7 @@ int main(int argc, char * argv[])
190185

191186
// Create a lambda function to invoke the controller callback when a command is received.
192187
auto controller_subscribe_callback =
193-
[&pendulum_controller](const pendulum_msgs::msg::JointState::SharedPtr msg) -> void
188+
[&pendulum_controller](pendulum_msgs::msg::JointState::ConstSharedPtr msg) -> void
194189
{
195190
pendulum_controller->on_sensor_message(msg);
196191
};
@@ -207,14 +202,14 @@ int main(int argc, char * argv[])
207202

208203
// Create a lambda function to accept user input to command the pendulum
209204
auto controller_command_callback =
210-
[&pendulum_controller](const pendulum_msgs::msg::JointCommand::SharedPtr msg) -> void
205+
[&pendulum_controller](pendulum_msgs::msg::JointCommand::ConstSharedPtr msg) -> void
211206
{
212207
pendulum_controller->on_pendulum_setpoint(msg);
213208
};
214209

215-
auto setpoint_sub = controller_node->create_subscription<pendulum_msgs::msg::JointCommand>
216-
("pendulum_setpoint", qos_profile, controller_command_callback, nullptr, false,
217-
setpoint_msg_strategy);
210+
auto setpoint_sub = controller_node->create_subscription<pendulum_msgs::msg::JointCommand>(
211+
"pendulum_setpoint", qos_profile, controller_command_callback, nullptr, false,
212+
setpoint_msg_strategy);
218213

219214
// Initialize the logger publisher.
220215
auto logger_pub = controller_node->create_publisher<pendulum_msgs::msg::RttestResults>(
@@ -267,8 +262,8 @@ int main(int argc, char * argv[])
267262
auto controller_publisher_timer = controller_node->create_wall_timer
268263
(pendulum_controller->get_publish_period(), controller_publish_callback);
269264
// Add a timer to enable regular publication of results messages.
270-
auto logger_publisher_timer = controller_node->create_wall_timer
271-
(logger_publisher_period, logger_publish_callback);
265+
auto logger_publisher_timer = controller_node->create_wall_timer(
266+
logger_publisher_period, logger_publish_callback);
272267

273268
// Set the priority of this thread to the maximum safe value, and set its scheduling policy to a
274269
// deterministic (real-time safe) algorithm, round robin.
@@ -291,6 +286,7 @@ int main(int argc, char * argv[])
291286
// End initialization phase
292287

293288
// Execution phase
289+
running = true;
294290

295291
// Unlike the default SingleThreadedExecutor::spin function, RttExecutor::spin runs in
296292
// bounded time (for as many iterations as specified in the rttest parameters).
@@ -301,6 +297,8 @@ int main(int argc, char * argv[])
301297
// End execution phase
302298

303299
// Teardown phase
300+
// deallocation is handled automatically by objects going out of scope
301+
running = false;
304302

305303
printf("PendulumMotor received %lu messages\n", pendulum_motor->messages_received);
306304
printf("PendulumController received %lu messages\n", pendulum_controller->messages_received);

pendulum_control/src/pendulum_logger.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ int main(int argc, char * argv[])
3030

3131
auto logger_node = rclcpp::node::Node::make_shared("pendulum_logger");
3232
std::string filename = "pendulum_logger_results.csv";
33+
std::ofstream fstream;
3334
{
34-
std::ofstream fstream;
3535
fstream.open(filename, std::ios_base::out);
3636
fstream << "iteration timestamp latency minor_pagefaults minor_pagefaults" << std::endl;
3737
fstream.close();
3838
}
39+
40+
fstream.open(filename, std::ios_base::app);
3941
size_t i = 0;
4042
auto logging_callback =
4143
[&filename, &i](const pendulum_msgs::msg::RttestResults::SharedPtr msg) {
@@ -52,15 +54,13 @@ int main(int argc, char * argv[])
5254
printf("Major pagefaults during execution: %lu\n\n", msg->major_pagefaults);
5355

5456
std::ofstream fstream;
55-
fstream.open(filename, std::ios_base::app);
5657
struct timespec timestamp;
5758
timestamp.tv_sec = msg->stamp.sec;
5859
timestamp.tv_nsec = msg->stamp.nanosec;
5960
fstream << i << " " << timespec_to_long(&timestamp) <<
6061
" " << msg->cur_latency << " " <<
6162
msg->minor_pagefaults << " " <<
6263
msg->major_pagefaults << std::endl;
63-
fstream.close();
6464
++i;
6565
};
6666

@@ -73,14 +73,12 @@ int main(int argc, char * argv[])
7373
qos_profile.reliability = RMW_QOS_POLICY_BEST_EFFORT;
7474
// The "KEEP_LAST" history setting tells DDS to store a fixed-size buffer of values before they
7575
// are sent, to aid with recovery in the event of dropped messages.
76-
// "depth" specifies the size of this buffer.
77-
// In this example, we are optimizing for performance and limited resource usage (preventing page
78-
// faults), instead of reliability. Thus, we set the size of the history buffer to 1.
7976
qos_profile.history = RMW_QOS_POLICY_KEEP_LAST_HISTORY;
80-
qos_profile.depth = 1;
77+
qos_profile.depth = 100;
8178

8279
auto subscription = logger_node->create_subscription<pendulum_msgs::msg::RttestResults>(
8380
"pendulum_statistics", qos_profile, logging_callback);
8481

8582
rclcpp::spin(logger_node);
83+
fstream.close();
8684
}

pendulum_msgs/msg/RttestResults.msg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
builtin_interfaces/Time stamp
22

3-
pendulum_msgs/JointCommand command
4-
pendulum_msgs/JointState state
3+
JointCommand command
4+
JointState state
55

66
uint64 cur_latency
77
float64 mean_latency

0 commit comments

Comments
 (0)