Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SIGSEGV in stl_iterator.h

64 views
Skip to first unread message

Jivanmukta

unread,
Mar 9, 2023, 5:18:34 AM3/9/23
to
When I run my program is VSCode, it shows:

Loaded '/lib/x86_64-linux-gnu/libstdc++.so.6'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libm.so.6'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libgcc_s.so.1'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libc.so.6'. Symbols loaded.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000428172 in
__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >*,
std::vector<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > >::__normal_iterator
(this=0x7fffffffca60, __i=<error reading variable>) at
/usr/include/c++/9/bits/stl_iterator.h:804
804 : _M_current(__i) { }
Execute debugger commands using "-exec <command>", for example "-exec
info registers" will list registers in use (when GDB is the debugger)


namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

// This iterator adapter is @a normal in the sense that it does not
// change the semantics of any of the operators of its iterator
// parameter. Its primary purpose is to convert an iterator that is
// not a class, e.g. a pointer, into an iterator that is a class.
// The _Container parameter exists solely so that different containers
// using this template can instantiate different types, even if the
// _Iterator parameter is the same.
using std::iterator_traits;
using std::iterator;
template<typename _Iterator, typename _Container>
class __normal_iterator
{
protected:
_Iterator _M_current;

typedef iterator_traits<_Iterator> __traits_type;

public:
typedef _Iterator iterator_type;
typedef typename __traits_type::iterator_category iterator_category;
typedef typename __traits_type::value_type value_type;
typedef typename __traits_type::difference_type difference_type;
typedef typename __traits_type::reference reference;
typedef typename __traits_type::pointer pointer;

_GLIBCXX_CONSTEXPR __normal_iterator() _GLIBCXX_NOEXCEPT
: _M_current(_Iterator()) { }

explicit
__normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPT
: _M_current(__i) { } // !!! HERE PROBLEM !!!

Paavo Helde

unread,
Mar 9, 2023, 7:11:59 AM3/9/23
to
09.03.2023 12:18 Jivanmukta kirjutas:
> When I run my program is VSCode, it shows:
>
> Loaded '/lib/x86_64-linux-gnu/libstdc++.so.6'. Symbols loaded.
> Loaded '/lib/x86_64-linux-gnu/libm.so.6'. Symbols loaded.
> Loaded '/lib/x86_64-linux-gnu/libgcc_s.so.1'. Symbols loaded.
> Loaded '/lib/x86_64-linux-gnu/libc.so.6'. Symbols loaded.
>
> Program received signal SIGSEGV, Segmentation fault.

The problem is in your code, find and fix it.

To help with that, you might want to enable the g++ STL debugging
features, by compiling all your C++ code with -D_GLIBCXX_DEBUG


Jivanmukta

unread,
Mar 9, 2023, 11:04:08 AM3/9/23
to
W dniu 9.03.2023 o 13:11, Paavo Helde pisze:
I have a problem when debugging.

TRACE("before insert");
identifiers[what].insert(identifiers[what].end(),
ids.begin(), ids.end());

TRACE is executed then SIGSEGV although I have a breakpoint at line with
insert.

Scott Lurndal

unread,
Mar 9, 2023, 11:44:28 AM3/9/23
to
Show your work What does the 'bt' command show? What does the
'info registers' command show? What does "x/i $pc" show?

Jivanmukta

unread,
Mar 9, 2023, 12:12:28 PM3/9/23
to
W dniu 9.03.2023 o 17:44, Scott Lurndal pisze:
I cannot see these. When I click Debugging Console tab I receive SIGSEGV
undepending where I have set a breakpoint.
I also have SIGSEGV after TRACE when I run my application from command
prompt, not VSCode.

Jivanmukta

unread,
Mar 9, 2023, 12:36:00 PM3/9/23
to
W dniu 9.03.2023 o 18:12, Jivanmukta pisze:
>> Show your work   What does the 'bt' command show?  What does the
>> 'info registers' command show?   What does "x/i $pc" show?
> I cannot see these. When I click Debugging Console tab I receive SIGSEGV
> undepending where I have set a breakpoint.
> I also have SIGSEGV after TRACE when I run my application from command
> prompt, not VSCode.

Could it be hardware problem, not with my application?

Jivanmukta

unread,
Mar 9, 2023, 12:41:28 PM3/9/23
to
W dniu 9.03.2023 o 18:35, Jivanmukta pisze:
> Could it be hardware problem, not with my application?

Probably not, because I can run my C++ program with different arguments.

Jivanmukta

unread,
Mar 9, 2023, 1:03:26 PM3/9/23
to
W dniu 9.03.2023 o 18:12, Jivanmukta pisze:
Question: how to TRACE values: identifiers[what].end(), ids.begin(),
ids.end()? I failed to cast them to unsigned long.

Scott Lurndal

unread,
Mar 9, 2023, 1:05:51 PM3/9/23
to
Well, there's your problem. VScode is a POS.

From the command line, prefix your application execution command
with the string 'gdb -q --args '.

When the sigsegv occurs, type
'bt'

which will produce a stack traceback.

'info registers'

will show the current register state at the time of the SIGSEGV

'x/i $pc'

will show the machine instruction that caused the SIGSEGV.

Look at the instruction to determine which register contains
the address, then check the 'info registers' output to see
what the address value is that caused the fault.

Scott Lurndal

unread,
Mar 9, 2023, 1:06:01 PM3/9/23
to
No.

Jivanmukta

unread,
Mar 9, 2023, 2:34:04 PM3/9/23
to
W dniu 9.03.2023 o 19:05, Scott Lurndal pisze:
(gdb) bt

#0 0x000000000043d68e in
__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >*,
std::__cxx1998::vector<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >,
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > > > >::__normal_iterator (this=0x7fffffffc1b0,
__i=<error reading variable>) at
/usr/include/c++/9/bits/stl_iterator.h:804
#1 0x000000000043a2aa in
std::__cxx1998::vector<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >,
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > > >::end (this=0x50) at
/usr/include/c++/9/bits/stl_vector.h:827
#2 0x0000000000436c09 in
std::__debug::vector<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >,
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > > >::end (this=0x38) at
/usr/include/c++/9/debug/vector:306
#3 0x00000000004488c3 in load_cache
(cache_filename="dirtyphp_cache_frameworks.xml",
parent_node_name=0x52f916 "frameworks", nodes_name=0x52f90c "framework",
dir=L"/home/robert/Projekty/laravel-lodash/vendor/laravel",
result_dir=L"/", options="", delim="~#@%_", cached=@0x7fffffffdd00:
true, identifiers=0x0, strings=0x0) at src/cache.cpp:97
#4 0x000000000044982e in cache::load_framework_cache
(this=0x7fffffffdd00,
framework_dir=L"/home/robert/Projekty/laravel-lodash/vendor/laravel",
delim="~#@%_", framework_identifiers=0x0)
at src/cache.cpp:133
#5 0x000000000044a0c3 in cache::load_vendor_cache (this=0x7fffffffdd00,
vendor_dir=L"/home/robert/Projekty/laravel-lodash/vendor",
delim="~#@%_", dir_separator=L"/",
framework_identifiers=std::__debug::unordered_map with 2 elements =
{...}, third_party_identifiers=std::__debug::unordered_map with 48
elements = {...}) at src/cache.cpp:189
#6 0x000000000046c361 in obfuscator::get_cmdline_options
(this=0x7fffffffd550, argc=8, argv=0x7fffffffdee8) at src/obfuscator.cpp:754
#7 0x00000000004240ba in main (argc=8, argv=0x7fffffffdee8) at
src/dirtyphp.cpp:148

(gdb) info registers
rax 0x58 88
rbx 0x38 56
rcx 0x7fffffffc390 140737488339856
rdx 0x58 88
rsi 0x58 88
rdi 0x7fffffffc1b0 140737488339376
rbp 0x7fffffffc190 0x7fffffffc190
rsp 0x7fffffffc190 0x7fffffffc190
r8 0x0 0
r9 0x7fffffffc0f0 140737488339184
r10 0x1 1
r11 0x246 582
r12 0x1 1
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x43d68e 0x43d68e
<__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >*,
std::__cxx1998::vector<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >,
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > > >
>::__normal_iterator(std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >* const&)+20>
eflags 0x10246 [ PF ZF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0

(gdb) x/i $pc
=> 0x43d68e
<__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >*,
std::__cxx1998::vector<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >,
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > > >
>::__normal_iterator(std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >* const&)+20>: mov
(%rax),%rdx


Scott Lurndal

unread,
Mar 9, 2023, 2:55:33 PM3/9/23
to
So, RAX is the register that contains the address from which
the data is being loaded. A virtual address less than 0x1000 is
generally invalid on most operating systems in order to fault on
NULL pointer dereferences.

It likely means that your objects were not correctly initialized
or have been overwritten inadvertantly by other code in your application.

Next thing to try is to insert the following instead of 'gdb -q --args '
in front of your command on the command line.

valgrind --leak-check=full --show-leak-kinds=all -v --log-file=/tmp/vg%p.log

Then look at the generated log file to identify where things started to go wrong.

Andrey Tarasevich

unread,
Mar 9, 2023, 8:34:12 PM3/9/23
to
The obvious and the most likely candidate is the value of `what`. What
is the value of `what`? Does it go out of `identifiers` range?

--
Best regards,
Andrey

Jivanmukta

unread,
Mar 10, 2023, 5:26:39 AM3/10/23
to
W dniu 9.03.2023 o 19:03, Jivanmukta pisze:
> Question: how to TRACE values: identifiers[what].end(), ids.begin(),
> ids.end()? I failed to cast them to unsigned long.

Could you answer me please? I Suspect there's something wrong with ids.

Jivanmukta

unread,
Mar 10, 2023, 5:41:30 AM3/10/23
to
W dniu 10.03.2023 o 02:33, Andrey Tarasevich pisze:
TRACE("ids.size: " << ids.size());
if (ids.size() > 0) { // nie wiem czy to ma sens?
int what = stoi(attr_what.value());
TRACE("what == " << what);
TRACE("size == " << identifiers[what].size());
TRACE("before insert");
identifiers[what].insert(identifiers[what].end(),
ids.begin(), ids.end());
TRACE("after insert"); // !!!błąd - czasami ids
puste i wtedy SIGV
}

what == 1 is TRACEd. Then SIGSEGV. size is not TRACEd. What does it mean?

I have defined:

identifiers_vector identifiers[index_what_num]

typedef std::vector<std::string> strvector;

class identifiers_vector : public strvector {
public:
identifiers_vector() = default;
identifiers_vector(const strvector &v) {
for (std::string s : v) {
push_back_identifier(s);
}
}
int index_of_identifier(const std::string &needle) const {
return index_of_string(*this, needle);
}
bool has_identifier(const std::string &needle) const {
return index_of_identifier(needle) >= 0;
}
void push_back_identifier(const std::string &s) {
if (!has_identifier(s)) {
push_back(s);
}
}
void sort_by_descending_length() {
std::sort(begin(), end(), [](std::string a, std::string b) {
return a.length() > b.length(); });
}
};

Jivanmukta

unread,
Mar 10, 2023, 5:49:48 AM3/10/23
to

enum index_what : unsigned short { i_actions, i_methods, i_functions,
i_properties, i_variables }; // don't change the order
constexpr unsigned short index_what_num = i_variables - i_actions + 1;

Paavo Helde

unread,
Mar 10, 2023, 6:15:31 AM3/10/23
to
Looks like so. Most probably you have corrupted your data by using code
which has UB. As you do not want to show your code, nobody can guess
where the bug is. My crystal ball says it is on line 42, but then again
I have not oiled it for a while.


Paavo Helde

unread,
Mar 10, 2023, 6:23:38 AM3/10/23
to
10.03.2023 12:41 Jivanmukta kirjutas:
> W dniu 10.03.2023 o 02:33, Andrey Tarasevich pisze:
>> The obvious and the most likely candidate is the value of `what`. What
>> is the value of `what`? Does it go out of `identifiers` range?
>>
>                 TRACE("ids.size: " << ids.size());
>                 if (ids.size() > 0) {   // nie wiem czy to ma sens?
>                     int what = stoi(attr_what.value());
>                     TRACE("what == " << what);
>                     TRACE("size == " << identifiers[what].size());
>                     TRACE("before insert");
>                     identifiers[what].insert(identifiers[what].end(),
> ids.begin(), ids.end());
>                     TRACE("after insert"); // !!!błąd - czasami ids
> puste i wtedy SIGV
>                 }
>
> what == 1 is TRACEd. Then SIGSEGV. size is not TRACEd. What does it mean?
>

Most probably it means that the size of 'identifiers' is less than 1.

Why don't you single-step through your code in the debugger and monitor
the data values directly?

From a short look on your code it looks like you are trying to reinvent
std::set or std::map, poorly. Maybe you should start from some book
covering the C++ standard library?

Jivanmukta

unread,
Mar 10, 2023, 6:42:30 AM3/10/23
to
W dniu 10.03.2023 o 12:23, Paavo Helde pisze:
> 10.03.2023 12:41 Jivanmukta kirjutas:
>> W dniu 10.03.2023 o 02:33, Andrey Tarasevich pisze:
>>> The obvious and the most likely candidate is the value of `what`.
>>> What is the value of `what`? Does it go out of `identifiers` range?
>>>
>>                  TRACE("ids.size: " << ids.size());
>>                  if (ids.size() > 0) {   // nie wiem czy to ma sens?
>>                      int what = stoi(attr_what.value());
>>                      TRACE("what == " << what);
>>                      TRACE("size == " << identifiers[what].size());
>>                      TRACE("before insert");
>>                      identifiers[what].insert(identifiers[what].end(),
>> ids.begin(), ids.end());
>>                      TRACE("after insert"); // !!!błąd - czasami ids
>> puste i wtedy SIGV
>>                  }
>>
>> what == 1 is TRACEd. Then SIGSEGV. size is not TRACEd. What does it mean?
>>
>
> Most probably it means that the size of 'identifiers' is less than 1.
how is it possible? here declaration of a parameter identifiers:

static bool load_cache(string cache_filename, const char
*parent_node_name, const char *nodes_name, wstring dir, wstring
result_dir, string options, string delim,
bool &cached, identifiers_vector
identifiers[index_what_num], apostrophed_strings_maps_map *strings) {

>
> Why don't you single-step through your code in the debugger and monitor
> the data values directly?
because i can't - wherever i set breakpoint i have sigsegv

Sam

unread,
Mar 10, 2023, 7:00:40 AM3/10/23
to
Jivanmukta writes:

> When I run my program is VSCode, it shows:
>
> Loaded '/lib/x86_64-linux-gnu/libstdc++.so.6'. Symbols loaded.
> Loaded '/lib/x86_64-linux-gnu/libm.so.6'. Symbols loaded.
> Loaded '/lib/x86_64-linux-gnu/libgcc_s.so.1'. Symbols loaded.
> Loaded '/lib/x86_64-linux-gnu/libc.so.6'. Symbols loaded.
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x0000000000428172 in

Sorry to hear about this segfault. You will find your debugger down the
hall, last door on your right.

Sam

unread,
Mar 10, 2023, 7:01:35 AM3/10/23
to
Just because the program crashes here doesn't mean this is where the problem
is. C++ does not work this way. The problem can be anywhere in your code.
You will need to use a debugger, and other tools, to figure out where it is.

Sam

unread,
Mar 10, 2023, 7:02:17 AM3/10/23
to
Nobody can answer this without debugging the full program, themselves.

Jivanmukta

unread,
Mar 10, 2023, 8:39:26 AM3/10/23
to
W dniu 10.03.2023 o 12:42, Jivanmukta pisze:
There's something wrong with my identifiers array. Here how I allocate it:

for (auto dir = vendor_frameworks_dirs.begin(); dir !=
vendor_frameworks_dirs.end(); ++dir)
{
*dir = normalize_path(*dir, delim);
TRACE("allocating identifiers vectors");
identifiers_vector *ptr = new
identifiers_vector[index_what_num];
framework_identifiers.insert(make_pair(*dir, ptr));
TRACE("identifiers vectors allocated and inserted");
}

Could *ptr be unitialized???!!!

Paavo Helde

unread,
Mar 10, 2023, 9:54:19 AM3/10/23
to
Here you are using C-style arrays or pointers, that's probably the root
of the problems. This parameter declaration

identifiers_vector identifiers[index_what_num]

is equivalent to

identifiers_vector* identifiers

by the ancient C rules. Throw it ought and use either

identifiers_vector& identifiers

or

std::vector<identifiers_vector>& identifiers


depending on whether you want one or many identifiers_vector vectors, I
am not able to tell which is what you want. Now you have ordered many
and probably passing one or zero of them.

Also, remove any mention of 'new' and raw pointers from your code, there
is no need to complicate ones' life without any reason. The std::vector
is perfectly capable of allocating any needed memory for its data
internally.

Also note that deriving from std::vector is usually considered bad style
as it is not meant for deriving, but that's another topic.


Jivanmukta

unread,
Mar 10, 2023, 10:55:04 AM3/10/23
to
W dniu 10.03.2023 o 12:42, Jivanmukta pisze:
When the code is executed:
TRACE("what == " << what);
(void)identifiers[what];
TRACE("after identifiers[what]");
TRACE("size == " << identifiers[what].size());
what == 1 and "after identifiers[what]" are TRACEd. Then SIGSEGV.
Why .size() causes SIGSEGV? Does it means there's something wrong with
identifiers[1] object?
I can't debug, I must TRACE.

Paavo Helde

unread,
Mar 10, 2023, 12:09:29 PM3/10/23
to
Most probably, yes. The first suspicion is that identifiers[1] does not
even exist. So you should TRACE the number of objects in the
identifiers, to see if identifiers[1] exists.

Oh wait, you cannot do that, because you do not have that information,
because you have decided to use some error-prone C-style array which
doesn't know its own length. So throw it out and replace by proper
std::vector. See my other post.



Andrey Tarasevich

unread,
Mar 10, 2023, 3:15:45 PM3/10/23
to
On 03/10/23 2:41 AM, Jivanmukta wrote:
>>
>> The obvious and the most likely candidate is the value of `what`. What
>> is the value of `what`? Does it go out of `identifiers` range?
>>
>                 TRACE("ids.size: " << ids.size());
>                 if (ids.size() > 0) {   // nie wiem czy to ma sens?
>                     int what = stoi(attr_what.value());
>                     TRACE("what == " << what);
>                     TRACE("size == " << identifiers[what].size());
>                     TRACE("before insert");
>                     identifiers[what].insert(identifiers[what].end(),
> ids.begin(), ids.end());
>                     TRACE("after insert"); // !!!błąd - czasami ids
> puste i wtedy SIGV
>                 }
>
> what == 1 is TRACEd. Then SIGSEGV. size is not TRACEd. What does it mean?

Er... Why are you trying to TRACE `identifiers[what].size()`? Nobody
cares about `identifiers[what].size()`.

We need `identifiers.size()`. What does `identifiers.size()` equal to?

--
Best regards,
Andrey

Andrey Tarasevich

unread,
Mar 10, 2023, 3:17:55 PM3/10/23
to
On 03/10/23 7:54 AM, Jivanmukta wrote:
>>
> When the code is executed:
>                     TRACE("what == " << what);
>                     (void)identifiers[what];
>                     TRACE("after identifiers[what]");
>                     TRACE("size == " << identifiers[what].size());
> what == 1 and "after identifiers[what]" are TRACEd. Then SIGSEGV.
> Why .size() causes SIGSEGV?

Because, as I have already stated above, `what` is out of bounds.

Why are you trying to TRACE `identifiers[what].size()`? You need
`identifiers.size()`.

> Does it means there's something wrong with
> identifiers[1] object?

Most likely, it does. `identifiers[1]` simply does not exist.

--
Best regards,
Andrey



Stefan Große Pawig

unread,
Mar 10, 2023, 6:05:22 PM3/10/23
to
Here: identifiers=0x0, so any dereferening is likely to result in a
segfault.

> #4 0x000000000044982e in cache::load_framework_cache (this=0x7fffffffdd00,
> framework_dir=L"/home/robert/Projekty/laravel-lodash/vendor/laravel",
> delim="~#@%_", framework_identifiers=0x0)
> at src/cache.cpp:133

Here: framework_identifiers=0x0

> #5 0x000000000044a0c3 in cache::load_vendor_cache (this=0x7fffffffdd00,
> vendor_dir=L"/home/robert/Projekty/laravel-lodash/vendor",
> delim="~#@%_", dir_separator=L"/",
> framework_identifiers=std::__debug::unordered_map with 2 elements = {...},
> third_party_identifiers=std::__debug::unordered_map with 48 elements =
> {...}) at src/cache.cpp:189
> [...]

You may want to check what you pass as 'framework_identifiers' argument
to cache::load_framework_cache().

Regards,
Stefan

Jivanmukta

unread,
Mar 11, 2023, 3:41:24 AM3/11/23
to
I solved the problem.
I made some changes that introduced logical error in my code, causing
identifiers[] array to be wrongly initialized.

Jivanmukta

unread,
Mar 11, 2023, 4:45:39 AM3/11/23
to
W dniu 10.03.2023 o 15:54, Paavo Helde pisze:

> Also note that deriving from std::vector is usually considered bad style
> as it is not meant for deriving, but that's another topic.
>
>

Why? Because it is not polymorphic? I don't need polymorphism in my class.

Paavo Helde

unread,
Mar 11, 2023, 9:52:19 AM3/11/23
to
Because a derived class will often have more stringent class invariant,
which can be ruined easily by calling the base class methods
inadvertently, which do not know or care about the invariant. This means
the class has functions in its interface which should not be used, but
they are there and accessible. As I said, not something very horrendous,
just bad style.

For example, it looks like your class identifiers_vector has an
additional class invariant demanding that there are no duplicate values.
This can be ruined inadvertently, e.g.:

void AddReverse(std::vector<std::string>& v) {
for (size_t i=0, n=v.size(); i<n; ++i) {
std::string s = v[i];
std::reverse(s.begin(), s.end());
v.push_back(s);
}
}

identifiers_vector v;
v.push_back_identifier("maser");
v.push_back_identifier("laser");
v.push_back_identifier("radar");
AddReverse(v); // oops, now it contains 2 "radar"-s.

A better style is to derive privately from a base class, or yet better,
having std::vector as a member instead of a base. This way it would be
also easier to refactor the class if at some point you decide using
std::set or std::map which automatically avoid duplicates would provide
a better implementation.

Jivanmukta

unread,
Mar 11, 2023, 12:52:41 PM3/11/23
to
W dniu 11.03.2023 o 15:52, Paavo Helde pisze:
Thank you for explanation.
0 new messages