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

dlmalloc: require __heap_end #394

Merged
merged 7 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,26 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
# oldest and newest supported LLVM version
clang_version: [10.0.0, 14.0.0]
clang_version: [10.0.0]
# use different LLVM versions among oses because of the lack of
# official assets on github.
include:
- os: ubuntu-latest
clang_version: 10.0.0
llvm_asset_suffix: x86_64-linux-gnu-ubuntu-18.04
- os: macos-latest
clang_version: 10.0.0
llvm_asset_suffix: x86_64-apple-darwin
- os: windows-latest
clang_version: 10.0.0
- os: ubuntu-latest
clang_version: 16.0.0
llvm_asset_suffix: x86_64-linux-gnu-ubuntu-18.04
- os: macos-latest
clang_version: 15.0.7
llvm_asset_suffix: x86_64-apple-darwin21.0
- os: windows-latest
clang_version: 16.0.0
steps:
- uses: actions/checkout@v1
with:
Expand Down Expand Up @@ -44,8 +62,8 @@ jobs:
- name: Install LLVM tools (MacOS)
shell: bash
run: |
curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.clang_version }}/clang+llvm-${{ matrix.clang_version }}-x86_64-apple-darwin.tar.xz | tar xJf -
export CLANG_DIR=`pwd`/clang+llvm-${{ matrix.clang_version }}-x86_64-apple-darwin/bin
curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.clang_version }}/clang+llvm-${{ matrix.clang_version }}-${{ matrix.llvm_asset_suffix }}.tar.xz | tar xJf -
export CLANG_DIR=`pwd`/clang+llvm-${{ matrix.clang_version }}-${{ matrix.llvm_asset_suffix }}/bin
echo "$CLANG_DIR" >> $GITHUB_PATH
echo "CC=$CLANG_DIR/clang" >> $GITHUB_ENV
echo "AR=$CLANG_DIR/llvm-ar" >> $GITHUB_ENV
Expand All @@ -55,8 +73,8 @@ jobs:
- name: Install LLVM tools (Linux)
shell: bash
run: |
curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.clang_version }}/clang+llvm-${{ matrix.clang_version }}-x86_64-linux-gnu-ubuntu-18.04.tar.xz | tar xJf -
export CLANG_DIR=`pwd`/clang+llvm-${{ matrix.clang_version }}-x86_64-linux-gnu-ubuntu-18.04/bin
curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.clang_version }}/clang+llvm-${{ matrix.clang_version }}-${{ matrix.llvm_asset_suffix }}.tar.xz | tar xJf -
export CLANG_DIR=`pwd`/clang+llvm-${{ matrix.clang_version }}-${{ matrix.llvm_asset_suffix }}/bin
echo "$CLANG_DIR" >> $GITHUB_PATH
echo "CLANG_DIR=$CLANG_DIR" >> $GITHUB_ENV
echo "CC=$CLANG_DIR/clang" >> $GITHUB_ENV
Expand All @@ -76,12 +94,14 @@ jobs:
run: |
cd test
make download
export WASI_DIR=$(realpath $CLANG_DIR/../lib/clang/${{ matrix.clang_version }}/lib/wasi/)
export WASI_DIR=$(realpath $($CLANG_DIR/clang -print-resource-dir)/lib/wasi/)
mkdir -p $WASI_DIR
cp download/lib/wasi/libclang_rt.builtins-wasm32.a $WASI_DIR
make test
# The older version of Clang does not provide the expected symbol for the
# test entrypoints: `undefined symbol: __main_argc_argv`.
# The older (<15.0.7) version of wasm-ld does not provide `__heap_end`,
# which is required by our malloc implementation.
if: matrix.os == 'ubuntu-latest' && matrix.clang_version != '10.0.0'

- uses: actions/upload-artifact@v1
Expand Down
29 changes: 12 additions & 17 deletions dlmalloc/src/malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -5215,7 +5215,7 @@ static void internal_inspect_all(mstate m,

/* Symbol marking the end of data, bss and explicit stack, provided by wasm-ld. */
extern char __heap_base;
extern char __heap_end __attribute__((__weak__));
extern char __heap_end;

/* Initialize the initial state of dlmalloc to be able to use free memory between __heap_base and initial. */
static void try_init_allocator(void) {
Expand All @@ -5227,23 +5227,18 @@ static void try_init_allocator(void) {

char *base = &__heap_base;
// Try to use the linker pseudo-symbol `__heap_end` for the initial size of
// the heap, but if that's not defined due to LLVM being too old perhaps then
// round up `base` to the nearest `PAGESIZE`. The initial size of linear
// memory will be at least the heap base to this page boundary, and it's then
// assumed that the initial linear memory image was truncated at that point.
// While this reflects the default behavior of `wasm-ld` it is also possible
// for users to craft larger linear memories by passing options to extend
// beyond this threshold. In this situation the memory will not be used for
// dlmalloc.
//
// Note that `sbrk(0)`, or in dlmalloc-ese `CALL_MORECORE(0)`, is specifically
// not used here. That captures the current size of the heap but is only
// correct if the we're the first to try to grow the heap. If the heap has
// grown elsewhere, such as a different allocator in place, then this would
// incorrectly claim such memroy as our own.
// the heap.
char *end = &__heap_end;
if (end == NULL)
end = (char*) page_align((size_t) base);
if (end < base) {
// "end" can be NULL when 1. you are using an old wasm-ld which doesn't
// provide `__heap_end` (< 15.0.7) and 2. something (other libraries
// or maybe your app?) includes a weak reference to `__heap_end` and
// 3. the weak reference is found by the linker before this strong
// reference.
//
// Note: This is a linker bug: https://github.com/llvm/llvm-project/issues/60829
__builtin_trap();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just remove this block and assume end is non-NULL.

llvm/llvm-project#60829 has been closed (and its really inconceivable to me that somebody would provide a weak definition of this (internal) symbol). If you want to keep some kind of check then perhaps just assert(end); with note referring to the bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its really inconceivable to me that somebody would provide a weak definition of this (internal) symbol

i actually have seen such a code. dump these values for diagnostic purposes.

If you want to keep some kind of check then perhaps just assert(end); with note referring to the bug.

it's rare for users to use wasi-libc w/o NDEBUG.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its really inconceivable to me that somebody would provide a weak definition of this (internal) symbol

i actually have seen such a code. dump these values for diagnostic purposes.

But I don't think we want to support that configuration, right? Why would somebody weakly define a linker-internal symbol? Can you point to the place where you have seen this? Maybe just if (!end) abort() in that case, with a TODO to remove once we can depend on the llvm that contains that fix?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its really inconceivable to me that somebody would provide a weak definition of this (internal) symbol

i actually have seen such a code. dump these values for diagnostic purposes.

But I don't think we want to support that configuration, right? Why would somebody weakly define a linker-internal symbol?

diagnostic purposes.
it just dumps something potentially useful for later trouble shooting.

Can you point to the place where you have seen this?

not open source.
but it's something similar to https://github.com/yamt/garbage/blob/03f9a1a1ee142194905818380f7f0e34287f9c64/wasm/hello/hello.c#L48

Maybe just if (!end) abort() in that case, with a TODO to remove once we can depend on the llvm that contains that fix?

i feel it's too early to assume https://reviews.llvm.org/D144747
given that even the latest wasi-sdk doesn't have the fix yet.

size_t initial_heap_size = end - base;

/* Check that initial heap is long enough to serve a minimal allocation request. */
Expand Down
1 change: 1 addition & 0 deletions expected/wasm32-wasi-threads/undefined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ __getf2
__global_base
__gttf2
__heap_base
__heap_end
__imported_wasi_snapshot_preview1_args_get
__imported_wasi_snapshot_preview1_args_sizes_get
__imported_wasi_snapshot_preview1_clock_res_get
Expand Down
1 change: 1 addition & 0 deletions expected/wasm32-wasi/undefined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ __floatunsitf
__getf2
__gttf2
__heap_base
__heap_end
__imported_wasi_snapshot_preview1_args_get
__imported_wasi_snapshot_preview1_args_sizes_get
__imported_wasi_snapshot_preview1_clock_res_get
Expand Down