diff options
author | Sverker Eriksson <[email protected]> | 2012-02-20 19:52:13 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2012-02-21 12:10:40 +0100 |
commit | 75b831aa879234db6d8821a32f4c411ef6cfc6ff (patch) | |
tree | 96018e44b4915f152484a6f6a770f0c064c07fc4 /lib/stdlib | |
parent | 520ddbc83ec87bcec262680bd915184182e3998e (diff) | |
download | otp-75b831aa879234db6d8821a32f4c411ef6cfc6ff.tar.gz otp-75b831aa879234db6d8821a32f4c411ef6cfc6ff.tar.bz2 otp-75b831aa879234db6d8821a32f4c411ef6cfc6ff.zip |
erts: Fix bignum-bug in ETS with compressed option
A large 64-bit immediate number will be stored as SMALL_BIG_EXT by ETS
compressed format. When uncompressing, the SMALL_BIG_EXT was first
decoded as as bignum (by bytes_to_big) and then turned into a small
(by big_norm). This works for normal "binary_to_term" as
decoded_size() over-estimates the needed heap size. But for ETS no
over-estimation is done as the real term size is known and stored in
DbTerm.
Fixed by preventing bytes_to_big() from writing bignum digit when the
number is seen to fit in an immediate.
Diffstat (limited to 'lib/stdlib')
-rw-r--r-- | lib/stdlib/test/ets_SUITE.erl | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 101828fdef..59532b65a0 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -72,6 +72,7 @@ exit_many_many_tables_owner/1]). -export([write_concurrency/1, heir/1, give_away/1, setopts/1]). -export([bad_table/1, types/1]). +-export([otp_9932/1]). -export([otp_9423/1]). -export([init_per_testcase/2, end_per_testcase/2]). @@ -145,6 +146,7 @@ all() -> exit_many_large_table_owner, exit_many_tables_owner, exit_many_many_tables_owner, write_concurrency, heir, give_away, setopts, bad_table, types, + otp_9932, otp_9423]. groups() -> @@ -5434,6 +5436,22 @@ types_do(Opts) -> ?line verify_etsmem(EtsMem). +%% OTP-9932: Memory overwrite when inserting large integers in compressed bag. +%% Will crash with segv on 64-bit opt if not fixed. +otp_9932(Config) when is_list(Config) -> + T = ets:new(xxx, [bag, compressed]), + Fun = fun(N) -> + Key = {1316110174588445 bsl N,1316110174588583 bsl N}, + S = {Key, Key}, + true = ets:insert(T, S), + [S] = ets:lookup(T, Key), + true = ets:insert(T, S), + [S] = ets:lookup(T, Key) + end, + lists:foreach(Fun, lists:seq(0, 16)), + ets:delete(T). + + otp_9423(doc) -> ["vm-deadlock caused by race between ets:delete and others on write_concurrency table"]; otp_9423(Config) when is_list(Config) -> InitF = fun(_) -> {0,0} end, |