Add GDB support for apps running upon Occlum

Please see the "gdb_support" in demos to find out how to
use GDB to debug your apps running upon Occlum.
This commit is contained in:
LI Qing 2020-02-04 08:01:42 +00:00
parent de904bf628
commit bd56504b20
8 changed files with 107 additions and 8 deletions

@ -23,5 +23,6 @@ This set of demos shows how real-world apps can be easily run inside SGX enclave
## Other demos
* `remote_attestation/`: This project demonstrates how an app running upon Occlum can perform SGX remote attestation.
* `embedded_mode/`: A cross-enclave memory throughput benchmark enabled by the embedded mode of Occlum.
* `gdb_support/`: This demo explains the technical detail of GDB support and demonstrates how to debug an app running upon Occlum with GDB.
* `remote_attestation/`: This project demonstrates how an app running upon Occlum can perform SGX remote attestation.

2
demos/gdb_support/.gitignore vendored Normal file

@ -0,0 +1,2 @@
sample
occlum_context

@ -0,0 +1,26 @@
# GDB support for apps running upon Occlum
## GDB support
We modified the GDB SGX plugin to support debugging the apps running upon Occlum. After Occlum loaded app's executable file and its dependencies(e.g. libc) from the secure FS, it notifies GDB to load the symbols from elf file to the correct address allocated by Occlum, so GDB can find all the symbols of the running app.
Currently, GDB cannot unload the app's symbols after running by Occlum, `gdb attach` command is not supported, and the backtrace cannot link the app with Occlum, we will support these features in the later version.
## How to use
Step 1: Build the sample app with debugging symbols, add `-g` flags generally
```
./build_sample_with_symbols.sh
```
Step 2: Debug the sample app running on Occlum via `occlum gdb`
```
./gdb_sample_on_occlum.sh
```
When completed, shell changes to GDB.
Step 3: Type `run` in the GDB shell to run the sample app
```
(gdb) run
```
GDB will stop at the `divide_by_zero` function because of the arithmetic exception.

@ -0,0 +1,5 @@
#!/bin/bash
set -e
rm -rf sample
occlum-gcc -g sample.c -o sample

@ -0,0 +1,14 @@
#!/bin/bash
set -e
rm -rf occlum_context && mkdir -p occlum_context
cd occlum_context
# 1. Initialize a directory as the Occlum context
occlum init
# 2. Generate a secure Occlum FS image and Occlum SGX enclave
cp ../sample image/bin
occlum build
# 3. Debug the user program inside an SGX enclave with GDB
occlum gdb /bin/sample

@ -0,0 +1,18 @@
#include <stdio.h>
// GDB will stop here
int divide_by_zero(int num) {
int result;
int zero = 0;
result = num / zero;
return result;
}
int main() {
int ret;
printf("Start to calculate\n");
ret = divide_by_zero(1);
return 0;
}

@ -41,6 +41,10 @@ pub fn do_spawn_without_exec(
Ok(new_tid)
}
// This function is used to provide information to debugger, so it is empty. Please do not remove it.
#[no_mangle]
pub extern "C" fn occlum_gdb_hook_load_elf(elf_base: u64, elf_path: &str, elf_path_len: usize) {}
fn new_process(
elf_path: &str,
argv: &[CString],
@ -63,6 +67,13 @@ fn new_process(
let cwd = parent_ref.lock().unwrap().get_cwd().to_owned();
let vm = init_vm::do_init(&exec_elf_file, &ldso_elf_file)?;
let auxtbl = init_auxtbl(&vm, &exec_elf_file)?;
// Notify debugger to load the symbols from elf file
let ldso_elf_base = vm.get_elf_ranges()[1].start() as u64;
occlum_gdb_hook_load_elf(ldso_elf_base, ldso_path, ldso_path.len());
let exec_elf_base = vm.get_elf_ranges()[0].start() as u64;
occlum_gdb_hook_load_elf(exec_elf_base, elf_path, elf_path.len());
let task = {
let ldso_entry = {
let ldso_range = vm.get_elf_ranges()[1];

@ -7,6 +7,7 @@ working_dir=`pwd`
context_dir="$working_dir/.occlum"
SGX_SDK="${SGX_SDK:-/opt/intel/sgxsdk}"
SGX_GDB="$SGX_SDK/bin/sgx-gdb"
ENCLAVE_SIGN_TOOL="$SGX_SDK/bin/x64/sgx_sign"
ENCLAVE_SIGN_KEY="$occlum_dir/etc/template/Enclave.pem"
@ -18,13 +19,22 @@ exit_error() {
report_arg_error() {
echo $1 >&2
echo ""
echo "Usage:"
echo " occlum init"
echo " occlum build [--sign-key <key_path>] [--sign-tool <tool_path>]"
echo " occlum run <program_name> <program_args>"
echo ""
echo " Run enclave in sgx release mode:"
echo " OCCLUM_RELEASE_ENCLAVE=1 occlum run <program_name> <program_args>"
cat <<EOF
Usage:
occlum init
Initialize a directory as the Occlum context
occlum build [--sign-key <key_path>] [--sign-tool <tool_path>]
Generate a secure Occlum FS image and Occlum SGX enclave.
occlum run <program_name> <program_args>
Run the user program inside an SGX enclave.
To run the enclave in SGX hardware release mode, use:
OCCLUM_RELEASE_ENCLAVE=1 occlum run <program_name> <program_args>
occlum gdb <program_name> <program_args>
Debug the program running inside an SGX enclave with GDB.
EOF
}
get_conf_default_stack_size() {
@ -180,6 +190,15 @@ cmd_run() {
echo "built" > "$context_dir/status"
}
cmd_gdb() {
cd "$working_dir"
echo "debugging" > "$context_dir/status"
OCCLUM_GDB=1 LD_LIBRARY_PATH="$context_dir/build/lib" $SGX_GDB --args "$context_dir/build/bin/occlum-run" "$@"
echo "built" > "$context_dir/status"
}
cmd_status() {
cat "$context_dir/status"
}
@ -202,6 +221,9 @@ case "$cmd" in
run)
cmd_run "${@:2}"
;;
gdb)
cmd_gdb "${@:2}"
;;
status)
cmd_status
;;