Verified Commit ce8e8b58 authored by jD91mZM2's avatar jD91mZM2

Fix signal-handling on Linux

parent e0064288
......@@ -26,6 +26,11 @@ dependencies = [
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.2.1"
......@@ -77,6 +82,8 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"strum 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"strum_macros 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -91,6 +98,7 @@ dependencies = [
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (git+https://gitlab.redox-os.org/redox-os/syscall.git)",
"strace 0.1.0 (git+https://gitlab.redox-os.org/redox-os/strace-redox)",
"structopt 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -159,6 +167,24 @@ dependencies = [
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-derive"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro-error"
version = "1.0.3"
......@@ -458,6 +484,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)" = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
......@@ -472,6 +499,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
"checksum num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c8b15b261814f992e33760b1fca9fe8b693d8a65299f20c9901688636cfb746"
"checksum num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
"checksum proc-macro-error 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880"
"checksum proc-macro-error-attr 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
......
......@@ -3,6 +3,7 @@ name = "gdbserver"
version = "0.1.0"
authors = ["jD91mZM2 <me@krake.one>"]
edition = "2018"
default-run = "gdbserver"
[dependencies]
gdb-remote-protocol = { path = "rust-gdb-remote-protocol" }
......@@ -11,6 +12,7 @@ memchr = "2.3.3"
env_logger = "0.7.1"
log = "0.4.8"
byteorder = "1.3.4"
num-traits = "0.2.12"
# f80 = { git = "https://gitlab.redox-os.org/redox-os/f80.git", rev = "d8de286" }
[[bin]]
......
all: minimal-asm redox-asm minimal-c
all: minimal-asm redox-asm minimal-c signal-c
clean:
rm minimal-asm redox-asm minimal-c
......
#include <stdio.h>
#include <signal.h>
int main() {
puts("Raising signal...");
raise(SIGUSR1);
puts("Raised signal");
}
Subproject commit 30a62316a98c4288287269717a28a558c97b8d82
Subproject commit 8230d289c59d53a7122de7d30ba3607602571fca
......@@ -9,8 +9,9 @@ use std::{
use gdb_remote_protocol::{
Error, FileSystem, Handler, Id, LibcFS, MemoryRegion, ProcessType,
StopReason, ThreadId, VCont, VContFeature,
Signal, StopReason, ThreadId, VCont, VContFeature,
};
use num_traits::FromPrimitive;
use log::debug;
use structopt::StructOpt;
......@@ -26,7 +27,7 @@ const ERROR_GET_PATH: u8 = std::u8::MAX - 1;
#[derive(Debug, StructOpt)]
pub struct Opt {
/// The address which to bind the server to
#[structopt(short = "a", long = "addr", default_value = "0.0.0.0:64126")]
#[structopt(short = "a", long = "addr", default_value = "127.0.0.1:64126")]
pub addr: String,
/// The type of address specified
#[structopt(short = "t", long = "type", default_value = "tcp", possible_values = &["tcp", "unix", "stdio"])]
......@@ -112,13 +113,13 @@ impl Handler for App {
self.tracee.cont(None)?;
}
VCont::ContinueWithSignal(signal) => {
self.tracee.cont(Some(signal))?;
self.tracee.cont(Signal::from_u8(signal).and_then(Signal::to_libc).map(|s| s as u8))?;
}
VCont::Step => {
self.tracee.step(None)?;
}
VCont::StepWithSignal(signal) => {
self.tracee.step(Some(signal))?;
self.tracee.step(Signal::from_u8(signal).and_then(Signal::to_libc).map(|s| s as u8))?;
}
VCont::RangeStep(ref range) => {
// std::ops::Range<T: Copy> should probably also be Copy, but it isn't.
......@@ -129,7 +130,9 @@ impl Handler for App {
break;
}
Ok(self.tracee.status())
let status = self.tracee.status();
debug!("vCont sending status {:?}", status);
Ok(status)
}
fn read_bytes(&self, object: String, annex: String, offset: u64, length: u64) -> Result<(Vec<u8>, bool)> {
let transfer_bytes = |source: &[u8]| -> Result<(Vec<u8>, bool)> {
......
......@@ -135,7 +135,7 @@ impl super::Target for Os {
}
}
fn status(&self) -> StopReason {
fn status_native(&self) -> StopReason {
unsafe {
if libc::WIFEXITED(self.last_status.get()) {
StopReason::Exited(
......@@ -238,6 +238,9 @@ impl super::Target for Os {
registers.xmm15 = Some(float.xmm_space[15] as _);
registers.mxcsr = Some(float.mxcsr);
registers.fs_base = Some(int.fs_base as _);
registers.gs_base = Some(int.gs_base as _);
Ok(registers)
}
......@@ -318,6 +321,9 @@ impl super::Target for Os {
.unwrap_or(float.xmm_space[15]);
float.mxcsr = registers.mxcsr.unwrap_or(float.mxcsr);
int.fs_base = registers.fs_base.unwrap_or(int.fs_base);
int.gs_base = registers.gs_base.unwrap_or(int.gs_base);
unsafe {
e!(libc::ptrace(libc::PTRACE_SETREGS, self.pid, 0, &int));
e!(libc::ptrace(libc::PTRACE_SETFPREGS, self.pid, 0, &float));
......
......@@ -2,7 +2,7 @@ use crate::Result;
use std::ops::RangeBounds;
use gdb_remote_protocol::StopReason;
use gdb_remote_protocol::{StopReason, Signal};
mod regs;
......@@ -21,7 +21,21 @@ pub trait Target: Sized {
fn new(program: String, args: Vec<String>) -> Result<Os, Box<dyn std::error::Error>>;
/// Get the last status of the tracee
fn status(&self) -> StopReason;
fn status_native(&self) -> StopReason;
/// Get the last status of the tracee, but convert it from libc signals to GDB signals
fn status(&self) -> StopReason {
match self.status_native() {
StopReason::Signal(sig) => StopReason::Signal(
Signal::from_libc(libc::c_int::from(sig)).unwrap_or(Signal::SIGTRAP) as u8,
),
StopReason::ExitedWithSignal(pid, sig) => StopReason::ExitedWithSignal(
pid,
Signal::from_libc(libc::c_int::from(sig)).unwrap_or(Signal::SIGTERM) as u8,
),
status => status,
}
}
/// Get the process/thread id
fn pid(&self) -> u32;
......
......@@ -166,7 +166,7 @@ impl super::Target for Os {
}
}
fn status(&self) -> StopReason {
fn status_native(&self) -> StopReason {
if syscall::wifexited(self.last_status.get()) {
StopReason::Exited(
self.pid as _,
......
......@@ -60,13 +60,16 @@ pub struct Registers {
pub xmm14: Option<u128>,
pub xmm15: Option<u128>,
pub mxcsr: Option<u32>,
pub fs_base: Option<u64>,
pub gs_base: Option<u64>,
}
impl Registers {
// The following sadly assume the endianness in order to only read
// 10 bits in the st* stuff instead of the full 16.
#[rustfmt::skip] // formatting can only make this horrible code look worse
pub fn decode(mut input: &[u8]) -> Self {
Self {
let res = Self {
rax: Some(input.read_u64::<NativeEndian>().unwrap()),
rbx: Some(input.read_u64::<NativeEndian>().unwrap()),
rcx: Some(input.read_u64::<NativeEndian>().unwrap()),
......@@ -92,14 +95,14 @@ impl Registers {
fs: Some(input.read_u32::<NativeEndian>().unwrap()),
gs: Some(input.read_u32::<NativeEndian>().unwrap()),
st0: Some(0),
st1: Some(0),
st2: Some(0),
st3: Some(0),
st4: Some(0),
st5: Some(0),
st6: Some(0),
st7: Some(0),
st0: Some(input.read_u64::<NativeEndian>().map(|_| 0).unwrap()),
st1: Some(input.read_u64::<NativeEndian>().map(|_| 0).unwrap()),
st2: Some(input.read_u64::<NativeEndian>().map(|_| 0).unwrap()),
st3: Some(input.read_u64::<NativeEndian>().map(|_| 0).unwrap()),
st4: Some(input.read_u64::<NativeEndian>().map(|_| 0).unwrap()),
st5: Some(input.read_u64::<NativeEndian>().map(|_| 0).unwrap()),
st6: Some(input.read_u64::<NativeEndian>().map(|_| 0).unwrap()),
st7: Some(input.read_u64::<NativeEndian>().map(|_| 0).unwrap()),
fctrl: Some(input.read_u32::<NativeEndian>().unwrap()),
fstat: Some(input.read_u32::<NativeEndian>().unwrap()),
ftag: Some(input.read_u32::<NativeEndian>().unwrap()),
......@@ -126,7 +129,12 @@ impl Registers {
xmm14: Some(input.read_u128::<NativeEndian>().unwrap()),
xmm15: Some(input.read_u128::<NativeEndian>().unwrap()),
mxcsr: Some(input.read_u32::<NativeEndian>().unwrap()),
}
fs_base: Some(input.read_u64::<NativeEndian>().unwrap()),
gs_base: Some(input.read_u64::<NativeEndian>().unwrap()),
};
assert!(input.is_empty(), "Input must be empty after parsing registers");
res
}
#[rustfmt::skip] // formatting can only make this horrible code look worse
pub fn encode(&self, output: &mut Vec<u8>) {
......@@ -189,5 +197,8 @@ impl Registers {
output.write_u128::<NativeEndian>(self.xmm14.unwrap_or(0)).unwrap();
output.write_u128::<NativeEndian>(self.xmm15.unwrap_or(0)).unwrap();
output.write_u32::<NativeEndian>(self.mxcsr.unwrap_or(0)).unwrap();
output.write_u64::<NativeEndian>(self.fs_base.unwrap_or(0)).unwrap();
output.write_u64::<NativeEndian>(self.gs_base.unwrap_or(0)).unwrap();
}
}
......@@ -69,4 +69,9 @@
<reg name="xmm15" bitsize="128" type="float" group="float" />
<reg name="mxcsr" bitsize="32" type="float" group="float" />
</feature>
<feature name="org.gnu.gdb.i386.segments">
<reg name="fs_base" bitsize="64" group="general" />
<reg name="gs_base" bitsize="64" group="general" />
</feature>
</target>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment