Crashing when calling QTcpSocket::setSocketDescriptor() - c++

my project using QTcpSocket and the function setSocketDescriptor(). The code is very normal
QTcpSocket *socket = new QTcpSocket();
socket->setSocketDescriptor(this->m_socketDescriptor);
This coding worked fine most of the time until I ran a performance testing on Windows Server 2016, the crash occurred. I debugging with the crash dump, here is the log
0000004f`ad1ff4e0 : ucrtbase!abort+0x4e
00000000`6ed19790 : Qt5Core!qt_logging_to_console+0x15a
000001b7`79015508 : Qt5Core!QMessageLogger::fatal+0x6d
0000004f`ad1ff0f0 : Qt5Core!QEventDispatcherWin32::installMessageHook+0xc0
00000000`00000000 : Qt5Core!QEventDispatcherWin32::createInternalHwnd+0xf3
000001b7`785b0000 : Qt5Core!QEventDispatcherWin32::registerSocketNotifier+0x13e
000001b7`7ad57580 : Qt5Core!QSocketNotifier::QSocketNotifier+0xf9
00000000`00000001 : Qt5Network!QLocalSocket::socketDescriptor+0x4cf7
00000000`00000000 : Qt5Network!QAbstractSocket::setSocketDescriptor+0x256
In the stderr log, I see those logs
CreateWindow() for QEventDispatcherWin32 internal window failed (Not enough storage is available to process this command.)
Qt: INTERNAL ERROR: failed to install GetMessage hook: 8, Not enough storage is available to process this command.
Here is the function, where the code was stopped on the Qt codebase
void QEventDispatcherWin32::installMessageHook()
{
Q_D(QEventDispatcherWin32);
if (d->getMessageHook)
return;
// setup GetMessage hook needed to drive our posted events
d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
if (Q_UNLIKELY(!d->getMessageHook)) {
int errorCode = GetLastError();
qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s",
errorCode, qPrintable(qt_error_string(errorCode)));
}
}
I did research and the error Not enough storage is available to process this command. maybe the OS (Windows) does not have enough resources to process this function (SetWindowsHookEx) and failed to create a hook, and then Qt fire a fatal signal, finally my app is killed.
I tested this on Windows Server 2019, the app is working fine, no crashes appear.
I just want to know more about the meaning of the error message (stderr) cause I don't really know what is "Not enough storage"? I think it is maybe the limit or bug of the Windows Server 2016? If yes, is there any way to overcome this issue on Windows Server 2016?

The error ‘Not enough storage is available to process this command’ usually occurs in Windows servers when the registry value is set incorrectly or after a recent reset or reinstallations, the configurations are not set correctly.
Below is verified procedure for this issue:
Click on Start > Run > regedit & press Enter
Find this key name HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters
Locate IRPStackSize
If this value does not exist Right Click on Parameters key and Click on New > Dword Value and type in IRPStackSize under the name.
The name of the value must be exactly (combination of uppercase and lowercase letters) the same as what I have above.
Right Click on the IRPStackSize and click on Modify
Select Decimal enter a value higher than 15(Maximum Value is 50 decimal) and Click Ok
You can close the registry editor and restart your computer.
Reference

After researching for a few days I finally can configure the Windows Server 2016 setting (registry) to prevent the crash.
So basically it is a limitation of the OS itself, it is called desktop heap limitation.
https://learn.microsoft.com/en-us/troubleshoot/windows-server/performance/desktop-heap-limitation-out-of-memory
(The funny thing is the error message is Not enough storage is available to process this command but the real problem came to desktop heap limitation. )
So for the solution, flowing the steps in this link: https://learn.microsoft.com/en-us/troubleshoot/system-center/orchestrator/increase-maximum-number-concurrent-policy-instances
I increased the 3rd parameter of SharedSection to 2048 and it fix the issue.
Summary steps:
Desktop Heap for the non-interactive desktops is identified by the third parameter of the SharedSection= segment of the following registry value:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows
The default data for this registry value will look something like the following:
%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,3072,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=Off MaxRequestThreads=16
The value to be entered into the Third Parameter of the SharedSection= segment should be based on the calculation of:
(number of desired concurrent policies) * 10 = (third parameter value)
Example: If it's desired to have 200 concurrent policy instances, then 200 * 10 = 2000, rounding up to a nice memory number gives you 2048as the third parameter resulting in the following update to be made to the registry value:
SharedSection=1024,3072,2048

Related

Streaming MutationGroups into Spanner

I'm trying to stream MutationGroups into spanner with SpannerIO.
The goal is to write new MuationGroups every 10 seconds, as we will use spanner to query near-time KPI's.
When I don't use any windows, I get the following error:
Exception in thread "main" java.lang.IllegalStateException: GroupByKey cannot be applied to non-bounded PCollection in the GlobalWindow without a trigger. Use a Window.into or Window.triggering transform prior to GroupByKey.
at org.apache.beam.sdk.transforms.GroupByKey.applicableTo(GroupByKey.java:173)
at org.apache.beam.sdk.transforms.GroupByKey.expand(GroupByKey.java:204)
at org.apache.beam.sdk.transforms.GroupByKey.expand(GroupByKey.java:120)
at org.apache.beam.sdk.Pipeline.applyInternal(Pipeline.java:537)
at org.apache.beam.sdk.Pipeline.applyTransform(Pipeline.java:472)
at org.apache.beam.sdk.values.PCollection.apply(PCollection.java:286)
at org.apache.beam.sdk.transforms.Combine$PerKey.expand(Combine.java:1585)
at org.apache.beam.sdk.transforms.Combine$PerKey.expand(Combine.java:1470)
at org.apache.beam.sdk.Pipeline.applyInternal(Pipeline.java:537)
at org.apache.beam.sdk.Pipeline.applyTransform(Pipeline.java:491)
at org.apache.beam.sdk.values.PCollection.apply(PCollection.java:299)
at org.apache.beam.sdk.io.gcp.spanner.SpannerIO$WriteGrouped.expand(SpannerIO.java:868)
at org.apache.beam.sdk.io.gcp.spanner.SpannerIO$WriteGrouped.expand(SpannerIO.java:823)
at org.apache.beam.sdk.Pipeline.applyInternal(Pipeline.java:537)
at org.apache.beam.sdk.Pipeline.applyTransform(Pipeline.java:472)
at org.apache.beam.sdk.values.PCollection.apply(PCollection.java:286)
at quantum.base.transform.entity.spanner.SpannerProtoWrite.expand(SpannerProtoWrite.java:52)
at quantum.base.transform.entity.spanner.SpannerProtoWrite.expand(SpannerProtoWrite.java:20)
at org.apache.beam.sdk.Pipeline.applyInternal(Pipeline.java:537)
at org.apache.beam.sdk.Pipeline.applyTransform(Pipeline.java:491)
at org.apache.beam.sdk.values.PCollection.apply(PCollection.java:299)
at quantum.entitybuilder.pipeline.EntityBuilderPipeline$Write$SpannerWrite.expand(EntityBuilderPipeline.java:388)
at quantum.entitybuilder.pipeline.EntityBuilderPipeline$Write$SpannerWrite.expand(EntityBuilderPipeline.java:372)
at org.apache.beam.sdk.Pipeline.applyInternal(Pipeline.java:537)
at org.apache.beam.sdk.Pipeline.applyTransform(Pipeline.java:491)
at org.apache.beam.sdk.values.PCollection.apply(PCollection.java:299)
at quantum.entitybuilder.pipeline.EntityBuilderPipeline.main(EntityBuilderPipeline.java:122)
:entityBuilder FAILED
Because of the error above I assume the input collection needs to be windowed and triggered, as SpannerIO uses a GroupByKey (this is also what I need for my use case):
...
.apply("1-minute windows", Window.<MutationGroup>into(FixedWindows.of(Duration.standardMinutes(1)))
.triggering(Repeatedly.forever(AfterProcessingTime
.pastFirstElementInPane()
.plusDelayOf(Duration.standardSeconds(10))
).orFinally(AfterWatermark.pastEndOfWindow()))
.discardingFiredPanes()
.withAllowedLateness(Duration.ZERO))
.apply(SpannerIO.write()
.withProjectId(entityConfig.getSpannerProject())
.withInstanceId(entityConfig.getSpannerInstance())
.withDatabaseId(entityConfig.getSpannerDb())
.grouped());
When I do this, I get the following exceptions during runtime:
java.lang.IllegalArgumentException: Attempted to get side input window for GlobalWindow from non-global WindowFn
org.apache.beam.sdk.transforms.windowing.PartitioningWindowFn$1.getSideInputWindow(PartitioningWindowFn.java:49)
com.google.cloud.dataflow.worker.StreamingModeExecutionContext$StepContext.issueSideInputFetch(StreamingModeExecutionContext.java:631)
com.google.cloud.dataflow.worker.StreamingModeExecutionContext$UserStepContext.issueSideInputFetch(StreamingModeExecutionContext.java:683)
com.google.cloud.dataflow.worker.StreamingSideInputFetcher.storeIfBlocked(StreamingSideInputFetcher.java:182)
com.google.cloud.dataflow.worker.StreamingSideInputDoFnRunner.processElement(StreamingSideInputDoFnRunner.java:71)
com.google.cloud.dataflow.worker.SimpleParDoFn.processElement(SimpleParDoFn.java:323)
com.google.cloud.dataflow.worker.util.common.worker.ParDoOperation.process(ParDoOperation.java:43)
com.google.cloud.dataflow.worker.util.common.worker.OutputReceiver.process(OutputReceiver.java:48)
com.google.cloud.dataflow.worker.SimpleParDoFn$1.output(SimpleParDoFn.java:271)
org.apache.beam.runners.core.SimpleDoFnRunner.outputWindowedValue(SimpleDoFnRunner.java:219)
org.apache.beam.runners.core.SimpleDoFnRunner.access$700(SimpleDoFnRunner.java:69)
org.apache.beam.runners.core.SimpleDoFnRunner$DoFnProcessContext.output(SimpleDoFnRunner.java:517)
org.apache.beam.runners.core.SimpleDoFnRunner$DoFnProcessContext.output(SimpleDoFnRunner.java:505)
org.apache.beam.sdk.values.ValueWithRecordId$StripIdsDoFn.processElement(ValueWithRecordId.java:145)
After investigating further it appears to be due to the .apply(Wait.on(input)) in SpannerIO: It has a global side input which does not seem to work with my fixed windows, as the docs of Wait.java state:
If signal is globally windowed, main input must also be. This typically would be useful
* only in a batch pipeline, because the global window of an infinite PCollection never
* closes, so the wait signal will never be ready.
As a temporary workaround I tried the following:
add a GlobalWindow with triggers instead of fixed windows:
.apply("globalwindow", Window.<MutationGroup>into(new GlobalWindows())
.triggering(Repeatedly.forever(AfterProcessingTime
.pastFirstElementInPane()
.plusDelayOf(Duration.standardSeconds(10))
).orFinally(AfterWatermark.pastEndOfWindow()))
.discardingFiredPanes()
.withAllowedLateness(Duration.ZERO))
This results in writes to spanner only when I drain my pipeline. I have the impression the Wait.on() signal is only triggered when the Global windows closes, and doesn't work with triggers.
Disable the .apply(Wait.on(input)) in SpannerIO:
This results in the pipeline getting stuck on the view creation which
is described in this SO post:
SpannerIO Dataflow 2.3.0 stuck in CreateDataflowView.
When I check the worker logs for clues, I do get the following warnings:
logger: "org.apache.beam.sdk.coders.SerializableCoder"
message: "Can't verify serialized elements of type SpannerSchema have well defined equals method. This may produce incorrect results on some PipelineRunner
logger: "org.apache.beam.sdk.coders.SerializableCoder"
message: "Can't verify serialized elements of type BoundedSource have well defined equals method. This may produce incorrect results on some PipelineRunner"
Note that everything works with the DirectRunner and that I'm trying to use the DataflowRunner.
Does anyone have any other suggestions for things I can try to get this running? I can hardly imagine that I'm the only one trying to stream MutationGroups into spanner.
Thanks in advance!
Currently, SpannerIO connector is not supported with Beam Streaming. Please follow this Pull Request which adds streaming support for spanner IO connector.

Access Strucuture Sensor via OpenNI 2 from UWP App targeting Windows 10

I'd like to access the Structure Sensor (https://structure.io) via OpenNI 2 (https://github.com/occipital/openni2) from an UWP App running on a Windows 10 Desktop.
The Setup
For this very reason I created a Windows Runtime Component (Universal Windows) in C++ besides my actual UWP App. This component exports several functions basically miming the initialization behavior of one of the samples in above OpenNI Github repo.
I extended the code to also iterate through all available devices:
// Initialize OpenNI
Status rc = OpenNI::initialize();
if (rc != STATUS_OK)
{
logError("Initialize failed + " + std::string(OpenNI::getExtendedError()));
return false;
}
// Get all attached sensors supported by OpenNI
Array<DeviceInfo> deviceList;
OpenNI::enumerateDevices(&deviceList);
for (int i = 0; i < deviceList.getSize(); i++) {
logInfo(deviceList[i].getName());
logInfo(deviceList[i].getUri());
}
// Actual open device
Device device;
rc = device.open(deviceList[0].getUri());
if (rc != STATUS_OK)
{
logError("Error = " + to_string(rc));
logError("Couldn't open device " + std::string(OpenNI::getExtendedError()));
return false;
}
The Problem
Calling above code from my UWP app through the Windows Runtime Component is successful when initializing OpenNI and enumerating over all available devices:
[INFO] PS1080
[INFO] \\?\usb#vid_1d27&pid_0600#13261#{c3b5f022-5a42-1980-1909-ea72095601b1}
Actually Opening the device via device.open is the actual problem (Error 1 = STATUS_ERROR)
[ERROR] Error = 1
[ERROR] Couldn't open device Could not open "\\?\usb#vid_1d27&pid_0600#13261#{c3b5f022-5a42-1980-1909-ea72095601b1}": USB device not found!
I'm also under the impression that above error message is a bit misleading, as the actual message when having no device attached is:
[ERROR] Error = 1
[ERROR] Couldn't open device DeviceOpen using default: no devices found
I already tried to add a USB device capability to the package mainifest without any success.
<DeviceCapability Name="usb">
<Device Id="vidpid:1D27 0600">
<!--<Function Type="classId:ff * *" />-->
<Function Type="name:vendorSpecific"/>
</Device>
</DeviceCapability>
I also verified that above code is working when directly building a classic C++ program without targeting UWP at all.
I would be very happy for any direction/hint you can provide me with
The Solution
Microsoft's UWP policy simply doesn't allow access to USB devices. But you can workaround that by grant the UWP AppContainer Process access to the Structure IO sensor.
Some manual work is required though:
Open the registry editor and go to the USB entry of the Structure IO sensor HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\VID_1D27&PID_0600
Uncollapse this node and right click on the node below this one and copy the whole key in to clipboard. The last digit is very important here and differs from machine to machine (e.g. HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\VID_1D27&PID_0600\13261)
Copy this key into following registry file where the brackets are. The following registry modification basically allows every UWP app access to the structure I/O sensor.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\VID_1D27&PID_0600\13261]
"Security"=hex:1,0,4,90,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,2,0,60,0,4,0,0,0,0,0,14,0,0,0,0,10,1,1,0,0,0,0,0,5,12,0,0,0,0,0,18,0,0,0,0,10,1,2,0,0,0,0,0,5,20,0,0,0,20,2,0,0,0,0,14,0,0,0,0,10,1,1,0,0,0,0,0,5,B,0,0,0,0,0,18,0,0,0,0,10,1,2,0,0,0,0,0,F,2,0,0,0,1,0,0,0
Modify the following batch script to point to the full path(!) of above registry file. This script is needed to modify the registry with the security string. This is only allowed by Window's SYSTEM account. That's why we need to create a task for that.
call schtasks /create /RU SYSTEM /SC ONCE /TN DeviceAC /TR "reg import c:\full\path\to\registry\file.reg" /ST 00:00
call schtasks /run /tn DeviceAC
call schtasks /delete /tn DeviceAC /f
Run the above batch script with Administrator privileges
After successfully executing the script, make sure there's a new entry called "Security" below you node from 2.
If the sensor is already connected to your PC you'll need to reconnect it.
Now the code from my Question above should work :)
You'll find a detailed read on how to solve this problem here:
https://developer.microsoft.com/en-us/windows/iot/Samples/CustomDeviceAccessor

How to refresh logon screensaver parameter changes?

I have a Windows service that may change the timeout on the logon screensaver in Windows (as described here.) To do that I change the following registry key to the timeout in seconds:
HKEY_USERS\.DEFAULT\Control Panel\Desktop\ScreenSaveTimeOut
The issue is that how do I make OS "read" or refresh the actual screensaver timeout after a change in the registry key above?
My practice shows that it is refreshed (for sure) only when I reboot the system, but in my case I need it to be applied without the reboot.
EDIT_1: After suggestion below I tried, as it seems to me, all possible combinations of the flags for the following:
DWORD bsmInfo1 = BSM_ALLDESKTOPS;
DWORD dwFlgs = BSF_FORCEIFHUNG | BSF_IGNORECURRENTTASK | BSF_NOTIMEOUTIFNOTHUNG | BSF_SENDNOTIFYMESSAGE;
int nbsm1 = ::BroadcastSystemMessage(dwFlgs, &bsmInfo1, WM_SETTINGCHANGE, 0, (LPARAM)L"Windows");
DWORD bsmInfo2 = BSM_ALLDESKTOPS;
int nbsm2 = ::BroadcastSystemMessage(dwFlgs, &bsmInfo2, WM_SETTINGCHANGE, 0, (LPARAM)L"WindowsThemeElement");
to no avail :( I receive 1 as a result from both calls but it has no effect.
I was able to resolve this.-.-.
If your service is running in the same session as the logon screensaver then you can call SystemParametersInfo with the SPI_SETSCREENSAVETIMEOUT flag.
SystemParametersInfo broadcasts the WM_SETTINGCHANGE message to all top level windows to indicate that a parameter has changed. If your code isn't running in the correct session then you could use BroadcastSystemMessage with the BSM_ALLDESKTOPS flag to deliver the WM_SETTINGCHANGE message. However, this does require the SE_TCB_NAME privilege, so your code would have to be running as SYSTEM.
I haven't actually tried this cross-session, so I can't guarantee that it works.

Restarting Application: Delay

I'm coding a restart feature into my newest Crysis Wars server modification that remotely reboots the server. This is useful if the server has a problem and a simple system reload does not fix it, also is useful to tell the server to restart at a specified time in order to free up memory.
I have coded the required functions in order to achieve this, and the application itself has no problem restarting. The issue is that the port is not closed quickly enough, resulting in a new instance of the application that cannot function properly.
I am looking for an ideal solution to this, that the program is shut down and launches two seconds later, instead of immediately. Doing this will give Windows enough time to free the port that the server was using, and clean up any existing memory.
Please Note: I have removed my other (related) question since apparently closing program ports is impossible without telling it to do so when it it assigned the port, which is something I cannot do since I don't have access to the sourcecode of the code that binds to the port.
The code, if it's required
int CScriptBind_GameRules::Restart(IFunctionHandler *pH)
{
bool arg1 = false;
const char *arg2 = "";
gEnv->pScriptSystem->BeginCall("Dynamic","GetValue");
gEnv->pScriptSystem->PushFuncParam("r.enable");
gEnv->pScriptSystem->EndCall(arg1);
gEnv->pScriptSystem->BeginCall("Dynamic","GetValue");
gEnv->pScriptSystem->PushFuncParam("r.line");
gEnv->pScriptSystem->EndCall(arg2);
if (arg1)
{
LogMsg(2, "System restart initiated.");
if (arg2)
{
LogMsg(2, "System Reboot.");
gEnv->pScriptSystem->BeginCall("os","execute");
gEnv->pScriptSystem->PushFuncParam(arg2);
gEnv->pScriptSystem->EndCall(), close((int)gEnv->pConsole->GetCVar("sv_port")->GetString());
return pH->EndFunction();
}
else
{
LogMsg(2, "Internal Faliure.");
return pH->EndFunction();
}
return pH->EndFunction();
}
LogMsg(2, "System restart cancelled: Feature is Disabled.");
return pH->EndFunction();
}
What I usually do is add a command-line parameter, 'StartupDelay'. When the server/whatever starts up, before attempting to run the listener etc, it checks for that parameter. If no param, it runs up normally, if it finds 'StartupDelay=2000', it sleeps for 2 seconds before attempting to start the listener etc.
Result - if started from desktop icon, it starts immediately. If it needs to 'restart itself' it sets the parameter to instruct the new instance of itself to wait as directed.

Jetty 8.1 flooding the log file with "Dispatched Failed" messages

We are using Jetty 8.1 as an embedded HTTP server. Under overload conditions the server sometimes starts flooding the log file with these messages:
warn: java.util.concurrent.RejectedExecutionException
warn: Dispatched Failed! SCEP#76107610{l(...)<->r(...),d=false,open=true,ishut=false,oshut=false,rb=false,wb=false,w=true,i=1r}...
The same message is repeated thousands of times, and the amount of logging appears to slow down the whole system. The messages itself are fine, our request handler ist just to slow to process the requests in time. But the huge number of repeated messages makes things actually worse and makes it more difficult for the system to recover from the overload.
So, my question is: is this a normal behaviour, or are we doing something wrong?
Here is how we set up the server:
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setAcceptQueueSize( 10 );
server.setConnectors( new Connector[]{ connector } );
server.setThreadPool( new ExecutorThreadPool( 32, 32, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>( 10 )));
The SelectChannelEndPoint is the origin of this log message.
To not see it, just set your named logger of org.eclipse.jetty.io.nio.SelectChannelEndPoint to LEVEL=OFF.
Now as for why you see it, that is more interesting to the developers of Jetty. Can you detail what specific version of Jetty you are using and also what specific JVM you are using?