Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug is enabled but there is no output #273

Open
Rlyown opened this issue May 6, 2024 · 5 comments
Open

Debug is enabled but there is no output #273

Rlyown opened this issue May 6, 2024 · 5 comments

Comments

@Rlyown
Copy link

Rlyown commented May 6, 2024

Issue description

Hi,

When I run my application, I encounter the following error message. I have set "debug": true in enclave.json, but it didn't work for me.

ERROR: Invalid exception occurred. The enclave is aborting. [openenclave-src/host/sgx/exception.c:oe_host_handle_exception:111]
ERROR: Unhandled in-enclave exception. To get more information, configure the enclave with CapturePFGPExceptions=1 and enable the in-enclave logging. [openenclave-src/host/sgx/linux/exception.c:_host_signal_handler:101]
ERROR: signal: segmentation fault (core dumped)

I also tried https://docs.edgeless.systems/ego/reference/config#advanced-users-tweak-underlying-enclave-configuration, it didn't work too.

This my enclave.json

{
  "exe": "test",
  "key": "private.pem",
  "debug": true,
  "heapSize": 2048,
  "executableHeap": false,
  "productID": 1,
  "securityVersion": 1
}

And this is the enclave.conf.

Debug=1
NumHeapPages=131072
NumStackPages=1024
NumTCS=32
ProductID=1
SecurityVersion=1
CapturePFGPExceptions=1

Could anyone give me some advice to debug this?

To reproduce

Steps to reproduce the behavior:

  1. ego-go build test.go
  2. ego sign
  3. /snap/ego-dev/current/opt/ego/bin/ego-oesign sign -e /snap/ego-dev/current/opt/ego/share/ego-enclave -c enclave.conf -k private.pem --payload test
  4. ego run test
  5. ./test

By the way, in step 4, I got segmentation fault. But in step 5, the application executes normally.

@Rlyown
Copy link
Author

Rlyown commented May 7, 2024

Finally I fixed my bugs by printf() debugging. But I still confused, the debug flag does not take effect.

@thomasten
Copy link
Member

Hi, I think CapturePFGPExceptions=1 doesn't work for all types of exceptions. Now that you know the bug, can you provide a minimal reproduction so that we can check if this is the case here?
For debugging, you could have used ego-gdb, which should stop when the exception happens.

@Rlyown
Copy link
Author

Rlyown commented May 8, 2024

Minimal sample code

I called a function from a library written in C using cgo. This function caused the program to crash. It allocates a block of memory via mmap and then writes the base address of that memory to the GS register.

It was precisely this action of writing to the GS register that led to the "ERROR: signal: segmentation fault (core dumped)". The program ran normally after I removed the line os_writegsbase(new_mem);.

This is a sample.

package main

import "fmt"

/*
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>

// write base addr of memory to GS segment register
#define os_writegsbase(base_addr)                                 \
    do {                                                          \
        uint64_t __gs_value = (uint64_t)(uint64_t *)base_addr;    \
        asm volatile("wrgsbase %0" ::"r"(__gs_value) : "memory"); \
    } while (0)

int mmap_function() {
  uint64_t new_size = 128 * 1024 * 1024; // 128 MB

  void *new_mem =
      mmap(NULL, new_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

#if defined(os_writegsbase)
  // the code crashed here in sgx mode
  os_writegsbase(new_mem);
#endif

  if (new_mem == MAP_FAILED) {
    perror("mmap error");
    return -1;
  }

  munmap(new_mem, new_size);

  return 0;
}
*/
import "C"

// the wrapper to call function in C
func CallMmapFunction() int {
        res := C.mmap_function()
        return int(res)
}

func main() {
        res := CallMmapFunction()
        fmt.Println(res)
}

To reproduce

The enclave.json is the same as the one I mentioned above.

  1. ego-go build test.go
  2. ego sign
  3. ego run test

@Rlyown
Copy link
Author

Rlyown commented May 8, 2024

Sorry I don't know much about open enclave or edgelessrt. I tried ego-gdb, but the output in this case is a bit hard to understand for me. Judging from the backtrace results, it seems that where it stops is not quite consistent with my expectations.

image

Sometimes when I rerun ego-gdb test, it gives me a different output.

image

@thomasten
Copy link
Member

Regarding SIGILL, see https://docs.edgeless.systems/ego/workflows/debug#inside-an-enclave

Thanks for the sample code. This can be tricky to debug. The gs register is used by the SGX runtime. If it is modified by the app, the runtime will most probably crash the next time it reads the register and uses the value. You can see the location of the crash in ego-gdb, but it's not obvious what caused it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants