View Issue Details

IDProjectCategoryView StatusLast Update
0002323NoesisGUIC++ SDKpublic2022-06-21 17:13
Reporterjack.barkov Assigned Tojsantos  
PrioritynormalSeveritycrashReproducibilitysometimes
Status resolvedResolutionfixed 
Product Version3.1.4 
Target Version3.1.5Fixed in Version3.1.5 
Summary0002323: Crash - Noesis::Thickness::TryParse
DescriptionAfter a while with a test application running, a crash is happening inside Noesis.dll
I don't know how to reproduce, it happens sometimes.

My detailed dump output:

*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************

KEY_VALUES_STRING: 1

    Key : AV.Dereference
    Value: NullPtr

    Key : AV.Fault
    Value: Write

    Key : Analysis.CPU.mSec
    Value: 2827

    Key : Analysis.DebugAnalysisManager
    Value: Create

    Key : Analysis.Elapsed.mSec
    Value: 5465

    Key : Analysis.Init.CPU.mSec
    Value: 187

    Key : Analysis.Init.Elapsed.mSec
    Value: 4824

    Key : Analysis.Memory.CommitPeak.Mb
    Value: 123

    Key : Timeline.Process.Start.DeltaSec
    Value: 29531

    Key : WER.Process.Version
    Value: 1.0.80.0


FILE_IN_CAB: 1f3e9c52-99e2-412a-bb32-e8e3c76a9a3b.dmp

NTGLOBALFLAG: 0

PROCESS_BAM_CURRENT_THROTTLED: 0

PROCESS_BAM_PREVIOUS_THROTTLED: 0

CONTEXT: (.ecxr)
eax=00000000 ebx=1268b278 ecx=00000000 edx=0019cbf0 esi=0019cbf4 edi=0019cbe8
eip=07c8c037 esp=0019cb58 ebp=0019cba8 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210202
Noesis!Noesis::Thickness::TryParse+0x408a7:
07c8c037 668901 mov word ptr [ecx],ax ds:002b:00000000=????
Resetting default scope

EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 07c8c037 (Noesis!Noesis::Thickness::TryParse+0x000408a7)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 00000000
Attempt to write to address 00000000

PROCESS_NAME: test1234.exe

WRITE_ADDRESS: 00000000

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

EXCEPTION_CODE_STR: c0000005

EXCEPTION_PARAMETER1: 00000001

EXCEPTION_PARAMETER2: 00000000

STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
0019cba8 07c9afe5 1268c610 12a92060 00000008 Noesis!Noesis::Thickness::TryParse+0x408a7
0019cc00 07c93988 00000500 0019eff8 00000000 Noesis!Noesis::DynamicTextureSource::GetPixelHeight+0x6145
0019cd58 07b83e28 00000000 00000001 00000000 Noesis!Noesis::Thickness::TryParse+0x481f8
0019ef90 07b82d4c 00000000 00000030 082ab440 Noesis!Noesis::RenderOptions::StaticGetClassType+0x5069
0019efdc 07b80552 275a97e4 0019f24c 1276d288 Noesis!Noesis::RenderOptions::StaticGetClassType+0x3f8d
0019f21c 07b7e62e 0019f24c 0019f5c0 0b947a68 Noesis!Noesis::RenderOptions::StaticGetClassType+0x1793
0019f23c 07b7e6a1 0019f24c 0019f520 3f800000 Noesis!Noesis::RelativeSource::StaticGetClassType+0x1dfc
0019f28c 005bf195 0019f2d0 75b9b81f 005d4bfd Noesis!Noesis::RelativeSource::StaticGetClassType+0x1e6f
0019f2f0 005d3bcb 128a80c8 000000ff 126af85c test1234_exe+0x1bf195
0019f318 005c8ba3 00f67230 0019f3a8 00bea153 test1234_exe+0x1d3bcb
0019f324 00bea153 edeb8890 00000204 0019f520 test1234_exe+0x1c8ba3
0019f3a8 00beb1f2 edeb8e30 0009096e 0019f49c test1234_exe+0x7ea153
0019f508 00be42a9 0097dc04 0019f5a4 be8466d0 test1234_exe+0x7eb1f2
0019f520 0097dc47 00000000 00000001 001b1ed8 test1234_exe+0x7e42a9
0019ff18 00d00098 00000022 002c0000 00d00098 test1234_exe+0x57dc47
0019ff70 75a0fa29 002c0000 75a0fa10 0019ffdc test1234_exe+0x900098
0019ff80 76f47a7e 002c0000 36e15315 00000000 KERNEL32!BaseThreadInitThunk+0x19
0019ffdc 76f47a4e ffffffff 76f68a29 00000000 ntdll!__RtlUserThreadStart+0x2f
0019ffec 00000000 04dea951 002c0000 00000000 ntdll!_RtlUserThreadStart+0x1b


STACK_COMMAND: ~0s; .ecxr ; kb

SYMBOL_NAME: Noesis+408a7

MODULE_NAME: Noesis

IMAGE_NAME: Noesis.dll

FAILURE_BUCKET_ID: NULL_POINTER_WRITE_c0000005_Noesis.dll!Unknown

OSPLATFORM_TYPE: x86

OSNAME: Windows 10

IMAGE_VERSION: 3.1.4.11278

FAILURE_ID_HASH: {bf357e83-43f7-28d9-5206-d6c832cdec19}

Followup: MachineOwner
---------

0:000> lmvm Noesis
Browse full module list
start end module name
07a80000 07dd2000 Noesis C (export symbols) Noesis.dll
    Loaded symbol image file: Noesis.dll
    Mapped memory image file: C:\test1234\Noesis.dll
    Image path: C:\test1234\Noesis.dll
    Image name: Noesis.dll
    Browse all global symbols functions data
    Timestamp: Thu Mar 17 17:45:59 2022 (62339E07)
    CheckSum: 00000000
    ImageSize: 00352000
    File version: 3.1.4.11278
    Product version: 3.1.4.11278
    File flags: 0 (Mask 0)
    File OS: 0 Unknown Base
    File type: 2.0 Dll
    File date: 00000000.00000000
    Translations: 0000.04b0
    Information from resource tables:
        CompanyName: Noesis Technologies
        ProductName: NoesisGUI-win-x86
        InternalName: Noesis.dll
        OriginalFilename: Noesis.dll
        ProductVersion: 3.1.4.11278
        FileVersion: 3.1.4.11278
        FileDescription: Noesis Library
        LegalCopyright: (C) Noesis Technologies S.L.


TagsNo tags attached.
PlatformWindows

Relationships

has duplicate 0002313 resolvedsfernandez Random crashs on Noesis.dll 

Activities

jsantos

jsantos

2022-04-06 16:17

manager   ~0007888

Could you please attach a minidump? The call-stack does not reveal enough information. Thank you!
jack.barkov

jack.barkov

2022-04-06 17:00

reporter   ~0007889

Sure, thanks.
jack.barkov

jack.barkov

2022-04-13 14:00

reporter   ~0007898

Any news about this crash?

Can I do something to help?

Thank you.
jsantos

jsantos

2022-04-13 17:04

manager   ~0007899

Last edited: 2022-04-13 17:05

The minidump reveals a problem uploading indices to the GPU

>	Noesis.dll!Noesis::VGLContext::PackImage(const Noesis::BatchGroup & k, const Noesis::DrawInfo & drawInfo, unsigned int stride, unsigned int & base, unsigned char * & vOut, unsigned short * & iOut) Line 2661	C++
     Noesis.dll!Noesis::VGLContext::UploadGPUGeometry() Line 3895	C++
     Noesis.dll!Noesis::VGLContext::Flush(bool endOfFrame, bool clearEffects, bool flipY) Line 1397	C++
     Noesis.dll!Noesis::RenderTreeHelper::RenderOffscreenNodes() Line 994	C++
     Noesis.dll!Noesis::RenderTreeHelper::RenderOffscreen(Noesis::RenderNode * node, const Noesis::Matrix4 & projection) Line 72	C++
     Noesis.dll!Noesis::RenderTree::RenderOffscreen(const Noesis::Matrix4 & projection) Line 291	C++
     Noesis.dll!Noesis::Renderer::RenderOffscreen(const Noesis::Matrix4 & projection) Line 173	C++
     Noesis.dll!Noesis::Renderer::RenderOffscreen() Line 151	C++

I have uploaded a debug version of Noesis with PDBs: https://drive.google.com/file/d/1__XucBUs7oJZNUmUd2bUqj0t8q8CKkh0/view?usp=sharing

Could you please try it?

Also, are you able to reproduce this in one of our examples? If not, could you tell me more about your test application?
jack.barkov

jack.barkov

2022-04-23 00:58

reporter   ~0007910

Last edited: 2022-04-23 00:58

Finally got it, an example to reproduce!

I could only find it actually because of the dll in debug...

I implemented a list of views, and called them separately to render.
From what I read in the documentation, this is correct, or I got it wrong.

To reproduce the error, just use the attached cpp in IntegrationGLUT.

Some strange things I noticed:

When I call CreateMessageBox() twice, using Opacity="0.8" in <Border> the crash doesn't happen.

-------------------

When I call CreateMessageBox() four times, using Opacity="0.8" in <Border> the crash happens.
If I remove Opacity="0.8", the crash does not happen....

-------------------

If I remove Opacity="0.8" and call CreateMessageBox() seven times the crash happens.

-------------------

From what I could analyze, the crash happens because when the GLRenderDevice::AllocatePage(DynamicBuffer& buffer) the buffer.numPages is 16, and an access is made
in the invalid position of the DynamicBuffer::pages[16] array, it accesses the memory incorrectly and then when the render is going to be executed, the crash happens.
And I couldn't find it before why with the dll in release, the NS_ASSERT is not being called...
print_0.png (219,344 bytes)   
print_0.png (219,344 bytes)   
code.zip (9,978 bytes)
jack.barkov

jack.barkov

2022-04-23 14:27

reporter   ~0007911

Another way to crash is to remove the CreateMessageBox() calls and call lots of CreateBackground().

It seems to be a bug with the number of views created.
crash_without_msgbox_but_many_simple_views.cpp (9,198 bytes)   
////////////////////////////////////////////////////////////////////////////////////////////////////
// NoesisGUI - http://www.noesisengine.com
// Copyright (c) 2013 Noesis Technologies S.L. All Rights Reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////


// This is a minimal integration example. For simplification purposes only basic input events are
// handled, no resource providers are used and the shutdown procedure is omitted. A more complete
// multiplatform integration sample with step by step comments can be found at 'Samples/Integration'


#ifdef _WIN32
#include "glut.h"
#pragma comment(linker,"/SUBSYSTEM:CONSOLE")
#endif

#ifdef __APPLE__
#include <GLUT/glut.h>
#endif

#ifdef __EMSCRIPTEN__
#include <GL/glut.h>
#include <GLES3/gl32.h>
#include <emscripten/html5.h>
#endif

#ifdef __linux__
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glut.h>
#endif

#ifdef _MSC_VER
#define UNUSED_ARGS(...) (void)(true ? (void)0 : ((void)(__VA_ARGS__)))
#else
#define UNUSED_ARGS(...)
#endif


#include <NsApp/ThemeProviders.h>
#include <NsRender/GLFactory.h>
#include <NsGui/FontProperties.h>
#include <NsGui/IntegrationAPI.h>
#include <NsGui/IRenderer.h>
#include <NsGui/IView.h>
#include <NsGui/Grid.h>
#include <NsCore/HighResTimer.h>

#include <list>

static Noesis::Ptr<Noesis::RenderDevice> _device;
static std::list<Noesis::IView*> _views;


///////////////////////////////////////////////////////////////////////////////////////////////////
static void NoesisInit()
{
    // A logging handler is installed here. You can also install a custom error handler and memory
    // allocator. By default errors are redirected to the logging handler
    Noesis::GUI::SetLogHandler([](const char*, uint32_t, uint32_t level, const char*, const char* msg)
        {
            // [TRACE] [DEBUG] [INFO] [WARNING] [ERROR]
            const char* prefixes[] = { "T", "D", "I", "W", "E" };
            printf("[NOESIS/%s] %s\n", prefixes[level], msg);
        });

    // https://www.noesisengine.com/docs/Gui.Core.Licensing.html
    Noesis::GUI::SetLicense("test", "DdcLQLOdC0BP5u4nYEGeHrB9wOVx63HR9/tSn75mF1d45M3x");

    // Noesis initialization. This must be the first step before using any NoesisGUI functionality
    Noesis::GUI::Init();

    _device = NoesisApp::GLFactory::CreateDevice(false);

    // Setup theme
    NoesisApp::SetThemeProviders();
    Noesis::GUI::LoadApplicationResources("Theme/NoesisTheme.DarkBlue.xaml");
}

static void CreateBackground()
{
    // For simplicity purposes we are not using resource providers in this sample. ParseXaml() is
    // enough if there is no extra XAML dependencies
    Noesis::Ptr<Noesis::Grid> xaml(Noesis::GUI::ParseXaml<Noesis::Grid>(R"(<?xml version="1.0" encoding="UTF-8"?>
<Grid 
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
	xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
	xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
	xmlns:noesis="clr-namespace:NoesisGUIExtensions;assembly=Noesis.GUI.Extensions">

    <Grid Grid.Column="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition Width="54"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="11"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <Button Grid.Column="1" Grid.Row="1" Content="Test" />
    </Grid>
</Grid>
    )"));

    // View creation to render and interact with the user interface
    // We transfer the ownership to a global pointer instead of a Ptr<> because there is no way
    // in GLUT to do shutdown and we don't want the Ptr<> to be released at global time
    Noesis::IView* view = Noesis::GUI::CreateView(xaml).GiveOwnership();
    view->SetFlags(Noesis::RenderFlags_PPAA | Noesis::RenderFlags_LCD);
    view->SetSize(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));

    // Renderer initialization with an OpenGL device
    view->GetRenderer()->Init(_device);

    _views.push_back(view);
}

///////////////////////////////////////////////////////////////////////////////////////////////////
static void DisplayFunc(void)
{
    glViewport(0, 0, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
    glDisable(GL_SCISSOR_TEST);
    glClearColor(0.0f, 0.0f, 0.25f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    for (auto& view : _views)
    {
        // Update view (layout, animations, ...)
        view->Update(glutGet(GLUT_ELAPSED_TIME) / 1000.0);

        // Offscreen rendering phase populates textures needed by the on-screen rendering
        view->GetRenderer()->UpdateRenderTree();
        view->GetRenderer()->RenderOffscreen();
    }

    // My custom render, goes here...
    // My custom render, goes here...
    // My custom render, goes here...
    // My custom render, goes here...

    for (auto& view : _views)
    {
        // If you are going to render here with your own engine you need to restore the GPU state
        // because noesis changes it. In this case only framebuffer and viewport need to be restored
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        glClearStencil(0);

        // Rendering is done in the active framebuffer
        view->GetRenderer()->Render();
    }

    glutSwapBuffers();
    glutPostRedisplay();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
static void ReshapeFunc(int width, int height)
{
    for (auto& view : _views)
    {
        view->SetSize(width, height);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
static void MouseMoveFunc(int x, int y)
{
    for (auto& view : _views)
    {
        view->MouseMove(x, y);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
static void MouseFunc(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON)
    {
        if (state == GLUT_DOWN)
        {
            for (auto& view : _views)
            {
                view->MouseButtonDown(x, y, Noesis::MouseButton_Left);
            }
        }
        else
        {
            for (auto& view : _views)
            {
                view->MouseButtonUp(x, y, Noesis::MouseButton_Left);
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_STENCIL);
    glutInitWindowSize(1000, 600);

#ifdef __EMSCRIPTEN__
    double width, height;
    emscripten_get_element_css_size("#canvas", &width, &height);
    emscripten_set_canvas_element_size("#canvas", (uint32_t)width, (uint32_t)height);
    glutInitWindowSize((uint32_t)width, (uint32_t)height);
#endif

    glutCreateWindow("NoesisGUI - GLUT integration");
    NoesisInit();

    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();
    CreateBackground();

    glutDisplayFunc(&DisplayFunc);
    glutReshapeFunc(&ReshapeFunc);
    glutPassiveMotionFunc(&MouseMoveFunc);
    glutMouseFunc(&MouseFunc);

    glutMainLoop();

    return 0;
}
jsantos

jsantos

2022-04-25 18:18

manager   ~0007913

Thank you for this!
jack.barkov

jack.barkov

2022-06-17 17:12

reporter   ~0007974

Any news about this bug?
Is it a bug or did I do something wrong?
Was the file I uploaded with the examples able to reproduce the crash?
Thanks.
jsantos

jsantos

2022-06-18 11:39

manager   ~0007978

Last edited: 2022-06-18 11:39

Next week I will be working on this. I will tell you more in a few days. Thanks for your patience
jsantos

jsantos

2022-06-20 13:09

manager   ~0007981

Last edited: 2022-06-20 13:10

There is definitely a bug in GLRenderDevice::AllocatePage (as you discovered). I will provide a patch here for testing.

But I am a bit confused because your examples are not crashing here. In fact, in your code it says:

    CreateMessageBox(); // ok
    CreateMessageBox(); // ok
    CreateMessageBox(); // ok
    CreateMessageBox(); // crashs here!

But in the call-stack you attached, the crash is not happening inside CreateMessageBox, but inside DisplayFunc
jsantos

jsantos

2022-06-20 13:13

manager   ~0007982

Last edited: 2022-06-20 13:14

If you go to GLRenderDevice.cpp at the top, and uncomment this:

#undef NS_LOG_TRACE
#define NS_LOG_TRACE(...) NS_LOG_(NS_LOG_LEVEL_TRACE, __VA_ARGS__)

You will see a message like this every time a new page is created:

[NOESIS/T] Page 'Vertices[2]' created (524288 KB)
[NOESIS/T] Page 'Indices[2]' created (131072 KB)

It seems your example is creating more than 16 pages (and this crashes), but I am not able to reproduce it in your examples. Do I need to do something special?
jack.barkov

jack.barkov

2022-06-21 13:22

reporter   ~0007993

Could you access that same computer that was working on D3D12?
I left the example crashing on both x86 and x64.
This issue is not related to this hardware.
All computers I've tested, this happens.

ID: 514 240 482
Pass: jsantos**

Thanks.
jack.barkov

jack.barkov

2022-06-21 13:23

reporter   ~0007995

Last edited: 2022-06-21 13:28

Note that I returned all the original code from the noesis sdk you were working on, I only changed the cpp that reproduces the error.

Thanks
jsantos

jsantos

2022-06-21 17:13

manager   ~0007998

Thanks for the help!

I just left in your machine the new fixed GLRenderDevice

Issue History

Date Modified Username Field Change
2022-04-06 16:14 jack.barkov New Issue
2022-04-06 16:16 jsantos Assigned To => jsantos
2022-04-06 16:16 jsantos Status new => assigned
2022-04-06 16:16 jsantos Target Version => 3.1.5
2022-04-06 16:17 jsantos Note Added: 0007888
2022-04-06 16:17 jsantos Status assigned => feedback
2022-04-06 17:00 jack.barkov Note Added: 0007889
2022-04-06 17:00 jack.barkov File Added: 1f3e9c52-99e2-412a-bb32-e8e3c76a9a3b.dmp
2022-04-06 17:00 jack.barkov Status feedback => assigned
2022-04-13 14:00 jack.barkov Note Added: 0007898
2022-04-13 17:04 jsantos Note Added: 0007899
2022-04-13 17:05 jsantos Status assigned => feedback
2022-04-13 17:05 jsantos Note Edited: 0007899
2022-04-21 19:53 sfernandez Relationship added has duplicate 0002313
2022-04-23 00:58 jack.barkov Note Added: 0007910
2022-04-23 00:58 jack.barkov File Added: print_0.png
2022-04-23 00:58 jack.barkov File Added: code.zip
2022-04-23 00:58 jack.barkov Status feedback => assigned
2022-04-23 00:58 jack.barkov Note Edited: 0007910
2022-04-23 14:27 jack.barkov Note Added: 0007911
2022-04-23 14:27 jack.barkov File Added: crash_without_msgbox_but_many_simple_views.cpp
2022-04-25 18:18 jsantos Note Added: 0007913
2022-06-17 17:12 jack.barkov Note Added: 0007974
2022-06-18 11:39 jsantos Note Added: 0007978
2022-06-18 11:39 jsantos Note Edited: 0007978
2022-06-20 13:09 jsantos Note Added: 0007981
2022-06-20 13:09 jsantos Note Edited: 0007981
2022-06-20 13:09 jsantos Note Edited: 0007981
2022-06-20 13:10 jsantos Note Edited: 0007981
2022-06-20 13:13 jsantos Note Added: 0007982
2022-06-20 13:13 jsantos Note Edited: 0007982
2022-06-20 13:14 jsantos Note Edited: 0007982
2022-06-21 13:22 jack.barkov Note Added: 0007993
2022-06-21 13:23 jack.barkov Note Added: 0007995
2022-06-21 13:28 jack.barkov Note Edited: 0007995
2022-06-21 17:13 jsantos Status assigned => resolved
2022-06-21 17:13 jsantos Resolution open => fixed
2022-06-21 17:13 jsantos Fixed in Version => 3.1.5
2022-06-21 17:13 jsantos Note Added: 0007998