|
|
Home » Developing U++ » U++ Developers corner » ASSERT when using ValueMap
ASSERT when using ValueMap [message #47651] |
Tue, 21 February 2017 16:23 |
NilaT
Messages: 70 Registered: November 2011 Location: Austria
|
Member |
|
|
Hello everyone, I've got a nice little "soft crash" again, may you can help me?
It happens when I try to "Add" something to a Value Map.
So my code basically looks like this:
Params params = HandleParams(param1, param2); // Params is a struct which contains some Strings, some ints, and a Time Variable
ValueMap result;
result.Add("key1", RawToValue(params.someVar));
It then crashes at:
****************** ASSERT FAILED: Assertion failed in C:\.....\uppsrc_2016\Core\Value.cpp, line 25
ptr()->GetType() >= 255 || !svo[ptr()->GetType()]
which happens to occur in the Value Destructor, ::RefRelease() to be exact.
Why is this happening??
Oh and another thing I already fixed, but it also bothers me:
ValueMap map = rpc["params"]; // rpc = RpcData type
int x = ValueTo<int>(map["someKey"]);
will crash, because it says invalid value convertion, double --> int
Why the heck is map["someKey"] a double value, when it's int?
I fixed it by using:
(int)ValueTo<double>(map["someKey"]);
Not nice... but works.
Thanks again for your help.
|
|
|
|
|
Re: ASSERT when using ValueMap [message #47669 is a reply to message #47668] |
Tue, 28 February 2017 08:46 |
cbpporter
Messages: 1406 Registered: September 2007
|
Ultimate Contributor |
|
|
Hi NilaT,
Unfortunately this is the reality of OSS: sometimes your issue gets addressed in 5 minutes, sometimes you wait half a year, sometimes it never gets fixed. One week wait time is often barely measurable.
Adding compilable test-cases which show the problem in isolation always help to get you problem in look at sooner rather than later camp.
But back to you problem: ValueMap.Add and RawToValue should be working fine in general since this is something you would instantly notice that is broken. So I would be inclined to say that the problem is what you are passing into RawToValue.
But to be sure, I did a quick test, with someVar being both int and double:
ValueMap result;
Value v = RawToValue(someVar);
result.Add("key1", v);
So it looks like indeed what you are passing into RawToValue causes the crash. Value implies some sort of copy and that might be the problem. Probably, if you use v in any way for reading it will crash.
To tell you more, I need to see the type of params.someVar, including the prototype of default, copy and move constructors and if there is any assign or move assign constructor. Is the class polymorphic?
|
|
|
Re: ASSERT when using ValueMap [message #47670 is a reply to message #47669] |
Tue, 28 February 2017 09:02 |
cbpporter
Messages: 1406 Registered: September 2007
|
Ultimate Contributor |
|
|
cbpporter wrote on Tue, 28 February 2017 09:46Hi NilaT,
Unfortunately this is the reality of OSS: sometimes your issue gets addressed in 5 minutes, sometimes you wait half a year, sometimes it never gets fixed. One week wait time is often barely measurable.
...
cbpporter
Fantastic strike of karma!
No 20 minutes after I wrote this, I got:
Quote:
Assertion failed in C:\SVN\upp\uppsrc\Core\Value.cpp, line 25
ptr()->GetType() >= 255 || !svo[ptr()->GetType()]
in piece of code that ran perfectly for the last few months.
I'm looking into it...
Nevermind. It was the code I used to test your issue, not mine. I inserted it into my real life product code because I had TheIDE open .
So indeed, Value destructor crashes under the scenario you described.
Thank you for reporting it and sorry I didn't catch it the first time I tried to reproduce.
As said, I will look into it.
[Updated on: Tue, 28 February 2017 09:07] Report message to a moderator
|
|
|
|
Re: ASSERT when using ValueMap [message #47683 is a reply to message #47651] |
Tue, 07 March 2017 00:43 |
|
mirek
Messages: 14038 Registered: November 2005
|
Ultimate Member |
|
|
NilaT wrote on Tue, 21 February 2017 16:23Hello everyone, I've got a nice little "soft crash" again, may you can help me?
It happens when I try to "Add" something to a Value Map.
So my code basically looks like this:
Params params = HandleParams(param1, param2); // Params is a struct which contains some Strings, some ints, and a Time Variable
ValueMap result;
result.Add("key1", RawToValue(params.someVar));
There must be something more to it. I have checked with
ValueMap result;
result.Add("key1", RawToValue(params.someVar));
and that works just fine.
Quote:
Oh and another thing I already fixed, but it also bothers me:
ValueMap map = rpc["params"]; // rpc = RpcData type
int x = ValueTo<int>(map["someKey"]);
will crash, because it says invalid value convertion, double --> int
Why the heck is map["someKey"] a double value, when it's int?
How do you know it is 'int' when reading JSON?
int/double/int64 (and sometimes bool) are used interchangeably. When reading JSON, double is used as "safe option" (because when it is number, it can always be double).
The safe and natural way how to write that is
will convert the Value to 'int' when possible.
Mirek
|
|
|
Re: ASSERT when using ValueMap [message #47684 is a reply to message #47651] |
Tue, 07 March 2017 00:58 |
|
mirek
Messages: 14038 Registered: November 2005
|
Ultimate Member |
|
|
[quote title=NilaT wrote on Tue, 21 February 2017 16:23]Hello everyone, I've got a nice little "soft crash" again, may you can help me?
It happens when I try to "Add" something to a Value Map.
So my code basically looks like this:
Params params = HandleParams(param1, param2); // Params is a struct which contains some Strings, some ints, and a Time Variable
ValueMap result;
result.Add("key1", RawToValue(params.someVar));
[/code]
OK, found it. Problem like was that params.someVar is likely of some type that is supported as "basic Value" (int, double, int64, String etc...).
E.g. this crashes:
int x;
ValueMap result;
result.Add("key1", RawToValue(x));
That is why nobody noticed this yet, as there is not reason to use RawToValue.
works just fine. Anyway, fixed....
Mirek
P.S.: Sorry for the delay, got a bit distracted after last release.
[Updated on: Tue, 07 March 2017 01:00] Report message to a moderator
|
|
|
|
Re: ASSERT when using ValueMap [message #47688 is a reply to message #47687] |
Tue, 07 March 2017 11:29 |
|
mirek
Messages: 14038 Registered: November 2005
|
Ultimate Member |
|
|
It is not inline functions, it is simply the fact that Value code is immensely complicated. Really, absolutely totally fucked hard.
Now the reason why it is so hard is not that I wanted to make everybody looking into it feel like idiot. It is because it is doing some really deep shit optimizations. Value is central to U++ and its perfomance and memory requirements affect everything.
For the record, my yesterday's fix was wrong and I have just spent 4 hours fixing it right (and no, single inline functions were not the problem). And this is just for fixing something that probably was not really in need of fixing - it was borderline to invalid use.
I agree that perhaps more comments would help there. Will try...
[Updated on: Tue, 07 March 2017 11:30] Report message to a moderator
|
|
|
|
Re: ASSERT when using ValueMap [message #47690 is a reply to message #47687] |
Tue, 07 March 2017 11:54 |
NilaT
Messages: 70 Registered: November 2011 Location: Austria
|
Member |
|
|
cbpporterLong story short, Value/ValueMap is not debug-able. Period.
mirek it is simply the fact that Value code is immensely complicated. Really, absolutely totally fucked hard.
This may be the most accurate description about U++ ever made!
U++ - it's free, it's good, but it's not documented and it's NOT DEBUG-ABLE REALLY FUCKED HARD CODE WITH SOME REALLY DEEP SHIT OPTIMIZATIONS - download now
Haha laughing so hard right now.
Ok, anyway... Thanks for fixing it, I don't know what RawToValue exactly does, so I use it everywhere. As I understand it, Value is some kind of container which can hold almost anything. But to do so, you have to "convert" it, and that's what RawToValue does... At least that's my belief.
One thing I'm still curious about... What the heck is this assert:
ptr()->GetType() >= 255 || !svo[ptr()->GetType()]
and what does it have in common with
inline _Uint4_t _Fetch_add_seq_cst_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value)
{ /* add _Value to *_Tgt atomically with
sequentially consistent memory order */
return (_INTRIN_SEQ_CST(_InterlockedExchangeAdd)((volatile long *)_Tgt, _Value));
}
Thanks
|
|
|
Re: ASSERT when using ValueMap [message #47691 is a reply to message #47690] |
Tue, 07 March 2017 12:10 |
|
mirek
Messages: 14038 Registered: November 2005
|
Ultimate Member |
|
|
NilaT wrote on Tue, 07 March 2017 11:54cbpporterLong story short, Value/ValueMap is not debug-able. Period.
mirek it is simply the fact that Value code is immensely complicated. Really, absolutely totally fucked hard.
This may be the most accurate description about U++ ever made!
Well, I believe not the whole U++. Just this piece of code.
Quote:
but it's not documented.
To be fair, there is shitload of related documentation and examples:
http://www.ultimatepp.org/src$Core$Value$en-us.html
even reading the first couple of senteces would save you a lot of troubles.
http://www.ultimatepp.org/srcdoc$Core$Tutorial$en-us.html
chapter 4 explains everything related to Value.
http://www.ultimatepp.org/reference$JSON$en-us.html
here is how to work with JSON...
I would sort of say that there is perception that documentation is completely missing which was true 5 years ago. Nowadays, there definitely are areas that need improvement, but it is not THAT bad.
Quote:
Ok, anyway... Thanks for fixing it, I don't know what RawToValue exactly does, so I use it everywhere. As I understand it, Value is some kind of container which can hold almost anything. But to do so, you have to "convert" it, and that's what RawToValue does... At least that's my belief.
Well, when type is aware about Value (or Value about type, which is the case of some basic types like 'int'), you do not need any explicit conversions. You are only supposed to use RawToValue for types when implicit conversion does not work.
Quote:
One thing I'm still curious about... What the heck is this assert:
ptr()->GetType() >= 255 || !svo[ptr()->GetType()]
and what does it have in common with
This assert basically checked that you are not using RawToValue for "SVO optimized types". Which I agree is borderline - it might happen this is needed in some template code, so I have changed the rule (I mean, you can now use RawToValue even for types that are alredy supported on higher level).
Quote:
inline _Uint4_t _Fetch_add_seq_cst_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value)
{ /* add _Value to *_Tgt atomically with
sequentially consistent memory order */
return (_INTRIN_SEQ_CST(_InterlockedExchangeAdd)((volatile long *)_Tgt, _Value));
}
Thanks
Now hard to say about this, but this is probably related to reference counting of one form of internal Value storage. Very likely things got messed up and Value destructor thought it has to release reference count while internal storage was NOT reference counted.
[Updated on: Tue, 07 March 2017 12:15] Report message to a moderator
|
|
|
|
|
|
Re: ASSERT when using ValueMap [message #47700 is a reply to message #47699] |
Tue, 07 March 2017 15:00 |
|
mirek
Messages: 14038 Registered: November 2005
|
Ultimate Member |
|
|
NilaT wrote on Tue, 07 March 2017 14:54Sorry for being too dumb to fix a 'trivial' error.
Ah, you misunderstood and that makes me sound like I am ranting...
Error was 'borderline' - by that I mean that it was very unusual usage (there reading docs would help). Anyway, I decided it should work even if used that atypical way, so had to fix that. It was not anything you were supposed to fix, that was my task.
It looked 'trivial' to fix at first, but things were more complicated than I anticipated.
What you did 'wrong' is that you have used RawToValue and ValueTo without reason and perhaps without complete understanding what they mean...
Params params = HandleParams(param1, param2); // Params is a struct which contains some Strings, some ints, and a Time Variable
ValueMap result;
result.Add("key1", params.someVar);
ValueMap map = rpc["params"]; // rpc = RpcData type
int x = map["someKey"];
would have worked (I supposed someVar is String or int or something like that).
Mirek
[Updated on: Tue, 07 March 2017 15:03] Report message to a moderator
|
|
|
|
Goto Forum:
Current Time: Fri Sep 20 07:25:52 CEST 2024
Total time taken to generate the page: 0.04012 seconds
|
|
|