Segmentation fault when logistic_map_10_pelemaey(1..10)
zacky1972 opened this issue · 2 comments
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
Steps to reproduce the behavior:
- Use Pelemay in the source code
defmodule LogisticMap do
import Pelemay
defpelemay do
def logistic_map_10_pelemay(list) do
list
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
|> Enum.map(&rem(22 * &1 * (&1 + 1), 6_700_417))
end
end
end
- Run in the command
iex -S mix
and the following execution:
iex> LogisticMap.logistic_map_10_pelemay(1..10)
- See a segmantation fault.
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
CpuInfo.all_profile
%{
compiler: %{
apple_clang: [
%{
bin: "/usr/bin/clang",
type: :apple_clang,
version: "12.0.0",
versions: "Apple clang version 12.0.0 (clang-1200.0.32.28)"
}
],
"apple_clang++": [
%{
bin: "/usr/bin/clang++",
type: :"apple_clang++",
version: "12.0.0",
versions: "Apple clang version 12.0.0 (clang-1200.0.32.28)"
}
],
cc_env: [],
cflags_env: "",
clang: [
%{
bin: "/usr/bin/clang",
type: :apple_clang,
version: "12.0.0",
versions: "Apple clang version 12.0.0 (clang-1200.0.32.28)"
}
],
"clang++": [
%{
bin: "/usr/bin/clang++",
type: :"apple_clang++",
version: "12.0.0",
versions: "Apple clang version 12.0.0 (clang-1200.0.32.28)"
}
],
cxx_env: [],
cxxflags_env: "",
"g++": [
%{
bin: "/usr/bin/g++",
type: :"apple_clang++",
version: "12.0.0",
versions: "Apple clang version 12.0.0 (clang-1200.0.32.28)"
},
%{
bin: "/usr/local/bin/g++-5",
type: :"g++",
version: "5.5.0",
versions: "g++-5 (Homebrew GCC 5.5.0_6) 5.5.0"
}
],
gcc: [
%{
bin: "/usr/bin/gcc",
type: :apple_clang,
version: "12.0.0",
versions: "Apple clang version 12.0.0 (clang-1200.0.32.28)"
},
%{
bin: "/usr/local/bin/gcc-5",
type: :gcc,
version: "5.5.0",
versions: "gcc-5 (Homebrew GCC 5.5.0_6) 5.5.0"
}
],
ldflags_env: ""
},
cpu: %{
cpu_model: "6-Core Intel Core i5",
cpu_models: ["6-Core Intel Core i5"],
cpu_type: "x86_64",
hyper_threading: :disabled,
num_of_cores_of_a_processor: 6,
num_of_ecores: 0,
num_of_pcores: 0,
num_of_processors: 1,
num_of_threads_of_a_processor: 6,
os_type: :macos,
total_num_of_cores: 6,
total_num_of_threads: 6
},
cuda: %{cuda: false},
elixir: %{version: "1.11.3"},
erlang: %{otp_version: 23},
kernel: %{
kernel_release: "19.6.0",
kernel_version: "Darwin 19.6.0",
system_version: "macOS 10.15.7 (19H114)"
},
metal: %{metal: true}
}
Additional context
This error occurs even if v0.0.14.
If run the following on iex
, such a segmentation fault doesn't occur:
iex> LogisticMap.logistic_map_10_pelemay(1..16)
Hey there! I was looking into this a bit and believe there is not enough space being allocated for the internal vector holding the list.
Valgrind revealed the following:
==30428== 1 errors in context 1 of 35:
==30428== Thread 6 2_scheduler:
==30428== Invalid read of size 8
==30428== at 0x4B3245F0: map_elem1_plus_1_mult_1_mult_elem1_mod_6700413_kernel_i64 (map_elem1_plus_1_mult_1_mult_elem1_mod_6700413_kernel.c:25)
==30428== by 0x4B323DAF: map_elem1_plus_1_mult_1_mult_elem1_mod_6700413_yielding_nif (libnifelixirlogisticmap.c:597)
==30428== by 0x3909A0: execute_nif (erl_nif.c:3117)
==30428== by 0x188CA8: process_main (beam_cold.h:184)
==30428== by 0x1A53EE: sched_thread_func (erl_process.c:8486)
==30428== by 0x4B532C: thr_wrapper (ethread.c:122)
==30428== by 0x49E6608: start_thread (pthread_create.c:477)
==30428== by 0x4B22292: clone (clone.S:95)
==30428== Address 0x49044118 is 8 bytes after a block of size 64 alloc'd
==30428== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==30428== by 0x3C887D: erts_sys_alloc (sys.c:871)
==30428== by 0x388BB4: erts_alloc_fnf (erl_alloc.h:294)
==30428== by 0x38AD65: enif_alloc (erl_nif.c:529)
==30428== by 0x4B325649: enif_get_int64_vec_from_list (basic.c:80)
==30428== by 0x4B32396E: map_elem1_plus_1_mult_1_mult_elem1_mod_6700413_nif (libnifelixirlogisticmap.c:536)
==30428== by 0x188CA8: process_main (beam_cold.h:184)
==30428== by 0x1A53EE: sched_thread_func (erl_process.c:8486)
==30428== by 0x4B532C: thr_wrapper (ethread.c:122)
==30428== by 0x49E6608: start_thread (pthread_create.c:477)
==30428== by 0x4B22292: clone (clone.S:95)
In basic.c:80
the line is
size_t nn = CACHE_LINE_SIZE;
ErlNifSInt64 *t = (ErlNifSInt64 *)enif_alloc(nn);
Since t
is being used as an array below (&t[i++]
) is the sizeof()
function missing during the allocation?
I was playing around with something like this that seemed to clear the mem leaks.
Where length
is derived from enif_get_list_lengh
since *vec_l
might be NULL.
size_t nn = CACHE_LINE_SIZE;
ErlNifSInt64 *t = (ErlNifSInt64 *)enif_alloc(sizeof(ErlNifSInt64) * length);
I'd like to get your thoughts before moving forward with a PR :)