diff options
123 files changed, 1534 insertions, 3771 deletions
diff --git a/erts/doc/src/erl_tracer.xml b/erts/doc/src/erl_tracer.xml index 63feebb0b5..fd3c17f337 100644 --- a/erts/doc/src/erl_tracer.xml +++ b/erts/doc/src/erl_tracer.xml @@ -653,7 +653,7 @@ ok <0.37.0> 3> erlang:trace(new, true, [send,{tracer, erl_msg_tracer, Tracer}]). 0 -{<0.39.0>,<0.27.0>} +{trace,<0.39.0>,<0.27.0>} 4> {ok, D} = file:open("/tmp/tmp.data",[write]). {trace,#Port<0.486>,<0.40.0>} {trace,<0.40.0>,<0.21.0>} @@ -758,18 +758,21 @@ static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) /* * argv[0]: TraceTag, should only be 'send' - * argv[1]: TracerState, process to send {argv[2], argv[4]} to + * argv[1]: TracerState, process to send {Tracee, Recipient} to * argv[2]: Tracee - * argv[3]: Recipient - * argv[4]: Options, ignored + * argv[3]: Message + * argv[4]: Options, map containing Recipient */ static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifPid to_pid; + ERL_NIF_TERM recipient, msg; if (enif_get_local_pid(env, argv[1], &to_pid)) { - ERL_NIF_TERM msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], argv[4]); + if (enif_get_map_value(env, argv[4], enif_make_atom(env, "extra"), &recipient)) { + msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], recipient); enif_send(env, &to_pid, NULL, msg); + } } return enif_make_atom(env, "ok"); diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index d0fa170e66..8ae87ac280 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -32,559 +32,20 @@ <p>This document describes the changes made to the ERTS application.</p> -<section><title>Erts 9.0</title> +<section><title>Erts 8.3.4</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> - <p>Fix various bugs regarding loading, upgrade and purge - of HiPE compiled code:</p> <list> <item>The native code - memory for a purged module was never deallocated.</item> - <item>Wrong functions could in some cases be called after - a module upgrade.</item> - <item><c>erlang:check_process_code</c> did not check for - recursive calls made from native code.</item> </list> <p> - Own Id: OTP-13968</p> - </item> - <item> - <p> - Hipe optional LLVM backend does require LLVM version 3.9 - or later as older versions forced strong dependencies on - erts internals structures.</p> - <p> - Own Id: OTP-14238</p> - </item> - <item> - <p>When an exception such as '<c>throw(HugeTerm)</c>' was - caught, <c>HugeTerm</c> term would be kept in the process - until the next exception occurred, potentially increasing - the heap size for the process. That has been - corrected.</p> - <p> - Own Id: OTP-14255 Aux Id: OTP-14400, OTP-14401 </p> - </item> - <item> - <p> - Slogans in crash dumps have been extended to print more - complex terms.</p> - <p> - Own Id: OTP-14303</p> - </item> - <item> - <p> - Fixed bug when using <c>enif_inspect_binary</c> in - combination with <c>enif_copy</c>. In some circumstances - the inspected binary could be realloced by the - <c>enif_copy</c> call when it shouldn't have been.</p> - <p> - Own Id: OTP-14304</p> - </item> - <item> - <p> - The address family <c>local</c> (AF_UNIX / AF_LOCAL) now - does not ensure zero termination of Linux Abstract - Addresses so they can use all bytes.</p> - <p> - Own Id: OTP-14305</p> - </item> - <item> - <p> - Use <c>-fno-PIE</c> for Gentoo Hardened and others that - don't accept linker flag <c>-no-pie</c>.</p> - <p> - Own Id: OTP-14307 Aux Id: PR-1379 </p> - </item> - <item> - <p> - Disable hipe for <c>ppc64le</c> architecture (little - endian) as it is not, and has never been, supported. It - was earlier equated with <c>ppc64</c> (big endian) which - lead to broken build without <c>--disable-hipe</c>.</p> - <p> - Own Id: OTP-14314 Aux Id: ERL-369, PR-1394 </p> - </item> - <item> - <p> - Fix 'epmd -kill' to return a failure exit status code if - epmd was not killed because of some error.</p> - <p> - Own Id: OTP-14324</p> - </item> - <item> - <p>Fixed the following dirty scheduler related bugs:</p> - <list> <item><p>the <c>+SDPcpu</c> command line argument - could cause the amount of dirty CPU schedulers to be set - to zero</p></item> - <item><p><c>erlang:system_flag(multi_scheduling, _)</c> - failed when only one normal scheduler was used together - with dirty scheduler support</p></item> </list> - <p> - Own Id: OTP-14335</p> - </item> - <item> - <p> - Fix erlexec to handle mismatch in sysconf and proc fs - when figuring out the cpu topology. This behaviour has - been seen when using docker together with - <c>--cpuset-cpus</c>.</p> - <p> - Own Id: OTP-14352</p> - </item> - <item> - <p> - Fixed memory segment cache used for multiblock carriers. - Huge (> 2GB) memory segments could cause a VM crash. - Creation of such huge memory segments used for multiblock - carriers is however very uncommon.</p> - <p> - Own Id: OTP-14360 Aux Id: ERL-401, PR-1417 </p> - </item> - <item> - <p> - Fix bug causing <c>code:is_module_native</c> to falsely - return true when <c>local</c> call trace is enabled for - the module.</p> - <p> - Own Id: OTP-14390</p> - </item> - <item> - <p> - Fix emulator crash when receive tracing on a - <c>trace_delivered</c> message.</p> - <p> - Own Id: OTP-14411</p> - </item> - <item> - <p> - <c>escript</c> did not handle paths with spaces correct.</p> - <p> - Own Id: OTP-14433</p> - </item> - <item> - <p> - Fix erroneous lock check assertion when <c>wx</c> is run - on MacOS X.</p> - <p> - Own Id: OTP-14437 Aux Id: ERL-360 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Added <c>erlang:garbage_collect/2</c> that takes an - option list as the last argument that can be used to - control whether a minor or a major garbage collection is - to be done. Doing a minor collection only collects terms - that have recently died, but is cheaper than a mjor - collection.</p> - <p> - Own Id: OTP-11695</p> - </item> - <item> - <p> - Optimized test for tuples with an atom as first element.</p> - <p> - Own Id: OTP-12148</p> - </item> - <item> - <p> - Erlang literals are no longer copied during process to - process messaging.</p> - <p> - Own Id: OTP-13529</p> - </item> - <item> - <p>Add support in the <c>erl_nif</c> API for asynchronous - message notifications when sockets or other file - descriptors are ready to accept read or write operations. - The following functions have been added:</p> <list> - <item><p>enif_select</p></item> - <item><p>enif_monitor_process</p></item> - <item><p>enif_demonitor_process</p></item> - <item><p>enif_compare_monitors</p></item> - <item><p>enif_open_resource_type_x</p></item> </list> - <p> - Own Id: OTP-13684</p> - </item> - <item> - <p>There are two new guard BIFs '<c>floor/1</c>' and - '<c>ceil/1</c>'. They both return integers. In the - '<c>math</c>' module, there are two new BIFs with the - same names that return floating point values.</p> - <p> - Own Id: OTP-13692</p> - </item> - <item> - <p> - Remove deprecated <c>erlang:hash/2</c>.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13827</p> - </item> - <item> - <p>Replaced usage of deprecated symbolic <seealso - marker="erts:erlang#type-time_unit"><c>time - unit</c></seealso> representations.</p> - <p> - Own Id: OTP-13831 Aux Id: OTP-13735 </p> - </item> - <item> - <p> - Added support in zlib for extraction of the inflation - dictionary.</p> - <p> - Own Id: OTP-13842</p> - </item> - <item> - <p> - The previously used purge strategy has been removed. The - optional purge strategy introduced in ERTS version 8.1 is - now the only strategy available.</p> - <p> - The new purge strategy is slightly incompatible with the - old strategy. Previously processes holding <c>fun</c>s - that referred to the module being purged either failed a - soft purge, or was killed during a hard purge. The new - strategy completely ignores <c>fun</c>s. If <c>fun</c>s - referring to the code being purged exist, and are used - after a purge, an exception will be raised upon usage. - That is, the behavior will be exactly the same as the - case when a <c>fun</c> is received by a process after the - purge.</p> - <p> - For more information see the documentation of <seealso - marker="erts:erlang#check_process_code/3"><c>erlang:check_process_code/3</c></seealso>.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13844 Aux Id: OTP-13833 </p> - </item> - <item> - <p> - Dirty schedulers are now enabled by default when the - runtime system is built with SMP support.</p> - <p> - Own Id: OTP-13860</p> - </item> - <item> - <p> - Improved ETS lookup/insert/delete speed for large - <c>set</c>, <c>bag</c> and <c>duplicate_bag</c> by a - significant reduction of the hash load factor. This speed - improvement comes at the expense of less than one word - per table entry. Tables with less than 256 entries are - not affected at all.</p> - <p> - Own Id: OTP-13903</p> - </item> - <item> - <p> - The NIF library <c>reload</c> feature is not supported - anymore. It has been marked as deprecated since OTP R15B. - This means that you are only allowed to do one successful - call to <c>erlang:load_nif/2</c> for each module - instance. A second call to <c>erlang:load_nif/2</c> will - return <c>{error, {reload, _}}</c> even if the NIF - library imlements the <c>reload</c> callback.</p> - <p> - Runtime upgrade of a NIF library is still supported by - using the Erlang module upgrade mechanics with a current - and an old module instance existing at the same time with - their corresponding NIF libraries.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13908</p> - </item> - <item> - <p> - Add <c>erlang:system_info(atom_count)</c> and - <c>erlang:system_info(atom_limit)</c> to provide a way to - retrieve the current and maximum number of atoms.</p> - <p> - Own Id: OTP-13976</p> - </item> - <item> - <p>The function <c>fmod/2</c> has been added to the - <c>math</c> module.</p> - <p> - Own Id: OTP-14000</p> - </item> - <item> - <p> - <c>erlang:load_nif/2</c> returns new error type - <c>notsup</c> when called for a HiPE compiled module, - which is not supported.</p> - <p> - Own Id: OTP-14002</p> - </item> - <item> - <p> - Add driver and nif lock instrumentation to lcnt</p> - <p> - Own Id: OTP-14069</p> - </item> - <item> - <p> - Reduce memory pressure by converting sub-binaries to - heap-binaries when possible. This is done during garbage - collection.</p> - <p> - Own Id: OTP-14149</p> - </item> - <item> - <p> - Dirty schedulers are now enabled and supported on Erlang - runtime systems with SMP support.</p> - <p> - Besides support for dirty NIFs also support for dirty - BIFs and dirty garbage collection have been introduced. - All garbage collections that potentially will take a long - time to complete are now performed on dirty schedulers if - enabled.</p> - <p> - <seealso - marker="erts:erlang#statistics/1"><c>erlang:statistics/1</c></seealso> - with arguments inspecting scheduler and run queue states - have been changed due to the dirty scheduler support. - Code using this functionality may have to be rewritten - taking these incompatibilities into consideration. - Examples of such uses are calls to <seealso - marker="erts:erlang#statistics_scheduler_wall_time"><c>erlang:statistics(scheduler_wall_time)</c></seealso>, - <seealso - marker="erts:erlang#statistics_total_run_queue_lengths"><c>statistics(total_run_queue_lengths)</c></seealso>, - <seealso - marker="erts:erlang#statistics_total_active_tasks"><c>statistics(total_active_tasks)</c></seealso>, - etc.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14152</p> - </item> - <item> - <p>Atoms may now contain arbitrary Unicode - characters.</p> - <p> - Own Id: OTP-14178</p> - </item> - <item> - <p> - Introduce an event manager in Erlang to handle OS - signals. A subset of OS signals may be subscribed to and - those are described in the Kernel application.</p> - <p> - Own Id: OTP-14186</p> - </item> - <item> - <p> - The <c>escript</c> program now handles symbolic links to - escripts.</p> - <p> - This is useful for standalone systems with - <c>escript</c>s residing on a bin directory not included - in the execution path (as it may cause their <c>erl</c> - program(s) to override the desired one). Instead the - <c>escript</c>s can be referred to via symbolic links - from a bin directory in the path.</p> - <p> - Own Id: OTP-14201 Aux Id: PR-1293 </p> - </item> - <item> - <p> - All uses of the magic binary kludge has been replaced by - uses of erlang references.</p> - <p> - A magic binary was presented as an empty binary, but - actually referred other data internally in the Erlang VM. - Since they were presented as empty binaries, different - magic binaries compared as equal, and also lost their - internal data when passed out of an erlang node.</p> - <p> - The new usage of references has not got any of these - strange semantic issues, and the usage of these - references has been optimized to give the same - performance benefits as well as memory usage benefits as - magic binaries had.</p> - <p> - A couple of examples of previous uses of magic binaries - are match specifications and NIF resources.</p> - <p> - Own Id: OTP-14205</p> - </item> - <item> - <p> - The non-smp emulators have been deprecated and are - scheduled for removal in OTP-21.</p> - <p> - In preperations for this, the threaded non-smp emulator - is no longer built by default and has to be enabled using - the --enable-plain-emulator to configure.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14272</p> - </item> - <item> - <p> - Allow HiPE to run on VM built with - <c>--enable-m32-build</c>.</p> - <p> - Own Id: OTP-14330 Aux Id: PR-1397 </p> - </item> - <item> - <p> - Upgraded the OTP internal PCRE library from version 8.33 - to version 8.40. This library is used for implementation - of the <seealso marker="stdlib:re"><c>re</c></seealso> - regular expressions module.</p> - <p> - Besides various bug fixes, the new version allows for - better stack protection. In order to utilize this - feature, the stack size of normal scheduler threads is - now by default set to 128 kilo words on all platforms. - The stack size of normal scheduler threads can be set - upon system start by passing the <seealso - marker="erts:erl#sched_thread_stack_size"><c>+sss</c></seealso> - command line argument to the <seealso - marker="erts:erl"><c>erl</c></seealso> command.</p> - <p> - See <url - href="http://pcre.org/original/changelog.txt"><c>http://pcre.org/original/changelog.txt</c></url> - for information about changes made to PCRE between the - versions 8.33 and 8.40.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14331 Aux Id: ERL-208 </p> - </item> - <item> - <p> - Remove generation of atoms in old latin1 external format. - The old latin1 format can still be decoded but is never - generated by <c>term_to_binary</c> or sent on a - distribution channel. The new utf8 format for atoms was - introduced in OTP R16. An OTP 20 node can therefore not - connect to nodes older than R16.</p> - <p> - Own Id: OTP-14337</p> - </item> - <item> - <p> - Added function <c>re:version/0</c> which returns - information about the OTP internal PCRE version used for - implementation of the <c>re</c> module.</p> - <p> - Own Id: OTP-14347 Aux Id: PR-1412 </p> - </item> - <item> - <p> - Added new debug bif <c>erlang:list_to_port/1</c>.</p> - <p> - Own Id: OTP-14348</p> - </item> - <item> - <p> - Various improvements of timer management internally in - the VM. These improvements both reduced memory - consumption of timer wheels as well as reduce the amount - of work that has to be performed in order to handle - timers.</p> - <p> - Own Id: OTP-14356</p> - </item> - <item> - <p> Sockets can now be bound to device (SO_BINDTODEVICE) - on platforms where it is supported. </p> <p> This has - been implemented e.g to support VRF-Lite under Linux; see - <url - href="https://www.kernel.org/doc/Documentation/networking/vrf.txt"> - VRF </url>, and GitHub pull request <url - href="https://github.com/erlang/otp/pull/1326">#1326</url>. - </p> - <p> - Own Id: OTP-14357 Aux Id: PR-1326 </p> - </item> - <item> - <p>Added the following <seealso - marker="erl"><c>erl</c></seealso> command line arguments - with which you can set suggested stack for dirty - schedulers:</p> <taglist> <tag><seealso - marker="erl#dcpu_sched_thread_stack_size"><c>+sssdcpu</c></seealso></tag> - <item><p>for dirty CPU schedulers</p></item> - <tag><seealso - marker="erl#dio_sched_thread_stack_size"><c>+sssdio</c></seealso></tag> - <item><p>for dirty IO schedulers</p></item> </taglist> - <p>The default suggested stack size for dirty schedulers - is 40 kilo words.</p> - <p> - Own Id: OTP-14380</p> - </item> - <item> - <p> - Changed erts startup program name, argv 0, to use the - environment variable <c>ESCRIPT_NAME</c> so that - <c>erlc</c>, <c>dialyzer</c>, <c>typer</c>, - <c>ct_run</c>, or the escript name can be seen with - external programs, such as ps and htop (depending on - options), on unix.</p> - <p> - Own Id: OTP-14381</p> - </item> - <item> - <p> - Improvements of <c>escript</c> documentation.</p> - <p> - Own Id: OTP-14384 Aux Id: OTP-14201 </p> - </item> - <item> - <p> - Add function <c>enif_hash</c> for NIFs to calculate hash - values of arbitrary terms.</p> - <p> - Own Id: OTP-14385 Aux Id: PR-1413 </p> - </item> - <item> - <p>'<c>./configure --enable-lock-counter</c>' will - enabling building of an additional emulator that has - support for lock counting. (The option previously - existed, but would turn on lock counting in the default - emulator being built.) To start the lock-counting - emulator, use '<c>erl -emu_type lcnt</c>'.</p> - <p>On Windows, <c>erl</c> recognized the undocumented - option <c>-debug</c> for starting a debug-compiled - emulator. That option has been removed. Use '<c>erl - -emu_type debug</c>' instead.</p> - <p> - Own Id: OTP-14407</p> - </item> - <item> - <p> - Warnings have been added to the relevant documentation - about not using un-secure distributed nodes in exposed - environments.</p> - <p> - Own Id: OTP-14425</p> - </item> - <item> - <p> - Improvement of the documentation of the environment - variable <c>ERL_CRASH_DUMP_SECONDS</c> as well as the - default behavior when it is not set.</p> - <p> - Own Id: OTP-14434</p> - </item> - <item> - <p> - Enabled off-heap message queue for some system processes - that might receive large amounts of messages.</p> + Add option to make SIGTERM trigger the OS default + behaviour instead of doing a gracefull shutdown. To + activate this bahviour the environment variable + ERL_ZZ_SIGTERM_KILL should be set to "true". This option + only works in OTP 19 as OTP 20 will have a different way + to deal with SIGTERM.</p> <p> - Own Id: OTP-14438</p> + Own Id: OTP-14418 Aux Id: ERIERL-15 </p> </item> </list> </section> diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 254e59f2c7..61c1e14741 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -149,6 +149,8 @@ endif LIBS += $(TYPE_LIBS) +ORIG_LIBS:= $(LIBS) + comma:=, space:= space+= @@ -965,7 +967,7 @@ $(OBJDIR)/%.o: hipe/%.c $(V_CC) $(subst O2,O3, $(CFLAGS)) $(INCLUDES) -c $< -o $@ $(BINDIR)/hipe_mkliterals$(TF_MARKER): $(OBJDIR)/hipe_mkliterals.o - $(ld_verbose)$(CC) $(LDFLAGS) -o $@ $< $(TYPE_LIBS) + $(ld_verbose)$(CC) $(LDFLAGS) -o $@ $< $(ORIG_LIBS) $(OBJDIR)/hipe_mkliterals.o: $(HIPE_ASM) $(TTF_DIR)/erl_alloc_types.h $(DTRACE_HEADERS) \ $(TTF_DIR)/OPCODES-GENERATED $(TTF_DIR)/TABLES-GENERATED diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 7134d2da56..40dd4129d2 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2047,8 +2047,6 @@ ebif_bang_2(BIF_ALIST_2) #define SEND_YIELD_CONTINUE (-8) -Sint do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext*); - static Sint remote_send(Process *p, DistEntry *dep, Eterm to, Eterm full_to, Eterm msg, ErtsSendContext* ctx) @@ -2102,8 +2100,8 @@ static Sint remote_send(Process *p, DistEntry *dep, return res; } -Sint -do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext* ctx) +static Sint +do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext *ctx) { Eterm portid; Port *pt; diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index 4889fac923..6fddba4b34 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -821,7 +821,7 @@ static void clear_literal_range(void* start, Uint size) #if HAVE_ERTS_MSEG -void* +static void* erts_alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p, Uint flags) { void *res; @@ -832,7 +832,7 @@ erts_alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p, Uint flags) return res; } -void* +static void* erts_alcu_mseg_realloc(Allctr_t *allctr, void *seg, Uint old_size, Uint *new_size_p) { @@ -845,7 +845,7 @@ erts_alcu_mseg_realloc(Allctr_t *allctr, void *seg, return res; } -void +static void erts_alcu_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size, Uint flags) { erts_mseg_dealloc_opt(allctr->alloc_no, seg, (UWord) size, flags, &allctr->mseg_opt); @@ -996,7 +996,7 @@ erts_alcu_exec_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size, Uint flags) #endif /* HAVE_ERTS_MSEG */ -void* +static void* erts_alcu_sys_alloc(Allctr_t *allctr, Uint* size_p, int superalign) { void *res; @@ -1013,7 +1013,7 @@ erts_alcu_sys_alloc(Allctr_t *allctr, Uint* size_p, int superalign) return res; } -void* +static void* erts_alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint *size_p, Uint old_size, int superalign) { void *res; @@ -1035,7 +1035,7 @@ erts_alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint *size_p, Uint old_size, return res; } -void +static void erts_alcu_sys_dealloc(Allctr_t *allctr, void *ptr, Uint size, int superalign) { #if ERTS_SA_MB_CARRIERS && ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h index f570703f25..7a96bd0319 100644 --- a/erts/emulator/beam/erl_alloc_util.h +++ b/erts/emulator/beam/erl_alloc_util.h @@ -195,10 +195,6 @@ extern UWord erts_literal_vspace_map[]; # define ERTS_VSPACE_WORD_BITS (sizeof(UWord)*8) #endif -void* erts_alcu_mseg_alloc(Allctr_t*, Uint *size_p, Uint flags); -void* erts_alcu_mseg_realloc(Allctr_t*, void *seg, Uint old_size, Uint *new_size_p); -void erts_alcu_mseg_dealloc(Allctr_t*, void *seg, Uint size, Uint flags); - #if HAVE_ERTS_MSEG # if defined(ARCH_32) void* erts_alcu_literal_32_mseg_alloc(Allctr_t*, Uint *size_p, Uint flags); @@ -218,9 +214,6 @@ void erts_alcu_exec_mseg_dealloc(Allctr_t*, void *seg, Uint size, Uint flags); # endif #endif /* HAVE_ERTS_MSEG */ -void* erts_alcu_sys_alloc(Allctr_t*, Uint *size_p, int superalign); -void* erts_alcu_sys_realloc(Allctr_t*, void *ptr, Uint *size_p, Uint old_size, int superalign); -void erts_alcu_sys_dealloc(Allctr_t*, void *ptr, Uint size, int superalign); #ifdef ARCH_32 void* erts_alcu_literal_32_sys_alloc(Allctr_t*, Uint *size_p, int superalign); void* erts_alcu_literal_32_sys_realloc(Allctr_t*, void *ptr, Uint *size_p, Uint old_size, int superalign); diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c index eea55b3239..71c64997c1 100644 --- a/erts/emulator/beam/erl_bits.c +++ b/erts/emulator/beam/erl_bits.c @@ -1636,7 +1636,7 @@ erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb) return LSB[0] | (LSB[1]<<8) | (LSB[2]<<16) | (LSB[3]<<24); } -void +static void erts_align_utf8_bytes(ErlBinMatchBuffer* mb, byte* buf) { Uint bits = mb->size - mb->offset; diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h index 632855255e..5da2b28a89 100644 --- a/erts/emulator/beam/erl_bits.h +++ b/erts/emulator/beam/erl_bits.h @@ -202,7 +202,6 @@ void erts_new_bs_put_string(ERL_BITS_PROTO_2(byte* iptr, Uint num_bytes)); Uint erts_bits_bufs_size(void); Uint32 erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb); -void erts_align_utf8_bytes(ErlBinMatchBuffer* mb, byte* buf); Eterm erts_bs_get_utf8(ErlBinMatchBuffer* mb); Eterm erts_bs_get_utf16(ErlBinMatchBuffer* mb, Uint flags); Eterm erts_bs_append(Process* p, Eterm* reg, Uint live, Eterm build_size_term, diff --git a/erts/emulator/beam/erl_cpu_topology.c b/erts/emulator/beam/erl_cpu_topology.c index 4347f9f2b7..d0fd763798 100644 --- a/erts/emulator/beam/erl_cpu_topology.c +++ b/erts/emulator/beam/erl_cpu_topology.c @@ -2243,45 +2243,6 @@ add_cpu_groups(int groups, return cgm; } -static void -remove_cpu_groups(erts_cpu_groups_callback_t callback, void *arg) -{ - erts_cpu_groups_map_t *prev_cgm, *cgm; - erts_cpu_groups_callback_list_t *prev_cgcl, *cgcl; - - ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx)); - - no_cpu_groups_callbacks--; - - prev_cgm = NULL; - for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) { - prev_cgcl = NULL; - for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) { - if (cgcl->callback == callback && cgcl->arg == arg) { - if (prev_cgcl) - prev_cgcl->next = cgcl->next; - else - cgm->callback_list = cgcl->next; - erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgcl); - if (!cgm->callback_list) { - if (prev_cgm) - prev_cgm->next = cgm->next; - else - cpu_groups_maps = cgm->next; - if (cgm->array) - erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm->array); - erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm); - } - return; - } - prev_cgcl = cgcl; - } - prev_cgm = cgm; - } - - erts_exit(ERTS_ABORT_EXIT, "Cpu groups not found\n"); -} - static int cpu_groups_lookup(erts_cpu_groups_map_t *map, ErtsSchedulerData *esdp) @@ -2321,21 +2282,3 @@ update_cpu_groups_maps(void) for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) make_cpu_groups_map(cgm, 0); } - -void -erts_add_cpu_groups(int groups, - erts_cpu_groups_callback_t callback, - void *arg) -{ - erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); - add_cpu_groups(groups, callback, arg); - erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); -} - -void erts_remove_cpu_groups(erts_cpu_groups_callback_t callback, - void *arg) -{ - erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); - remove_cpu_groups(callback, arg); - erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); -} diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index 08a0f0e83b..0addfaa3c7 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -676,7 +676,7 @@ int db_create_hash(Process *p, DbTable *tbl) sizeof(DbTableHashFineLocks)); for (i=0; i<DB_HASH_LOCK_CNT; ++i) { erts_smp_rwmtx_init_opt_x(&tb->locks->lck_vec[i].lck, &rwmtx_opt, - "db_hash_slot", make_small(i)); + "db_hash_slot", tb->common.the_name); } /* This important property is needed to guarantee the two buckets * involved in a grow/shrink operation it protected by the same lock: diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 00fc6116e5..fc2b34e70f 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -13933,7 +13933,11 @@ erts_continue_exit_process(Process *p) erts_set_gc_state(p, 1); state = erts_smp_atomic32_read_acqb(&p->state); - if (state & ERTS_PSFLG_ACTIVE_SYS) { + if (state & ERTS_PSFLG_ACTIVE_SYS +#ifdef ERTS_DIRTY_SCHEDULERS + || p->dirty_sys_tasks +#endif + ) { if (cleanup_sys_tasks(p, state, CONTEXT_REDS) >= CONTEXT_REDS/2) goto yield; } diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c index 0acc2432a7..f8341f788a 100644 --- a/erts/emulator/drivers/unix/unix_efile.c +++ b/erts/emulator/drivers/unix/unix_efile.c @@ -969,17 +969,21 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd, fdrec.sfv_len = SENDFILE_CHUNK_SIZE; else fdrec.sfv_len = *nbytes; + retval = sendfilev(out_fd, &fdrec, 1, &len); - /* Sometimes sendfilev can return -1 and still send data. - When that happens we just pretend that no error happend. */ - if (retval != -1 || errno == EAGAIN || errno == EINTR || - len != 0) { + if (retval == -1 && errno == EINVAL) { + /* On some solaris versions (I've seen it on SunOS 5.10), + using a sfv_len larger then a filesize will result in + a -1 && errno == EINVAL return. We translate this so + a successful send of the data.*/ + retval = len; + } + + if (retval != -1 || errno == EAGAIN || errno == EINTR) { *offset += len; *nbytes -= len; written += len; - if (errno != EAGAIN && errno != EINTR && len != 0) - retval = len; } } while (len == SENDFILE_CHUNK_SIZE); #elif defined(__DARWIN__) diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile index 2479ccc01f..fcd7244ae9 100644 --- a/erts/emulator/test/Makefile +++ b/erts/emulator/test/Makefile @@ -117,7 +117,6 @@ MODULES= \ tracer_SUITE \ tracer_test \ scheduler_SUITE \ - old_scheduler_SUITE \ port_trace_SUITE \ unique_SUITE \ z_SUITE \ diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl index 355be7a36d..4d17276e5c 100644 --- a/erts/emulator/test/binary_SUITE.erl +++ b/erts/emulator/test/binary_SUITE.erl @@ -1358,17 +1358,19 @@ do_trapping(N, Bif, ArgFun) -> io:format("N=~p: Do ~p ~s gc.\n", [N, Bif, case N rem 2 of 0 -> "with"; 1 -> "without" end]), Pid = spawn(?MODULE,trapping_loop,[Bif, ArgFun, 1000, self()]), receive ok -> ok end, - receive after 100 -> ok end, Ref = make_ref(), case N rem 2 of - 0 -> erlang:garbage_collect(Pid, [{async,Ref}]), - receive after 100 -> ok end; + 0 -> + erlang:garbage_collect(Pid, [{async,Ref}]), + receive after 1 -> ok end; 1 -> void end, - exit(Pid,kill), + exit(Pid, kill), case N rem 2 of - 0 -> receive {garbage_collect, Ref, _} -> ok end; - 1 -> void + 0 -> + receive {garbage_collect, Ref, _} -> ok end; + 1 -> + void end, receive after 1 -> ok end, do_trapping(N-1, Bif, ArgFun). diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl index ed03284a5b..779d81daa5 100644 --- a/erts/emulator/test/bs_construct_SUITE.erl +++ b/erts/emulator/test/bs_construct_SUITE.erl @@ -35,7 +35,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 10}}]. + {timetrap, {minutes, 1}}]. all() -> [test1, test2, test3, test4, test5, testf, not_used, diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl index 95171d04ce..1251d644ae 100644 --- a/erts/emulator/test/call_trace_SUITE.erl +++ b/erts/emulator/test/call_trace_SUITE.erl @@ -43,7 +43,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 30}}]. + {timetrap, {minutes, 2}}]. all() -> Common = [errors, on_load], diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl index 0b9f76a892..031b05790d 100644 --- a/erts/emulator/test/ddll_SUITE.erl +++ b/erts/emulator/test/ddll_SUITE.erl @@ -55,7 +55,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 10}}]. + {timetrap, {minutes, 1}}]. all() -> [ddll_test, errors, reference_count, kill_port, diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl index 434e729310..dc7afa381b 100644 --- a/erts/emulator/test/distribution_SUITE.erl +++ b/erts/emulator/test/distribution_SUITE.erl @@ -62,8 +62,7 @@ -export([sender/3, receiver2/2, dummy_waiter/0, dead_process/0, roundtrip/1, bounce/1, do_dist_auto_connect/1, inet_rpc_server/1, dist_parallel_sender/3, dist_parallel_receiver/0, - dist_evil_parallel_receiver/0, - sendersender/4, sendersender2/4]). + dist_evil_parallel_receiver/0]). %% epmd_module exports -export([start_link/0, register_node/2, register_node/3, port_please/2]). @@ -129,52 +128,53 @@ bulk_send_small(Config) when is_list(Config) -> bulk_send_big(Config) when is_list(Config) -> bulk_send(32, 64). -bulk_send_bigbig(Config) when is_list(Config) -> - bulk_sendsend(32*5, 4). - bulk_send(Terms, BinSize) -> ct:timetrap({seconds, 30}), io:format("Sending ~w binaries, each of size ~w K", [Terms, BinSize]), {ok, Node} = start_node(bulk_receiver), Recv = spawn(Node, erlang, apply, [fun receiver/2, [0, 0]]), - Bin = list_to_binary(lists:duplicate(BinSize*1024, 253)), + Bin = binary:copy(<<253>>, BinSize*1024), Size = Terms*size(Bin), {Elapsed, {Terms, Size}} = test_server:timecall(?MODULE, sender, [Recv, Bin, Terms]), stop_node(Node), - {comment, integer_to_list(trunc(Size/1024/max(1,Elapsed)+0.5)) ++ " K/s"}. + {comment, integer_to_list(round(Size/1024/max(1,Elapsed))) ++ " K/s"}. -bulk_sendsend(Terms, BinSize) -> +sender(To, _Bin, 0) -> + To ! {done, self()}, + receive + Any -> + Any + end; +sender(To, Bin, Left) -> + To ! {term, Bin}, + sender(To, Bin, Left-1). + +bulk_send_bigbig(Config) when is_list(Config) -> + Terms = 32*5, + BinSize = 4, {Rate1, MonitorCount1} = bulk_sendsend2(Terms, BinSize, 5), {Rate2, MonitorCount2} = bulk_sendsend2(Terms, BinSize, 995), Ratio = if MonitorCount2 == 0 -> MonitorCount1 / 1.0; true -> MonitorCount1 / MonitorCount2 end, - Comment = integer_to_list(Rate1) ++ " K/s, " ++ - integer_to_list(Rate2) ++ " K/s, " ++ - integer_to_list(MonitorCount1) ++ " monitor msgs, " ++ - integer_to_list(MonitorCount2) ++ " monitor msgs, " ++ - float_to_list(Ratio) ++ " monitor ratio", - if - %% A somewhat arbitrary ratio, but hopefully one that will - %% accommodate a wide range of CPU speeds. - Ratio > 8.0 -> - {comment,Comment}; - true -> - io:put_chars(Comment), - ct:fail(ratio_too_low) - end. + Comment0 = io_lib:format("~p K/s, ~p K/s, " + "~p monitor msgs, ~p monitor msgs, " + "~.1f monitor ratio", + [Rate1,Rate2,MonitorCount1, + MonitorCount2,Ratio]), + Comment = lists:flatten(Comment0), + {comment,Comment}. bulk_sendsend2(Terms, BinSize, BusyBufSize) -> ct:timetrap({seconds, 30}), - io:format("Sending ~w binaries, each of size ~w K", + io:format("\nSending ~w binaries, each of size ~w K", [Terms, BinSize]), {ok, NodeRecv} = start_node(bulk_receiver), Recv = spawn(NodeRecv, erlang, apply, [fun receiver/2, [0, 0]]), - Bin = list_to_binary(lists:duplicate(BinSize*1024, 253)), - %%Size = Terms*size(Bin), + Bin = binary:copy(<<253>>, BinSize*1024), %% SLF LEFT OFF HERE. %% When the caller uses small hunks, like 4k via @@ -185,74 +185,62 @@ bulk_sendsend2(Terms, BinSize, BusyBufSize) -> %% default busy size and "+zdbbl 5", and if the 5 case gets %% "many many more" monitor messages, then we know we're working. - {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++ integer_to_list(BusyBufSize)), - _Send = spawn(NodeSend, erlang, apply, [fun sendersender/4, [self(), Recv, Bin, Terms]]), + {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++ + integer_to_list(BusyBufSize)), + _Send = spawn(NodeSend, erlang, apply, + [fun sendersender/4, [self(), Recv, Bin, Terms]]), {Elapsed, {_TermsN, SizeN}, MonitorCount} = - receive - %% On some platforms (windows), the time taken is 0 so we - %% simulate that some little time has passed. - {sendersender, {0.0,T,MC}} -> - {0.0015, T, MC}; - {sendersender, BigRes} -> - BigRes - end, + receive + %% On some platforms (Windows), the time taken is 0 so we + %% simulate that some little time has passed. + {sendersender, {0.0,T,MC}} -> + {0.0015, T, MC}; + {sendersender, BigRes} -> + BigRes + end, stop_node(NodeRecv), stop_node(NodeSend), - {trunc(SizeN/1024/Elapsed+0.5), MonitorCount}. - -sender(To, _Bin, 0) -> - To ! {done, self()}, - receive - Any -> - Any - end; -sender(To, Bin, Left) -> - To ! {term, Bin}, - sender(To, Bin, Left-1). + {round(SizeN/1024/Elapsed), MonitorCount}. %% Sender process to be run on a slave node sendersender(Parent, To, Bin, Left) -> erlang:system_monitor(self(), [busy_dist_port]), - [spawn(fun() -> sendersender2(To, Bin, Left, false) end) || - _ <- lists:seq(1,1)], + _ = spawn(fun() -> + sendersender_send(To, Bin, Left), + exit(normal) + end), {USec, {Res, MonitorCount}} = - timer:tc(?MODULE, sendersender2, [To, Bin, Left, true]), + timer:tc(fun() -> + sendersender_send(To, Bin, Left), + To ! {done, self()}, + count_monitors(0) + end), Parent ! {sendersender, {USec/1000000, Res, MonitorCount}}. -sendersender2(To, Bin, Left, SendDone) -> - sendersender3(To, Bin, Left, SendDone, 0). +sendersender_send(_To, _Bin, 0) -> + ok; +sendersender_send(To, Bin, Left) -> + To ! {term, Bin}, + sendersender_send(To, Bin, Left-1). -sendersender3(To, _Bin, 0, SendDone, MonitorCount) -> - if SendDone -> - To ! {done, self()}; - true -> - ok - end, +count_monitors(MonitorCount) -> receive {monitor, _Pid, _Type, _Info} -> - sendersender3(To, _Bin, 0, SendDone, MonitorCount + 1) + count_monitors(MonitorCount + 1) after 0 -> - if SendDone -> - receive - Any when is_tuple(Any), size(Any) == 2 -> - {Any, MonitorCount} - end; - true -> - exit(normal) - end - end; -sendersender3(To, Bin, Left, SendDone, MonitorCount) -> - To ! {term, Bin}, - %%timer:sleep(50), - sendersender3(To, Bin, Left-1, SendDone, MonitorCount). + receive + {_,_}=Any -> + {Any,MonitorCount} + end + end. %% Receiver process to be run on a slave node. receiver(Terms, Size) -> receive {term, Bin} -> - receiver(Terms+1, Size+size(Bin)); + receiver(Terms+1, Size+byte_size(Bin)); {done, ReplyTo} -> ReplyTo ! {Terms, Size} end. diff --git a/erts/emulator/test/evil_SUITE.erl b/erts/emulator/test/evil_SUITE.erl index 9416ac7a02..fb1954ce37 100644 --- a/erts/emulator/test/evil_SUITE.erl +++ b/erts/emulator/test/evil_SUITE.erl @@ -34,7 +34,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 30}}]. + {timetrap, {minutes, 1}}]. all() -> [heap_frag, encode_decode_ext, decode_integer_ext, diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl index 76e3556bc4..ad6d8c890f 100644 --- a/erts/emulator/test/exception_SUITE.erl +++ b/erts/emulator/test/exception_SUITE.erl @@ -33,7 +33,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 10}}]. + {timetrap, {minutes, 1}}]. all() -> [badmatch, pending_errors, nil_arith, stacktrace, diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl index 35dd147550..2c2cb9c32d 100644 --- a/erts/emulator/test/gc_SUITE.erl +++ b/erts/emulator/test/gc_SUITE.erl @@ -203,89 +203,90 @@ long_receive() -> end. minor_major_gc_option_self(_Config) -> - Endless = fun Endless() -> - receive - {gc, Type} -> erlang:garbage_collect(self(), [{type, Type}]) - after 100 -> ok end, - Endless() - end, - - %% Try as major, a test process will self-trigger GC - P1 = spawn(Endless), - erlang:garbage_collect(P1, []), - erlang:trace(P1, true, [garbage_collection]), - P1 ! {gc, major}, - expect_trace_messages(P1, [gc_major_start, gc_major_end]), - erlang:trace(P1, false, [garbage_collection]), - erlang:exit(P1, kill), - - %% Try as minor, a test process will self-trigger GC - P2 = spawn(Endless), - erlang:garbage_collect(P2, []), - erlang:trace(P2, true, [garbage_collection]), - P2 ! {gc, minor}, - expect_trace_messages(P2, [gc_minor_start, gc_minor_end]), - erlang:trace(P2, false, [garbage_collection]), - erlang:exit(P2, kill). + %% Try as major, the test process will self-trigger GC + check_gc_tracing_around( + fun(Pid, Ref) -> + Pid ! {gc, Ref, major} + end, [gc_major_start, gc_major_end]), + + %% Try as minor, the test process will self-trigger GC + check_gc_tracing_around( + fun(Pid, Ref) -> + Pid ! {gc, Ref, minor} + end, [gc_minor_start, gc_minor_end]). minor_major_gc_option_async(_Config) -> - Endless = fun Endless() -> - receive after 100 -> ok end, - Endless() - end, - - %% Try with default option, must be major gc - P1 = spawn(Endless), - erlang:garbage_collect(P1, []), - erlang:trace(P1, true, [garbage_collection]), - erlang:garbage_collect(P1, []), - expect_trace_messages(P1, [gc_major_start, gc_major_end]), - erlang:trace(P1, false, [garbage_collection]), - erlang:exit(P1, kill), + %% Try with default option, must be major GC + check_gc_tracing_around( + fun(Pid, _Ref) -> + erlang:garbage_collect(Pid, []) + end, [gc_major_start, gc_major_end]), %% Try with the 'major' type - P2 = spawn(Endless), - erlang:garbage_collect(P2, []), - erlang:trace(P2, true, [garbage_collection]), - erlang:garbage_collect(P2, [{type, major}]), - expect_trace_messages(P2, [gc_major_start, gc_major_end]), - erlang:trace(P2, false, [garbage_collection]), - erlang:exit(P2, kill), + check_gc_tracing_around( + fun(Pid, _Ref) -> + erlang:garbage_collect(Pid, [{type, major}]) + end, [gc_major_start, gc_major_end]), %% Try with 'minor' option, once - P3 = spawn(Endless), - erlang:garbage_collect(P3, []), - erlang:trace(P3, true, [garbage_collection]), - erlang:garbage_collect(P3, [{type, minor}]), - expect_trace_messages(P3, [gc_minor_start, gc_minor_end]), - erlang:trace(P3, false, [garbage_collection]), - erlang:exit(P3, kill), + check_gc_tracing_around( + fun(Pid, _Ref) -> + erlang:garbage_collect(Pid, [{type, minor}]) + end, [gc_minor_start, gc_minor_end]), %% Try with 'minor' option, once, async - P4 = spawn(Endless), + check_gc_tracing_around( + fun(Pid, Ref) -> + ?assertEqual(async, + erlang:garbage_collect(Pid, [{type, minor}, {async, Ref}])), + + receive + {garbage_collect, Ref, true} -> + ok + after 10000 -> + ct:fail("Did not receive a completion notification on async GC") + end + end, [gc_minor_start, gc_minor_end]). + +%% Traces garbage collection around the given operation, and fails the test if +%% it results in any unexpected messages or if the expected trace tags are not +%% received. +check_gc_tracing_around(Fun, ExpectedTraceTags) -> Ref = erlang:make_ref(), - erlang:garbage_collect(P4, []), - erlang:trace(P4, true, [garbage_collection]), - ?assertEqual(async, - erlang:garbage_collect(P4, [{type, minor}, {async, Ref}])), - expect_trace_messages(P4, [gc_minor_start, gc_minor_end]), - erlang:trace(P4, false, [garbage_collection]), - receive {garbage_collect, Ref, true} -> ok; - Other4 -> ct:pal("Unexpected message: ~p~n" - ++ "while waiting for async gc result", [Other4]) - after 2000 -> ?assert(false) - end, - erlang:exit(P4, kill). - -%% Given a list of atoms, trace tags - receives messages and checks if they are -%% trace events, and if the tag matches. Else will crash failing the test. -expect_trace_messages(_Pid, []) -> ok; + Pid = spawn( + fun Endless() -> + receive + {gc, Ref, Type} -> + erlang:garbage_collect(self(), [{type, Type}]) + after 100 -> + ok + end, + Endless() + end), + erlang:garbage_collect(Pid, []), + erlang:trace(Pid, true, [garbage_collection]), + Fun(Pid, Ref), + expect_trace_messages(Pid, ExpectedTraceTags), + erlang:trace(Pid, false, [garbage_collection]), + erlang:exit(Pid, kill), + check_no_unexpected_messages(). + +%% Ensures that trace messages with the provided tags have all been received +%% within a reasonable timeframe. +expect_trace_messages(_Pid, []) -> + ok; expect_trace_messages(Pid, [Tag | TraceTags]) -> receive - {trace, Pid, Tag, _Data} -> ok; - AnythingElse -> - ct:pal("Unexpected message: ~p~nWhile expected {trace, _, ~p, _}", - [AnythingElse, Tag]), - ?assert(false) - end, - expect_trace_messages(Pid, TraceTags). + {trace, Pid, Tag, _Data} -> + expect_trace_messages(Pid, TraceTags) + after 4000 -> + ct:fail("Didn't receive tag ~p within 4000ms", [Tag]) + end. + +check_no_unexpected_messages() -> + receive + Anything -> + ct:fail("Unexpected message: ~p", [Anything]) + after 0 -> + ok + end. diff --git a/erts/emulator/test/lttng_SUITE.erl b/erts/emulator/test/lttng_SUITE.erl index c12f63706a..1c1952f912 100644 --- a/erts/emulator/test/lttng_SUITE.erl +++ b/erts/emulator/test/lttng_SUITE.erl @@ -40,7 +40,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 10}}]. + {timetrap, {minutes, 1}}]. all() -> [t_lttng_list, diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl index eb189c2c33..92ddc23592 100644 --- a/erts/emulator/test/match_spec_SUITE.erl +++ b/erts/emulator/test/match_spec_SUITE.erl @@ -42,7 +42,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 30}}]. + {timetrap, {minutes, 1}}]. all() -> case test_server:is_native(match_spec_SUITE) of diff --git a/erts/emulator/test/nested_SUITE.erl b/erts/emulator/test/nested_SUITE.erl index 7af2873ce2..5059317172 100644 --- a/erts/emulator/test/nested_SUITE.erl +++ b/erts/emulator/test/nested_SUITE.erl @@ -27,7 +27,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 10}}]. + {timetrap, {minutes, 1}}]. all() -> [case_in_case, case_in_after, catch_in_catch, diff --git a/erts/emulator/test/old_scheduler_SUITE.erl b/erts/emulator/test/old_scheduler_SUITE.erl deleted file mode 100644 index 8515a87df8..0000000000 --- a/erts/emulator/test/old_scheduler_SUITE.erl +++ /dev/null @@ -1,384 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% - --module(old_scheduler_SUITE). - --include_lib("common_test/include/ct.hrl"). - --export([all/0, suite/0, - init_per_testcase/2, end_per_testcase/2]). --export([equal/1, many_low/1, few_low/1, max/1, high/1]). - -suite() -> - [{ct_hooks,[ts_install_cth]}, - {timetrap, {minutes, 11}}]. - -all() -> - case catch erlang:system_info(modified_timing_level) of - Level when is_integer(Level) -> - {skipped, - "Modified timing (level " ++ - integer_to_list(Level) ++ - ") is enabled. Testcases gets messed " - "up by modfied timing."}; - _ -> [equal, many_low, few_low, max, high] - end. - - -%%----------------------------------------------------------------------------------- -%% TEST SUITE DESCRIPTION -%% -%% The test case function spawns two controlling processes: Starter and Receiver. -%% Starter spawns a number of prio A and a number of prio B test processes. Each -%% test process loops for a number of times, sends a report to the Receiver, then -%% loops again. For each report, the Receiver increases a counter that corresponds -%% to the priority of the sender. After a certain amount of time, the Receiver -%% sends the collected data to the main test process and waits for the test case -%% to terminate. From this data, it's possible to calculate the average run time -%% relationship between the prio A and B test processes. -%% -%% Note that in order to be able to run tests with high or max prio test processes, -%% the main test process and the Receiver needs to run at max prio, or they will -%% be starved by the test processes. The controlling processes must not wait for -%% messages from a normal (or low) prio process while max or high prio test processes -%% are running (which happens e.g. if an io function is called). -%%----------------------------------------------------------------------------------- - -init_per_testcase(_Case, Config) -> - %% main test process needs max prio - Prio = process_flag(priority, max), - MS = erlang:system_flag(multi_scheduling, block_normal), - [{prio,Prio},{multi_scheduling, MS}|Config]. - -end_per_testcase(_Case, Config) -> - erlang:system_flag(multi_scheduling, unblock_normal), - Prio=proplists:get_value(prio, Config), - process_flag(priority, Prio), - ok. - -ok(Config) when is_list(Config) -> - case proplists:get_value(multi_scheduling, Config) of - blocked -> - {comment, - "Multi-scheduling blocked during test. This testcase was not " - "written to work with multiple schedulers."}; - _ -> ok - end. - -%% Run equal number of low and normal prio processes. - -equal(Config) when is_list(Config) -> - Self = self(), - - %% specify number of test processes to run - Normal = {normal,500}, - Low = {low,500}, - - %% specify time of test (in seconds) - Time = 30, - - %% start controllers - Receiver = - spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end), - Starter = - spawn(fun() -> starter(Normal, Low, Receiver) end), - - %% receive test data from Receiver - {NRs,NAvg,LRs,LAvg,Ratio} = - receive - {Receiver,Res} -> Res - end, - - %% stop controllers and test processes - exit(Starter, kill), - exit(Receiver, kill), - - io:format("Reports: ~w normal (~w/proc), ~w low (~w/proc). Ratio: ~w~n", - [NRs,NAvg,LRs,LAvg,Ratio]), - - %% runtime ratio between normal and low should be ~8 - if Ratio < 7.5 ; Ratio > 8.5 -> - ct:fail({bad_ratio,Ratio}); - true -> - ok(Config) - end. - - -%% Run many low and few normal prio processes. - -many_low(Config) when is_list(Config) -> - Self = self(), - Normal = {normal,1}, - Low = {low,1000}, - - %% specify time of test (in seconds) - Time = 30, - - Receiver = - spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end), - Starter = - spawn(fun() -> starter(Normal, Low, Receiver) end), - {NRs,NAvg,LRs,LAvg,Ratio} = - receive - {Receiver,Res} -> Res - end, - exit(Starter, kill), - exit(Receiver, kill), - io:format("Reports: ~w normal (~w/proc), ~w low (~w/proc). Ratio: ~w~n", - [NRs,NAvg,LRs,LAvg,Ratio]), - if Ratio < 7.5 ; Ratio > 8.5 -> - ct:fail({bad_ratio,Ratio}); - true -> - ok(Config) - end. - - -%% Run few low and many normal prio processes. - -few_low(Config) when is_list(Config) -> - Self = self(), - Normal = {normal,1000}, - Low = {low,1}, - - %% specify time of test (in seconds) - Time = 30, - - Receiver = - spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end), - Starter = - spawn(fun() -> starter(Normal, Low, Receiver) end), - {NRs,NAvg,LRs,LAvg,Ratio} = - receive - {Receiver,Res} -> Res - end, - exit(Starter, kill), - exit(Receiver, kill), - io:format("Reports: ~w normal (~w/proc), ~w low (~w/proc). Ratio: ~w~n", - [NRs,NAvg,LRs,LAvg,Ratio]), - if Ratio < 7.0 ; Ratio > 8.5 -> - ct:fail({bad_ratio,Ratio}); - true -> - ok(Config) - end. - - -%% Run max prio processes and verify they get at least as much -%% runtime as high, normal and low. - -max(Config) when is_list(Config) -> - max = process_flag(priority, max), % should already be max (init_per_tc) - Self = self(), - Max = {max,2}, - High = {high,2}, - Normal = {normal,100}, - Low = {low,100}, - - %% specify time of test (in seconds) - Time = 30, - - Receiver1 = - spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, High) end), - Starter1 = - spawn(fun() -> starter(Max, High, Receiver1) end), - {M1Rs,M1Avg,HRs,HAvg,Ratio1} = - receive - {Receiver1,Res1} -> Res1 - end, - exit(Starter1, kill), - exit(Receiver1, kill), - io:format("Reports: ~w max (~w/proc), ~w high (~w/proc). Ratio: ~w~n", - [M1Rs,M1Avg,HRs,HAvg,Ratio1]), - if Ratio1 < 1.0 -> - ct:fail({bad_ratio,Ratio1}); - true -> - ok(Config) - end, - - Receiver2 = - spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, Normal) end), - Starter2 = - spawn(fun() -> starter(Max, Normal, Receiver2) end), - {M2Rs,M2Avg,NRs,NAvg,Ratio2} = - receive - {Receiver2,Res2} -> Res2 - end, - exit(Starter2, kill), - exit(Receiver2, kill), - io:format("Reports: ~w max (~w/proc), ~w normal (~w/proc). Ratio: ~w~n", - [M2Rs,M2Avg,NRs,NAvg,Ratio2]), - if Ratio2 < 1.0 -> - ct:fail({bad_ratio,Ratio2}); - true -> - ok - end, - - Receiver3 = - spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, Low) end), - Starter3 = - spawn(fun() -> starter(Max, Low, Receiver3) end), - {M3Rs,M3Avg,LRs,LAvg,Ratio3} = - receive - {Receiver3,Res3} -> Res3 - end, - exit(Starter3, kill), - exit(Receiver3, kill), - io:format("Reports: ~w max (~w/proc), ~w low (~w/proc). Ratio: ~w~n", - [M3Rs,M3Avg,LRs,LAvg,Ratio3]), - if Ratio3 < 1.0 -> - ct:fail({bad_ratio,Ratio3}); - true -> - ok(Config) - end. - - -%% Run high prio processes and verify they get at least as much -%% runtime as normal and low. - -high(Config) when is_list(Config) -> - max = process_flag(priority, max), % should already be max (init_per_tc) - Self = self(), - High = {high,2}, - Normal = {normal,100}, - Low = {low,100}, - - %% specify time of test (in seconds) - Time = 30, - - Receiver1 = - spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, High, Normal) end), - Starter1 = - spawn(fun() -> starter(High, Normal, Receiver1) end), - {H1Rs,H1Avg,NRs,NAvg,Ratio1} = - receive - {Receiver1,Res1} -> Res1 - end, - exit(Starter1, kill), - exit(Receiver1, kill), - io:format("Reports: ~w high (~w/proc), ~w normal (~w/proc). Ratio: ~w~n", - [H1Rs,H1Avg,NRs,NAvg,Ratio1]), - if Ratio1 < 1.0 -> - ct:fail({bad_ratio,Ratio1}); - true -> - ok - end, - - Receiver2 = - spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, High, Low) end), - Starter2 = - spawn(fun() -> starter(High, Low, Receiver2) end), - {H2Rs,H2Avg,LRs,LAvg,Ratio2} = - receive - {Receiver2,Res2} -> Res2 - end, - exit(Starter2, kill), - exit(Receiver2, kill), - io:format("Reports: ~w high (~w/proc), ~w low (~w/proc). Ratio: ~w~n", - [H2Rs,H2Avg,LRs,LAvg,Ratio2]), - if Ratio2 < 1.0 -> - ct:fail({bad_ratio,Ratio2}); - true -> - ok(Config) - end. - - -%%----------------------------------------------------------------------------------- -%% Controller processes and help functions -%%----------------------------------------------------------------------------------- - -receiver(T0, TimeSec, Main, {P1,P1N}, {P2,P2N}) -> - %% prio should be max so that mailbox doesn't overflow - process_flag(priority, max), - receiver(T0, TimeSec*1000, Main, P1,P1N,0, P2,P2N,0, 100000). - -%% uncomment lines below to get life sign (debug) -receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, 0) -> - % T = erlang:convert_time_unit(erlang:monotonic_time() - T0, native, millisecond), - % erlang:display({round(T/1000),P1Rs,P2Rs}), - receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, 100000); - -receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, C) -> - Remain = Time - erlang:convert_time_unit(erlang:monotonic_time() - T0, - native, millisecond), % test time remaining - Remain1 = if Remain < 0 -> - 0; - true -> - Remain - end, - {P1Rs1,P2Rs1} = - receive - {_Pid,P1} -> % report from a P1 process - {P1Rs+1,P2Rs}; - {_Pid,P2} -> % report from a P2 process - {P1Rs,P2Rs+1} - after Remain1 -> - {P1Rs,P2Rs} - end, - if Remain > 0 -> % keep going - receiver(T0, Time, Main, P1,P1N,P1Rs1, P2,P2N,P2Rs1, C-1); - true -> % finish - %% calculate results and send to main test process - P1Avg = P1Rs1/P1N, - P2Avg = P2Rs1/P2N, - Ratio = if P2Avg < 1.0 -> P1Avg; - true -> P1Avg/P2Avg - end, - Main ! {self(),{P1Rs1,round(P1Avg),P2Rs1,round(P2Avg),Ratio}}, - flush_loop() - end. - -starter({P1,P1N}, {P2,P2N}, Receiver) -> - %% start N1 processes with prio P1 - start_p(P1, P1N, Receiver), - %% start N2 processes with prio P2 - start_p(P2, P2N, Receiver), - erlang:display({started,P1N+P2N}), - flush_loop(). - -start_p(_, 0, _) -> - ok; -start_p(Prio, N, Receiver) -> - spawn_link(fun() -> p(Prio, Receiver) end), - start_p(Prio, N-1, Receiver). - -p(Prio, Receiver) -> - %% set process priority - process_flag(priority, Prio), - p_loop(0, Prio, Receiver). - -p_loop(100, Prio, Receiver) -> - receive after 0 -> ok end, - %% if Receiver gone, we're done - case is_process_alive(Receiver) of - false -> exit(bye); - true -> ok - end, - %% send report - Receiver ! {self(),Prio}, - p_loop(0, Prio, Receiver); - -p_loop(N, Prio, Receiver) -> - p_loop(N+1, Prio, Receiver). - - -flush_loop() -> - receive _ -> - ok - end, - flush_loop(). diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl index 94ee9851dd..fccbaf13ee 100644 --- a/erts/emulator/test/port_SUITE.erl +++ b/erts/emulator/test/port_SUITE.erl @@ -153,7 +153,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 10}}]. + {timetrap, {minutes, 1}}]. all() -> [otp_6224, {group, stream}, basic_ping, slow_writes, diff --git a/erts/emulator/test/port_trace_SUITE.erl b/erts/emulator/test/port_trace_SUITE.erl index 03efdc15db..bfc3c8cb51 100644 --- a/erts/emulator/test/port_trace_SUITE.erl +++ b/erts/emulator/test/port_trace_SUITE.erl @@ -52,7 +52,7 @@ -define(ECHO_DRV_REMOTE_SEND_TERM, 15). suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 30}}]. + {timetrap, {minutes, 2}}]. all() -> [port_specs, ports, open_close, diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl index e14185e881..4204d12eb3 100644 --- a/erts/emulator/test/process_SUITE.erl +++ b/erts/emulator/test/process_SUITE.erl @@ -134,6 +134,11 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> [{testcase, Func}|Config]. end_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> + %% Restore max_heap_size to default value. + erlang:system_flag(max_heap_size, + #{size => 0, + kill => true, + error_logger => true}), ok. fun_spawn(Fun) -> @@ -1024,36 +1029,48 @@ bump_big(Prev, Limit) -> %% Priority 'low' should be mixed with 'normal' using a factor of %% about 8. (OTP-2644) low_prio(Config) when is_list(Config) -> - case erlang:system_info(schedulers_online) of - 1 -> - ok = low_prio_test(Config); - _ -> - erlang:system_flag(multi_scheduling, block_normal), - ok = low_prio_test(Config), - erlang:system_flag(multi_scheduling, unblock_normal), - {comment, - "Test not written for SMP runtime system. " - "Multi scheduling blocked during test."} - end. + erlang:system_flag(multi_scheduling, block_normal), + Prop = low_prio_test(Config), + erlang:system_flag(multi_scheduling, unblock_normal), + Str = lists:flatten(io_lib:format("Low/high proportion is ~.3f", + [Prop])), + {comment,Str}. low_prio_test(Config) when is_list(Config) -> process_flag(trap_exit, true), - S = spawn_link(?MODULE, prio_server, [0, 0]), + + %% Spawn the server running with high priority. The server must + %% not run at normal priority as that would skew the results for + %% two reasons: + %% + %% 1. There would be one more normal-priority processes than + %% low-priority processes. + %% + %% 2. The receive queue would grow faster than the server process + %% could process it. That would in turn trigger the reduction + %% punishment for the clients. + S = spawn_opt(?MODULE, prio_server, [0, 0], [link,{priority,high}]), + + %% Spawn the clients and let them run for a while. PCs = spawn_prio_clients(S, erlang:system_info(schedulers_online)), - ct:sleep({seconds,3}), + ct:sleep({seconds,2}), lists:foreach(fun (P) -> exit(P, kill) end, PCs), + + %% Stop the server and retrieve the result. S ! exit, - receive {'EXIT', S, {A, B}} -> check_prio(A, B) end, - ok. + receive + {'EXIT', S, {A, B}} -> + check_prio(A, B) + end. check_prio(A, B) -> Prop = A/B, ok = io:format("Low=~p, High=~p, Prop=~p\n", [A, B, Prop]), - %% It isn't 1/8, it's more like 0.3, but let's check that - %% the low-prio processes get some little chance to run at all. - true = (Prop < 1.0), - true = (Prop > 1/32). + %% Prop is expected to be appr. 1/8. Allow a reasonable margin. + true = Prop < 1/4, + true = Prop > 1/16, + Prop. prio_server(A, B) -> receive @@ -2057,6 +2074,7 @@ max_heap_size_test(Option, Size, Kill, ErrorLogger) -> end, if ErrorLogger -> receive + %% There must be at least one error message. {error, _, {emulator, _, [Pid|_]}} -> ok end; @@ -2069,22 +2087,33 @@ max_heap_size_test(Option, Size, Kill, ErrorLogger) -> {'DOWN', Ref, process, Pid, die} -> ok end, - flush(); + %% If the process was not killed, the limit may have + %% been reached more than once and there may be + %% more {error, ...} messages left. + receive_error_messages(Pid); true -> ok end, + + %% Make sure that there are no unexpected messages. + receive_unexpected(). + +receive_error_messages(Pid) -> receive - M -> - ct:fail({unexpected_message, M}) - after 10 -> + {error, _, {emulator, _, [Pid|_]}} -> + receive_error_messages(Pid) + after 1000 -> ok end. -flush() -> +receive_unexpected() -> receive - _M -> - flush() - after 1000 -> + {info_report, _, _} -> + %% May be an alarm message from os_mon. Ignore. + receive_unexpected(); + M -> + ct:fail({unexpected_message, M}) + after 10 -> ok end. diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl index 83653a7a36..c7d5a3f5a0 100644 --- a/erts/emulator/test/receive_SUITE.erl +++ b/erts/emulator/test/receive_SUITE.erl @@ -39,25 +39,43 @@ groups() -> call_with_huge_message_queue(Config) when is_list(Config) -> Pid = spawn_link(fun echo_loop/0), - - {Time,ok} = tc(fun() -> calls(10, Pid) end), - - [self() ! {msg,N} || N <- lists:seq(1, 500000)], + _WarmUpTime = time_calls(Pid), + Time = time_calls(Pid), + _ = [self() ! {msg,N} || N <- lists:seq(1, 500000)], + io:format("Time for empty message queue: ~p", [Time]), erlang:garbage_collect(), - {NewTime1,ok} = tc(fun() -> calls(10, Pid) end), - {NewTime2,ok} = tc(fun() -> calls(10, Pid) end), + call_with_huge_message_queue_1(Pid, Time, 5). + +call_with_huge_message_queue_1(_Pid, _Time, 0) -> + ct:fail(bad_ratio); +call_with_huge_message_queue_1(Pid, Time, NumTries) -> + HugeTime = time_calls(Pid), + io:format("Time for huge message queue: ~p", [HugeTime]), + + case (HugeTime+1) / (Time+1) of + Q when Q < 10 -> + ok; + Q -> + io:format("Too high ratio: ~p\n", [Q]), + call_with_huge_message_queue_1(Pid, Time, NumTries-1) + end. - io:format("Time for empty message queue: ~p", [Time]), - io:format("Time1 for huge message queue: ~p", [NewTime1]), - io:format("Time2 for huge message queue: ~p", [NewTime2]), - - case hd(lists:sort([(NewTime1+1) / (Time+1), (NewTime2+1) / (Time+1)])) of - Q when Q < 10 -> - ok; - Q -> - ct:fail("Best Q = ~p", [Q]) - end, - ok. +%% Time a number calls. Try to avoid returning a zero time. +time_calls(Pid) -> + time_calls(Pid, 10). + +time_calls(_Pid, 0) -> + 0; +time_calls(Pid, NumTries) -> + case timer:tc(fun() -> calls(Pid) end) of + {0,ok} -> + time_calls(Pid, NumTries-1); + {Time,ok} -> + Time + end. + +calls(Pid) -> + calls(100, Pid). calls(0, _) -> ok; calls(N, Pid) -> @@ -108,6 +126,3 @@ echo_loop() -> Pid ! {Ref,Msg}, echo_loop() end. - -tc(Fun) -> - timer:tc(erlang, apply, [Fun,[]]). diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl index 7cbd93a0f3..a977eb41c4 100644 --- a/erts/emulator/test/timer_bif_SUITE.erl +++ b/erts/emulator/test/timer_bif_SUITE.erl @@ -488,24 +488,40 @@ registered_process(Config) when is_list(Config) -> same_time_yielding(Config) when is_list(Config) -> Mem = mem(), + Ref = make_ref(), SchdlrsOnln = erlang:system_info(schedulers_online), Tmo = erlang:monotonic_time(millisecond) + 3000, Tmrs = lists:map(fun (I) -> process_flag(scheduler, (I rem SchdlrsOnln) + 1), - erlang:start_timer(Tmo, self(), hej, [{abs, true}]) + erlang:start_timer(Tmo, self(), Ref, [{abs, true}]) end, lists:seq(1, (?TIMEOUT_YIELD_LIMIT*3+1)*SchdlrsOnln)), true = mem_larger_than(Mem), - lists:foreach(fun (Tmr) -> receive {timeout, Tmr, hej} -> ok end end, Tmrs), + receive_all_timeouts(length(Tmrs), Ref), Done = erlang:monotonic_time(millisecond), true = Done >= Tmo, + MsAfterTmo = Done - Tmo, + io:format("Done ~p ms after Tmo\n", [MsAfterTmo]), case erlang:system_info(build_type) of - opt -> true = Done < Tmo + 200; - _ -> true = Done < Tmo + 1000 + opt -> + true = MsAfterTmo < 200; + _ -> + true = MsAfterTmo < 1000 end, Mem = mem(), ok. +%% Read out all timeouts in receive queue order. This is efficient +%% even if there are very many messages. + +receive_all_timeouts(0, _Ref) -> + ok; +receive_all_timeouts(N, Ref) -> + receive + {timeout, _Tmr, Ref} -> + receive_all_timeouts(N-1, Ref) + end. + same_time_yielding_with_cancel(Config) when is_list(Config) -> same_time_yielding_with_cancel_test(false, false). diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl index 643c2e0472..bd0ea22de9 100644 --- a/erts/emulator/test/trace_SUITE.erl +++ b/erts/emulator/test/trace_SUITE.erl @@ -46,7 +46,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 5}}]. + {timetrap, {minutes, 1}}]. all() -> [cpu_timestamp, receive_trace, link_receive_call_correlation, @@ -184,10 +184,10 @@ receive_trace(Config) when is_list(Config) -> {'EXIT', Intruder, {badarg, _}} = receive_first(), %% Untrace the process; we should not receive anything. - ?line 1 = erlang:trace(Receiver, false, ['receive']), - ?line Receiver ! {hello, there}, - ?line Receiver ! any_garbage, - ?line receive_nothing(), + 1 = erlang:trace(Receiver, false, ['receive']), + Receiver ! {hello, there}, + Receiver ! any_garbage, + receive_nothing(), %% Verify restrictions in matchspec for 'receive' F3 = fun (Pat) -> {'EXIT', {badarg,_}} = (catch erlang:trace_pattern('receive', Pat, [])) end, diff --git a/erts/emulator/test/trace_port_SUITE.erl b/erts/emulator/test/trace_port_SUITE.erl index e4db368ea1..5eb27a7b68 100644 --- a/erts/emulator/test/trace_port_SUITE.erl +++ b/erts/emulator/test/trace_port_SUITE.erl @@ -37,7 +37,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap, {seconds, 30}}]. + {timetrap, {minutes, 2}}]. all() -> [call_trace, return_trace, send, receive_trace, diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml index c5074418cd..499a7e40c3 100644 --- a/lib/asn1/doc/src/notes.xml +++ b/lib/asn1/doc/src/notes.xml @@ -32,55 +32,6 @@ <p>This document describes the changes made to the asn1 application.</p> -<section><title>Asn1 5.0</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Add compile option <c>-compile(no_native)</c> in modules - with <c>on_load</c> directive which is not yet supported - by HiPE.</p> - <p> - Own Id: OTP-14316 Aux Id: PR-1390 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>The <c>error</c> tuple returned from the <c>encode</c> - and <c>decode</c> functions will now include the stack - backtrace to make it easier to understand what went - wrong.</p> - <p> - Own Id: OTP-13961</p> - </item> - <item> - <p>The deprecated module <c>asn1rt</c> has been removed. - The deprecated functions <c>asn1ct:encode/3</c> and - <c>asn1ct:decode/3</c> have been removed. The - undocumented function <c>asn1ct:encode/2</c> has been - removed.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14146</p> - </item> - <item> - <p>The new '<c>maps</c>' option changes the - representation of the types <c>SEQUENCE</c> and - <c>SET</c> to be maps (instead of records).</p> - <p> - Own Id: OTP-14219</p> - </item> - </list> - </section> - -</section> - <section><title>Asn1 4.0.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk index 7329a9f879..e4bf3e2236 100644 --- a/lib/asn1/vsn.mk +++ b/lib/asn1/vsn.mk @@ -1 +1 @@ -ASN1_VSN = 5.0 +ASN1_VSN = 4.0.4 diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml index cc676e955b..a0079fd0c0 100644 --- a/lib/common_test/doc/src/notes.xml +++ b/lib/common_test/doc/src/notes.xml @@ -33,74 +33,6 @@ <file>notes.xml</file> </header> -<section><title>Common_Test 1.15</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Errors in the documentation for user HTML stylesheets - have been corrected.</p> - <p> - Own Id: OTP-14332 Aux Id: seq13299 </p> - </item> - <item> - <p>Internal code change: Calls to <c>catch</c> followed - by a call to <c>erlang:get_stacktrace/0</c> has been - rewritten to use <c>try</c> instead of <c>catch</c> to - make the code future-proof.</p> - <p> - Own Id: OTP-14400</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>The <c>ct_slave</c> modules now handle nodenames in - the same way as nodenames passed to <c>-sname</c>. That - means <c>ct_slave:start('[email protected]').</c> will now - work.</p> - <p> - Own Id: OTP-13806</p> - </item> - <item> - <p> - Added the new option, <c>keep_logs</c>. If setting the - value for this option to an integer, N, common_test will - remove all ct_run.* directories in the current log - directory, except the N newest.</p> - <p> - Own Id: OTP-14179</p> - </item> - <item> - <p> - The existing <c>ct_netconfc:open/1,2</c> opens an SSH - connection with one SSH channel realizing one Netconf - session. To allow testing of multiple sessions over the - same SSH connection, the following functions are added to - <c>ct_netconfc</c>:</p> - <p> - * <c>connect/1,2</c> - establish an SSH connection * - <c>disconnect/1</c> - close the given SSH connection * - <c>session/1,2,3</c> - open an ssh channel on the given - connection and send 'hello' to start a Netconf session</p> - <p> - Own Id: OTP-14284</p> - </item> - <item> - <p> - The function ct_ssh:shell/2,3 is added.</p> - <p> - Own Id: OTP-14415 Aux Id: seq13315 </p> - </item> - </list> - </section> - -</section> - <section><title>Common_Test 1.14</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk index a219aa4736..e6ae8b2e7a 100644 --- a/lib/common_test/vsn.mk +++ b/lib/common_test/vsn.mk @@ -1 +1 @@ -COMMON_TEST_VSN = 1.15 +COMMON_TEST_VSN = 1.14 diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index f11d6c73f2..1dc0c808e7 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -32,180 +32,6 @@ <p>This document describes the changes made to the Compiler application.</p> -<section><title>Compiler 7.1</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p>For many releases, it has been legal to override a BIF - with a local function having the same name. However, - calling a local function with the same name as guard BIF - as filter in a list comprehension was not allowed.</p> - <p> - Own Id: OTP-13690</p> - </item> - <item> - <p>compile:forms/2 would not return the module name as - documented when one of the options '<c>from_core</c>', - '<c>from_asm</c>', or '<c>from_beam</c>' was given. Also, - the compiler would crash if one of those options was - combined with '<c>native</c>'.</p> - <p> - Own Id: OTP-14408 Aux Id: ERL-417 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Optimized test for tuples with an atom as first element.</p> - <p> - Own Id: OTP-12148</p> - </item> - <item> - <p> - Compilation of modules with huge literal binary strings - is now much faster.</p> - <p> - Own Id: OTP-13794</p> - </item> - <item> - <p>Replaced usage of deprecated symbolic <seealso - marker="erts:erlang#type-time_unit"><c>time - unit</c></seealso> representations.</p> - <p> - Own Id: OTP-13831 Aux Id: OTP-13735 </p> - </item> - <item> - <p>The undocumented and unsupported module - <c>sys_pre_expand</c> has been removed. As a partical - replacement for the functionality, there is a new - function <c>erl_internal:add_predefined_functions/1</c> - and <c>erl_expand_records</c> will now add a module - prefix to calls to BIFs and imported functions.</p> - <p> - Own Id: OTP-13856</p> - </item> - <item> - <p>The internal compiler passes now start all generated - variables with "@" to avoid any conflicts with variables - in languages such as Elixir or LFE.</p> - <p> - Own Id: OTP-13924</p> - </item> - <item> - <p>The function <c>fmod/2</c> has been added to the - <c>math</c> module.</p> - <p> - Own Id: OTP-14000</p> - </item> - <item> - <p>Code generation for complicated guards have been - improved.</p> - <p> - Own Id: OTP-14042</p> - </item> - <item> - <p> - The compiler has new warnings for repeated identical map - keys.</p> - <p> - A map expression such as,</p> - <p> - <c> #{'a' => 1, 'b' => 2, 'a' => 3}.</c></p> - <p> - will produce a warning for the repeated key 'a'.</p> - <p> - Own Id: OTP-14058</p> - </item> - <item> - <p>By default, there will now be a warning when - <c>export_all</c> is used. The warning can be disabled - using <c>nowarn_export_all</c>.</p> - <p> - Own Id: OTP-14071</p> - </item> - <item> - <p> - Optimize maps pattern matching by only examining the - common keys in each clause first instead of all keys. - This will reduce the number of lookups of each key in - maps pattern matching.</p> - <p> - Own Id: OTP-14072</p> - </item> - <item> - <p>There is a new '<c>deterministc</c>' option to omit - '<c>source</c>' and '<c>options</c>' tuples in the BEAM - file.</p> - <p> - Own Id: OTP-14087</p> - </item> - <item> - <p> - Analyzing modules with binary construction with huge - strings is now much faster. The compiler also compiles - such modules slightly faster.</p> - <p> - Own Id: OTP-14125 Aux Id: ERL-308 </p> - </item> - <item> - <p>Atoms may now contain arbitrary Unicode - characters.</p> - <p> - Own Id: OTP-14178</p> - </item> - <item> - <p><c>compile:file/2</c> now accepts the option - <c>extra_chunks</c> to include extra chunks in the BEAM - file.</p> - <p> - Own Id: OTP-14221</p> - </item> - <item> - <p>The format of debug information that is stored in BEAM - files (when <c>debug_info</c> is used) has been changed. - The purpose of the change is to better support other - BEAM-based languages such as Elixir or LFE.</p> - <p>All tools included in OTP (dialyzer, debugger, cover, - and so on) will handle both the new format and the - previous format. Tools that retrieve the debug - information using <c>beam_lib:chunk(Beam, - [abstract_code])</c> will continue to work with both the - new and old format. Tools that call - <c>beam_lib:chunk(Beam, ["Abst"])</c> will not work with - the new format.</p> - <p>For more information, see the description of - <c>debug_info</c> in the documentation for - <c>beam_lib</c> and the description of the - <c>{debug_info,{Backend,Data}}</c> option in the - documentation for <c>compile</c>.</p> - <p> - Own Id: OTP-14369 Aux Id: PR-1367 </p> - </item> - <item> - <p>In a future release, <c>erlang:get_stacktrace/0</c> - will probably only work when called from within a - '<c>try</c>' expression (otherwise it will return - <c>[]</c>.</p> - <p>To help prepare for that change, the compiler will now - by default warn if '<c>get_stacktrace/0</c>' is used in a - way that will not work in the future. Note that the - warning will not be issued if '<c>get_stacktrace/0</c>' - is used in a function that uses neither '<c>catch</c>' - nor '<c>try</c>' (because that could be a legal use if - the function is called from within a '<c>try</c>'.</p> - <p> - Own Id: OTP-14401</p> - </item> - </list> - </section> - -</section> - <section><title>Compiler 7.0.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index 463c264a5f..5c87304a01 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 7.1 +COMPILER_VSN = 7.0.4 diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 4ae7edd8b2..688ec339aa 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -609,7 +609,7 @@ struct digest_type_t { }md; }; -struct digest_type_t digest_types[] = +static struct digest_type_t digest_types[] = { {{"md4"}, {&EVP_md4}}, {{"md5"}, {&EVP_md5}}, @@ -666,7 +666,7 @@ struct cipher_type_t { #define COND_NO_DES_PTR(Ptr) (Ptr) #endif -struct cipher_type_t cipher_types[] = +static struct cipher_type_t cipher_types[] = { {{"rc2_cbc"}, #ifndef OPENSSL_NO_RC2 diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 9a98bfc7c7..62b013e463 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -31,134 +31,6 @@ </header> <p>This document describes the changes made to the Crypto application.</p> -<section><title>Crypto 4.0</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - LibreSSL can now be used by the modernized crypto app.</p> - <p> - Own Id: OTP-14247</p> - </item> - <item> - <p> - Add compile option <c>-compile(no_native)</c> in modules - with <c>on_load</c> directive which is not yet supported - by HiPE.</p> - <p> - Own Id: OTP-14316 Aux Id: PR-1390 </p> - </item> - <item> - <p> - Fix a bug in aes cfb128 function introduced by the bug - fix in GitHub pull request <url - href="https://github.com/erlang/otp/pull/1393">#1393</url>.</p> - <p> - Own Id: OTP-14435 Aux Id: PR-1462, PR-1393, OTP-14313 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Add basic support for CMAC</p> - <p> - Own Id: OTP-13779 Aux Id: ERL-82 PR-1138 </p> - </item> - <item> - <p> - Removed functions deprecated in crypto-3.0 first released - in OTP-R16B01</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13873</p> - </item> - <item> - <p> - The <c>crypto</c> application now supports OpenSSL 1.1.</p> - <p> - Own Id: OTP-13900</p> - </item> - <item> - <p> - Allow Erlang/OTP to use OpenSSL in FIPS-140 mode, in - order to satisfy specific security requirements (mostly - by different parts of the US federal government). </p> - <p> - See the new crypto users guide "FIPS mode" chapter about - building and using the FIPS support which is disabled by - default.</p> - <p> - (Thanks to dszoboszlay and legoscia)</p> - <p> - Own Id: OTP-13921 Aux Id: PR-1180 </p> - </item> - <item> - <p> - Crypto chacha20-poly1305 as in RFC 7539 enabled for - OpenSSL >= 1.1.</p> - <p> - Thanks to mururu.</p> - <p> - Own Id: OTP-14092 Aux Id: PR-1291 </p> - </item> - <item> - <p> - RSA key generation added to <c>crypto:generate_key/2</c>. - Thanks to wiml.</p> - <p> - An interface is also added to - <c>public_key:generate_key/1</c>.</p> - <p> - Own Id: OTP-14140 Aux Id: ERL-165, PR-1299 </p> - </item> - <item> - <p> - Raised minimum requeriment for OpenSSL version to - OpenSSL-0.9.8.c although we recommend a much higher - version, that is a version that is still maintained - officially by the OpenSSL project. Note that using such - an old version may restrict the crypto algorithms - supported.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14171</p> - </item> - <item> - <p> - Deprecate crypto:rand_uniform/2 as it is not - cryptographically strong</p> - <p> - Own Id: OTP-14274</p> - </item> - <item> - <p> - The Crypto application now supports generation of - cryptographically strong random numbers (floats < 1.0 - and integer arbitrary ranges) as a plugin to the 'rand' - module.</p> - <p> - Own Id: OTP-14317 Aux Id: PR-1372 </p> - </item> - <item> - <p> - This replaces the hard coded test values for AES, CMAC - and GCM ciphers with the full validation set from NIST's - CAVP program.</p> - <p> - Own Id: OTP-14436 Aux Id: PR-1396 </p> - </item> - </list> - </section> - -</section> - <section><title>Crypto 3.7.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index 796e3b6d84..f3e0623ac9 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 4.0 +CRYPTO_VSN = 3.7.4 diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml index fa85567a84..532a17bd81 100644 --- a/lib/debugger/doc/src/notes.xml +++ b/lib/debugger/doc/src/notes.xml @@ -33,42 +33,6 @@ <p>This document describes the changes made to the Debugger application.</p> -<section><title>Debugger 4.2.2</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> The Erlang shell, <c>qlc:string_to_handle()</c>, and - the Debugger (the Evaluator area and Edit variable window - of the Bindings area) can parse pids, ports, references, - and external funs, as long as they can be created in the - running system. </p> - <p> - Own Id: OTP-14296</p> - </item> - <item> - <p> Fix editing of simple binary values in the Bindings - area of the Debugger's Attach Process Window. </p> - <p> - Own Id: OTP-14318</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Miscellaneous updates due to atoms containing - arbitrary Unicode characters. </p> - <p> - Own Id: OTP-14285</p> - </item> - </list> - </section> - -</section> - <section><title>Debugger 4.2.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk index 3534570ef5..f5440865ef 100644 --- a/lib/debugger/vsn.mk +++ b/lib/debugger/vsn.mk @@ -1 +1 @@ -DEBUGGER_VSN = 4.2.2 +DEBUGGER_VSN = 4.2.1 diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml index 36ecc4a87b..f7613b3145 100644 --- a/lib/dialyzer/doc/src/notes.xml +++ b/lib/dialyzer/doc/src/notes.xml @@ -32,69 +32,6 @@ <p>This document describes the changes made to the Dialyzer application.</p> -<section><title>Dialyzer 3.2</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> The check of bad type variables in type declarations - was mistakingly removed in Erlang/OTP 18, and is now - re-introduced. </p> - <p> - Own Id: OTP-14423 Aux Id: OTP-14323 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Analyzing modules with binary construction with huge - strings is now much faster. The compiler also compiles - such modules slightly faster.</p> - <p> - Own Id: OTP-14125 Aux Id: ERL-308 </p> - </item> - <item> - <p> The peak memory consumption is reduced. </p> - <p> - Own Id: OTP-14127</p> - </item> - <item> - <p>TypEr has been removed as separate application and is - now a part of the Dialyzer application. Documentation for - TypEr has been added in the Dialyzer application.</p> - <p> - Own Id: OTP-14336</p> - </item> - <item> - <p>The format of debug information that is stored in BEAM - files (when <c>debug_info</c> is used) has been changed. - The purpose of the change is to better support other - BEAM-based languages such as Elixir or LFE.</p> - <p>All tools included in OTP (dialyzer, debugger, cover, - and so on) will handle both the new format and the - previous format. Tools that retrieve the debug - information using <c>beam_lib:chunk(Beam, - [abstract_code])</c> will continue to work with both the - new and old format. Tools that call - <c>beam_lib:chunk(Beam, ["Abst"])</c> will not work with - the new format.</p> - <p>For more information, see the description of - <c>debug_info</c> in the documentation for - <c>beam_lib</c> and the description of the - <c>{debug_info,{Backend,Data}}</c> option in the - documentation for <c>compile</c>.</p> - <p> - Own Id: OTP-14369 Aux Id: PR-1367 </p> - </item> - </list> - </section> - -</section> - <section><title>Dialyzer 3.1.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk index 4a1a7c25a0..0919fba834 100644 --- a/lib/dialyzer/vsn.mk +++ b/lib/dialyzer/vsn.mk @@ -1 +1 @@ -DIALYZER_VSN = 3.2 +DIALYZER_VSN = 3.1 diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml index 27b5a3ac3d..4982488335 100644 --- a/lib/edoc/doc/src/notes.xml +++ b/lib/edoc/doc/src/notes.xml @@ -32,28 +32,6 @@ <p>This document describes the changes made to the EDoc application.</p> -<section><title>Edoc 0.9</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>To support stable builds, <c>edoc</c> no longer - includes time stamps in the footer for generated - files.</p> - <p> - Own Id: OTP-14277</p> - </item> - <item> - <p> Miscellaneous updates due to atoms containing - arbitrary Unicode characters. </p> - <p> - Own Id: OTP-14285</p> - </item> - </list> - </section> - -</section> - <section><title>Edoc 0.8.1</title> <section><title>Improvements and New Features</title> diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk index 1a933b2ad8..d66802fdac 100644 --- a/lib/edoc/vsn.mk +++ b/lib/edoc/vsn.mk @@ -1 +1 @@ -EDOC_VSN = 0.9 +EDOC_VSN = 0.8.1 diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl index ac3447cfe6..4bfb0dd291 100644 --- a/lib/eldap/test/eldap_basic_SUITE.erl +++ b/lib/eldap/test/eldap_basic_SUITE.erl @@ -119,7 +119,10 @@ init_per_suite(Config) -> {ldaps_server, LDAPS_server} | Config]. end_per_suite(_Config) -> - ssl:stop(). + try ssl:stop() + catch + _:_ -> ok + end. init_per_group(return_values, Config) -> diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml index 0653730572..4824a755d9 100644 --- a/lib/erl_docgen/doc/src/notes.xml +++ b/lib/erl_docgen/doc/src/notes.xml @@ -31,42 +31,7 @@ </header> <p>This document describes the changes made to the <em>erl_docgen</em> application.</p> - <section><title>Erl_Docgen 0.7</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Sort index of C functions alphabetically in the sidebar.</p> - <p> - Own Id: OTP-14333 Aux Id: ERL-393 </p> - </item> - <item> - <p> The right side index of functions now handle - functions with same name but different arity. </p> - <p> - Own Id: OTP-14431</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Improvements in the OTP documentation style.</p> - <p> - (Thanks to Mariano Guerra)</p> - <p> - Own Id: OTP-14371 Aux Id: PR-1215 </p> - </item> - </list> - </section> - -</section> - -<section><title>Erl_Docgen 0.6.1</title> + <section><title>Erl_Docgen 0.6.1</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index e586960c06..77d503b4d2 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -31,39 +31,6 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> -<section><title>Erl_Interface 3.10</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Fix bug where gethostname would incorrectly fail with - enametoolong on Linux.</p> - <p> - Own Id: OTP-14310</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Remove generation of atoms in old latin1 external format. - The old latin1 format can still be decoded but is never - generated by <c>term_to_binary</c> or sent on a - distribution channel. The new utf8 format for atoms was - introduced in OTP R16. An OTP 20 node can therefore not - connect to nodes older than R16.</p> - <p> - Own Id: OTP-14337</p> - </item> - </list> - </section> - -</section> - <section><title>Erl_Interface 3.9.3</title> <section><title>Improvements and New Features</title> diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index 01fcee86dd..563694a0c1 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1,2 +1,2 @@ -EI_VSN = 3.10 +EI_VSN = 3.9.3 ERL_INTERFACE_VSN = $(EI_VSN) diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml index 2a4ca6d12c..cd4e230254 100644 --- a/lib/eunit/doc/src/notes.xml +++ b/lib/eunit/doc/src/notes.xml @@ -33,21 +33,6 @@ </header> <p>This document describes the changes made to the EUnit application.</p> -<section><title>Eunit 2.3.3</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p>The surefire reports from <c>eunit</c> will no longer - have names with embedded double quotes.</p> - <p> - Own Id: OTP-14287</p> - </item> - </list> - </section> - -</section> - <section><title>Eunit 2.3.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk index 107ad5c101..7eee75ee10 100644 --- a/lib/eunit/vsn.mk +++ b/lib/eunit/vsn.mk @@ -1 +1 @@ -EUNIT_VSN = 2.3.3 +EUNIT_VSN = 2.3.2 diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml index 9167d0aaec..38f8dbfea3 100644 --- a/lib/hipe/doc/src/notes.xml +++ b/lib/hipe/doc/src/notes.xml @@ -31,101 +31,6 @@ </header> <p>This document describes the changes made to HiPE.</p> -<section><title>Hipe 3.16</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Fix hipe compiler flags <c>o0</c> and <c>o1</c> that have - previously been ignored by mistake.</p> - <p> - Own Id: OTP-13862 Aux Id: PR-1154 </p> - </item> - <item> - <p> - Fix LLVM backend to not convert all remote calls to own - module, like <c>?MODULE:foo()</c>, into local calls.</p> - <p> - Own Id: OTP-13983</p> - </item> - <item> - <p> - Hipe optional LLVM backend does require LLVM version 3.9 - or later as older versions forced strong dependencies on - erts internals structures.</p> - <p> - Own Id: OTP-14238</p> - </item> - <item> - <p> - Fix a bug that has been seen causing failed loading of - hipe compiled modules on NetBSD due to unaligned data - pointers.</p> - <p> - Own Id: OTP-14302 Aux Id: ERL-376, PR-1386 </p> - </item> - <item> - <p> - Fix miscompilation bug in hipe that could cause wrong - function clause to be called from non-tail calls, where - the return value is unused, if the right function clause - is only reachable from those non-tail calls.</p> - <p> - Own Id: OTP-14306 Aux Id: ERL-278, PR-1392 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Improve hipe compilation time for large functions.</p> - <p> - Own Id: OTP-13810 Aux Id: PR-1124 </p> - </item> - <item> - <p>Replaced usage of deprecated symbolic <seealso - marker="erts:erlang#type-time_unit"><c>time - unit</c></seealso> representations.</p> - <p> - Own Id: OTP-13831 Aux Id: OTP-13735 </p> - </item> - <item> - <p> - Speed up hipe compile time register allocation for larger - function.</p> - <p> - Own Id: OTP-13879</p> - </item> - <item> - <p> - Various code generation improvements.</p> - <p> - Own Id: OTP-14261 Aux Id: PR-1360 </p> - </item> - <item> - <p> - Improve hipe compiler to generate code with better CPU - register utilization at runtime by the use of 'Live Range - Splitting' techniques.</p> - <p> - Own Id: OTP-14293 Aux Id: PR-1380 </p> - </item> - <item> - <p> - Allow HiPE to run on VM built with - <c>--enable-m32-build</c>.</p> - <p> - Own Id: OTP-14330 Aux Id: PR-1397 </p> - </item> - </list> - </section> - -</section> - <section><title>Hipe 3.15.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk index 0ef4aa7f09..172d976931 100644 --- a/lib/hipe/vsn.mk +++ b/lib/hipe/vsn.mk @@ -1 +1 @@ -HIPE_VSN = 3.16 +HIPE_VSN = 3.15.4 diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index ccf7628f72..1fad94fac1 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -33,49 +33,7 @@ <file>notes.xml</file> </header> - <section><title>Inets 6.4</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p>Typos have been fixed.</p> - <p> - Own Id: OTP-14387</p> - </item> - <item> - <p> - httpd_util:rfc1123_date/1 gracefully handle invalid DST - dates by returning the original time in the expected - rfc1123 format.</p> - <p> - Own Id: OTP-14394</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Add unicode binary support to http_uri functions</p> - <p> - Own Id: OTP-14404</p> - </item> - <item> - <p> - httpc - Change timeout handling so the redirects casuse a - new timer to be set. This means that a simple redirected - request could return after 2*timeout milliseconds.</p> - <p> - Own Id: OTP-14429</p> - </item> - </list> - </section> - -</section> - -<section><title>Inets 6.3.9</title> + <section><title>Inets 6.3.9</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index 89c17a8679..4b2bcc7242 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -1175,17 +1175,20 @@ handle_empty_queue(Session, ProfileName, TimeOut, State) -> %% If a pipline | keep_alive session has been idle for some time is not %% closed by the server, the client may want to close it. NewState = activate_queue_timeout(TimeOut, State), - update_session(ProfileName, Session, #session.queue_length, 0), - %% Note mfa will be initialized when a new request - %% arrives. - {noreply, - NewState#state{request = undefined, - mfa = undefined, - status_line = undefined, - headers = undefined, - body = undefined - } - }. + case update_session(ProfileName, Session, #session.queue_length, 0) of + {stop, Reason} -> + {stop, {shutdown, Reason}, State}; + _ -> + %% Note mfa will be initialized when a new request + %% arrives. + {noreply, + NewState#state{request = undefined, + mfa = undefined, + status_line = undefined, + headers = undefined, + body = undefined + }} + end. receive_response(Request, Session, Data, State) -> NewState = init_wait_for_response_state(Request, State), @@ -1677,7 +1680,7 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) -> Session2 = erlang:setelement(Pos, Session, Value), insert_session(Session2, ProfileName); error:badarg -> - exit(normal); %% Manager has been shutdown + {stop, normal}; T:E -> %% Unexpected this must be an error! Stacktrace = erlang:get_stacktrace(), @@ -1697,14 +1700,14 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) -> Session, (catch httpc_manager:lookup_session(SessionId, ProfileName)), T, E]), - exit({failed_updating_session, - [{profile, ProfileName}, - {session_id, SessionId}, - {pos, Pos}, - {value, Value}, - {etype, T}, - {error, E}, - {stacktrace, Stacktrace}]}) + {stop, {failed_updating_session, + [{profile, ProfileName}, + {session_id, SessionId}, + {pos, Pos}, + {value, Value}, + {etype, T}, + {error, E}, + {stacktrace, Stacktrace}]}} end. diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 96796f11c0..758cef7ac4 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 6.4 +INETS_VSN = 6.3.9 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml index 9ae188be6c..30f607c357 100644 --- a/lib/jinterface/doc/src/notes.xml +++ b/lib/jinterface/doc/src/notes.xml @@ -31,26 +31,6 @@ </header> <p>This document describes the changes made to the Jinterface application.</p> -<section><title>Jinterface 1.8</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Remove generation of atoms in old latin1 external format. - The old latin1 format can still be decoded but is never - generated by <c>term_to_binary</c> or sent on a - distribution channel. The new utf8 format for atoms was - introduced in OTP R16. An OTP 20 node can therefore not - connect to nodes older than R16.</p> - <p> - Own Id: OTP-14337</p> - </item> - </list> - </section> - -</section> - <section><title>Jinterface 1.7.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk index 373e2dab22..c29d9df3d7 100644 --- a/lib/jinterface/vsn.mk +++ b/lib/jinterface/vsn.mk @@ -1 +1 @@ -JINTERFACE_VSN = 1.8 +JINTERFACE_VSN = 1.7.1 diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 975518d791..7127a59a0c 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -31,141 +31,6 @@ </header> <p>This document describes the changes made to the Kernel application.</p> -<section><title>Kernel 5.3</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Fix bug where gethostname would incorrectly fail with - enametoolong on Linux.</p> - <p> - Own Id: OTP-14310</p> - </item> - <item> - <p> - Fix bug causing <c>code:is_module_native</c> to falsely - return true when <c>local</c> call trace is enabled for - the module.</p> - <p> - Own Id: OTP-14390</p> - </item> - <item> - <p> - Add early reject of invalid node names from distributed - nodes.</p> - <p> - Own Id: OTP-14426</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Since Unicode is now allowed in atoms an extra check is - needed for node names, which are restricted to Latin-1.</p> - <p> - Own Id: OTP-13805</p> - </item> - <item> - <p>Replaced usage of deprecated symbolic <seealso - marker="erts:erlang#type-time_unit"><c>time - unit</c></seealso> representations.</p> - <p> - Own Id: OTP-13831 Aux Id: OTP-13735 </p> - </item> - <item> - <p><c>file:write_file(Name, Data, [raw])</c> would turn - <c>Data</c> into a single binary before writing. This - meant it could not take advantage of the <c>writev()</c> - system call if it was given a list of binaries and told - to write with <c>raw</c> mode.</p> - <p> - Own Id: OTP-13909</p> - </item> - <item> - <p>The performance of the <c>disk_log</c> has been - somewhat improved in some corner cases (big items), and - the documentation has been clarified. </p> - <p> - Own Id: OTP-14057 Aux Id: PR-1245 </p> - </item> - <item> - <p>Functions for detecting changed code has been added. - <c>code:modified_modules/0</c> returns all currently - loaded modules that have changed on disk. - <c>code:module_status/1</c> returns the status for a - module. In the shell and in <c>c</c> module, <c>mm/0</c> - is short for <c>code:modified_modules/0</c>, and - <c>lm/0</c> reloads all currently loaded modules that - have changed on disk.</p> - <p> - Own Id: OTP-14059</p> - </item> - <item> - <p> - Introduce an event manager in Erlang to handle OS - signals. A subset of OS signals may be subscribed to and - those are described in the Kernel application.</p> - <p> - Own Id: OTP-14186</p> - </item> - <item> - <p> Sockets can now be bound to device (SO_BINDTODEVICE) - on platforms where it is supported. </p> <p> This has - been implemented e.g to support VRF-Lite under Linux; see - <url - href="https://www.kernel.org/doc/Documentation/networking/vrf.txt"> - VRF </url>, and GitHub pull request <url - href="https://github.com/erlang/otp/pull/1326">#1326</url>. - </p> - <p> - Own Id: OTP-14357 Aux Id: PR-1326 </p> - </item> - <item> - <p> - Added option to store shell_history on disk so that the - history can be reused between sessions.</p> - <p> - Own Id: OTP-14409 Aux Id: PR-1420 </p> - </item> - <item> - <p> The size of crash reports created by - <c>gen_server</c>, <c>gen_statem</c> and <c>proc_lib</c> - is limited with aid of the Kernel application variable - <c>error_logger_format_depth</c>. The purpose is to limit - the size of the <c>error_logger</c> process when - processes with huge message queues or states crash. </p> - <p> The new function - <c>error_logger:get_format_depth/0</c> can be used to - retrieve the value of the Kernel application variable - <c>error_logger_format_depth</c>. </p> - <p> - Own Id: OTP-14417</p> - </item> - <item> - <p> One of the ETS tables used by the <c>global</c> - module is created with <c>{read_concurrency, true}</c> in - order to reduce contention. </p> - <p> - Own Id: OTP-14419</p> - </item> - <item> - <p> - Warnings have been added to the relevant documentation - about not using un-secure distributed nodes in exposed - environments.</p> - <p> - Own Id: OTP-14425</p> - </item> - </list> - </section> - -</section> - <section><title>Kernel 5.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl index 3cbb75a633..1233e362f2 100644 --- a/lib/kernel/test/os_SUITE.erl +++ b/lib/kernel/test/os_SUITE.erl @@ -319,31 +319,38 @@ perf_counter_api(_Config) -> true = is_integer(os:perf_counter()), true = os:perf_counter() > 0, - T1 = os:perf_counter(), + Conv = fun(T1, T2) -> + erlang:convert_time_unit(T2 - T1, perf_counter, nanosecond) + end, + + do_perf_counter_test([], Conv, 120000000, 80000000), + do_perf_counter_test([1000], fun(T1, T2) -> T2 - T1 end, 120, 80). + +do_perf_counter_test(CntArgs, Conv, Upper, Lower) -> + %% We run the test multiple times to try to get a somewhat + %% stable value... what does this test? That the + %% calculate_perf_counter_unit in sys_time.c works somewhat ok. + do_perf_counter_test(CntArgs, Conv, Upper, Lower, 10). + +do_perf_counter_test(CntArgs, _Conv, Upper, Lower, 0) -> + ct:fail("perf_counter_test ~p ~p ~p",[CntArgs, Upper, Lower]); +do_perf_counter_test(CntArgs, Conv, Upper, Lower, Iters) -> + + T1 = apply(os, perf_counter, CntArgs), timer:sleep(100), - T2 = os:perf_counter(), - TsDiff = erlang:convert_time_unit(T2 - T1, perf_counter, nanosecond), - ct:pal("T1: ~p~n" + T2 = apply(os, perf_counter, CntArgs), + TsDiff = Conv(T1, T2), + ct:log("T1: ~p~n" "T2: ~p~n" "TsDiff: ~p~n", [T1,T2,TsDiff]), - %% We allow a 15% diff - true = TsDiff < 115000000, - true = TsDiff > 85000000, - - T1Ms = os:perf_counter(1000), - timer:sleep(100), - T2Ms = os:perf_counter(1000), - MsDiff = T2Ms - T1Ms, - ct:pal("T1Ms: ~p~n" - "T2Ms: ~p~n" - "MsDiff: ~p~n", - [T1Ms,T2Ms,MsDiff]), - - %% We allow a 15% diff - true = MsDiff < 115, - true = MsDiff > 85. + if + TsDiff < Upper, TsDiff > Lower -> + ok; + true -> + do_perf_counter_test(CntArgs, Conv, Upper, Lower, Iters-1) + end. %% Util functions diff --git a/lib/kernel/test/sendfile_SUITE.erl b/lib/kernel/test/sendfile_SUITE.erl index 2673c38494..e839959623 100644 --- a/lib/kernel/test/sendfile_SUITE.erl +++ b/lib/kernel/test/sendfile_SUITE.erl @@ -100,13 +100,13 @@ init_per_testcase(TC,Config) when TC == t_sendfile_recvduring; %% Check if sendfile is supported on this platform case catch sendfile_send(Send) of ok -> - Config; + init_per_testcase(t_sendfile, Config); Error -> ct:log("Error: ~p",[Error]), {skip,"Not supported"} end; init_per_testcase(_Tc,Config) -> - Config. + Config ++ [{sendfile_opts,[{use_threads,false}]}]. t_sendfile_small(Config) when is_list(Config) -> diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index 4edecd8969..76b020e8ed 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1 +1 @@ -KERNEL_VSN = 5.3 +KERNEL_VSN = 5.2 diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml index aa3d434dd7..a05a339003 100644 --- a/lib/megaco/doc/src/notes.xml +++ b/lib/megaco/doc/src/notes.xml @@ -37,21 +37,7 @@ section is the version number of Megaco.</p> - <section><title>Megaco 3.18.2</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p>Typos have been fixed.</p> - <p> - Own Id: OTP-14387</p> - </item> - </list> - </section> - -</section> - -<section><title>Megaco 3.18.1</title> + <section><title>Megaco 3.18.1</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk index ca8049daee..0d40f863b2 100644 --- a/lib/megaco/vsn.mk +++ b/lib/megaco/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = megaco -MEGACO_VSN = 3.18.2 +MEGACO_VSN = 3.18.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)" diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml index 3ca4026190..062a62298b 100644 --- a/lib/mnesia/doc/src/notes.xml +++ b/lib/mnesia/doc/src/notes.xml @@ -39,26 +39,7 @@ thus constitutes one section in this document. The title of each section is the version number of Mnesia.</p> - <section><title>Mnesia 4.15</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Removed the wrapping of select continuations in extension - plugin handling. This might require the user to rewrite - user backend plugin if used.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14039</p> - </item> - </list> - </section> - -</section> - -<section><title>Mnesia 4.14.3</title> + <section><title>Mnesia 4.14.3</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl index 17b47c059e..93a7e21f4e 100644 --- a/lib/mnesia/src/mnesia_controller.erl +++ b/lib/mnesia/src/mnesia_controller.erl @@ -1888,7 +1888,7 @@ info_format(Tab, Size, Mem, Media) -> StrT = mnesia_lib:pad_name(atom_to_list(Tab), 15, []), StrS = mnesia_lib:pad_name(integer_to_list(Size), 8, []), StrM = mnesia_lib:pad_name(integer_to_list(Mem), 8, []), - io:format("~s: with ~s records occupying ~s ~s~n", + io:format("~ts: with ~s records occupying ~s ~s~n", [StrT, StrS, StrM, Media]). %% Handle early arrived messages diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk index 81b15d65db..e272a469bb 100644 --- a/lib/mnesia/vsn.mk +++ b/lib/mnesia/vsn.mk @@ -1 +1 @@ -MNESIA_VSN = 4.15 +MNESIA_VSN = 4.14.3 diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml index fbcfe67a12..bd9aa265f8 100644 --- a/lib/observer/doc/src/notes.xml +++ b/lib/observer/doc/src/notes.xml @@ -32,57 +32,6 @@ <p>This document describes the changes made to the Observer application.</p> -<section><title>Observer 2.4</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - <c>etop</c> had a hardcoded timeout value of 1 second - when waiting for data from a remote node. When this - expired, which could happen for instance if there were - very many processes on the remote node, etop would exit - with reason <c>connection_lost</c>. To overcome this - problem, the timeout is now changed to be the same as the - update interval, which is configurable.</p> - <p> - Own Id: OTP-14393</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Show dirty-scheduler threads in performance monitor graph - and add a column with maximum allocated memory in the - Memory Allocators table.</p> - <p> - Own Id: OTP-14137</p> - </item> - <item> - <p> - Keep table and port selection after refresh of tables. - Store settings before shutdown and restore when starting - application.</p> - <p> - Own Id: OTP-14270</p> - </item> - <item> - <p> - When observing a node older than OTP-19.0, a pop-up will - be displayed when trying to access port information. - Earlier, observer would crash in this situation.</p> - <p> - Own Id: OTP-14345 Aux Id: ERL-399 </p> - </item> - </list> - </section> - -</section> - <section><title>Observer 2.3.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl index 7352af936c..c7ee294719 100644 --- a/lib/observer/src/observer_lib.erl +++ b/lib/observer/src/observer_lib.erl @@ -636,12 +636,12 @@ user_term_multiline(Parent, Title, Default) -> parse_string(Str) -> try - Tokens = case erl_scan:string(Str) of + Tokens = case erl_scan:string(Str, 1, [text]) of {ok, Ts, _} -> Ts; {error, {_SLine, SMod, SError}, _} -> throw(io_lib:format("~s", [SMod:format_error(SError)])) end, - case erl_parse:parse_term(Tokens) of + case lib:extended_parse_term(Tokens) of {error, {_PLine, PMod, PError}} -> throw(io_lib:format("~s", [PMod:format_error(PError)])); Res -> Res diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk index 21edfcd184..ca9ad72473 100644 --- a/lib/observer/vsn.mk +++ b/lib/observer/vsn.mk @@ -1 +1 @@ -OBSERVER_VSN = 2.4 +OBSERVER_VSN = 2.3.1 diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml index e9f81fb86e..5a16445577 100644 --- a/lib/parsetools/doc/src/notes.xml +++ b/lib/parsetools/doc/src/notes.xml @@ -31,33 +31,6 @@ </header> <p>This document describes the changes made to the Parsetools application.</p> -<section><title>Parsetools 2.1.5</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Minor documentation fixes</p> - <p> - Own Id: OTP-14276 Aux Id: PR-1357 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Miscellaneous updates due to atoms containing - arbitrary Unicode characters. </p> - <p> - Own Id: OTP-14285</p> - </item> - </list> - </section> - -</section> - <section><title>Parsetools 2.1.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk index 502ca00a47..d102c63730 100644 --- a/lib/parsetools/vsn.mk +++ b/lib/parsetools/vsn.mk @@ -1 +1 @@ -PARSETOOLS_VSN = 2.1.5 +PARSETOOLS_VSN = 2.1.4 diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml index 64592a6d87..dd83e1961d 100644 --- a/lib/public_key/doc/src/notes.xml +++ b/lib/public_key/doc/src/notes.xml @@ -35,41 +35,6 @@ <file>notes.xml</file> </header> -<section><title>Public_Key 1.4.1</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Bug for <c>public_key:generate_key({namedCurve,OID})</c> - fixed.</p> - <p> - Own Id: OTP-14258</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Modernized internal representation used for crl - validation by use of maps.</p> - <p> - Own Id: OTP-14111</p> - </item> - <item> - <p> - Support EC key in pkix_sign/2</p> - <p> - Own Id: OTP-14294</p> - </item> - </list> - </section> - -</section> - <section><title>Public_Key 1.4</title> <section><title>Improvements and New Features</title> diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk index 83a77d2a28..b94768ae77 100644 --- a/lib/public_key/vsn.mk +++ b/lib/public_key/vsn.mk @@ -1 +1 @@ -PUBLIC_KEY_VSN = 1.4.1 +PUBLIC_KEY_VSN = 1.4 diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml index ff11a6ca11..b47d451055 100644 --- a/lib/reltool/doc/src/notes.xml +++ b/lib/reltool/doc/src/notes.xml @@ -38,24 +38,7 @@ thus constitutes one section in this document. The title of each section is the version number of Reltool.</p> - <section><title>Reltool 0.7.4</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> The User's Guide examples are updated after removal - of support for Dets files created with Erlang/OTP R7 and - earlier. </p> <p>The examples are not correct, and will - be updated before the release of Erlang/OTP 20.0.</p> - <p> - Own Id: OTP-14422 Aux Id: OTP-13830 </p> - </item> - </list> - </section> - -</section> - -<section><title>Reltool 0.7.3</title> + <section><title>Reltool 0.7.3</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/reltool/doc/src/reltool_examples.xml b/lib/reltool/doc/src/reltool_examples.xml index 83eee6017a..49bde56964 100644 --- a/lib/reltool/doc/src/reltool_examples.xml +++ b/lib/reltool/doc/src/reltool_examples.xml @@ -41,30 +41,31 @@ <p>The main process in Reltool is the server. It can be used as it is or be used via the GUI frontend process. When the GUI is started, a server process will automatically be started. The GUI - process is started with <c>reltool:start/0</c>, - <c>reltool:start/1</c> or <c>reltool:start_link/1</c>. The pid of - its server can be obtained with <c>reltool:get_server/1</c></p> + process is started with + <seealso marker="reltool#start-0"><c>reltool:start/0</c></seealso>, + <seealso marker="reltool#start-1"><c>reltool:start/1</c></seealso> or + <seealso marker="reltool#start_link-1"><c>reltool:start_link/1</c></seealso>. + The pid of its server can be obtained with + <seealso marker="reltool#start_link-1"><c>reltool:get_server/1</c></seealso> + </p> <pre> -Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] - [async-threads:0] [kernel-poll:false] - -Eshell V5.7.3 (abort with ^G) +Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] +[hipe] [kernel-poll:false] +Eshell V9.0 (abort with ^G) +1> 1> {ok, Win} = reltool:start([]). {ok,<0.36.01>} -2> {ok, Server} = reltool:get_server([]). +2> {ok, Server} = reltool:get_server(Win). {ok,<0.37.01>} 3> reltool:get_config(Server). {ok,{sys,[]}} -4> reltool:stop(Win). -ok - - -5> {ok, Server2} = reltool:start_server([]). +4> +4> {ok, Server2} = reltool:start_server([]). {ok,<0.6535.01>} -6> reltool:get_config(Server2). +5> reltool:get_config(Server2). {ok,{sys,[]}} -7> reltool:stop(Server2). +6> reltool:stop(Server2). ok </pre> @@ -74,13 +75,11 @@ ok <title>Inspecting the configuration</title> <pre> -Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] - [async-threads:0] [kernel-poll:false] - -Eshell V5.7.3 (abort with ^G) -1> Config = {sys, [{escript, - "examples/display_args", - [{incl_cond, include}]}, +Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] +[hipe] [kernel-poll:false] +Eshell V9.0 (abort with ^G) +1> +1> Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]}, {app, inets, [{incl_cond, include}]}, {app, mnesia, [{incl_cond, exclude}]}, {app, ssl, [{incl_cond, exclude}]}, @@ -92,88 +91,105 @@ Eshell V5.7.3 (abort with ^G) {app,ssl,[{incl_cond,exclude}]}, {app,runtime_tools,[{incl_cond,exclude}]}, {app,syntax_tools,[{incl_cond,exclude}]}]} - - - +2> 2> {ok, Server} = reltool:start_server([Config]). -{ok,<0.35.0>} +{ok,<0.66.0>} +3> 3> reltool:get_config(Server). -{ok,{sys,[{escript,"/clearcase/otp/tools/reltool/examples/display_args", - [{incl_cond,include}]}]}} +{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args", + [{incl_cond,include}]}, + {app,inets,[{incl_cond,include}]}, + {app,mnesia,[{incl_cond,exclude}]}, + {app,runtime_tools,[{incl_cond,exclude}]}, + {app,ssl,[{incl_cond,exclude}]}, + {app,syntax_tools,[{incl_cond,exclude}]}]}} +4> 4> reltool:get_config(Server, false, false). -{ok,{sys,[{escript,"/clearcase/otp/tools/reltool/examples/display_args", - [{incl_cond,include}]}]}} - - - +{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args", + [{incl_cond,include}]}, + {app,inets,[{incl_cond,include}]}, + {app,mnesia,[{incl_cond,exclude}]}, + {app,runtime_tools,[{incl_cond,exclude}]}, + {app,ssl,[{incl_cond,exclude}]}, + {app,syntax_tools,[{incl_cond,exclude}]}]}} +5> 5> reltool:get_config(Server, true, false). -{ok,{sys,[{root_dir,"/ldisk/hakan/otp_test"}, +{ok,{sys,[{root_dir,"/usr/local/lib/erlang"}, {lib_dirs,[]}, - {escript,"/clearcase/otp/tools/reltool/examples/display_args", + {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args", [{incl_cond,include}]}, {mod_cond,all}, {incl_cond,derived}, + {app,inets, + [{incl_cond,include},{vsn,undefined},{lib_dir,undefined}]}, + {app,mnesia,[{incl_cond,exclude}]}, + {app,runtime_tools,[{incl_cond,exclude}]}, + {app,ssl,[{incl_cond,exclude}]}, + {app,syntax_tools,[{incl_cond,exclude}]}, {boot_rel,"start_clean"}, + {rel,"start_clean","1.0",[]}, + {rel,"start_sasl","1.0",[sasl]}, {emu_name,"beam"}, {relocatable,true}, {profile,development}, - {incl_sys_files,[".*"]}, - {excl_sys_files,[]}, - {incl_app_files,[".*"]}, - {excl_app_files,[]}, - {incl_archive_dirs,[".*"]}, - {excl_archive_dirs,["^include$","^priv$"]}, + {incl_sys_filters,[".*"]}, + {excl_sys_filters,[]}, + {incl_app_filters,[".*"]}, + {excl_app_filters,[]}, + {incl_archive_filters,[".*"]}, + {excl_archive_filters,[[...]|...]}, {archive_opts,[]}, - {app_type,permanent}, - {app_file,keep}, - {debug_info,keep}]}} - - - + {rel_app_type,...}, + {...}|...]}} +6> 6> reltool:get_config(Server, true, true). -{ok,{sys,[{root_dir,"/ldisk/hakan/otp_test"}, +{ok,{sys,[{root_dir,"/usr/local/lib/erlang"}, {lib_dirs,[]}, - {escript,"/clearcase/otp/tools/reltool/examples/display_args", + {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args", [{incl_cond,include}]}, {mod_cond,all}, {incl_cond,derived}, - {erts,[{vsn,"5.7.3"}, - {mod,erl_prim_loader,[]}, - {mod,erlang,[]}, - {mod,init,[]}, - {mod,otp_ring0,[]}, - {mod,prim_file,[]}, - {mod,prim_inet,[]}, - {mod,prim_zip,[]}, - {mod,zlib,[]}]}, + {erts,[{app,erts, + [{vsn,"9.0"}, + {lib_dir,"/usr/local/lib/erlang/lib/erts-9.0"}, + {mod,erl_prim_loader,[]}, + {mod,erl_tracer,[]}, + {mod,erlang,[]}, + {mod,erts_code_purger,[]}, + {mod,erts_dirty_process_code_checker,[]}, + {mod,erts_internal,[]}, + {mod,erts_literal_area_collector,[]}, + {mod,init,[]}, + {mod,otp_ring0,...}, + {mod,...}, + {...}|...]}]}, {app,compiler, - [{vsn,"4.6.3"}, + [{vsn,"7.0.4"}, + {lib_dir,"/usr/local/lib/erlang/lib/compiler-7.0.4"}, + {mod,beam_a,[]}, {mod,beam_asm,[]}, {mod,beam_block,[]}, - {mod,beam_bool,[]}, + {mod,beam_bs,[]}, {mod,beam_bsm,[]}, {mod,beam_clean,[]}, {mod,beam_dead,[]}, {mod,beam_dict,[]}, {mod,beam_disasm,[]}, - {mod,beam_flatten,[]}, - {mod,beam_jump,[]}, - {mod,beam_listing,[]}, - {mod,beam_opcodes,...}, + {mod,beam_except,[]}, + {mod,beam_flatten,...}, {mod,...}, {...}|...]}, {app,crypto, - [{vsn,"1.6.1"}, + [{vsn,"3.7.4"}, + {lib_dir,"/usr/local/lib/erlang/lib/crypto-3.7.4"}, {mod,crypto,[]}, - {mod,crypto_app,[]}, - {mod,crypto_server,[]}, - {mod,crypto_sup,[]}]}, + {mod,crypto_ec_curves,[]}]}, {app,hipe, - [{vsn,"3.7.3"}, + [{vsn,"3.15.4"}, + {lib_dir,"/usr/local/lib/erlang/lib/hipe-3.15.4"}, {mod,cerl_cconv,[]}, {mod,cerl_closurean,[]}, {mod,cerl_hipeify,[]}, - {mod,cerl_hybrid_transform,[]}, {mod,cerl_lib,[]}, {mod,cerl_messagean,[]}, {mod,cerl_pmatch,[]}, @@ -182,65 +198,110 @@ Eshell V5.7.3 (abort with ^G) {mod,cerl_typean,...}, {mod,...}, {...}|...]}, + {app,inets, + [{incl_cond,include}, + {vsn,"6.3.9"}, + {lib_dir,"/usr/local/lib/erlang/lib/inets-6.3.9"}, + {mod,ftp,[]}, + {mod,ftp_progress,[]}, + {mod,ftp_response,[]}, + {mod,ftp_sup,[]}, + {mod,http_chunk,[]}, + {mod,http_request,[]}, + {mod,http_response,...}, + {mod,...}, + {...}|...]}, {app,kernel, - [{vsn,"2.13.3"}, + [{vsn,"5.2"}, + {lib_dir,"/usr/local/lib/erlang/lib/kernel-5.2"}, {mod,application,[]}, {mod,application_controller,[]}, {mod,application_master,[]}, {mod,application_starter,[]}, {mod,auth,[]}, {mod,code,[]}, - {mod,code_server,[]}, - {mod,disk_log,[]}, - {mod,disk_log_1,...}, + {mod,code_server,...}, + {mod,...}, + {...}|...]}, + {app,mnesia,[{incl_cond,exclude}]}, + {app,runtime_tools,[{incl_cond,exclude}]}, + {app,sasl, + [{vsn,"3.0.3"}, + {lib_dir,"/usr/local/lib/erlang/lib/sasl-3.0.3"}, + {mod,alarm_handler,[]}, + {mod,erlsrv,[]}, + {mod,format_lib_supp,[]}, + {mod,misc_supp,...}, {mod,...}, {...}|...]}, + {app,ssl,[{incl_cond,exclude}]}, {app,stdlib, - [{vsn,"1.16.3"}, + [{vsn,"3.3"}, + {lib_dir,"/usr/local/lib/erlang/lib/stdlib-3.3"}, {mod,array,[]}, - {mod,base64,[]}, - {mod,beam_lib,[]}, - {mod,c,[]}, - {mod,calendar,[]}, - {mod,dets,[]}, - {mod,dets_server,[]}, - {mod,dets_sup,...}, + {mod,base64,...}, {mod,...}, {...}|...]}, + {app,syntax_tools,[{incl_cond,exclude}]}, + {app,tools, + [{vsn,"2.9.1"},{lib_dir,[...]},{mod,...},{...}|...]}, {boot_rel,"start_clean"}, + {rel,"start_clean","1.0",[]}, + {rel,"start_sasl","1.0",[...]}, {emu_name,"beam"}, {relocatable,true}, - {profile,development}, - {incl_sys_files,[".*"]}, - {excl_sys_files,[]}, - {incl_app_files,[".*"]}, - {excl_app_files,[]}, - {incl_archive_dirs,[".*"]}, - {excl_archive_dirs,["^include$",[...]]}, - {archive_opts,[]}, - {app_type,permanent}, - {app_file,...}, - {...}]}} - - - -7> reltool:get_config([{sys,[{profile, embedded}]}]). -{ok,{sys,[{profile,embedded}, + {profile,...}, + {...}|...]}} +7> +7> reltool:get_config([{sys, [{profile, embedded}]}], true, false). +{ok,{sys,[{root_dir,"/usr/local/lib/erlang"}, + {lib_dirs,[]}, + {mod_cond,all}, + {incl_cond,derived}, + {boot_rel,"start_clean"}, + {rel,"start_clean","1.0",[]}, + {rel,"start_sasl","1.0",[sasl]}, + {emu_name,"beam"}, + {relocatable,true}, + {profile,embedded}, {incl_sys_filters,["^bin","^erts","^lib","^releases"]}, {excl_sys_filters,["^bin/(erlc|dialyzer|typer)(|\\.exe)$", "^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$", "^erts.*/bin/.*(debug|pdb)"]}, - {incl_app_filters,["^ebin","^include","^priv"]}]}} -8> reltool:get_config([{sys,[{profile, standalone}]}]). -{ok,{sys,[{profile,standalone}, + {incl_app_filters,["^ebin","^include","^priv"]}, + {excl_app_filters,[]}, + {incl_archive_filters,[".*"]}, + {excl_archive_filters,["^include$","^priv$"]}, + {archive_opts,[]}, + {rel_app_type,permanent}, + {embedded_app_type,load}, + {app_file,keep}, + {debug_info,keep}]}} +8> +8> reltool:get_config([{sys, [{profile, standalone}]}], true, false). +{ok,{sys,[{root_dir,"/usr/local/lib/erlang"}, + {lib_dirs,[]}, + {mod_cond,all}, + {incl_cond,derived}, + {boot_rel,"start_clean"}, + {rel,"start_clean","1.0",[]}, + {rel,"start_sasl","1.0",[sasl]}, + {emu_name,"beam"}, + {relocatable,true}, + {profile,standalone}, {incl_sys_filters,["^bin/(erl|epmd)(|\\.exe|\\.ini)$", "^bin/start(|_clean).boot$","^erts.*/bin","^lib$"]}, {excl_sys_filters,["^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$", "^erts.*/bin/(start|escript|to_erl|run_erl)(|\\.exe)$", "^erts.*/bin/.*(debug|pdb)"]}, {incl_app_filters,["^ebin","^priv"]}, - {excl_app_filters,["^ebin/.*\\.appup$"]}]}} - + {excl_app_filters,["^ebin/.*\\.appup$"]}, + {incl_archive_filters,[".*"]}, + {excl_archive_filters,["^include$","^priv$"]}, + {archive_opts,[]}, + {rel_app_type,permanent}, + {app_file,keep}, + {debug_info,keep}]}} </pre> </section> @@ -248,43 +309,51 @@ Eshell V5.7.3 (abort with ^G) <section> <title>Generate release and script files</title> <pre> -5> {ok, Server} = reltool:start_server([{config, {sys, [{boot_rel, "NAME"}, +Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] +[hipe] [kernel-poll:false] +Eshell V9.0 (abort with ^G) +1> +1> {ok, Server} = reltool:start_server([{config, {sys, [{boot_rel, "NAME"}, {rel, "NAME", "VSN", [sasl]}]}}]). {ok,<0.1288.0>} -6> reltool:get_config(Server). +2> +2> reltool:get_config(Server). {ok,{sys,[{boot_rel,"NAME"}, {rel,"NAME","VSN",[sasl]}]}} -7> reltool:get_rel(Server, "NAME"). +3> +3> reltool:get_rel(Server, "NAME"). {ok,{release,{"NAME","VSN"}, - {erts,"5.7"}, - [{kernel,"2.13"},{stdlib,"1.16"},{sasl,"2.1.6"}]}} -8> reltool:get_script(Server, "NAME"). + {erts,"9.0"}, + [{kernel,"5.2"},{stdlib,"3.3"},{sasl,"3.0.3"}]}} +4> +4> reltool:get_script(Server, "NAME"). {ok,{script,{"NAME","VSN"}, - [{preLoaded,[erl_prim_loader,erlang,init,otp_ring0, - prim_eval,prim_file,prim_inet,prim_zip, - zlib]}, + [{preLoaded,[erl_prim_loader,erl_tracer,erlang, + erts_code_purger,erts_dirty_process_code_checker, + erts_internal,erts_literal_area_collector,init,otp_ring0, + prim_eval,prim_file,prim_inet,prim_zip,zlib]}, {progress,preloaded}, - {path,["$ROOT/lib/kernel-2.13/ebin", - "$ROOT/lib/stdlib-1.16/ebin"]}, + {path,["$ROOT/lib/kernel-5.2/ebin", + "$ROOT/lib/stdlib-3.3/ebin"]}, {primLoad,[error_handler]}, {kernel_load_completed}, {progress,kernel_load_completed}, - {path,["$ROOT/lib/kernel-2.13/ebin"]}, + {path,["$ROOT/lib/kernel-5.2/ebin"]}, {primLoad,[application,application_controller, application_master,application_starter,auth,code, code_server,disk_log,disk_log_1,disk_log_server, disk_log_sup,dist_ac,dist_util,erl_boot_server|...]}, - {path,["$ROOT/lib/stdlib-1.16/ebin"]}, - {primLoad,[array,base64,beam_lib,c,calendar,dets, + {path,["$ROOT/lib/stdlib-3.3/ebin"]}, + {primLoad,[array,base64,beam_lib,binary,c,calendar,dets, dets_server,dets_sup,dets_utils,dets_v9,dict|...]}, - {path,["$ROOT/lib/sasl-2.1.6/ebin"]}, + {path,["$ROOT/lib/sasl-3.0.3/ebin"]}, {primLoad,[alarm_handler,erlsrv,format_lib_supp,misc_supp, - overload,rb,rb_format_supp,release_handler, - release_handler_1,sasl|...]}, + rb,rb_format_supp,release_handler,release_handler_1,sasl, + sasl_report|...]}, {progress,modules_loaded}, - {path,["$ROOT/lib/kernel-2.13/ebin", - "$ROOT/lib/stdlib-1.16/ebin","$ROOT/lib/sasl-2.1.6/ebin"]}, + {path,["$ROOT/lib/kernel-5.2/ebin", + "$ROOT/lib/stdlib-3.3/ebin","$ROOT/lib/sasl-3.0.3/ebin"]}, {kernelProcess,heart,{heart,start,[]}}, {kernelProcess,error_logger,{error_logger,start_link,[]}}, {kernelProcess,application_controller, @@ -296,7 +365,8 @@ Eshell V5.7.3 (abort with ^G) {apply,{...}}, {apply,...}, {...}|...]}} -9> reltool:stop(Server). +5> +5> reltool:stop(Server). ok </pre> </section> @@ -304,13 +374,11 @@ ok <section> <title>Create a target system</title> <pre> -Erlang R13B02 (erts-5.7.3) [source] [64-bit] [smp:4:4] [rq:4] - [async-threads:0] [kernel-poll:false] - -Eshell V5.7.3 (abort with ^G) -1> Config = {sys, [{escript, - "examples/display_args", - [{incl_cond, include}]}, +Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] +[hipe] [kernel-poll:false] +Eshell V9.0 (abort with ^G) +1> +1> Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]}, {app, inets, [{incl_cond, include}]}, {app, mnesia, [{incl_cond, exclude}]}, {app, ssl, [{incl_cond, exclude}]}, @@ -322,156 +390,183 @@ Eshell V5.7.3 (abort with ^G) {app,ssl,[{incl_cond,exclude}]}, {app,runtime_tools,[{incl_cond,exclude}]}, {app,syntax_tools,[{incl_cond,exclude}]}]} - - - +2> 2> {ok, Spec} = reltool:get_target_spec([Config]). {ok,[{create_dir,"releases", - [{write_file,"start_erl.data","5.7.3 1.0"}, - {create_dir,"1.0", - [{write_file,"start_clean.rel", - [37,37,32,114,101,108,32,103,101,110,101|...]}, - {write_file,"start_clean.script", - [37,37,32,115,99,114,105,112,116,32|...]}, - {write_file,"start_clean.boot", - <<131,104,3,100,0,6,115,99,114,...>>}, - {write_file,"start_sasl.rel", - [37,37,32,114,101,108,32,103,101,110,101|...]}, - {write_file,"start_sasl.script", - [37,37,32,115,99,114,105,112,116,32|...]}, - {write_file,"start_sasl.boot", - <<131,104,3,100,0,6,115,99,114,...>>}]}]}, + [{write_file,"start_erl.data","9.0 1.0\n"}, + {create_dir,"1.0", + [{write_file,"start_clean.rel", + [37,37,32,114,101,108,32,103,101,110,101,114,97,116|...]}, + {write_file,"start_clean.script", + [37,37,32,115,99,114,105,112,116,32,103,101,110|...]}, + {write_file,"start_clean.boot", + <<131,104,3,119,6,115,99,114,105,112,116,104,...>>}, + {write_file,"start_sasl.rel", + [37,37,32,114,101,108,32,103,101,110,101|...]}, + {write_file,"start_sasl.script", + [37,37,32,115,99,114,105,112,116,32|...]}, + {write_file,"start_sasl.boot", + <<131,104,3,119,6,115,99,114,105,...>>}]}]}, {create_dir,"bin", - [{copy_file,"display_args.escript", - "/clearcase/otp/tools/reltool/examples/display_args"}, - {copy_file,"display_args","erts-5.7.3/bin/escript"}, - {copy_file,"start","erts-5.7.3/bin/start"}, - {copy_file,"erl","erts-5.7.3/bin/dyn_erl"}, - {copy_file,"epmd","erts-5.7.3/bin/epmd"}, - {copy_file,"to_erl","erts-5.7.3/bin/to_erl"}, - {copy_file,"run_erl","erts-5.7.3/bin/run_erl"}, - {copy_file,"escript","erts-5.7.3/bin/escript"}, - {copy_file,"erlc","erts-5.7.3/bin/erlc"}, - {copy_file,"dialyzer","erts-5.7.3/bin/dialyzer"}, - {copy_file,"typer","erts-5.7.3/bin/typer"}, - {write_file,"start_clean.boot", - <<131,104,3,100,0,6,115,...>>}, - {write_file,"start_sasl.boot",<<131,104,3,100,0,6,...>>}, - {write_file,"start.boot",<<131,104,3,100,0,...>>}]}, - {create_dir,"misc", - [{copy_file,"makewhatis"},{copy_file,"format_man_pages"}]}, + [{copy_file,"display_args.escript", + "/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args"}, + {copy_file,"display_args","erts-9.0/bin/escript"}, + {copy_file,"start","erts-9.0/bin/start"}, + {copy_file,"ct_run","erts-9.0/bin/ct_run"}, + {copy_file,"dialyzer","erts-9.0/bin/dialyzer"}, + {copy_file,"run_erl","erts-9.0/bin/run_erl"}, + {copy_file,"erl","erts-9.0/bin/dyn_erl"}, + {copy_file,"to_erl","erts-9.0/bin/to_erl"}, + {copy_file,"epmd","erts-9.0/bin/epmd"}, + {copy_file,"erlc","erts-9.0/bin/erlc"}, + {copy_file,"typer","erts-9.0/bin/typer"}, + {copy_file,"escript","erts-9.0/bin/escript"}, + {write_file,"start_clean.boot",<<131,104,3,119,6,115,...>>}, + {write_file,"start_sasl.boot",<<131,104,3,119,6,...>>}, + {write_file,"start.boot",<<131,104,3,119,...>>}]}, {copy_file,"Install"}, + {create_dir,"misc", + [{copy_file,"makewhatis"},{copy_file,"format_man_pages"}]}, {create_dir,"usr", - [{create_dir,"lib", - [{copy_file,"liberts_r.a"},{copy_file,"liberts.a"}]}, - {create_dir,"include", - [{copy_file,"erl_fixed_size_int_types.h"}, - {copy_file,"erl_int_sizes_config.h"}, - {copy_file,"erl_memory_trace_parser.h"}, - {create_dir,"obsolete",[{copy_file,"driver.h"}]}, - {copy_file,"driver_int.h"}, - {copy_file,"erl_driver.h"}]}]}, - {create_dir,"erts-5.7.3", - [{create_dir,"lib", - [{create_dir,"internal", - [{copy_file,"liberts_internal_r.a"}, - {copy_file,"liberts_internal.a"}, - {copy_file,"libethread.a"}, - {copy_file,"README"}]}, - {copy_file,"liberts_r.a"}, - {copy_file,"liberts.a"}]}, - {create_dir,"bin", - [{copy_file,"start"}, - {copy_file,"erl","erts-5.7.3/bin/dyn_erl"}, - {copy_file,"epmd"}, - {copy_file,"to_erl"}, - {copy_file,"run_erl"}, - {copy_file,"escript"}, - {copy_file,"erlc"}, - {copy_file,"dialyzer"}, - {copy_file,"typer"}, - {copy_file,"erlexec"}, - {copy_file,[...]}, - {copy_file,...}, - {...}|...]}, - {create_dir,"doc",[]}, - {create_dir,"man",[]}, - {create_dir,"include", - [{create_dir,"internal", - [{create_dir,"tile",[{copy_file,...},{...}]}, - {create_dir,"sparc64",[{...}]}, - {create_dir,"sparc32",[...]}, - {create_dir,[...],...}, - {create_dir,...}, - {...}|...]}, - {copy_file,"erl_fixed_size_int_types.h"}, - {copy_file,"erl_int_sizes_config.h"}, - {copy_file,"erl_memory_trace_parser.h"}, - {copy_file,"driver_int.h"}, - {copy_file,"erl_driver.h"}]}, - {create_dir,"src",[{copy_file,"setuid_socket_wrap.c"}]}]}, + [{create_dir,"lib", + [{copy_file,"liberts.a"}, + {copy_file,"liberl_interface_st.a"}, + {copy_file,"liberts_r.a"}, + {copy_file,"libic.a"}, + {copy_file,"liberl_interface.a"}, + {copy_file,"libei_st.a"}, + {copy_file,"libei.a"}]}, + {create_dir,"include", + [{copy_file,"erl_memory_trace_parser.h"}, + {copy_file,"driver_int.h"}, + {copy_file,"ei_connect.h"}, + {copy_file,"ei.h"}, + {copy_file,"erl_nif_api_funcs.h"}, + {copy_file,"erl_fixed_size_int_types.h"}, + {copy_file,"erl_int_sizes_config.h"}, + {copy_file,"erl_interface.h"}, + {copy_file,"eicode.h"}, + {copy_file,"erl_driver.h"}, + {copy_file,"erlang.idl"}, + {copy_file,[...]}, + {copy_file,...}, + {...}]}]}, + {create_dir,"erts-9.0", + [{create_dir,"bin", + [{copy_file,"start"}, + {copy_file,"ct_run"}, + {copy_file,"erlexec"}, + {copy_file,"dialyzer"}, + {copy_file,"beam.smp"}, + {copy_file,"run_erl"}, + {copy_file,"erl","erts-9.0/bin/dyn_erl"}, + {copy_file,"to_erl"}, + {copy_file,"epmd"}, + {copy_file,"erl_child_setup"}, + {copy_file,"heart"}, + {copy_file,[...]}, + {copy_file,...}, + {...}|...]}, + {create_dir,"lib", + [{create_dir,"internal", + [{copy_file,"liberts_internal.a"}, + {copy_file,"liberts_internal_r.a"}, + {copy_file,"libethread.a"}, + {copy_file,"README"}]}, + {copy_file,"liberts.a"}, + {copy_file,"liberts_r.a"}]}, + {create_dir,"src",[{copy_file,"setuid_socket_wrap.c"}]}, + {create_dir,"doc",[]}, + {create_dir,"man",[]}, + {create_dir,"include", + [{create_dir,"internal", + [{create_dir,"i386",[{...}|...]}, + {copy_file,"erl_errno.h"}, + {copy_file,[...]}, + {copy_file,...}, + {...}|...]}, + {copy_file,"erl_memory_trace_parser.h"}, + {copy_file,"driver_int.h"}, + {copy_file,"erl_nif_api_funcs.h"}, + {copy_file,"erl_fixed_size_int_types.h"}, + {copy_file,"erl_int_sizes_config.h"}, + {copy_file,[...]}, + {copy_file,...}, + {...}]}]}, {create_dir,"lib", - [{archive,"compiler-4.6.3.ez",[], - [{create_dir,"compiler-4.6.3", - [{create_dir,"ebin", - [{copy_file,"compiler.appup"}, - {copy_file,[...]}, - {copy_file,...}, - {...}|...]}, - {create_dir,"src", - [{copy_file,[...]}, - {copy_file,...},{...}|...]}]}]}, - {archive,"crypto-1.6.1.ez",[], - [{create_dir,"crypto-1.6.1", - [{create_dir,"ebin", - [{copy_file,[...]}, - {copy_file,...},{...}|...]}, - {create_dir,"src",[{copy_file,...},{...}|...]}]}]}, - {create_dir,"crypto-1.6.1", - [{create_dir,"priv", - [{create_dir,"lib",[{copy_file,[...]}]}, - {create_dir,"obj",[{copy_file,...},{...}]}]}]}, - {archive,"erts-5.7.3.ez",[], - [{create_dir,"erts-5.7.3", - [{create_dir,"ebin",[{...}|...]}, - {create_dir,"src",[...]}]}]}, - {archive,"hipe-3.7.3.ez",[], - [{create_dir,"hipe-3.7.3", - [{create_dir,"util",[...]}, - {create_dir,[...],...}, - {create_dir,...}, - {...}|...]}]}, - {archive,"kernel-2.13.3.ez",[], - [{create_dir,"kernel-2.13.3", - [{create_dir,[...],...},{create_dir,...},{...}]}]}, - {create_dir,"kernel-2.13.3", - [{create_dir,"include", - [{copy_file,[...]},{copy_file,...},{...}]}]}, - {archive,"stdlib-1.16.3.ez",[], - [{create_dir,"stdlib-1.16.3",[{...}|...]}]}, - {create_dir,"stdlib-1.16.3", - [{create_dir,"include",[{...}|...]}]}]}]} - - - -3> TargetDir = "my_target_dir". -"my_target_dir" + [{archive,"compiler-7.0.4.ez",[], + [{create_dir,"compiler-7.0.4", + [{create_dir,"src", + [{copy_file,"beam_flatten.erl"}, + {copy_file,[...]}, + {copy_file,...}, + {...}|...]}, + {create_dir,"ebin", + [{copy_file,[...]},{copy_file,...},{...}|...]}]}]}, + {archive,"crypto-3.7.4.ez",[], + [{create_dir,"crypto-3.7.4", + [{create_dir,"src",[{copy_file,[...]},{copy_file,...}]}, + {create_dir,"ebin",[{copy_file,...},{...}|...]}]}]}, + {create_dir,"crypto-3.7.4", + [{create_dir,"priv", + [{create_dir,"lib",[{copy_file,[...]},{copy_file,...}]}, + {create_dir,"obj",[{copy_file,...},{...}|...]}]}]}, + {archive,"erts-9.0.ez",[], + [{create_dir,"erts-9.0", + [{create_dir,"src",[{...}|...]}, + {create_dir,"ebin",[...]}]}]}, + {archive,"hipe-3.15.4.ez",[], + [{create_dir,"hipe-3.15.4", + [{create_dir,"flow",[...]}, + {copy_file,[...]}, + {create_dir,...}, + {...}|...]}]}, + {archive,"inets-6.3.9.ez",[], + [{create_dir,"inets-6.3.9", + [{create_dir,[...],...},{create_dir,...},{...}]}]}, + {create_dir,"inets-6.3.9", + [{create_dir,"priv",[{create_dir,[...],...}]}, + {create_dir,"include",[{copy_file,...},{...}]}]}, + {archive,"kernel-5.2.ez",[], + [{create_dir,"kernel-5.2",[{...}|...]}]}, + {create_dir,"kernel-5.2", + [{create_dir,"include",[{...}|...]}]}, + {archive,"sasl-3.0.3.ez",[],[{create_dir,[...],...}]}, + {archive,"stdlib-3.3.ez",[],[{create_dir,...}]}, + {create_dir,"stdlib-3.3",[{create_dir,...}]}, + {archive,"tools-2.9.1.ez",[],[...]}]}]} +3> +3> TargetDir = "/tmp/my_target_dir". +"/tmp/my_target_dir" +4> 4> reltool:eval_target_spec(Spec, code:root_dir(), TargetDir). -{error,"/clearcase/otp/tools/reltool/my_target_dir: no such file or directory"} -5> file:make_dir("my_target_dir"). +{error,"/tmp/my_target_dir: no such file or directory"} +5> +5> file:make_dir(TargetDir). ok +6> 6> reltool:eval_target_spec(Spec, code:root_dir(), TargetDir). ok +7> 7> file:list_dir(TargetDir). -{ok,["lib","erts-5.7.3","usr","Install","misc","bin","releases"]} +{ok,["bin","Install","lib","misc","usr","erts-9.0", + "releases"]} +8> 8> file:list_dir(filename:join([TargetDir,"lib"])). -{ok,["stdlib-1.16.3","stdlib-1.16.3.ez","kernel-2.13.3", - "kernel-2.13.3.ez","hipe-3.7.3.ez","erts-5.7.3.ez", - "crypto-1.6.1","crypto-1.6.1.ez","compiler-4.6.3.ez"]} -9> file:make_dir("yet_another_target_dir"). +{ok,["tools-2.9.1.ez","kernel-5.2.ez","inets-6.3.9.ez", + "kernel-5.2","sasl-3.0.3.ez","hipe-3.15.4.ez","inets-6.3.9", + "crypto-3.7.4","crypto-3.7.4.ez","stdlib-3.3.ez", + "erts-9.0.ez","stdlib-3.3","compiler-7.0.4.ez"]} +9> +9> file:make_dir("/tmp/yet_another_target_dir"). ok -10> reltool:create_target(Config, "yet_another_target_dir"). +10> +10> reltool:create_target([Config], "/tmp/yet_another_target_dir"). ok +11> +11> file:list_dir("/tmp/yet_another_target_dir"). +{ok,["bin","Install","lib","misc","usr","erts-9.0", + "releases"]} </pre> </section> diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk index 3617f6e0d9..2d07eeb8f0 100644 --- a/lib/reltool/vsn.mk +++ b/lib/reltool/vsn.mk @@ -1 +1 @@ -RELTOOL_VSN = 0.7.4 +RELTOOL_VSN = 0.7.3 diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml index 388fa54fa8..49615cf077 100644 --- a/lib/runtime_tools/doc/src/notes.xml +++ b/lib/runtime_tools/doc/src/notes.xml @@ -32,41 +32,6 @@ <p>This document describes the changes made to the Runtime_Tools application.</p> -<section><title>Runtime_Tools 1.12</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Add compile option <c>-compile(no_native)</c> in modules - with <c>on_load</c> directive which is not yet supported - by HiPE.</p> - <p> - Own Id: OTP-14316 Aux Id: PR-1390 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Sockets can now be bound to device (SO_BINDTODEVICE) - on platforms where it is supported. </p> <p> This has - been implemented e.g to support VRF-Lite under Linux; see - <url - href="https://www.kernel.org/doc/Documentation/networking/vrf.txt"> - VRF </url>, and GitHub pull request <url - href="https://github.com/erlang/otp/pull/1326">#1326</url>. - </p> - <p> - Own Id: OTP-14357 Aux Id: PR-1326 </p> - </item> - </list> - </section> - -</section> - <section><title>Runtime_Tools 1.11.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk index 5ee39a25fe..8ec532de76 100644 --- a/lib/runtime_tools/vsn.mk +++ b/lib/runtime_tools/vsn.mk @@ -1 +1 @@ -RUNTIME_TOOLS_VSN = 1.12 +RUNTIME_TOOLS_VSN = 1.11.1 diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml index 03b8a333a9..8684151b3a 100644 --- a/lib/sasl/doc/src/notes.xml +++ b/lib/sasl/doc/src/notes.xml @@ -31,23 +31,6 @@ </header> <p>This document describes the changes made to the SASL application.</p> -<section><title>SASL 3.0.4</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Documented default values for the 'mod' and - 'start_phases' fields in .app files were not allowed as - actual values in a .app file. This is now corrected.</p> - <p> - Own Id: OTP-14029</p> - </item> - </list> - </section> - -</section> - <section><title>SASL 3.0.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk index 2608ca5e00..6aa662a743 100644 --- a/lib/sasl/vsn.mk +++ b/lib/sasl/vsn.mk @@ -1 +1 @@ -SASL_VSN = 3.0.4 +SASL_VSN = 3.0.3 diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 1cc76904e7..f1919a6bb1 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -34,24 +34,7 @@ </header> - <section><title>SNMP 5.2.6</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p>Internal code change: Calls to <c>catch</c> followed - by a call to <c>erlang:get_stacktrace/0</c> has been - rewritten to use <c>try</c> instead of <c>catch</c> to - make the code future-proof.</p> - <p> - Own Id: OTP-14400</p> - </item> - </list> - </section> - -</section> - -<section><title>SNMP 5.2.5</title> + <section><title>SNMP 5.2.5</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index d41b1999cc..30b8ee1124 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 5.2.6 +SNMP_VSN = 5.2.5 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index f6b6f53d33..bddae00dd2 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -30,169 +30,6 @@ <file>notes.xml</file> </header> -<section><title>Ssh 4.5</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - The internal handling of SSH options is re-written.</p> - <p> - Previously there were no checks if a client option was - given to a daemon or vice versa. This is corrected now. - If your code has e.g. a client-only option in a call to - start a daemon, the call will fail.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-12872</p> - </item> - <item> - <p> - Modernization of key exchange algorithms. See - draft-ietf-curdle-ssh-kex-sha2 for a discussion.</p> - <p> - Removed an outdated weak algorithm and added stronger - replacements to keep interoperability with other modern - ssh clients and servers. The default ordering of the - algorithms is also adjusted.</p> - <p> - Retired: The nowadays unsecure key-exchange - <c>diffie-hellman-group1-sha1</c> is not enabled by - default, but can be enabled with the option - <c>preferred-algorithms</c>.</p> - <p> - Added: The new stronger key-exchange - <c>diffie-hellman-group16-sha512</c>, - <c>diffie-hellman-group18-sha512</c> and - <c>diffie-hellman-group14-sha256</c> are added and - enabled by default.</p> - <p> - The questionable [RFC 6194] sha1-based algorithms - <c>diffie-hellman-group-exchange-sha1</c> and - <c>diffie-hellman-group14-sha1</c> are however still kept - enabled by default for compatibility with ancient clients - and servers that lack modern key-exchange alternatives. - When the draft-ietf-curdle-ssh-kex-sha2 becomes an rfc, - those sha1-based algorithms and - <c>diffie-hellman-group1-sha1</c> will be deprecated by - IETF. They might then be removed from the default list in - Erlang/OTP.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14110</p> - </item> - <item> - <p> - Modernized internal representation of sftp by use of - maps.</p> - <p> - Own Id: OTP-14117</p> - </item> - <item> - <p> - The Extension Negotiation Mechanism and the extension - <c>server-sig-algs</c> in - draft-ietf-curdle-ssh-ext-info-05 are implemented.</p> - <p> - The related draft-ietf-curdle-rsa-sha2-05 is implemented - and introduces the signature algorithms - <c>rsa-sha2-256</c> and <c>rsa-sha2-512</c>.</p> - <p> - Own Id: OTP-14193</p> - </item> - <item> - <p> - The functions <c>ssh:connect</c>, <c>ssh:shell</c> and - <c>ssh:start_channel</c> now accept an IP-tuple as Host - destination argument.</p> - <p> - Own Id: OTP-14243</p> - </item> - <item> - <p> - The function <c>ssh:daemon_info/1</c> now returns Host - and Profile as well as the Port info in the property - list.</p> - <p> - Own Id: OTP-14259</p> - </item> - <item> - <p> - Removed the option <c>public_key_alg</c> which was - deprecated in 18.2. Use <c>pref_public_key_algs</c> - instead.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14263</p> - </item> - <item> - <p> - The SSH application is refactored regarding daemon - starting. The resolution of contradicting <c>Host</c> - argument and <c>ip</c> option were not described. There - were also strange corner cases when the <c>'any'</c> - value was used in <c>Host</c> argument or <c>ip</c> - option. This is (hopefully) resolved now, but it may - cause incompatibilities for code using both <c>Host</c> - and the <c>ip</c> option. The value 'loopback' has been - added for a correct way of naming those addresses.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14264</p> - </item> - <item> - <p> - The supervisor code is refactored. The naming of - listening IP-Port-Profile triples are slightly changed to - improve consistency in strange corner cases as resolved - by OTP-14264</p> - <p> - Own Id: OTP-14267 Aux Id: OTP-14266 </p> - </item> - <item> - <p> - The <c>idle_time</c> option can now be used in daemons.</p> - <p> - Own Id: OTP-14312</p> - </item> - <item> - <p> - Added test cases for IETF-CURDLE Extension Negotiation - (ext-info)</p> - <p> - Own Id: OTP-14361</p> - </item> - <item> - <p> - Testcases for IETF-CURDLE extension - <c>server-sig-algs</c> including <c>rsa-sha2-*</c></p> - <p> - Own Id: OTP-14362 Aux Id: OTP-14361 </p> - </item> - <item> - <p> - The option <c>auth_methods</c> can now also be used in - clients to select which authentication options that are - used and in which order.</p> - <p> - Own Id: OTP-14399</p> - </item> - <item> - <p> - Checks that a ECDSA public key (<c>ecdsa-sha2-nistp*</c>) - stored in a file has the correct size.</p> - <p> - Own Id: OTP-14410</p> - </item> - </list> - </section> - -</section> - <section><title>Ssh 4.4.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl index 6cf659f830..ac64a7bf14 100644 --- a/lib/ssh/src/ssh_auth.erl +++ b/lib/ssh/src/ssh_auth.erl @@ -28,7 +28,8 @@ -include("ssh_auth.hrl"). -include("ssh_transport.hrl"). --export([publickey_msg/1, password_msg/1, keyboard_interactive_msg/1, +-export([get_public_key/2, + publickey_msg/1, password_msg/1, keyboard_interactive_msg/1, service_request_msg/1, init_userauth_request_msg/1, userauth_request_msg/1, handle_userauth_request/3, handle_userauth_info_request/2, handle_userauth_info_response/2 @@ -136,41 +137,49 @@ keyboard_interactive_msg([#ssh{user = User, Ssh) end. -publickey_msg([SigAlg, #ssh{user = User, - session_id = SessionId, - service = Service, - opts = Opts} = Ssh]) -> - Hash = ssh_transport:sha(SigAlg), + +get_public_key(SigAlg, #ssh{opts = Opts}) -> KeyAlg = key_alg(SigAlg), {KeyCb,KeyCbOpts} = ?GET_OPT(key_cb, Opts), UserOpts = ?GET_OPT(user_options, Opts), case KeyCb:user_key(KeyAlg, [{key_cb_private,KeyCbOpts}|UserOpts]) of - {ok, PrivKey} -> - SigAlgStr = atom_to_list(SigAlg), + {ok, PrivKey} -> try Key = ssh_transport:extract_public_key(PrivKey), public_key:ssh_encode(Key, ssh2_pubkey) of - PubKeyBlob -> - SigData = build_sig_data(SessionId, User, Service, - PubKeyBlob, SigAlgStr), - Sig = ssh_transport:sign(SigData, Hash, PrivKey), - SigBlob = list_to_binary([?string(SigAlgStr), - ?binary(Sig)]), - ssh_transport:ssh_packet( - #ssh_msg_userauth_request{user = User, - service = Service, - method = "publickey", - data = [?TRUE, - ?string(SigAlgStr), - ?binary(PubKeyBlob), - ?binary(SigBlob)]}, - Ssh) + PubKeyBlob -> {ok,{PrivKey,PubKeyBlob}} catch _:_ -> - {not_ok, Ssh} + not_ok end; - _Error -> + _Error -> + not_ok + end. + + +publickey_msg([SigAlg, #ssh{user = User, + session_id = SessionId, + service = Service} = Ssh]) -> + case get_public_key(SigAlg, Ssh) of + {ok, {PrivKey,PubKeyBlob}} -> + SigAlgStr = atom_to_list(SigAlg), + SigData = build_sig_data(SessionId, User, Service, + PubKeyBlob, SigAlgStr), + Hash = ssh_transport:sha(SigAlg), + Sig = ssh_transport:sign(SigData, Hash, PrivKey), + SigBlob = list_to_binary([?string(SigAlgStr), + ?binary(Sig)]), + ssh_transport:ssh_packet( + #ssh_msg_userauth_request{user = User, + service = Service, + method = "publickey", + data = [?TRUE, + ?string(SigAlgStr), + ?binary(PubKeyBlob), + ?binary(SigBlob)]}, + Ssh); + _ -> {not_ok, Ssh} end. diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index f1ce337947..8d3ddb09a4 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -453,16 +453,20 @@ init_ssh_record(Role, _Socket, PeerAddr, Opts) -> PeerName0 when is_list(PeerName0) -> PeerName0 end, - S0#ssh{c_vsn = Vsn, - c_version = Version, - io_cb = case ?GET_OPT(user_interaction, Opts) of - true -> ssh_io; - false -> ssh_no_io - end, - userauth_pubkeys = ?GET_OPT(pref_public_key_algs, Opts), - userauth_quiet_mode = ?GET_OPT(quiet_mode, Opts), - peer = {PeerName, PeerAddr} - }; + S1 = + S0#ssh{c_vsn = Vsn, + c_version = Version, + io_cb = case ?GET_OPT(user_interaction, Opts) of + true -> ssh_io; + false -> ssh_no_io + end, + userauth_quiet_mode = ?GET_OPT(quiet_mode, Opts), + peer = {PeerName, PeerAddr} + }, + S1#ssh{userauth_pubkeys = [K || K <- ?GET_OPT(pref_public_key_algs, Opts), + is_usable_user_pubkey(K, S1) + ] + }; server -> S0#ssh{s_vsn = Vsn, @@ -1700,29 +1704,49 @@ handle_ssh_msg_ext_info(#ssh_msg_ext_info{data=Data}, D0) -> lists:foldl(fun ext_info/2, D0, Data). -ext_info({"server-sig-algs",SigAlgs}, D0 = #data{ssh_params=#ssh{role=client, - userauth_pubkeys=ClientSigAlgs}=Ssh0}) -> - %% Make strings to eliminate risk of beeing bombed with odd strings that fills the atom table: - SupportedAlgs = lists:map(fun erlang:atom_to_list/1, ssh_transport:supported_algorithms(public_key)), - ServerSigAlgs = [list_to_atom(SigAlg) || SigAlg <- string:tokens(SigAlgs,","), - %% length of SigAlg is implicitly checked by the comparison - %% in member/2: - lists:member(SigAlg, SupportedAlgs) - ], - CommonAlgs = [Alg || Alg <- ServerSigAlgs, - lists:member(Alg, ClientSigAlgs)], - SelectedAlgs = - case CommonAlgs of - [] -> ClientSigAlgs; % server-sig-algs value is just an advice - _ -> CommonAlgs - end, - D0#data{ssh_params = Ssh0#ssh{userauth_pubkeys = SelectedAlgs} }; +ext_info({"server-sig-algs",SigAlgsStr}, + D0 = #data{ssh_params=#ssh{role=client, + userauth_pubkeys=ClientSigAlgs}=Ssh0}) -> + %% ClientSigAlgs are the pub_key algortithms that: + %% 1) is usable, that is, the user has such a public key and + %% 2) is either the default list or set by the caller + %% with the client option 'pref_public_key_algs' + %% + %% The list is already checked for duplicates. + + SigAlgs = [A || Astr <- string:tokens(SigAlgsStr, ","), + A <- try [list_to_existing_atom(Astr)] + %% list_to_existing_atom will fail for unknown algorithms + catch _:_ -> [] + end], + + CommonAlgs = [A || A <- SigAlgs, + lists:member(A, ClientSigAlgs)], + + %% Re-arrange the client supported public-key algorithms so that the server + %% preferred ones are tried first. + %% Trying algorithms not mentioned by the server is ok, since the server can't know + %% if the client supports 'server-sig-algs' or not. + + D0#data{ + ssh_params = + Ssh0#ssh{ + userauth_pubkeys = + CommonAlgs ++ (ClientSigAlgs -- CommonAlgs) + }}; ext_info(_, D0) -> %% Not implemented D0. %%%---------------------------------------------------------------- +is_usable_user_pubkey(A, Ssh) -> + case ssh_auth:get_public_key(A, Ssh) of + {ok,_} -> true; + _ -> false + end. + +%%%---------------------------------------------------------------- handle_request(ChannelPid, ChannelId, Type, Data, WantReply, From, D) -> case ssh_channel:cache_lookup(cache(D), ChannelId) of #channel{remote_id = Id} = Channel -> diff --git a/lib/ssh/src/ssh_dbg.erl b/lib/ssh/src/ssh_dbg.erl index 003b3856e6..3f742ad9b6 100644 --- a/lib/ssh/src/ssh_dbg.erl +++ b/lib/ssh/src/ssh_dbg.erl @@ -22,10 +22,8 @@ -module(ssh_dbg). --export([messages/0, messages/1, messages/2, - ct_messages/0, - auth/0, auth/1, auth/2, - ct_auth/0, +-export([messages/0, messages/1, messages/2, messages/3, + auth/0, auth/1, auth/2, auth/3, stop/0 ]). @@ -37,50 +35,52 @@ -include("ssh_connect.hrl"). -include("ssh_auth.hrl"). --record(data, { - writer, - acc = []}). %%%================================================================ -messages() -> - messages(fun(String,_D) -> io:format(String) end). +messages() -> start(msg). +messages(F) -> start(msg,F). +messages(F,X) -> start(msg,F,X). +messages(F,M,I) -> start(msg,F,M,I). -ct_messages() -> - messages(fun(String,_D) -> ct:log(String,[]) end). +auth() -> start(auth). +auth(F) -> start(auth,F). +auth(F,X) -> start(auth,F,X). +auth(F,M,I) -> start(auth,F,M,I). -messages(Write) when is_function(Write,2) -> - messages(Write, fun(X) -> X end). - -messages(Write, MangleArg) when is_function(Write,2), - is_function(MangleArg,1) -> - cond_start(msg, Write, MangleArg), - dbg_ssh_messages(), - dbg_ssh_auth(). +stop() -> dbg:stop(). +%%%---------------------------------------------------------------- +start(Type) -> start(Type, fun io:format/2). -auth() -> - auth(fun(String,_D) -> io:format(String) end). +start(Type, F) when is_function(F,2) -> start(Type, fmt_fun(F)); +start(Type, F) when is_function(F,3) -> start(Type, F, id_fun()). -ct_auth() -> - auth(fun(String,_D) -> ct:log(String,[]) end). +start(Type, WriteFun, MangleArgFun) when is_function(WriteFun, 3), + is_function(MangleArgFun, 1) -> + start(Type, WriteFun, MangleArgFun, []); +start(Type, WriteFun, InitValue) -> + start(Type, WriteFun, id_fun(), InitValue). -auth(Write) when is_function(Write,2) -> - auth(Write, fun(X) -> X end). +start(Type, WriteFun, MangleArgFun, InitValue) when is_function(WriteFun, 3), + is_function(MangleArgFun, 1) -> + cond_start(Type, WriteFun, MangleArgFun, InitValue), + dbg_ssh(Type). -auth(Write, MangleArg) when is_function(Write,2), - is_function(MangleArg,1) -> - cond_start(auth, Write, MangleArg), - dbg_ssh_auth(). +%%%---------------------------------------------------------------- +fmt_fun(F) -> fun(Fmt,Args,Data) -> F(Fmt,Args), Data end. +id_fun() -> fun(X) -> X end. -dbg_ssh_messages() -> +%%%---------------------------------------------------------------- +dbg_ssh(msg) -> + dbg_ssh(auth), dbg:tp(ssh_message,encode,1, x), dbg:tp(ssh_message,decode,1, x), dbg:tpl(ssh_transport,select_algorithm,4, x), dbg:tp(ssh_transport,hello_version_msg,1, x), dbg:tp(ssh_transport,handle_hello_version,1, x), - dbg:tpl(ssh_connection_handler,ext_info,2, x). + dbg:tpl(ssh_connection_handler,ext_info,2, x); -dbg_ssh_auth() -> +dbg_ssh(auth) -> dbg:tp(ssh_transport,hello_version_msg,1, x), dbg:tp(ssh_transport,handle_hello_version,1, x), dbg:tp(ssh_message,encode,1, x), @@ -89,15 +89,11 @@ dbg_ssh_auth() -> lists:foreach(fun(F) -> dbg:tp(ssh_auth, F, x) end, [publickey_msg, password_msg, keyboard_interactive_msg]). -%%%---------------------------------------------------------------- -stop() -> - dbg:stop(). - %%%================================================================ -cond_start(Type, Write, MangleArg) -> +cond_start(Type, WriteFun, MangleArgFun, Init) -> try dbg:start(), - setup_tracer(Type, Write, MangleArg), + setup_tracer(Type, WriteFun, MangleArgFun, Init), dbg:p(new,[c,timestamp]) catch _:_ -> ok @@ -136,12 +132,13 @@ msg_formater(_, {trace_ts,Pid,call,{ssh_transport,handle_hello_version,[Hello]}, msg_formater(_, {trace_ts,_Pid,return_from,{ssh_transport,handle_hello_version,1},_,_TS}, D) -> D; -msg_formater(_, {trace_ts,Pid,call,{ssh_connection_handler,ext_info,[{"server-sig-algs",_SigAlgs},State]},TS}, D) -> +msg_formater(_, {trace_ts,Pid,call,{ssh_connection_handler,ext_info,[{"server-sig-algs",SigAlgs},State]},TS}, D) -> try lists:keyfind(ssh, 1, tuple_to_list(State)) of false -> D; #ssh{userauth_pubkeys = PKs} -> - fmt("~n~s ~p Client got suggestion to use user public key sig-algs~n ~p~n", [ts(TS),Pid,PKs], D) + fmt("~n~s ~p Client got suggestion to use user public key sig-algs~n ~p~n and can use~n ~p~n", + [ts(TS),Pid,string:tokens(SigAlgs,","),PKs], D) catch _:_ -> D @@ -206,21 +203,25 @@ msg_formater(msg, {trace_ts,Pid,'receive',ErlangMsg,TS}, D) -> msg_formater(_, _, D) -> D. +%%%---------------------------------------------------------------- +-record(data, {writer, + acc}). -fmt(Fmt, Args, D=#data{writer=Write,acc=Acc}) -> - D#data{acc = Write(io_lib:format(Fmt, Args), Acc)}. +fmt(Fmt, Args, D=#data{writer=Write, acc=Acc}) -> + D#data{acc = Write(Fmt,Args,Acc)}. ts({_,_,Usec}=Now) -> {_Date,{HH,MM,SS}} = calendar:now_to_local_time(Now), io_lib:format("~.2.0w:~.2.0w:~.2.0w.~.6.0w",[HH,MM,SS,Usec]); ts(_) -> "-". -%%%---------------------------------------------------------------- -setup_tracer(Type, Write, MangleArg) -> + +setup_tracer(Type, WriteFun, MangleArgFun, Init) -> Handler = fun(Arg, D) -> - msg_formater(Type, MangleArg(Arg), D) + msg_formater(Type, MangleArgFun(Arg), D) end, - InitialData = #data{writer = Write}, + InitialData = #data{writer = WriteFun, + acc = Init}, {ok,_} = dbg:tracer(process, {Handler, InitialData}), ok. diff --git a/lib/ssh/src/ssh_options.erl b/lib/ssh/src/ssh_options.erl index aebb5a7062..7eeed70739 100644 --- a/lib/ssh/src/ssh_options.erl +++ b/lib/ssh/src/ssh_options.erl @@ -674,7 +674,11 @@ check_pref_public_key_algs(V) -> PKs = ssh_transport:supported_algorithms(public_key), CHK = fun(A, Ack) -> case lists:member(A, PKs) of - true -> [A|Ack]; + true -> + case lists:member(A,Ack) of + false -> [A|Ack]; + true -> Ack % Remove duplicates + end; false -> error_in_check(A, "Not supported public key") end end, diff --git a/lib/ssh/test/ssh_algorithms_SUITE.erl b/lib/ssh/test/ssh_algorithms_SUITE.erl index 0f69910e40..98964a2c8a 100644 --- a/lib/ssh/test/ssh_algorithms_SUITE.erl +++ b/lib/ssh/test/ssh_algorithms_SUITE.erl @@ -131,9 +131,14 @@ init_per_group(public_key=Tag, Alg, Config) -> ct:log("Init tests for public_key ~p",[Alg]), PrefAlgs = {preferred_algorithms,[{Tag,[Alg]}]}, %% Daemon started later in init_per_testcase - [{pref_algs,PrefAlgs}, - {tag_alg,{Tag,Alg}} - | Config]; + try + setup_pubkey(Alg, + [{pref_algs,PrefAlgs}, + {tag_alg,{Tag,Alg}} + | Config]) + catch + _:_ -> {skip, io_lib:format("Unsupported: ~p",[Alg])} + end; init_per_group(Tag, Alg, Config) -> PA = @@ -167,18 +172,24 @@ init_per_testcase(TC, Config) -> init_per_testcase(TC, proplists:get_value(tag_alg,Config), Config). -init_per_testcase(_, {public_key,Alg}, Config) -> - Opts = pubkey_opts(Config), +init_per_testcase(TC, {public_key,Alg}, Config) -> + ExtraOpts = case TC of + simple_connect -> + [{user_dir, proplists:get_value(priv_dir,Config)}]; + _ -> + [] + end, + Opts = pubkey_opts(Config) ++ ExtraOpts, case {ssh_file:user_key(Alg,Opts), ssh_file:host_key(Alg,Opts)} of {{ok,_}, {ok,_}} -> - ssh_dbg:ct_auth(), - start_pubkey_daemon([proplists:get_value(pref_algs,Config)], + start_pubkey_daemon([proplists:get_value(pref_algs,Config) + | ExtraOpts], [{extra_daemon,true}|Config]); - {{ok,_}, _} -> - {skip, "No host key"}; + {{ok,_}, {error,Err}} -> + {skip, io_lib:format("No host key: ~p",[Err])}; - {_, {ok,_}} -> - {skip, "No user key"}; + {{error,Err}, {ok,_}} -> + {skip, io_lib:format("No user key: ~p",[Err])}; _ -> {skip, "Neither host nor user key"} @@ -193,7 +204,6 @@ init_per_testcase(_, _, Config) -> end_per_testcase(_TC, Config) -> - catch ssh_dbg:stop(), case proplists:get_value(extra_daemon, Config, false) of true -> case proplists:get_value(srvr_pid,Config) of @@ -223,6 +233,19 @@ simple_exec(Config) -> ssh_test_lib:std_simple_exec(Host, Port, Config). %%-------------------------------------------------------------------- +%% A simple exec call +simple_connect(Config) -> + {Host,Port} = proplists:get_value(srvr_addr, Config), + Opts = + case proplists:get_value(tag_alg, Config) of + {public_key,Alg} -> [{pref_public_key_algs,[Alg]}]; + _ -> [] + end, + ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts), + ct:log("~p:~p connected! ~p",[?MODULE,?LINE,ConnectionRef]), + ssh:close(ConnectionRef). + +%%-------------------------------------------------------------------- %% Testing if no group matches simple_exec_groups_no_match_too_small(Config) -> try_exec_simple_group({400,500,600}, Config). @@ -304,9 +327,15 @@ sshc_simple_exec_os_cmd(Config) -> %%-------------------------------------------------------------------- %% Connect to the ssh server of the OS sshd_simple_exec(Config) -> + ClientPubKeyOpts = + case proplists:get_value(tag_alg,Config) of + {public_key,Alg} -> [{pref_public_key_algs,[Alg]}]; + _ -> [] + end, ConnectionRef = ssh_test_lib:connect(22, [{silently_accept_hosts, true}, proplists:get_value(pref_algs,Config), - {user_interaction, false}]), + {user_interaction, false} + | ClientPubKeyOpts]), {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity), success = ssh_connection:exec(ConnectionRef, ChannelId0, "echo testing", infinity), @@ -363,8 +392,8 @@ split(Alg) -> ssh_test_lib:to_atoms(string:tokens(atom_to_list(Alg), " + ")). specific_test_cases(Tag, Alg, SshcAlgos, SshdAlgos, TypeSSH) -> case Tag of - public_key -> []; - _ -> [simple_exec, simple_sftp] + public_key -> [simple_connect]; + _ -> [simple_connect, simple_exec, simple_sftp] end ++ case supports(Tag, Alg, SshcAlgos) of true when TypeSSH == openSSH -> @@ -439,10 +468,26 @@ setup_pubkey(Config) -> Keys = [ssh_test_lib:setup_dsa(DataDir, UserDir), ssh_test_lib:setup_rsa(DataDir, UserDir), - ssh_test_lib:setup_ecdsa("256", DataDir, UserDir)], + ssh_test_lib:setup_ecdsa("256", DataDir, UserDir) + ], ssh_test_lib:write_auth_keys(Keys, UserDir), % 'authorized_keys' shall contain ALL pub keys Config. +setup_pubkey(Alg, Config) -> + DataDir = proplists:get_value(data_dir, Config), + UserDir = proplists:get_value(priv_dir, Config), + ct:log("Setup keys for ~p",[Alg]), + case Alg of + 'ssh-dss' -> ssh_test_lib:setup_dsa(DataDir, UserDir); + 'ssh-rsa' -> ssh_test_lib:setup_rsa(DataDir, UserDir); + 'rsa-sha2-256' -> ssh_test_lib:setup_rsa(DataDir, UserDir); + 'rsa-sha2-512' -> ssh_test_lib:setup_rsa(DataDir, UserDir); + 'ecdsa-sha2-nistp256' -> ssh_test_lib:setup_ecdsa("256", DataDir, UserDir); + 'ecdsa-sha2-nistp384' -> ssh_test_lib:setup_ecdsa("384", DataDir, UserDir); + 'ecdsa-sha2-nistp521' -> ssh_test_lib:setup_ecdsa("521", DataDir, UserDir) + end, + Config. + simple_exec_group(I, Config) when is_integer(I) -> simple_exec_group({I,I,I}, Config); diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384 new file mode 100644 index 0000000000..4c39e916e9 --- /dev/null +++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384 @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDAughXu55DNyhxe6x+MNjv4oZKWUDh7bhi4CqjvxhCp9KMpsybltcq+ +lsuKTarzTdKgBwYFK4EEACKhZANiAASu1vvDL0SQoXGtzlltaPHPyDfEVMG/sKLA +pqv8vfRN5Wcs7+yaRKw92nYEKGXfZLbhVX8ArFPMtXPWHcRHCntvL1Acn2kJQ8Gc +7iL4NAr8JhTIUBv4YMhHDa9Pv/CH2zk= +-----END EC PRIVATE KEY----- diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub new file mode 100644 index 0000000000..caa9604c84 --- /dev/null +++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa384.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBK7W+8MvRJChca3OWW1o8c/IN8RUwb+wosCmq/y99E3lZyzv7JpErD3adgQoZd9ktuFVfwCsU8y1c9YdxEcKe28vUByfaQlDwZzuIvg0CvwmFMhQG/hgyEcNr0+/8IfbOQ== uabhnil@elxadlj3q32 diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521 new file mode 100644 index 0000000000..1e16fcbd57 --- /dev/null +++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521 @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHbAgEBBEEWXGoVLiNwQVUwAGZWxOu6uxtU8ntxyZNlcWU4Z8pze9kq3eK7a9XH +l/wxL75Vk1QdOiR/rE3s/L/zOuChp44o1aAHBgUrgQQAI6GBiQOBhgAEAfCrtwjO +kQYKr4/F3uanS7Eby1+SYDdRl1ABuDFhNC3CivVBFt4CnRneV+Mf0viDAxD+HEpd +/GaE2CdsFoVpglN5AVG+fEePY2PiCLHmjc4/pBuR+tWhErzcWAd0KLBCBuc4OAvl +aLLYV1NAJI6COnnfGTCVvYYE5nKMG4LLX0zaWtWl +-----END EC PRIVATE KEY----- diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub new file mode 100644 index 0000000000..069683eba7 --- /dev/null +++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa521.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHwq7cIzpEGCq+Pxd7mp0uxG8tfkmA3UZdQAbgxYTQtwor1QRbeAp0Z3lfjH9L4gwMQ/hxKXfxmhNgnbBaFaYJTeQFRvnxHj2Nj4gix5o3OP6QbkfrVoRK83FgHdCiwQgbnODgL5Wiy2FdTQCSOgjp53xkwlb2GBOZyjBuCy19M2lrVpQ== uabhnil@elxadlj3q32 diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384 new file mode 100644 index 0000000000..5835bcd74c --- /dev/null +++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384 @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDB+l0+SMLYgQ3ZRzg2Pn5u+1ZwKbEnJzXsTKTJM9QSJbKkbA7uCnjdS +CvEW+66CoHqgBwYFK4EEACKhZANiAAT6awCCIrcCr9H4wq0bJ/rQou3tpLHyyf33 +c8D6FPn48/hNqinpx7b0le/0D+Rrhdl9edIplAf6oki7yoFFGl4yuzWtv7rag9jB +vv6w1508ChOmyQ094rFt/xj4KVBhEHI= +-----END EC PRIVATE KEY----- diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub new file mode 100644 index 0000000000..714fc4eb89 --- /dev/null +++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key384.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPprAIIitwKv0fjCrRsn+tCi7e2ksfLJ/fdzwPoU+fjz+E2qKenHtvSV7/QP5GuF2X150imUB/qiSLvKgUUaXjK7Na2/utqD2MG+/rDXnTwKE6bJDT3isW3/GPgpUGEQcg== uabhnil@elxadlj3q32 diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521 new file mode 100644 index 0000000000..81aa8df39f --- /dev/null +++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521 @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHbAgEBBEHHxgYEfDclsu5bW+pZfg+bkaqWpgEpXtuzLVm++FFPjhAPhMkurSRj +WQ+CuI2TxgYkBbYFNjn9JqgdMF7FzaiojKAHBgUrgQQAI6GBiQOBhgAEAFTM8TKG +xexxmfAGuyl/Tpk4wytB/OyuVfkF+Q3H1v17HLcpMacA5xUFr80+D5XnjxGttBsS ++X0uexR7QbPbhhPqADgQzFqvTsB1mUNAZnJBD6QNCZkfWwRRwFYQWSmisb43H6G3 +iUTKqiCXMXO8drKLA+Wi+L7VyfoI1CvatBBlDHbV +-----END EC PRIVATE KEY----- diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub new file mode 100644 index 0000000000..17b9a1d834 --- /dev/null +++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key521.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBABUzPEyhsXscZnwBrspf06ZOMMrQfzsrlX5BfkNx9b9exy3KTGnAOcVBa/NPg+V548RrbQbEvl9LnsUe0Gz24YT6gA4EMxar07AdZlDQGZyQQ+kDQmZH1sEUcBWEFkporG+Nx+ht4lEyqoglzFzvHayiwPlovi+1cn6CNQr2rQQZQx21Q== uabhnil@elxadlj3q32 diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index 7208baca6e..48332d2e5a 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,5 +1,5 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 4.5 +SSH_VSN = 4.4.2 APP_VSN = "ssh-$(SSH_VSN)" diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index 1a93572dc7..29ec3f9d57 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -28,114 +28,6 @@ <p>This document describes the changes made to the SSL application.</p> -<section><title>SSL 8.2</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - ECDH-ECDSA key exchange supported, was accidently - dismissed in earlier versions.</p> - <p> - Own Id: OTP-14421</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - TLS-1.2 clients will now always send hello messages on - its own format, as opposed to earlier versions that will - send the hello on the lowest supported version, this is a - change supported by the latest RFC.</p> - <p> - This will make interoperability with some newer servers - smoother. Potentially, but unlikely, this could cause a - problem with older servers if they do not adhere to the - RFC and ignore unknown extensions.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13820</p> - </item> - <item> - <p> - Allow Erlang/OTP to use OpenSSL in FIPS-140 mode, in - order to satisfy specific security requirements (mostly - by different parts of the US federal government). </p> - <p> - See the new crypto users guide "FIPS mode" chapter about - building and using the FIPS support which is disabled by - default.</p> - <p> - (Thanks to dszoboszlay and legoscia)</p> - <p> - Own Id: OTP-13921 Aux Id: PR-1180 </p> - </item> - <item> - <p> - Implemented DTLS cookie generation, requiered by spec, - instead of using hardcode value.</p> - <p> - Own Id: OTP-14076</p> - </item> - <item> - <p> - Implement sliding window replay protection of DTLS - records.</p> - <p> - Own Id: OTP-14077</p> - </item> - <item> - <p> - TLS client processes will by default call - public_key:pkix_verify_hostname/2 to verify the hostname - of the connection with the server certifcates specified - hostname during certificate path validation. The user may - explicitly disables it. Also if the hostname can not be - derived from the first argument to connnect or is not - supplied by the server name indication option, the check - will not be performed.</p> - <p> - Own Id: OTP-14197</p> - </item> - <item> - <p> - Extend connection_information/[1,2] . The values - session_id, master_secret, client_random and - server_random can no be accessed by - connection_information/2. Note only session_id will be - added to connection_information/1. The rational is that - values concerning the connection security should have to - be explicitly requested.</p> - <p> - Own Id: OTP-14291</p> - </item> - <item> - <p> - Chacha cipher suites are currently not tested enough to - be most prefered ones</p> - <p> - Own Id: OTP-14382</p> - </item> - <item> - <p> - Basic support for DTLS that been tested together with - OpenSSL.</p> - <p> - Test by providing the option {protocol, dtls} to the ssl - API functions connect and listen.</p> - <p> - Own Id: OTP-14388</p> - </item> - </list> - </section> - -</section> - <section><title>SSL 8.1.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl index 2de947d8b4..f338471829 100644 --- a/lib/ssl/src/dtls_connection.erl +++ b/lib/ssl/src/dtls_connection.erl @@ -115,7 +115,7 @@ send_handshake_flight(#state{socket = Socket, {Encoded, ConnectionStates} = encode_handshake_flight(lists:reverse(Flight), Version, 1400, Epoch, ConnectionStates0), send(Transport, Socket, Encoded), - start_flight(State0#state{connection_states = ConnectionStates}); + {State0#state{connection_states = ConnectionStates}, []}; send_handshake_flight(#state{socket = Socket, transport_cb = Transport, @@ -129,7 +129,7 @@ send_handshake_flight(#state{socket = Socket, {EncChangeCipher, ConnectionStates} = encode_change_cipher(ChangeCipher, Version, Epoch, ConnectionStates1), send(Transport, Socket, [HsBefore, EncChangeCipher]), - start_flight(State0#state{connection_states = ConnectionStates}); + {State0#state{connection_states = ConnectionStates}, []}; send_handshake_flight(#state{socket = Socket, transport_cb = Transport, @@ -145,7 +145,7 @@ send_handshake_flight(#state{socket = Socket, {HsAfter, ConnectionStates} = encode_handshake_flight(lists:reverse(Flight1), Version, 1400, Epoch, ConnectionStates2), send(Transport, Socket, [HsBefore, EncChangeCipher, HsAfter]), - start_flight(State0#state{connection_states = ConnectionStates}); + {State0#state{connection_states = ConnectionStates}, []}; send_handshake_flight(#state{socket = Socket, transport_cb = Transport, @@ -159,7 +159,7 @@ send_handshake_flight(#state{socket = Socket, {HsAfter, ConnectionStates} = encode_handshake_flight(lists:reverse(Flight1), Version, 1400, Epoch, ConnectionStates1), send(Transport, Socket, [EncChangeCipher, HsAfter]), - start_flight(State0#state{connection_states = ConnectionStates}). + {State0#state{connection_states = ConnectionStates}, []}. queue_change_cipher(ChangeCipher, #state{flight_buffer = Flight, connection_states = ConnectionStates0} = State) -> @@ -235,12 +235,14 @@ init([Role, Host, Port, Socket, Options, User, CbInfo]) -> end. callback_mode() -> - state_functions. + [state_functions, state_enter]. %%-------------------------------------------------------------------- %% State functions %%-------------------------------------------------------------------- +init(enter, _, State) -> + {keep_state, State}; init({call, From}, {start, Timeout}, #state{host = Host, port = Port, role = client, ssl_options = SslOpts, @@ -282,6 +284,8 @@ init({call, _} = Type, Event, #state{role = server} = State) -> init(Type, Event, State) -> ssl_connection:init(Type, Event, State, ?MODULE). +error(enter, _, State) -> + {keep_state, State}; error({call, From}, {start, _Timeout}, {Error, State}) -> {stop_and_reply, normal, {reply, From, {error, Error}}, State}; error({call, From}, Msg, State) -> @@ -295,6 +299,11 @@ error(_, _, _) -> #state{}) -> gen_statem:state_function_result(). %%-------------------------------------------------------------------- +hello(enter, _, #state{role = server} = State) -> + {keep_state, State}; +hello(enter, _, #state{role = client} = State0) -> + {State, Actions} = handle_flight_timer(State0), + {keep_state, State, Actions}; hello(internal, #client_hello{cookie = <<>>, client_version = Version} = Hello, #state{role = server, transport_cb = Transport, @@ -374,6 +383,9 @@ hello(state_timeout, Event, State) -> hello(Type, Event, State) -> ssl_connection:hello(Type, Event, State, ?MODULE). +abbreviated(enter, _, State0) -> + {State, Actions} = handle_flight_timer(State0), + {keep_state, State, Actions}; abbreviated(info, Event, State) -> handle_info(Event, abbreviated, State); abbreviated(internal = Type, @@ -391,6 +403,9 @@ abbreviated(state_timeout, Event, State) -> abbreviated(Type, Event, State) -> ssl_connection:abbreviated(Type, Event, State, ?MODULE). +certify(enter, _, State0) -> + {State, Actions} = handle_flight_timer(State0), + {keep_state, State, Actions}; certify(info, Event, State) -> handle_info(Event, certify, State); certify(internal = Type, #server_hello_done{} = Event, State) -> @@ -400,6 +415,9 @@ certify(state_timeout, Event, State) -> certify(Type, Event, State) -> ssl_connection:certify(Type, Event, State, ?MODULE). +cipher(enter, _, State0) -> + {State, Actions} = handle_flight_timer(State0), + {keep_state, State, Actions}; cipher(info, Event, State) -> handle_info(Event, cipher, State); cipher(internal = Type, #change_cipher_spec{type = <<1>>} = Event, @@ -417,6 +435,8 @@ cipher(state_timeout, Event, State) -> cipher(Type, Event, State) -> ssl_connection:cipher(Type, Event, State, ?MODULE). +connection(enter, _, State) -> + {keep_state, State}; connection(info, Event, State) -> handle_info(Event, connection, State); connection(internal, #hello_request{}, #state{host = Host, port = Port, @@ -449,6 +469,9 @@ connection(internal, #client_hello{}, #state{role = server, allow_renegotiate = connection(Type, Event, State) -> ssl_connection:connection(Type, Event, State, ?MODULE). +%%TODO does this make sense for DTLS ? +downgrade(enter, _, State) -> + {keep_state, State}; downgrade(Type, Event, State) -> ssl_connection:downgrade(Type, Event, State, ?MODULE). @@ -750,14 +773,16 @@ next_event(connection = StateName, no_record, {#ssl_tls{epoch = Epoch, type = ?HANDSHAKE, version = _Version}, State1} = _Record when Epoch == CurrentEpoch-1 -> - {State, MoreActions} = send_handshake_flight(State1, CurrentEpoch), - {next_state, StateName, State, Actions ++ MoreActions}; + {State2, MoreActions} = send_handshake_flight(State1, CurrentEpoch), + {NextRecord, State} = next_record(State2), + next_event(StateName, NextRecord, State, Actions ++ MoreActions); %% From FLIGHT perspective CHANGE_CIPHER_SPEC is treated as a handshake {#ssl_tls{epoch = Epoch, type = ?CHANGE_CIPHER_SPEC, version = _Version}, State1} = _Record when Epoch == CurrentEpoch-1 -> - {State, MoreActions} = send_handshake_flight(State1, CurrentEpoch), - {next_state, StateName, State, Actions ++ MoreActions}; + {State2, MoreActions} = send_handshake_flight(State1, CurrentEpoch), + {NextRecord, State} = next_record(State2), + next_event(StateName, NextRecord, State, Actions ++ MoreActions); {#ssl_tls{epoch = _Epoch, version = _Version}, State1} -> %% TODO maybe buffer later epoch @@ -774,14 +799,16 @@ next_event(connection = StateName, Record, #ssl_tls{epoch = Epoch, type = ?HANDSHAKE, version = _Version} when Epoch == CurrentEpoch-1 -> - {State, MoreActions} = send_handshake_flight(State0, CurrentEpoch), - {next_state, StateName, State, Actions ++ MoreActions}; + {State1, MoreActions} = send_handshake_flight(State0, CurrentEpoch), + {NextRecord, State} = next_record(State1), + next_event(StateName, NextRecord, State, Actions ++ MoreActions); %% From FLIGHT perspective CHANGE_CIPHER_SPEC is treated as a handshake #ssl_tls{epoch = Epoch, type = ?CHANGE_CIPHER_SPEC, version = _Version} when Epoch == CurrentEpoch-1 -> - {State, MoreActions} = send_handshake_flight(State0, CurrentEpoch), - {next_state, StateName, State, Actions ++ MoreActions}; + {State1, MoreActions} = send_handshake_flight(State0, CurrentEpoch), + {NextRecord, State} = next_record(State1), + next_event(StateName, NextRecord, State, Actions ++ MoreActions); _ -> next_event(StateName, no_record, State0, Actions) end; @@ -841,13 +868,13 @@ next_flight(Flight) -> change_cipher_spec => undefined, handshakes_after_change_cipher_spec => []}. -start_flight(#state{transport_cb = gen_udp, - flight_state = {retransmit, Timeout}} = State) -> +handle_flight_timer(#state{transport_cb = gen_udp, + flight_state = {retransmit, Timeout}} = State) -> start_retransmision_timer(Timeout, State); -start_flight(#state{transport_cb = gen_udp, +handle_flight_timer(#state{transport_cb = gen_udp, flight_state = connection} = State) -> {State, []}; -start_flight(State) -> +handle_flight_timer(State) -> %% No retransmision needed i.e DTLS over SCTP {State#state{flight_state = reliable}, []}. diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index 96c3ab86e9..352874c77d 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -600,8 +600,12 @@ next_record(#state{protocol_buffers = next_record(#state{protocol_buffers = #protocol_buffers{tls_packets = [], tls_cipher_texts = []}, socket = Socket, transport_cb = Transport} = State) -> - tls_socket:setopts(Transport, Socket, [{active,once}]), - {no_record, State}; + case tls_socket:setopts(Transport, Socket, [{active,once}]) of + ok -> + {no_record, State}; + _ -> + {socket_closed, State} + end; next_record(State) -> {no_record, State}. @@ -626,10 +630,15 @@ passive_receive(State0 = #state{user_data_buffer = Buffer}, StateName) -> next_event(StateName, Record, State) -> next_event(StateName, Record, State, []). +next_event(StateName, socket_closed, State, _) -> + ssl_connection:handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State), + {stop, {shutdown, transport_closed}, State}; next_event(connection = StateName, no_record, State0, Actions) -> case next_record_if_active(State0) of {no_record, State} -> ssl_connection:hibernate_after(StateName, State, Actions); + {socket_closed, State} -> + next_event(StateName, socket_closed, State, Actions); {#ssl_tls{} = Record, State} -> {next_state, StateName, State, [{next_event, internal, {protocol_record, Record}} | Actions]}; {#alert{} = Alert, State} -> diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 58870a3419..d13b1b3f2a 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -240,6 +240,7 @@ error_handling_tests()-> error_handling_tests_tls()-> [controller_dies, tls_client_closes_socket, + tls_closed_in_active_once, tls_tcp_error_propagation_in_active_mode, tls_tcp_connect, tls_tcp_connect_big, @@ -430,6 +431,7 @@ init_per_testcase(prf, Config) -> init_per_testcase(TestCase, Config) when TestCase == tls_ssl_accept_timeout; TestCase == tls_client_closes_socket; + TestCase == tls_closed_in_active_once; TestCase == tls_downgrade -> ssl_test_lib:ct_log_supported_protocol_versions(Config), ct:timetrap({seconds, 15}), @@ -961,6 +963,48 @@ tls_client_closes_socket(Config) when is_list(Config) -> ssl_test_lib:check_result(Server, {error,closed}). %%-------------------------------------------------------------------- +tls_closed_in_active_once() -> + [{doc, "Test that ssl_closed is delivered in active once with non-empty buffer, check ERL-420."}]. + +tls_closed_in_active_once(Config) when is_list(Config) -> + ClientOpts = ssl_test_lib:ssl_options(client_opts, Config), + ServerOpts = ssl_test_lib:ssl_options(server_opts, Config), + {_ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config), + TcpOpts = [binary, {reuseaddr, true}], + Port = ssl_test_lib:inet_port(node()), + Server = fun() -> + {ok, Listen} = gen_tcp:listen(Port, TcpOpts), + {ok, TcpServerSocket} = gen_tcp:accept(Listen), + {ok, ServerSocket} = ssl:ssl_accept(TcpServerSocket, ServerOpts), + lists:foreach( + fun(_) -> + ssl:send(ServerSocket, "some random message\r\n") + end, lists:seq(1, 20)), + %% Close TCP instead of SSL socket to trigger the bug: + gen_tcp:close(TcpServerSocket), + gen_tcp:close(Listen) + end, + spawn_link(Server), + {ok, Socket} = ssl:connect(Hostname, Port, [{active, false} | ClientOpts]), + Result = tls_closed_in_active_once_loop(Socket), + ssl:close(Socket), + case Result of + ok -> ok; + _ -> ct:fail(Result) + end. + +tls_closed_in_active_once_loop(Socket) -> + ssl:setopts(Socket, [{active, once}]), + receive + {ssl, Socket, _} -> + tls_closed_in_active_once_loop(Socket); + {ssl_closed, Socket} -> + ok + after 5000 -> + no_ssl_closed_received + end. + +%%-------------------------------------------------------------------- connect_dist() -> [{doc,"Test a simple connect as is used by distribution"}]. diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index ad7f2f2e95..a7caa71dcb 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -1098,7 +1098,7 @@ handle_event(_, _, State, Data) -> <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> or <seealso marker="#enter_loop/5"><c>enter_loop/5,6</c></seealso> - would be weird on the border of whichcraft + would be weird on the border of witchcraft since there has been no earlier call to a <seealso marker="#state callback">state callback</seealso> in this server. diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml index fad0896d9b..a8a252cb35 100644 --- a/lib/stdlib/doc/src/notes.xml +++ b/lib/stdlib/doc/src/notes.xml @@ -31,418 +31,6 @@ </header> <p>This document describes the changes made to the STDLIB application.</p> -<section><title>STDLIB 3.4</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p>For many releases, it has been legal to override a BIF - with a local function having the same name. However, - calling a local function with the same name as guard BIF - as filter in a list comprehension was not allowed.</p> - <p> - Own Id: OTP-13690</p> - </item> - <item> - <p> A new (default) pseudo-random number generator - algorithm Xoroshiro116+ has been implemented in the - <c>rand</c> module. </p><p> The old algorithm - implementations had a number of flaws so they are all - deprecated, but corrected versions of two of them have - been added. See the documentation. </p> - <p> - Own Id: OTP-14295 Aux Id: PR-1372 </p> - </item> - <item> - <p> The Erlang shell, <c>qlc:string_to_handle()</c>, and - the Debugger (the Evaluator area and Edit variable window - of the Bindings area) can parse pids, ports, references, - and external funs, as long as they can be created in the - running system. </p> - <p> - Own Id: OTP-14296</p> - </item> - <item> - <p>Internal code change: Calls to <c>catch</c> followed - by a call to <c>erlang:get_stacktrace/0</c> has been - rewritten to use <c>try</c> instead of <c>catch</c> to - make the code future-proof.</p> - <p> - Own Id: OTP-14400</p> - </item> - <item> - <p> The state machine engine <c>gen_statem</c> can now - handle generic time-outs (multiple named) as well as - absolute time-out time. See the documentation. </p><p> - The <c>gen_statem</c> callback <c>Module:init/1</c> has - become mandatory to harmonize with other <c>gen_*</c> - modules. This may be an incompatibility for - <c>gen_statem</c> callback modules that use - <c>gen_statem:enter_loop/4-6</c>. </p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14531</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - Improved unicode support for strings. Added normalization - functions in the <c>unicode</c> module. Extended the - <c>string</c> module API with new functions with improved - unicode handling and that works on grapheme clusters. The - new functions operates on the <c>unicode:chardata()</c> - type, thus they also accept <c>UTF-8 binaries</c> as - input. </p> - <p> - The old string API have been marked as obsolete. The - return values have been changed for some error cases.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-10289 Aux Id: OTP-10309 </p> - </item> - <item> - <p>There are two new guard BIFs '<c>floor/1</c>' and - '<c>ceil/1</c>'. They both return integers. In the - '<c>math</c>' module, there are two new BIFs with the - same names that return floating point values.</p> - <p> - Own Id: OTP-13692</p> - </item> - <item> - <p> - Making code_change, terminate and handle_info callbacks - optional in the OTP behaviours.</p> - <p> - Own Id: OTP-13801</p> - </item> - <item> - <p> The support for Dets files created with Erlang/OTP R7 - and earlier is removed. </p> - <p> - Own Id: OTP-13830</p> - </item> - <item> - <p>Replaced usage of deprecated symbolic <seealso - marker="erts:erlang#type-time_unit"><c>time - unit</c></seealso> representations.</p> - <p> - Own Id: OTP-13831 Aux Id: OTP-13735 </p> - </item> - <item> - <p>The function <c>fmod/2</c> has been added to the - <c>math</c> module.</p> - <p> - Own Id: OTP-14000</p> - </item> - <item> - <p>The EXIT signals received from processes using - <c>proc_lib</c> now looks like EXIT signals from - processes that were spawned using <c>spawn_link</c>. In - particular, that means that the stack trace is now - included in the EXIT signal so that it can see where the - process crashed.</p> - <p> - Own Id: OTP-14001</p> - </item> - <item> - <p><c>sets:add_element/2</c> is faster when adding an - element that is already present, and - <c>sets:del_element/2</c> is faster when the element to - be deleted is not present. This optimization can make - certain operations, such as sets:union/2 with many - overlapping elements, up to two orders of magnitude - faster.</p> - <p> - Own Id: OTP-14035</p> - </item> - <item> - <p> - Add information in doc about supervisor shutdown reason - when maximum restart frequency is reached.</p> - <p> - Own Id: OTP-14037 Aux Id: PR-1233 </p> - </item> - <item> - <p> - Added <c>rand:jump/[0|1]</c> functions.</p> - <p> - Own Id: OTP-14038 Aux Id: PR-1235 </p> - </item> - <item> - <p>Functions for detecting changed code has been added. - <c>code:modified_modules/0</c> returns all currently - loaded modules that have changed on disk. - <c>code:module_status/1</c> returns the status for a - module. In the shell and in <c>c</c> module, <c>mm/0</c> - is short for <c>code:modified_modules/0</c>, and - <c>lm/0</c> reloads all currently loaded modules that - have changed on disk.</p> - <p> - Own Id: OTP-14059</p> - </item> - <item> - <p>Each assert macro in <c>assert.hrl</c> now has a - corresponding version with an extra argument, for adding - comments to assertions. These can for example be printed - as part of error reports, to clarify the meaning of the - check that failed.</p> - <p> - Own Id: OTP-14066</p> - </item> - <item> - <p><c>error_logger_tty_h</c> and - <c>error_logger_file_h</c> now inserts the node - information for nonlocal messages before the message - itself instead of after, both for readability and so as - not to change the line termination property at the end of - the message.</p> - <p> - Own Id: OTP-14068</p> - </item> - <item> - <p>The Erlang code linter checks for badly formed type - constraints. </p> - <p> - Own Id: OTP-14070 Aux Id: PR-1214 </p> - </item> - <item> - <p>By default, there will now be a warning when - <c>export_all</c> is used. The warning can be disabled - using <c>nowarn_export_all</c>.</p> - <p> - Own Id: OTP-14071</p> - </item> - <item> - <p>When a <c>gen_server</c> process crashes, the - stacktrace for the client will be printed to facilitate - debugging.</p> - <p> - Own Id: OTP-14089</p> - </item> - <item> - <p> - Optimized ETS operations by changing table identifier - type from integer to reference. The reference enables a - more direct mapping to the table with less potential lock - contention and makes especially creation and deletion of - tables scale much better.</p> - <p> - The change of the opaque type for the ETS table - identifiers may cause failure in code that make faulty - assumptions about this opaque type.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14094</p> - </item> - <item> - <p><c>take/2</c> has been added to <c>dict</c>, - <c>orddict</c>, and <c>gb_trees</c>. <c>take_any/2</c> - has been added to <c>gb_trees</c>.</p> - <p> - Own Id: OTP-14102</p> - </item> - <item> - <p> - Extend gen_event API to handle options as well.</p> - <p> - Own Id: OTP-14123</p> - </item> - <item> - <p> - Advice on how to tune the supervisor restart frequency - (intensity and period) is added to System Documentation - - Design Principles - Supervisor Behaviour.</p> - <p> - Own Id: OTP-14168 Aux Id: PR-1289 </p> - </item> - <item> - <p> - gen_fsm is deprecated and is replaced by gen_statem, - however for backwards compatibility reasons gen_fsm may - continue to exist as an undocumented feature for quite - some time.</p> - <p> - Own Id: OTP-14183</p> - </item> - <item> - <p>The shell functions <c>c/1</c> and <c>c/2</c> have - been extended so that if the argument is a module name - instead of a file name, it automatically locates the - .beam file and the corresponding source file, and then - recompiles the module using the same compiler options - (plus any options passed to c/2). If compilation fails, - the old beam file is preserved. Also adds <c>c(Mod, Opts, - Filter)</c>, where the Filter argument allows you to - remove old compiler options before the new options are - added.</p> <p>New utility functions <c>file_find/2/3</c> - and <c>find_source/1/2/3</c> have been added to - <c>filelib</c>.</p> - <p> - Own Id: OTP-14190</p> - </item> - <item> - <p><c>erl_tar</c> in previous versions of OTP only - supports the USTAR format. That limited path names to at - most 255 bytes, and did not support Unicode characters in - names in a portable way.</p> - <p><c>erl_tar</c> now has support for reading tar - archives in the formats currently in common use, such as - v7, STAR, USTAR, PAX, and GNU tar's extensions to the - STAR/USTAR format. When writing tar archives, - <c>erl_tar</c> can now write them in the <c>PAX</c> - format if necessary (for example, to support very long - filenames or filenames with Unicode characters). If - possible, <c>erl_tar</c> will still write tar archives in - the USTAR for maximum portability.</p> - <p> - Own Id: OTP-14226</p> - </item> - <item> - <p><c>base64:mime_decode/1</c> has been optimized so that - it is now almost as fast as<c>base64:decode/1</c>; it - used be noticably slower.</p> - <p> - Own Id: OTP-14245</p> - </item> - <item> - <p><c>erl_tar</c> will now strip any leading '<c>/</c>' - from pathnames when extracting files from a tar archive - and write a message to the error logger. There is also - new check for directory traversal attacks; if a relative - path points above the current working directory the - extraction will be aborted.</p> - <p> - Own Id: OTP-14278</p> - </item> - <item> - <p> Miscellaneous updates due to atoms containing - arbitrary Unicode characters. </p> - <p> - Own Id: OTP-14285</p> - </item> - <item> - <p> - The Crypto application now supports generation of - cryptographically strong random numbers (floats < 1.0 - and integer arbitrary ranges) as a plugin to the 'rand' - module.</p> - <p> - Own Id: OTP-14317 Aux Id: PR-1372 </p> - </item> - <item> - <p> - Add new function <c>ets:select_replace/2</c> which - performs atomic "compare-and-swap" operations for ETS - objects using match specifications.</p> - <p> - Own Id: OTP-14319 Aux Id: PR-1076 </p> - </item> - <item> - <p> The Erlang code linter checks for bad <c>dialyzer</c> - attributes. It also checks for bad type variables in type - declarations. </p> - <p> - Own Id: OTP-14323</p> - </item> - <item> - <p> Two new functions has been implemented in the - <c>rand</c> module; <c>normal/2</c> and - <c>normal_s/3</c>, that both produce normal distribution - (pseudo) random numbers with mean value and variance - according to arguments. </p> - <p> - Own Id: OTP-14328 Aux Id: PR-1382 </p> - </item> - <item> - <p> - Upgraded the OTP internal PCRE library from version 8.33 - to version 8.40. This library is used for implementation - of the <seealso marker="stdlib:re"><c>re</c></seealso> - regular expressions module.</p> - <p> - Besides various bug fixes, the new version allows for - better stack protection. In order to utilize this - feature, the stack size of normal scheduler threads is - now by default set to 128 kilo words on all platforms. - The stack size of normal scheduler threads can be set - upon system start by passing the <seealso - marker="erts:erl#sched_thread_stack_size"><c>+sss</c></seealso> - command line argument to the <seealso - marker="erts:erl"><c>erl</c></seealso> command.</p> - <p> - See <url - href="http://pcre.org/original/changelog.txt"><c>http://pcre.org/original/changelog.txt</c></url> - for information about changes made to PCRE between the - versions 8.33 and 8.40.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14331 Aux Id: ERL-208 </p> - </item> - <item> - <p> - Added function <c>re:version/0</c> which returns - information about the OTP internal PCRE version used for - implementation of the <c>re</c> module.</p> - <p> - Own Id: OTP-14347 Aux Id: PR-1412 </p> - </item> - <item> - <p>The format of debug information that is stored in BEAM - files (when <c>debug_info</c> is used) has been changed. - The purpose of the change is to better support other - BEAM-based languages such as Elixir or LFE.</p> - <p>All tools included in OTP (dialyzer, debugger, cover, - and so on) will handle both the new format and the - previous format. Tools that retrieve the debug - information using <c>beam_lib:chunk(Beam, - [abstract_code])</c> will continue to work with both the - new and old format. Tools that call - <c>beam_lib:chunk(Beam, ["Abst"])</c> will not work with - the new format.</p> - <p>For more information, see the description of - <c>debug_info</c> in the documentation for - <c>beam_lib</c> and the description of the - <c>{debug_info,{Backend,Data}}</c> option in the - documentation for <c>compile</c>.</p> - <p> - Own Id: OTP-14369 Aux Id: PR-1367 </p> - </item> - <item> - <p> - Add option hibernate_after to gen_server, gen_statem and - gen_event. Also added to the deprecated gen_fsm - behaviour.</p> - <p> - Own Id: OTP-14405</p> - </item> - <item> - <p> The size of crash reports created by - <c>gen_server</c>, <c>gen_statem</c> and <c>proc_lib</c> - is limited with aid of the Kernel application variable - <c>error_logger_format_depth</c>. The purpose is to limit - the size of the <c>error_logger</c> process when - processes with huge message queues or states crash. </p> - <p> The new function - <c>error_logger:get_format_depth/0</c> can be used to - retrieve the value of the Kernel application variable - <c>error_logger_format_depth</c>. </p> - <p> - Own Id: OTP-14417</p> - </item> - </list> - </section> - -</section> - <section><title>STDLIB 3.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index f062c7fe6e..f7bd21472c 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1 +1 @@ -STDLIB_VSN = 3.4 +STDLIB_VSN = 3.3 diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml index 11c37459d6..e8de0ffce2 100644 --- a/lib/syntax_tools/doc/src/notes.xml +++ b/lib/syntax_tools/doc/src/notes.xml @@ -32,21 +32,6 @@ <p>This document describes the changes made to the Syntax_Tools application.</p> -<section><title>Syntax_Tools 2.1.2</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Miscellaneous updates due to atoms containing - arbitrary Unicode characters. </p> - <p> - Own Id: OTP-14285</p> - </item> - </list> - </section> - -</section> - <section><title>Syntax_Tools 2.1.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk index 9b33f1e1f4..c5e363112b 100644 --- a/lib/syntax_tools/vsn.mk +++ b/lib/syntax_tools/vsn.mk @@ -1 +1 @@ -SYNTAX_TOOLS_VSN = 2.1.2 +SYNTAX_TOOLS_VSN = 2.1.1 diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index ae2b4b00a0..bc17fd5307 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -31,35 +31,6 @@ </header> <p>This document describes the changes made to the Tools application.</p> -<section><title>Tools 2.10</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - In some situations, <c>make:all()</c> and friends did not - detect changes in include files located in the current - directory. This is now corrected.</p> - <p> - Own Id: OTP-14339 Aux Id: ERL-395 </p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>The <c>make</c> module now accepts the - <c>{emake,Emake}</c> option.</p> - <p> - Own Id: OTP-14253</p> - </item> - </list> - </section> - -</section> - <section><title>Tools 2.9.1</title> <section><title>Improvements and New Features</title> diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index 8aa7814e1d..f60da27c44 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1 +1 @@ -TOOLS_VSN = 2.10 +TOOLS_VSN = 2.9.1 diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml index 18661d1071..9086117c81 100644 --- a/lib/wx/doc/src/notes.xml +++ b/lib/wx/doc/src/notes.xml @@ -32,21 +32,6 @@ <p>This document describes the changes made to the wxErlang application.</p> -<section><title>Wx 1.8.1</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Fix a livelock that could be caused by <c>wx:batch/1</c>.</p> - <p> - Own Id: OTP-14289</p> - </item> - </list> - </section> - -</section> - <section><title>Wx 1.8</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk index b9100e7c87..cfa256fb12 100644 --- a/lib/wx/vsn.mk +++ b/lib/wx/vsn.mk @@ -1 +1 @@ -WX_VSN = 1.8.1 +WX_VSN = 1.8 diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml index a7592dc344..56856d026e 100644 --- a/lib/xmerl/doc/src/notes.xml +++ b/lib/xmerl/doc/src/notes.xml @@ -37,14 +37,16 @@ <section><title>Fixed Bugs and Malfunctions</title> <list> <item> - <p> - Improves accumulator fun in xmerl_scan so that only one - #xmlText record is returned for strings which have - character references.</p> - <p> - (Thanks to Jimmy Zöger)</p> - <p> - Own Id: OTP-14377 Aux Id: PR-1369 </p> + <p> A couple of bugs are fixed in the sax parser + (xmerl_sax_parser). </p> <list> <item>The continuation + function was not called correctly when the XML directive + was fragmented. </item> <item>When the event callback + modules (xmerl_sax_old_dom and xmerl_sax_simple) got an + endDocument event at certain conditions the parser + crashed.</item> <item>Replaced internal ets table with + map to avoid table leakage.</item> </list> + <p> + Own Id: OTP-14430</p> </item> </list> </section> diff --git a/lib/xmerl/src/xmerl_sax_old_dom.erl b/lib/xmerl/src/xmerl_sax_old_dom.erl index fefcf03fce..411121370f 100644 --- a/lib/xmerl/src/xmerl_sax_old_dom.erl +++ b/lib/xmerl/src/xmerl_sax_old_dom.erl @@ -127,9 +127,10 @@ build_dom(endDocument, State#xmerl_sax_old_dom_state{dom=[Decl, Current#xmlElement{ content=lists:reverse(C) }]}; - _ -> - %%?dbg("~p\n", [D]), - ?error("we're not at end the document when endDocument event is encountered.") + _ -> + %% endDocument is also sent by the parser when a fault occur to tell + %% the event receiver that no more input will be sent + State end; %% Element diff --git a/lib/xmerl/src/xmerl_sax_parser.erl b/lib/xmerl/src/xmerl_sax_parser.erl index 1aef6c58c4..e383c4c349 100644 --- a/lib/xmerl/src/xmerl_sax_parser.erl +++ b/lib/xmerl/src/xmerl_sax_parser.erl @@ -64,7 +64,7 @@ %% Description: Parse file containing an XML document. %%---------------------------------------------------------------------- file(Name,Options) -> - case file:open(Name, [raw, read,binary]) of + case file:open(Name, [raw, read_ahead, read,binary]) of {error, Reason} -> {error,{Name, file:format_error(Reason)}}; {ok, FD} -> @@ -120,21 +120,22 @@ stream(Xml, Options, InputType) when is_binary(Xml), is_list(Options) -> normal -> parse end, - case detect_charset(Xml, State) of - {error, Reason} -> {fatal_error, - { - State#xmerl_sax_parser_state.current_location, - State#xmerl_sax_parser_state.entity, - 1 - }, - Reason, - [], - State#xmerl_sax_parser_state.event_state}; - {Xml1, State1} -> - parse_binary(Xml1, - State1#xmerl_sax_parser_state{input_type = InputType}, - ParseFunction) - end + try + {Xml1, State1} = detect_charset(Xml, State), + parse_binary(Xml1, + State1#xmerl_sax_parser_state{input_type = InputType}, + ParseFunction) + catch + throw:{fatal_error, {State2, Reason}} -> + {fatal_error, + { + State2#xmerl_sax_parser_state.current_location, + State2#xmerl_sax_parser_state.entity, + 1 + }, + Reason, [], + State2#xmerl_sax_parser_state.event_state} + end end. %%---------------------------------------------------------------------- @@ -156,8 +157,8 @@ parse_binary(Xml, #xmerl_sax_parser_state{encoding={utf16,big}}=State, F) -> xmerl_sax_parser_utf16be:F(Xml, State); parse_binary(Xml, #xmerl_sax_parser_state{encoding=latin1}=State, F) -> xmerl_sax_parser_latin1:F(Xml, State); -parse_binary(_, #xmerl_sax_parser_state{encoding=Enc}, _) -> - {error, lists:flatten(io_lib:format("Charcter set ~p not supported", [Enc]))}. +parse_binary(_, #xmerl_sax_parser_state{encoding=Enc}, State) -> + ?fatal_error(State, lists:flatten(io_lib:format("Charcter set ~p not supported", [Enc]))). %%---------------------------------------------------------------------- %% Function: initial_state/0 @@ -211,8 +212,7 @@ parse_options([{entity, Entity} |Options], State) -> parse_options([skip_external_dtd |Options], State) -> parse_options(Options, State#xmerl_sax_parser_state{skip_external_dtd = true}); parse_options([O |_], _State) -> - {error, - lists:flatten(io_lib:format("Option: ~p not supported", [O]))}. + {error, lists:flatten(io_lib:format("Option: ~p not supported", [O]))}. check_encoding_option(E) when E==utf8; E=={utf16,little}; E=={utf16,big}; @@ -230,16 +230,10 @@ check_encoding_option(E) -> %% Output: {utf8|utf16le|utf16be|iso8859, Xml, State} %% Description: Detects which character set is used in a binary stream. %%---------------------------------------------------------------------- -detect_charset(<<>>, #xmerl_sax_parser_state{continuation_fun = undefined} = _) -> - {error, "Can't detect character encoding due to no indata"}; -detect_charset(<<>>, #xmerl_sax_parser_state{continuation_fun = CFun, - continuation_state = CState} = State) -> - case CFun(CState) of - {<<>>, _} -> - {error, "Can't detect character encoding due to lack of indata"}; - {NewBytes, NewContState} -> - detect_charset(NewBytes, State#xmerl_sax_parser_state{continuation_state = NewContState}) - end; +detect_charset(<<>>, #xmerl_sax_parser_state{continuation_fun = undefined} = State) -> + ?fatal_error(State, "Can't detect character encoding due to lack of indata"); +detect_charset(<<>>, State) -> + cf(<<>>, State, fun detect_charset/2); detect_charset(Bytes, State) -> case unicode:bom_to_encoding(Bytes) of {latin1, 0} -> @@ -249,25 +243,47 @@ detect_charset(Bytes, State) -> {RealBytes, State#xmerl_sax_parser_state{encoding=Enc}} end. +detect_charset_1(<<16#00>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); +detect_charset_1(<<16#00, 16#3C>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); +detect_charset_1(<<16#00, 16#3C, 16#00>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); detect_charset_1(<<16#00, 16#3C, 16#00, 16#3F, _/binary>> = Xml, State) -> {Xml, State#xmerl_sax_parser_state{encoding={utf16, big}}}; +detect_charset_1(<<16#3C>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); +detect_charset_1(<<16#3C, 16#00>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); +detect_charset_1(<<16#3C, 16#00, 16#3F>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); detect_charset_1(<<16#3C, 16#00, 16#3F, 16#00, _/binary>> = Xml, State) -> {Xml, State#xmerl_sax_parser_state{encoding={utf16, little}}}; -detect_charset_1(<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml2/binary>> = Xml, State) -> - case parse_xml_directive(Xml2) of +detect_charset_1(<<16#3C>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); +detect_charset_1(<<16#3C, 16#3F>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); +detect_charset_1(<<16#3C, 16#3F, 16#78>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); +detect_charset_1(<<16#3C, 16#3F, 16#78, 16#6D>> = Xml, State) -> + cf(Xml, State, fun detect_charset_1/2); +detect_charset_1(<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml2/binary>>, State) -> + {Xml3, State1} = read_until_end_of_xml_directive(Xml2, State), + case parse_xml_directive(Xml3) of {error, Reason} -> - {error, Reason}; + ?fatal_error(State, Reason); AttrList -> case lists:keysearch("encoding", 1, AttrList) of {value, {_, E}} -> case convert_encoding(E) of {error, Reason} -> - {error, Reason}; + ?fatal_error(State, Reason); Enc -> - {Xml, State#xmerl_sax_parser_state{encoding=Enc}} + {<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml3/binary>>, + State1#xmerl_sax_parser_state{encoding=Enc}} end; _ -> - {Xml, State} + {<<16#3C, 16#3F, 16#78, 16#6D, 16#6C, Xml3/binary>>, State1} end end; detect_charset_1(Xml, State) -> @@ -377,7 +393,7 @@ parse_value_1(<<C, Rest/binary>>, Stop, Acc) -> parse_value_1(Rest, Stop, [C |Acc]). %%====================================================================== -%%Default functions +%% Default functions %%====================================================================== %%---------------------------------------------------------------------- %% Function: default_event_cb(Event, LineNo, State) -> Result @@ -393,7 +409,7 @@ default_event_cb(_Event, _LineNo, State) -> %%---------------------------------------------------------------------- %% Function: default_continuation_cb(IoDevice) -> Result %% IoDevice = iodevice() -%% Output: Result = {[char()], State} +%% Output: Result = {binary(), IoDevice} %% Description: Default continuation callback reading blocks. %%---------------------------------------------------------------------- default_continuation_cb(IoDevice) -> @@ -403,3 +419,82 @@ default_continuation_cb(IoDevice) -> {ok, FileBin} -> {FileBin, IoDevice} end. + +%%---------------------------------------------------------------------- +%% Function: read_until_end_of_xml_directive(Rest, State) -> Result +%% Rest = binary() +%% Output: Result = {binary(), State} +%% Description: Reads a utf8 or latin1 until it finds '?>' +%%---------------------------------------------------------------------- +read_until_end_of_xml_directive(Rest, State) -> + case binary:match(Rest, <<"?>">>) of + nomatch -> + case cf(Rest, State) of + {<<>>, _} -> + ?fatal_error(State, "Can't detect character encoding due to lack of indata"); + {NewBytes, NewState} -> + read_until_end_of_xml_directive(NewBytes, NewState) + end; + _ -> + {Rest, State} + end. + + +%%---------------------------------------------------------------------- +%% Function : cf(Rest, State) -> Result +%% Parameters: Rest = binary() +%% State = #xmerl_sax_parser_state{} +%% NextCall = fun() +%% Result : {Rest, State} +%% Description: Function that uses provided fun to read another chunk from +%% input stream and calls the fun in NextCall. +%%---------------------------------------------------------------------- +cf(_Rest, #xmerl_sax_parser_state{continuation_fun = undefined} = State) -> + ?fatal_error(State, "Continuation function undefined"); +cf(Rest, #xmerl_sax_parser_state{continuation_fun = CFun, continuation_state = CState} = State) -> + Result = + try + CFun(CState) + catch + throw:ErrorTerm -> + ?fatal_error(State, ErrorTerm); + exit:Reason -> + ?fatal_error(State, {'EXIT', Reason}) + end, + case Result of + {<<>>, _} -> + ?fatal_error(State, "Can't detect character encoding due to lack of indata"); + {NewBytes, NewContState} -> + {<<Rest/binary, NewBytes/binary>>, + State#xmerl_sax_parser_state{continuation_state = NewContState}} + end. + +%%---------------------------------------------------------------------- +%% Function : cf(Rest, State, NextCall) -> Result +%% Parameters: Rest = binary() +%% State = #xmerl_sax_parser_state{} +%% NextCall = fun() +%% Result : {Rest, State} +%% Description: Function that uses provided fun to read another chunk from +%% input stream and calls the fun in NextCall. +%%---------------------------------------------------------------------- +cf(_Rest, #xmerl_sax_parser_state{continuation_fun = undefined} = State, _) -> + ?fatal_error(State, "Continuation function undefined"); +cf(Rest, #xmerl_sax_parser_state{continuation_fun = CFun, continuation_state = CState} = State, + NextCall) -> + Result = + try + CFun(CState) + catch + throw:ErrorTerm -> + ?fatal_error(State, ErrorTerm); + exit:Reason -> + ?fatal_error(State, {'EXIT', Reason}) + end, + case Result of + {<<>>, _} -> + ?fatal_error(State, "Can't detect character encoding due to lack of indata"); + {NewBytes, NewContState} -> + NextCall(<<Rest/binary, NewBytes/binary>>, + State#xmerl_sax_parser_state{continuation_state = NewContState}) + end. diff --git a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc index f3470b2809..1dca9608cb 100644 --- a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc +++ b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc @@ -64,38 +64,42 @@ %% Description: Parsing XML from input stream. %%---------------------------------------------------------------------- parse(Xml, State) -> - RefTable = ets:new(xmerl_sax_entity_refs, [private]), - - State1 = event_callback(startDocument, State), - - case catch parse_document(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of - {ok, Rest, State2} -> - State3 = event_callback(endDocument, State2), - ets:delete(RefTable), - case check_if_rest_ok(State3#xmerl_sax_parser_state.input_type, Rest) of - true -> - {ok, State3#xmerl_sax_parser_state.event_state, Rest}; - false -> - format_error(fatal_error, State3, "Input found after legal document") - end; - {fatal_error, {State2, Reason}} -> - State3 = event_callback(endDocument, State2), - ets:delete(RefTable), - format_error(fatal_error, State3, Reason); - {event_receiver_error, State2, {Tag, Reason}} -> - State3 = event_callback(endDocument, State2), - ets:delete(RefTable), - format_error(Tag, State3, Reason); - {endDocument, Rest, State2} -> - State3 = event_callback(endDocument, State2), - ets:delete(RefTable), - {ok, State3#xmerl_sax_parser_state.event_state, Rest}; - Other -> - _State2 = event_callback(endDocument, State1), - ets:delete(RefTable), - {fatal_error, Other} + RefTable = maps:new(), + + try + State1 = event_callback(startDocument, State), + Result = parse_document(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}), + handle_end_document(Result) + catch + throw:Exception -> + handle_end_document(Exception); + _:OtherError -> + handle_end_document({other, OtherError, State}) end. + % case catch parse_document(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of + % {ok, Rest, State2} -> + % State3 = event_callback(endDocument, State2), + % case check_if_rest_ok(State3#xmerl_sax_parser_state.input_type, Rest) of + % true -> + % {ok, State3#xmerl_sax_parser_state.event_state, Rest}; + % false -> + % format_error(fatal_error, State3, "Input found after legal document") + % end; + % {fatal_error, {State2, Reason}} -> + % State3 = event_callback(endDocument, State2), + % format_error(fatal_error, State3, Reason); + % {event_receiver_error, State2, {Tag, Reason}} -> + % State3 = event_callback(endDocument, State2), + % format_error(Tag, State3, Reason); + % {endDocument, Rest, State2} -> + % State3 = event_callback(endDocument, State2), + % {ok, State3#xmerl_sax_parser_state.event_state, Rest}; + % Other -> + % _State2 = event_callback(endDocument, State1), + % {fatal_error, Other} + % end. + %%---------------------------------------------------------------------- %% Function: parse_dtd(Xml, State) -> Result %% Input: Xml = string() | binary() @@ -105,38 +109,120 @@ parse(Xml, State) -> %% Description: Parsing XML DTD from input stream. %%---------------------------------------------------------------------- parse_dtd(Xml, State) -> - RefTable = ets:new(xmerl_sax_entity_refs, [private]), - - State1 = event_callback(startDocument, State), - - case catch parse_external_entity_1(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of - {fatal_error, {State2, Reason}} -> - State3 = event_callback(endDocument, State2), - ets:delete(RefTable), - format_error(fatal_error, State3, Reason); - {event_receiver_error, State2, {Tag, Reason}} -> - State3 = event_callback(endDocument, State2), - format_error(Tag, State3, Reason); - {Rest, State2} when is_record(State2, xmerl_sax_parser_state) -> - State3 = event_callback(endDocument, State2), - ets:delete(RefTable), - {ok, State3#xmerl_sax_parser_state.event_state, Rest}; - {endDocument, Rest, State2} when is_record(State2, xmerl_sax_parser_state) -> - State3 = event_callback(endDocument, State2), - ets:delete(RefTable), - {ok, State3#xmerl_sax_parser_state.event_state, Rest}; - Other -> - _State2 = event_callback(endDocument, State1), - ets:delete(RefTable), - {fatal_error, Other} + RefTable = maps:new(), + + try + State1 = event_callback(startDocument, State), + Result = parse_external_entity_1(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}), + handle_end_document(Result) + catch + throw:Exception -> + handle_end_document(Exception); + _:OtherError -> + handle_end_document({other, OtherError, State}) end. + % case catch parse_external_entity_1(Xml, State1#xmerl_sax_parser_state{ref_table=RefTable}) of + % {fatal_error, {State2, Reason}} -> + % State3 = event_callback(endDocument, State2), + % format_error(fatal_error, State3, Reason); + % {event_receiver_error, State2, {Tag, Reason}} -> + % State3 = event_callback(endDocument, State2), + % format_error(Tag, State3, Reason); + % {Rest, State2} when is_record(State2, xmerl_sax_parser_state) -> + % State3 = event_callback(endDocument, State2), + % {ok, State3#xmerl_sax_parser_state.event_state, Rest}; + % {endDocument, Rest, State2} when is_record(State2, xmerl_sax_parser_state) -> + % State3 = event_callback(endDocument, State2), + % {ok, State3#xmerl_sax_parser_state.event_state, Rest}; + % Other -> + % _State2 = event_callback(endDocument, State1), + % {fatal_error, Other} + % end. + + %%====================================================================== %% Internal functions %%====================================================================== %%---------------------------------------------------------------------- +%% Function: handle_end_document(ParserResult) -> Result +%% Input: ParseResult = term() +%% Output: Result = {ok, Rest, EventState} | +%% EventState = term() +%% Description: Ends the parsing and formats output +%%---------------------------------------------------------------------- +handle_end_document({ok, Rest, State}) -> + %%ok case from parse + try + State1 = event_callback(endDocument, State), + case check_if_rest_ok(State1#xmerl_sax_parser_state.input_type, Rest) of + true -> + {ok, State1#xmerl_sax_parser_state.event_state, Rest}; + false -> + format_error(fatal_error, State1, "Input found after legal document") + end + catch + throw:{event_receiver_error, State2, {Tag, Reason}} -> + format_error(Tag, State2, Reason); + _:Other -> + {fatal_error, Other} + end; +handle_end_document({endDocument, Rest, State}) -> + %% ok case from parse and parse_dtd + try + State1 = event_callback(endDocument, State), + {ok, State1#xmerl_sax_parser_state.event_state, Rest} + catch + throw:{event_receiver_error, State2, {Tag, Reason}} -> + format_error(Tag, State2, Reason); + _:Other -> + {fatal_error, Other} + end; +handle_end_document({fatal_error, {State, Reason}}) -> + try + State1 = event_callback(endDocument, State), + format_error(fatal_error, State1, Reason) + catch + throw:{event_receiver_error, State2, {Tag, Reason}} -> + format_error(Tag, State2, Reason); + _:Other -> + {fatal_error, Other} + end; +handle_end_document({event_receiver_error, State, {Tag, Reason}}) -> + try + State1 = event_callback(endDocument, State), + format_error(Tag, State1, Reason) + catch + throw:{event_receiver_error, State2, {Tag, Reason}} -> + format_error(Tag, State2, Reason); + _:Other -> + {fatal_error, Other} + end; +handle_end_document({Rest, State}) when is_record(State, xmerl_sax_parser_state) -> + %%ok case from parse_dtd + try + State1 = event_callback(endDocument, State), + {ok, State1#xmerl_sax_parser_state.event_state, Rest} + catch + throw:{event_receiver_error, State2, {Tag, Reason}} -> + format_error(Tag, State2, Reason); + _:Other -> + {fatal_error, Other} + end; +handle_end_document({other, Error, State}) -> + try + _State1 = event_callback(endDocument, State), + {fatal_error, Error} + catch + throw:{event_receiver_error, State2, {Tag, Reason}} -> + format_error(Tag, State2, Reason); + _:Other -> + {fatal_error, Other} + end. + +%%---------------------------------------------------------------------- %% Function: parse_document(Rest, State) -> Result %% Input: Rest = string() | binary() %% State = #xmerl_sax_parser_state{} @@ -439,6 +525,7 @@ check_if_rest_ok(stream, _) -> check_if_rest_ok(_, _) -> false. + %%---------------------------------------------------------------------- %% Function: parse_pi_1(Rest, State) -> Result %% Input: Rest = string() | binary() @@ -883,11 +970,11 @@ send_end_prefix_mapping_event([{Prefix, _Uri} |Ns], State) -> parse_eq(?STRING_EMPTY, State) -> cf(?STRING_EMPTY, State, fun parse_eq/2); parse_eq(?STRING_REST("=", Rest), State) -> - {Rest, State}; + {Rest, State}; parse_eq(?STRING_UNBOUND_REST(C, _) = Bytes, State) when ?is_whitespace(C) -> - {_WS, Rest, State1} = - whitespace(Bytes, State, []), - parse_eq(Rest, State1); + {_WS, Rest, State1} = + whitespace(Bytes, State, []), + parse_eq(Rest, State1); parse_eq(Bytes, State) -> unicode_incomplete_check([Bytes, State, fun parse_eq/2], "expecting = or whitespace"). @@ -905,11 +992,11 @@ parse_eq(Bytes, State) -> parse_att_value(?STRING_EMPTY, State) -> cf(?STRING_EMPTY, State, fun parse_att_value/2); parse_att_value(?STRING_UNBOUND_REST(C, Rest), State) when C == $'; C == $" -> - parse_att_value(Rest, State, C, []); + parse_att_value(Rest, State, C, []); parse_att_value(?STRING_UNBOUND_REST(C, _) = Bytes, State) when ?is_whitespace(C) -> - {_WS, Rest, State1} = - whitespace(Bytes, State, []), - parse_att_value(Rest, State1); + {_WS, Rest, State1} = + whitespace(Bytes, State, []), + parse_att_value(Rest, State1); parse_att_value(Bytes, State) -> unicode_incomplete_check([Bytes, State, fun parse_att_value/2], "\', \" or whitespace expected"). @@ -1360,17 +1447,20 @@ parse_pe_reference_1(Bytes, State, Name) -> %%---------------------------------------------------------------------- -%% Function: insert_reference(Reference, State) -> Result -%% Parameters: Reference = string() +%% Function: insert_reference(Name, Ref, State) -> Result +%% Parameters: Name = string() +%% Ref = {Type, Value} +%% Type = atom() +%% Value = term() %% State = #xmerl_sax_parser_state{} %% Result : %%---------------------------------------------------------------------- -insert_reference({Name, Type, Value}, Table) -> - case ets:lookup(Table, Name) of - [{Name, _, _}] -> - ok; +insert_reference(Name, Value, #xmerl_sax_parser_state{ref_table = Map} = State) -> + case maps:find(Name, Map) of + error -> + State#xmerl_sax_parser_state{ref_table = maps:put(Name, Value, Map)}; _ -> - ets:insert(Table, {Name, Type, Value}) + State end. @@ -1391,8 +1481,8 @@ look_up_reference("apos", _, _) -> look_up_reference("quot", _, _) -> {internal_general, "quot", "\""}; look_up_reference(Name, HaveToExist, State) -> - case ets:lookup(State#xmerl_sax_parser_state.ref_table, Name) of - [{Name, Type, Value}] -> + case maps:find(Name, State#xmerl_sax_parser_state.ref_table) of + {ok, {Type, Value}} -> {Type, Name, Value}; _ -> case HaveToExist of @@ -1474,7 +1564,7 @@ parse_system_litteral(?STRING_EMPTY, State, Stop, Acc) -> parse_system_litteral(?STRING_UNBOUND_REST(Stop, Rest), State, Stop, Acc) -> {lists:reverse(Acc), Rest, State}; parse_system_litteral(?STRING_UNBOUND_REST(C, Rest), State, Stop, Acc) -> - parse_system_litteral(Rest, State, Stop, [C |Acc]); + parse_system_litteral(Rest, State, Stop, [C |Acc]); parse_system_litteral(Bytes, State, Stop, Acc) -> unicode_incomplete_check([Bytes, State, Stop, Acc, fun parse_system_litteral/4], undefined). @@ -1646,9 +1736,11 @@ parse_external_entity(State, _PubId, SysId) -> end_tags = []}, - EventState = handle_external_entity(ExtRef, State1), + {EventState, RefTable} = handle_external_entity(ExtRef, State1), - NewState = event_callback({endEntity, SysId}, SaveState#xmerl_sax_parser_state{event_state=EventState}), + NewState = event_callback({endEntity, SysId}, + SaveState#xmerl_sax_parser_state{event_state=EventState, + ref_table=RefTable}), NewState#xmerl_sax_parser_state{file_type=normal}. @@ -1675,7 +1767,8 @@ handle_external_entity({file, FileToOpen}, State) -> entity=filename:basename(FileToOpen), input_type=file}), ok = file:close(FD), - EntityState#xmerl_sax_parser_state.event_state + {EntityState#xmerl_sax_parser_state.event_state, + EntityState#xmerl_sax_parser_state.ref_table} end; handle_external_entity({http, Url}, State) -> @@ -1695,7 +1788,9 @@ handle_external_entity({http, Url}, State) -> input_type=file}), ok = file:close(FD), ok = file:delete(TmpFile), - EntityState#xmerl_sax_parser_state.event_state + {EntityState#xmerl_sax_parser_state.event_state, + EntityState#xmerl_sax_parser_state.ref_table} + end catch throw:{error, Error} -> @@ -1716,7 +1811,7 @@ handle_external_entity({Tag, _Url}, State) -> parse_external_entity_1(?STRING_EMPTY, #xmerl_sax_parser_state{file_type=Type} = State) -> case catch cf(?STRING_EMPTY, State, fun parse_external_entity_1/2) of {Rest, State1} when is_record(State1, xmerl_sax_parser_state) -> - {Rest, State}; + {Rest, State1}; {fatal_error, {State1, "No more bytes"}} when Type == dtd; Type == entity -> {?STRING_EMPTY, State1}; Other -> @@ -2442,24 +2537,24 @@ parse_entity_def(?STRING_EMPTY, State, Name) -> cf(?STRING_EMPTY, State, Name, fun parse_entity_def/3); parse_entity_def(?STRING_UNBOUND_REST(C, Rest), State, Name) when C == $'; C == $" -> {Value, Rest1, State1} = parse_entity_value(Rest, State, C, []), - insert_reference({Name, internal_general, Value}, State1#xmerl_sax_parser_state.ref_table), - State2 = event_callback({internalEntityDecl, Name, Value}, State1), - {_WS, Rest2, State3} = whitespace(Rest1, State2, []), - parse_def_end(Rest2, State3); + State2 = insert_reference(Name, {internal_general, Value}, State1), + State3 = event_callback({internalEntityDecl, Name, Value}, State2), + {_WS, Rest2, State4} = whitespace(Rest1, State3, []), + parse_def_end(Rest2, State4); parse_entity_def(?STRING_UNBOUND_REST(C, _) = Rest, State, Name) when C == $S; C == $P -> {PubId, SysId, Rest1, State1} = parse_external_id(Rest, State, false), {Ndata, Rest2, State2} = parse_ndata(Rest1, State1), case Ndata of undefined -> - insert_reference({Name, external_general, {PubId, SysId}}, - State2#xmerl_sax_parser_state.ref_table), - State3 = event_callback({externalEntityDecl, Name, PubId, SysId}, State2), - {Rest2, State3}; + State3 = insert_reference(Name, {external_general, {PubId, SysId}}, + State2), + State4 = event_callback({externalEntityDecl, Name, PubId, SysId}, State3), + {Rest2, State4}; _ -> - insert_reference({Name, unparsed, {PubId, SysId, Ndata}}, - State2#xmerl_sax_parser_state.ref_table), - State3 = event_callback({unparsedEntityDecl, Name, PubId, SysId, Ndata}, State2), - {Rest2, State3} + State3 = insert_reference(Name, {unparsed, {PubId, SysId, Ndata}}, + State2), + State4 = event_callback({unparsedEntityDecl, Name, PubId, SysId, Ndata}, State3), + {Rest2, State4} end; parse_entity_def(Bytes, State, Name) -> unicode_incomplete_check([Bytes, State, Name, fun parse_entity_def/3], @@ -2636,19 +2731,19 @@ parse_pe_def(?STRING_EMPTY, State, Name) -> parse_pe_def(?STRING_UNBOUND_REST(C, Rest), State, Name) when C == $'; C == $" -> {Value, Rest1, State1} = parse_entity_value(Rest, State, C, []), Name1 = "%" ++ Name, - insert_reference({Name1, internal_parameter, Value}, - State1#xmerl_sax_parser_state.ref_table), - State2 = event_callback({internalEntityDecl, Name1, Value}, State1), - {_WS, Rest2, State3} = whitespace(Rest1, State2, []), - parse_def_end(Rest2, State3); + State2 = insert_reference(Name1, {internal_parameter, Value}, + State1), + State3 = event_callback({internalEntityDecl, Name1, Value}, State2), + {_WS, Rest2, State4} = whitespace(Rest1, State3, []), + parse_def_end(Rest2, State4); parse_pe_def(?STRING_UNBOUND_REST(C, _) = Bytes, State, Name) when C == $S; C == $P -> {PubId, SysId, Rest1, State1} = parse_external_id(Bytes, State, false), Name1 = "%" ++ Name, - insert_reference({Name1, external_parameter, {PubId, SysId}}, - State1#xmerl_sax_parser_state.ref_table), - State2 = event_callback({externalEntityDecl, Name1, PubId, SysId}, State1), - {_WS, Rest2, State3} = whitespace(Rest1, State2, []), - parse_def_end(Rest2, State3); + State2 = insert_reference(Name1, {external_parameter, {PubId, SysId}}, + State1), + State3 = event_callback({externalEntityDecl, Name1, PubId, SysId}, State2), + {_WS, Rest2, State4} = whitespace(Rest1, State3, []), + parse_def_end(Rest2, State4); parse_pe_def(Bytes, State, Name) -> unicode_incomplete_check([Bytes, State, Name, fun parse_pe_def/3], "\", \', SYSTEM or PUBLIC expected"). diff --git a/lib/xmerl/src/xmerl_sax_simple_dom.erl b/lib/xmerl/src/xmerl_sax_simple_dom.erl index 7eb3afd499..d842bd982b 100644 --- a/lib/xmerl/src/xmerl_sax_simple_dom.erl +++ b/lib/xmerl/src/xmerl_sax_simple_dom.erl @@ -129,8 +129,9 @@ build_dom(endDocument, State#xmerl_sax_simple_dom_state{dom=[Decl, {Tag, Attributes, lists:reverse(Content)}]}; _ -> - ?dbg("~p\n", [D]), - ?error("we're not at end the document when endDocument event is encountered.") + %% endDocument is also sent by the parser when a fault occur to tell + %% the event receiver that no more input will be sent + State end; %% Element diff --git a/lib/xmerl/test/Makefile b/lib/xmerl/test/Makefile index e5c89f84b9..3204f081ba 100644 --- a/lib/xmerl/test/Makefile +++ b/lib/xmerl/test/Makefile @@ -126,5 +126,6 @@ release_tests_spec: opt @tar cfh - xmerl_xsd_MS2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) @tar cfh - xmerl_xsd_NIST2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) @tar cfh - xmerl_xsd_Sun2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + @tar cfh - xmerl_sax_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) @tar cfh - xmerl_sax_stream_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) chmod -R u+w "$(RELSYSDIR)" diff --git a/lib/xmerl/test/xmerl_sax_SUITE.erl b/lib/xmerl/test/xmerl_sax_SUITE.erl index eb9cefe0df..68b9bcc4a2 100644 --- a/lib/xmerl/test/xmerl_sax_SUITE.erl +++ b/lib/xmerl/test/xmerl_sax_SUITE.erl @@ -33,7 +33,6 @@ %%====================================================================== %% External functions %%====================================================================== - %%---------------------------------------------------------------------- %% Initializations %%---------------------------------------------------------------------- @@ -42,12 +41,15 @@ all() -> [{group, bugs}]. groups() -> - [{bugs, [], [ticket_8213, ticket_8214, ticket_11551]}]. + [{bugs, [], [ticket_8213, ticket_8214, ticket_11551, + fragmented_xml_directive, + old_dom_event_fun_endDocument_bug, + event_fun_endDocument_error_test, + event_fun_startDocument_error_test]}]. -%%---------------------------------------------------------------------- +%%====================================================================== %% Tests -%%---------------------------------------------------------------------- - +%%====================================================================== %%---------------------------------------------------------------------- %% Test Case %% ID: ticket_8213 @@ -56,7 +58,6 @@ ticket_8213(_Config) -> {ok,ok,[]} = xmerl_sax_parser:stream("<elem/>", [{event_fun, fun (_E,_,_) -> ok end}]), ok. - %%---------------------------------------------------------------------- %% Test Case %% ID: ticket_8214 @@ -99,3 +100,66 @@ ticket_11551(_Config) -> <a>hej</a>">>, {ok, undefined, <<"\n\n<?xml", _/binary>>} = xmerl_sax_parser:stream(Stream3, []), ok. + +%%---------------------------------------------------------------------- +%% Test Case +%% ID: fragmented_xml_directive +%% Test of fragmented xml directive by reading one byte per continuation ca +fragmented_xml_directive(Config) -> + DataDir = proplists:get_value(data_dir, Config), + Name = filename:join(DataDir, "test_data_1.xml"), + {ok, Fd} = file:open(Name, [raw, read,binary]), + Cf = fun cf_fragmented_xml_directive/1, + {ok, undefined, _} = xmerl_sax_parser:stream(<<>>, + [{continuation_fun, Cf}, + {continuation_state, Fd}]), + ok. + +%%---------------------------------------------------------------------- +%% Test Case +%% ID: old_dom_event_fun_endDocument_bug +%% The old_dom backend previous generateded an uncatched exception +%% instead of the correct fatal_error from the parser. +old_dom_event_fun_endDocument_bug(_Config) -> + %% Stream contains bad characters, + {fatal_error, _, _, _, _} = + xmerl_sax_parser:stream([60,63,120,109,108,32,118,101,114,115,105,111,110,61,39,49,46,48,39,32,101,110,99,111,100,105,110,103,61,39,117,116,102,45,56,39,63,62,60, + 99,111,109,109,97,110,100,62,60,104,101,97,100,101,114,62,60,116,114,97,110,115,97,99,116,105,111,110,73,100,62,49,60,47,116,114,97,110, + 115,97,99,116,105,111,110,73,100,62,60,47,104,101,97,100,101,114,62,60,98,111,100,121,62,95,226,130,172,59,60,60,47,98,111,100,121,62,60, + 47,99,111,109,109,97,110,100,62,60,47,120,49,95,49,62], + [{event_fun,fun xmerl_sax_old_dom:event/3}, + {event_state,xmerl_sax_old_dom:initial_state()}]), + ok. + +%%---------------------------------------------------------------------- +%% Test Case +%% ID: event_fun_endDocument_error_test +event_fun_endDocument_error_test(_Config) -> + Stream = <<"<?xml version=\"1.0\" encoding=\"utf-8\"?><a>hej</a>">>, + Ef = fun(endDocument, _ , _) -> throw({event_error, "endDocument error"}); + (_, _, S) -> S + end, + {event_error, _, _, _, _} = xmerl_sax_parser:stream(Stream, [{event_fun, Ef}]), + ok. + +%%---------------------------------------------------------------------- +%% Test Case +%% ID: event_fun_startDocument_error_test +event_fun_startDocument_error_test(_Config) -> + Stream = <<"<?xml version=\"1.0\" encoding=\"utf-8\"?><a>hej</a>">>, + Ef = fun(startDocument, _ , _) -> throw({event_error, "endDocument error"}); + (_, _, S) -> S + end, + {event_error, _, _, _, _} = xmerl_sax_parser:stream(Stream, [{event_fun, Ef}]), + ok. + +%%====================================================================== +%% Internal functions +%%====================================================================== +cf_fragmented_xml_directive(IoDevice) -> + case file:read(IoDevice, 1) of + eof -> + {<<>>, IoDevice}; + {ok, FileBin} -> + {FileBin, IoDevice} + end. diff --git a/lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml b/lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml new file mode 100644 index 0000000000..efbaee6b81 --- /dev/null +++ b/lib/xmerl/test/xmerl_sax_SUITE_data/test_data_1.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<a> +Hej +</a> diff --git a/lib/xmerl/test/xmerl_sax_stream_SUITE.erl b/lib/xmerl/test/xmerl_sax_stream_SUITE.erl index a306eb66a2..7315f67374 100644 --- a/lib/xmerl/test/xmerl_sax_stream_SUITE.erl +++ b/lib/xmerl/test/xmerl_sax_stream_SUITE.erl @@ -40,7 +40,8 @@ all() -> [ one_document, two_documents, - one_document_and_junk + one_document_and_junk, + end_of_stream ]. %%---------------------------------------------------------------------- @@ -62,6 +63,9 @@ end_per_testcase(_Func, _Config) -> %%---------------------------------------------------------------------- %% Tests %%---------------------------------------------------------------------- + +%%---------------------------------------------------------------------- +%% Send One doc over stream one_document(Config) -> Port = 11111, @@ -107,6 +111,8 @@ one_document(Config) -> end, ok. +%%---------------------------------------------------------------------- +%% Send Two doc over stream two_documents(Config) -> Port = 11111, @@ -152,6 +158,8 @@ two_documents(Config) -> end, ok. +%%---------------------------------------------------------------------- +%% Send one doc and then junk on stream one_document_and_junk(Config) -> Port = 11111, @@ -196,6 +204,13 @@ one_document_and_junk(Config) -> ct:fail("Timeout") end, ok. + +%%---------------------------------------------------------------------- +%% Test of continuation when end of stream +end_of_stream(Config) -> + Stream = <<"<?xml version=\"1.0\" encoding=\"utf-8\"?><a>hej</a>">>, + {ok, undefined, <<>>} = xmerl_sax_parser:stream(Stream, []), + ok. %%---------------------------------------------------------------------- %% Utility functions diff --git a/otp_versions.table b/otp_versions.table index 1e94dcee88..e86ace6e02 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,4 +1,4 @@ -OTP-20.0 : asn1-5.0 common_test-1.15 compiler-7.1 cosProperty-1.2.2 crypto-4.0 debugger-4.2.2 dialyzer-3.2 edoc-0.9 erl_docgen-0.7 erl_interface-3.10 erts-9.0 eunit-2.3.3 hipe-3.16 inets-6.4 jinterface-1.8 kernel-5.3 megaco-3.18.2 mnesia-4.15 observer-2.4 orber-3.8.3 parsetools-2.1.5 public_key-1.4.1 reltool-0.7.4 runtime_tools-1.12 sasl-3.0.4 snmp-5.2.6 ssh-4.5 ssl-8.2 stdlib-3.4 syntax_tools-2.1.2 tools-2.10 wx-1.8.1 xmerl-1.3.14 # cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 diameter-1.12.2 eldap-1.2.2 et-1.6 ic-4.4.2 odbc-2.12 os_mon-2.4.2 otp_mibs-1.1.1 : +OTP-19.3.5 : erts-8.3.4 xmerl-1.3.14 # asn1-4.0.4 common_test-1.14 compiler-7.0.4 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.4 debugger-4.2.1 dialyzer-3.1.1 diameter-1.12.2 edoc-0.8.1 eldap-1.2.2 erl_docgen-0.6.1 erl_interface-3.9.3 et-1.6 eunit-2.3.2 gs-1.6.2 hipe-3.15.4 ic-4.4.2 inets-6.3.9 jinterface-1.7.1 kernel-5.2 megaco-3.18.1 mnesia-4.14.3 observer-2.3.1 odbc-2.12 orber-3.8.2 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.4 percept-0.9 public_key-1.4 reltool-0.7.3 runtime_tools-1.11.1 sasl-3.0.3 snmp-5.2.5 ssh-4.4.2 ssl-8.1.3 stdlib-3.3 syntax_tools-2.1.1 tools-2.9.1 typer-0.9.12 wx-1.8 : OTP-19.3.4 : inets-6.3.9 ssl-8.1.3 # asn1-4.0.4 common_test-1.14 compiler-7.0.4 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.4 debugger-4.2.1 dialyzer-3.1.1 diameter-1.12.2 edoc-0.8.1 eldap-1.2.2 erl_docgen-0.6.1 erl_interface-3.9.3 erts-8.3.3 et-1.6 eunit-2.3.2 gs-1.6.2 hipe-3.15.4 ic-4.4.2 jinterface-1.7.1 kernel-5.2 megaco-3.18.1 mnesia-4.14.3 observer-2.3.1 odbc-2.12 orber-3.8.2 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.4 percept-0.9 public_key-1.4 reltool-0.7.3 runtime_tools-1.11.1 sasl-3.0.3 snmp-5.2.5 ssh-4.4.2 stdlib-3.3 syntax_tools-2.1.1 tools-2.9.1 typer-0.9.12 wx-1.8 xmerl-1.3.13 : OTP-19.3.3 : dialyzer-3.1.1 erts-8.3.3 inets-6.3.8 # asn1-4.0.4 common_test-1.14 compiler-7.0.4 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.4 debugger-4.2.1 diameter-1.12.2 edoc-0.8.1 eldap-1.2.2 erl_docgen-0.6.1 erl_interface-3.9.3 et-1.6 eunit-2.3.2 gs-1.6.2 hipe-3.15.4 ic-4.4.2 jinterface-1.7.1 kernel-5.2 megaco-3.18.1 mnesia-4.14.3 observer-2.3.1 odbc-2.12 orber-3.8.2 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.4 percept-0.9 public_key-1.4 reltool-0.7.3 runtime_tools-1.11.1 sasl-3.0.3 snmp-5.2.5 ssh-4.4.2 ssl-8.1.2 stdlib-3.3 syntax_tools-2.1.1 tools-2.9.1 typer-0.9.12 wx-1.8 xmerl-1.3.13 : OTP-19.3.2 : erts-8.3.2 # asn1-4.0.4 common_test-1.14 compiler-7.0.4 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.4 debugger-4.2.1 dialyzer-3.1 diameter-1.12.2 edoc-0.8.1 eldap-1.2.2 erl_docgen-0.6.1 erl_interface-3.9.3 et-1.6 eunit-2.3.2 gs-1.6.2 hipe-3.15.4 ic-4.4.2 inets-6.3.7 jinterface-1.7.1 kernel-5.2 megaco-3.18.1 mnesia-4.14.3 observer-2.3.1 odbc-2.12 orber-3.8.2 os_mon-2.4.2 otp_mibs-1.1.1 parsetools-2.1.4 percept-0.9 public_key-1.4 reltool-0.7.3 runtime_tools-1.11.1 sasl-3.0.3 snmp-5.2.5 ssh-4.4.2 ssl-8.1.2 stdlib-3.3 syntax_tools-2.1.1 tools-2.9.1 typer-0.9.12 wx-1.8 xmerl-1.3.13 : |