1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#![allow(unused_variables)]
use async_std::{
net::{TcpListener, TcpStream, ToSocketAddrs},
prelude::*,
task,
};
use futures::channel::mpsc;
use gdb_protocol::packet::CheckedPacket;
use probe_rs::Session;
use std::sync::atomic::AtomicUsize;
use std::sync::{Arc, Mutex};
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
type Sender<T> = mpsc::UnboundedSender<T>;
type Receiver<T> = mpsc::UnboundedReceiver<T>;
const CONNECTION_STRING: &str = "127.0.0.1:1337";
pub fn run(connection_string: Option<impl AsRef<str>>, session: Arc<Mutex<Session>>) -> Result<()> {
let connection_string = connection_string
.map(|cs| cs.as_ref().to_owned())
.unwrap_or_else(|| CONNECTION_STRING.to_owned());
println!("GDB stub listening on {}", connection_string);
task::block_on(accept_loop(connection_string, session))
}
async fn accept_loop(addr: impl ToSocketAddrs, session: Arc<Mutex<Session>>) -> Result<()> {
let listener = TcpListener::bind(addr).await?;
let mut incoming = listener.incoming();
while let Some(stream) = incoming.next().await {
let (packet_stream_sender, packet_stream_receiver) = mpsc::unbounded();
let acks_due = Arc::new(AtomicUsize::new(0));
let (tbd_sender, tbd_receiver) = mpsc::unbounded();
let stream = Arc::new(stream?);
let inbound_broker_handle = task::spawn(inbound_broker_loop(
Arc::clone(&stream),
tbd_sender,
packet_stream_receiver,
acks_due,
));
if let Err(e) =
super::worker::worker(tbd_receiver, packet_stream_sender, session.clone()).await
{
eprintln!(
"An error with the current connection has been encountered. It has been closed."
);
eprintln!("{:?}", e);
};
println!("Accepted a new connection from: {}", stream.peer_addr()?);
if let Err(e) = inbound_broker_handle.await {
eprintln!(
"An error with the current connection has been encountered. It has been closed."
);
eprintln!("{:?}", e);
}
}
Ok(())
}
async fn inbound_broker_loop(
stream: Arc<TcpStream>,
packet_stream: Sender<CheckedPacket>,
mut packet_stream_2: Receiver<CheckedPacket>,
acks_due: Arc<AtomicUsize>,
) -> Result<()> {
use futures::future::FutureExt;
let mut buffer = vec![];
let mut tmp_buf = [0; 1024];
#[allow(clippy::unnecessary_mut_passed)]
loop {
let mut packet_stream_2 = packet_stream_2.next().fuse();
let mut s = &*stream;
let mut read = s.read(&mut tmp_buf).fuse();
let t = std::time::Instant::now();
futures::select! {
packet = packet_stream_2 => {
if let Some(packet) = packet {
super::writer::writer(packet, stream.clone(), packet_stream.clone(), &mut buffer).await?
}
},
n = read => {
match n {
Ok(n) => {
if n == 0 {
println!("GDB connection closed.");
break Ok(());
}
buffer.extend(&tmp_buf[0..n]);
log::info!("Current buf {}", String::from_utf8_lossy(&buffer));
super::reader::reader(stream.clone(), packet_stream.clone(), &mut buffer).await?
},
Err(e) => {
}
}
}
}
}
}