mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 15:33:44 +03:00
record stack traces
This commit is contained in:
parent
0276dd54aa
commit
c5c00d5740
@ -518,6 +518,37 @@ epsilon and negative checks everywhere in kinematics, but why? Should research
|
|||||||
it more, but I think the better approach is to use fixed-point arithmetic for
|
it more, but I think the better approach is to use fixed-point arithmetic for
|
||||||
everything (aka u8 or whatever).
|
everything (aka u8 or whatever).
|
||||||
|
|
||||||
|
Problems with floats:
|
||||||
|
- they dont natively order
|
||||||
|
- they arent PartialEq
|
||||||
|
- serialization sometimes breaks
|
||||||
|
- epsilon comparison issues
|
||||||
|
|
||||||
|
Options:
|
||||||
|
- just to solve epsilon comparison issues
|
||||||
|
- https://crates.io/crates/float-cmp
|
||||||
|
- https://crates.io/crates/approx
|
||||||
|
- just to get Ord and Eq
|
||||||
|
- https://crates.io/crates/decorum
|
||||||
|
- https://crates.io/crates/ordered-float
|
||||||
|
- use rational / fraction types
|
||||||
|
- https://crates.io/crates/fraction
|
||||||
|
- https://crates.io/crates/rug
|
||||||
|
- this seems a bit overpowered
|
||||||
|
- use my own custom wrapper type around u8 or whatever size makes sense for each thing
|
||||||
|
- representing 0.1s or 0.1m or whatever
|
||||||
|
- use a fixed point arithmetic crate
|
||||||
|
- https://crates.io/crates/fpa
|
||||||
|
- https://crates.io/crates/fixed
|
||||||
|
- https://crates.io/crates/fix
|
||||||
|
- would want to wrap the types anyway; only some operations make sense
|
||||||
|
|
||||||
|
|
||||||
|
- can we compare results with the prev float approach? make them store the
|
||||||
|
other thing, compare results? or compare the results of a sim?
|
||||||
|
- is it possible to do this change gradually? unlikely...
|
||||||
|
|
||||||
|
|
||||||
- moment in time (tick)
|
- moment in time (tick)
|
||||||
- resolution: 0.1s with u32, so about 13.5 years
|
- resolution: 0.1s with u32, so about 13.5 years
|
||||||
- duration
|
- duration
|
||||||
@ -822,3 +853,10 @@ It happens because a car was previously throttling itself due to somebody in
|
|||||||
the way, but as soon as they start a turn, the car eagerly jumps ahead.
|
the way, but as soon as they start a turn, the car eagerly jumps ahead.
|
||||||
|
|
||||||
ah no, it's because we use max_lookahead_dist in accel_to_follow, and the speed limit we assert is the old road's speed.
|
ah no, it's because we use max_lookahead_dist in accel_to_follow, and the speed limit we assert is the old road's speed.
|
||||||
|
|
||||||
|
## Moving away from piston
|
||||||
|
|
||||||
|
- options
|
||||||
|
- gfx (pre-II or not?) + winit
|
||||||
|
- https://suhr.github.io/gsgt/
|
||||||
|
- glium (unmaintained)
|
||||||
|
@ -71,4 +71,5 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
sim::save_backtraces("call_graph.json");
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
|
use abstutil;
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashSet;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct CallStack {
|
|
||||||
calls: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref BACKTRACES: Mutex<HashMap<String, CallStack>> = Mutex::new(HashMap::new());
|
static ref BACKTRACES: Mutex<HashSet<Vec<String>>> = Mutex::new(HashSet::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn capture_backtrace() {
|
pub fn capture_backtrace(event: &str) {
|
||||||
let bt = Backtrace::new();
|
let bt = Backtrace::new();
|
||||||
let mut found_this_fxn = false;
|
let mut found_this_fxn = false;
|
||||||
let mut calls: Vec<String> = Vec::new();
|
let mut calls: Vec<String> = vec![event.to_string()];
|
||||||
for f in bt.frames() {
|
for f in bt.frames() {
|
||||||
let raw_name = format!("{}", f.symbols()[0].name().unwrap());
|
let raw_name = format!("{}", f.symbols()[0].name().unwrap());
|
||||||
let mut raw_name_parts: Vec<&str> = raw_name.split("::").collect();
|
let mut raw_name_parts: Vec<&str> = raw_name.split("::").collect();
|
||||||
@ -33,15 +29,14 @@ pub fn capture_backtrace() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let caller = &calls[0];
|
BACKTRACES.lock().unwrap().insert(calls);
|
||||||
let stack = CallStack {
|
|
||||||
calls: calls[1..].to_vec(),
|
|
||||||
};
|
|
||||||
println!("insert {}: {:?}", caller, stack);
|
|
||||||
let mut remember = BACKTRACES.lock().unwrap();
|
|
||||||
remember.insert(caller.to_string(), stack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO dump to file
|
pub fn save_backtraces(path: &str) {
|
||||||
// TODO manually call when events are created and at other interesting points
|
abstutil::write_json(path, &(*BACKTRACES.lock().unwrap())).unwrap();
|
||||||
// TODO compiler flag so capture_backtrace is usually a no-op
|
}
|
||||||
|
|
||||||
|
// TODO call from all interesting methods in a few different types; maybe use macros to help
|
||||||
|
// TODO compiler flag so capture_backtrace is usually a no-op. actually, looks like this doesn't
|
||||||
|
// work in --release mode, so use that.
|
||||||
|
// TODO script to organize and visualize results
|
||||||
|
@ -48,6 +48,7 @@ use dimensioned::si;
|
|||||||
pub use events::Event;
|
pub use events::Event;
|
||||||
use geom::{Angle, Pt2D};
|
use geom::{Angle, Pt2D};
|
||||||
pub use helpers::load;
|
pub use helpers::load;
|
||||||
|
pub use instrument::save_backtraces;
|
||||||
use map_model::{LaneID, Map, TurnID};
|
use map_model::{LaneID, Map, TurnID};
|
||||||
pub use sim::{Benchmark, Sim};
|
pub use sim::{Benchmark, Sim};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -7,6 +7,7 @@ use draw_car::DrawCar;
|
|||||||
use draw_ped::DrawPedestrian;
|
use draw_ped::DrawPedestrian;
|
||||||
use driving::DrivingSimState;
|
use driving::DrivingSimState;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
|
use instrument::capture_backtrace;
|
||||||
use intersections::IntersectionSimState;
|
use intersections::IntersectionSimState;
|
||||||
use kinematics::Vehicle;
|
use kinematics::Vehicle;
|
||||||
use map_model::{IntersectionID, LaneID, LaneType, Map, Turn, TurnID};
|
use map_model::{IntersectionID, LaneID, LaneType, Map, Turn, TurnID};
|
||||||
@ -169,6 +170,7 @@ impl Sim {
|
|||||||
&self.car_properties,
|
&self.car_properties,
|
||||||
)? {
|
)? {
|
||||||
events.push(Event::CarReachedParkingSpot(p.clone()));
|
events.push(Event::CarReachedParkingSpot(p.clone()));
|
||||||
|
capture_backtrace("CarReachedParkingSpot");
|
||||||
self.parking_state.add_parked_car(p.clone());
|
self.parking_state.add_parked_car(p.clone());
|
||||||
self.spawner.car_reached_parking_spot(
|
self.spawner.car_reached_parking_spot(
|
||||||
self.time,
|
self.time,
|
||||||
@ -185,6 +187,7 @@ impl Sim {
|
|||||||
.step(&mut events, TIMESTEP, map, &mut self.intersection_state)?
|
.step(&mut events, TIMESTEP, map, &mut self.intersection_state)?
|
||||||
{
|
{
|
||||||
events.push(Event::PedReachedParkingSpot(ped, spot));
|
events.push(Event::PedReachedParkingSpot(ped, spot));
|
||||||
|
capture_backtrace("PedReachedParkingSpot");
|
||||||
self.spawner.ped_reached_parking_spot(
|
self.spawner.ped_reached_parking_spot(
|
||||||
self.time,
|
self.time,
|
||||||
ped,
|
ped,
|
||||||
|
@ -138,7 +138,7 @@ impl TransitSimState {
|
|||||||
self.buses.get_mut(&car).unwrap().state =
|
self.buses.get_mut(&car).unwrap().state =
|
||||||
BusState::AtStop(stop_idx, time + 10.0 * si::S);
|
BusState::AtStop(stop_idx, time + 10.0 * si::S);
|
||||||
events.push(Event::BusArrivedAtStop(car, stop.id));
|
events.push(Event::BusArrivedAtStop(car, stop.id));
|
||||||
capture_backtrace();
|
capture_backtrace("BusArrivedAtStop");
|
||||||
if view.debug {
|
if view.debug {
|
||||||
println!("{} arrived at stop {:?}, now waiting", car, stop);
|
println!("{} arrived at stop {:?}, now waiting", car, stop);
|
||||||
}
|
}
|
||||||
@ -156,6 +156,7 @@ impl TransitSimState {
|
|||||||
let next_stop = route.next_stop(stop_idx);
|
let next_stop = route.next_stop(stop_idx);
|
||||||
self.buses.get_mut(&car).unwrap().state = BusState::DrivingToStop(next_stop);
|
self.buses.get_mut(&car).unwrap().state = BusState::DrivingToStop(next_stop);
|
||||||
events.push(Event::BusDepartedFromStop(car, stop.id));
|
events.push(Event::BusDepartedFromStop(car, stop.id));
|
||||||
|
capture_backtrace("BusDepartedFromStop");
|
||||||
if view.debug {
|
if view.debug {
|
||||||
println!("{} departing from stop {:?}", car, stop);
|
println!("{} departing from stop {:?}", car, stop);
|
||||||
}
|
}
|
||||||
@ -210,6 +211,7 @@ impl TransitSimState {
|
|||||||
for p in walking_sim.get_peds_waiting_at_stop(stop.id).into_iter() {
|
for p in walking_sim.get_peds_waiting_at_stop(stop.id).into_iter() {
|
||||||
if trips.should_ped_board_bus(p, b.route) {
|
if trips.should_ped_board_bus(p, b.route) {
|
||||||
events.push(Event::PedEntersBus(p, b.car));
|
events.push(Event::PedEntersBus(p, b.car));
|
||||||
|
capture_backtrace("PedEntersBus");
|
||||||
b.passengers.push(p);
|
b.passengers.push(p);
|
||||||
walking_sim.ped_joined_bus(p, stop.id);
|
walking_sim.ped_joined_bus(p, stop.id);
|
||||||
}
|
}
|
||||||
@ -226,6 +228,7 @@ impl TransitSimState {
|
|||||||
b.passengers.retain(|p| {
|
b.passengers.retain(|p| {
|
||||||
if trips.should_ped_leave_bus(*p, stop.id) {
|
if trips.should_ped_leave_bus(*p, stop.id) {
|
||||||
events.push(Event::PedLeavesBus(*p, car));
|
events.push(Event::PedLeavesBus(*p, car));
|
||||||
|
capture_backtrace("PedLeavesBus");
|
||||||
// TODO would be a little cleaner to return this info up to sim and have it
|
// TODO would be a little cleaner to return this info up to sim and have it
|
||||||
// plumb through to spawner? not sure
|
// plumb through to spawner? not sure
|
||||||
spawner.ped_finished_bus_ride(now, *p, stop.id, trips, map);
|
spawner.ped_finished_bus_ride(now, *p, stop.id, trips, map);
|
||||||
|
@ -4,6 +4,7 @@ use dimensioned::si;
|
|||||||
use draw_ped::DrawPedestrian;
|
use draw_ped::DrawPedestrian;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use geom::{Line, Pt2D};
|
use geom::{Line, Pt2D};
|
||||||
|
use instrument::capture_backtrace;
|
||||||
use intersections::{IntersectionSimState, Request};
|
use intersections::{IntersectionSimState, Request};
|
||||||
use map_model::{BuildingID, BusStop, IntersectionID, Lane, LaneID, Map, Turn, TurnID};
|
use map_model::{BuildingID, BusStop, IntersectionID, Lane, LaneID, Map, Turn, TurnID};
|
||||||
use multimap::MultiMap;
|
use multimap::MultiMap;
|
||||||
@ -216,6 +217,7 @@ impl Pedestrian {
|
|||||||
fp.dist_along -= new_dist;
|
fp.dist_along -= new_dist;
|
||||||
if fp.dist_along < 0.0 * si::M {
|
if fp.dist_along < 0.0 * si::M {
|
||||||
events.push(Event::PedReachedBuilding(self.id, fp.bldg));
|
events.push(Event::PedReachedBuilding(self.id, fp.bldg));
|
||||||
|
capture_backtrace("PedReachedBuilding");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
@ -399,6 +401,7 @@ impl WalkingSimState {
|
|||||||
Action::WaitAtBusStop(stop) => {
|
Action::WaitAtBusStop(stop) => {
|
||||||
self.peds.get_mut(&id).unwrap().active = false;
|
self.peds.get_mut(&id).unwrap().active = false;
|
||||||
events.push(Event::PedReachedBusStop(*id, stop));
|
events.push(Event::PedReachedBusStop(*id, stop));
|
||||||
|
capture_backtrace("PedReachedBusStop");
|
||||||
self.peds_per_bus_stop.insert(stop, *id);
|
self.peds_per_bus_stop.insert(stop, *id);
|
||||||
}
|
}
|
||||||
Action::StartParkedCar(ref spot) => {
|
Action::StartParkedCar(ref spot) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user