diff options
author | Rickard Green <[email protected]> | 2010-09-01 15:55:19 +0200 |
---|---|---|
committer | Rickard Green <[email protected]> | 2010-09-01 15:55:19 +0200 |
commit | 9ec4e178b59ded6cd8bf420d7ed0e0ef1178a168 (patch) | |
tree | d92c857e67e1d4cb45ef79a3881267b93dcb7c70 /erts/emulator/beam | |
parent | 4690a4ebdb1bf201cae743a597dcfa74bb4fb587 (diff) | |
download | otp-9ec4e178b59ded6cd8bf420d7ed0e0ef1178a168.tar.gz otp-9ec4e178b59ded6cd8bf420d7ed0e0ef1178a168.tar.bz2 otp-9ec4e178b59ded6cd8bf420d7ed0e0ef1178a168.zip |
Fix crash when calling erlang:system_info(update_cpu_info)
Calling erlang:system_info(update_cpu_info) on platforms where no
CPU topology was found could result in a crash if other CPU
information had changed. This bug was introduced in the 'dev'
branch before R14B (commit 1b273b618002d65159453fdfb9520a9476e4423a).
That is, the bug has never been seen in a released runtime system.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/erl_process.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 761096e9ad..2609457415 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -4009,7 +4009,7 @@ signal_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size) int s_ix = 1; int cpu_ix; - if (cpu_bind_order != ERTS_CPU_BIND_NONE) { + if (cpu_bind_order != ERTS_CPU_BIND_NONE && size) { cpu_bind_order_sort(cpudata, size, cpu_bind_order, 1); @@ -5523,7 +5523,6 @@ late_cpu_bind_init(void) erts_cpu_topology_t *cpudata; int cpudata_size; create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); - ASSERT(cpudata); signal_schedulers_bind_change(cpudata, cpudata_size); destroy_tmp_cpu_topology_copy(cpudata); } @@ -5538,23 +5537,29 @@ erts_update_cpu_info(void) if (changed) { erts_cpu_topology_t *cpudata; int cpudata_size; - erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); - - system_cpudata_size = erts_get_cpu_topology_size(erts_cpuinfo); - system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, - (sizeof(erts_cpu_topology_t) - * system_cpudata_size)); - if (!erts_get_cpu_topology(erts_cpuinfo, system_cpudata) - || ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(system_cpudata, - system_cpudata_size)) { + if (system_cpudata) erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); + + system_cpudata_size = erts_get_cpu_topology_size(erts_cpuinfo); + if (!system_cpudata_size) system_cpudata = NULL; - system_cpudata_size = 0; + else { + system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, + (sizeof(erts_cpu_topology_t) + * system_cpudata_size)); + + if (!erts_get_cpu_topology(erts_cpuinfo, system_cpudata) + || (ERTS_INIT_CPU_TOPOLOGY_OK + != verify_topology(system_cpudata, + system_cpudata_size))) { + erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); + system_cpudata = NULL; + system_cpudata_size = 0; + } } create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); - ASSERT(cpudata); signal_schedulers_bind_change(cpudata, cpudata_size); destroy_tmp_cpu_topology_copy(cpudata); } |