Browse Source

feat: implement searchd --mockstack

daemon will calculate necessary stack sizes for recursive evaluation of
expressions, matching, and filters. Calculated values then dumped to
console.
Aleksey N. Vinogradov 11 months ago
parent
commit
fe9473dc3f
3 changed files with 35 additions and 18 deletions
  1. 17 4
      src/searchd.cpp
  2. 15 11
      src/stackmock.cpp
  3. 3 3
      src/stackmock.h

+ 17 - 4
src/searchd.cpp

@@ -19922,6 +19922,7 @@ void ShowHelp ()
 		"--pidfile\t\tforce using the PID file (useful with --console)\n"
 		"--safetrace\t\tonly use system backtrace() call in crash reports\n"
 		"--coredump\t\tsave core dump file on crash\n"
+		"--mockstack\t\tdump safe stack sizes and exit\n"
 		"\n"
 		"Examples:\n"
 		"searchd --config /usr/local/sphinx/etc/manticore.conf\n"
@@ -21390,6 +21391,7 @@ int WINAPI ServiceMain ( int argc, char **argv ) EXCLUDES (MainThread)
 	bool			bNewClusterForce = false;
 	bool			bForcePseudoSharding = false;
 	const char*		szCmdConfigFile = nullptr;
+	bool			bMeasureStack = false;
 
 	DWORD			uReplayFlags = 0;
 
@@ -21413,6 +21415,7 @@ int WINAPI ServiceMain ( int argc, char **argv ) EXCLUDES (MainThread)
 		OPT1 ( "--pidfile" )		bOptPIDFile = true;
 		OPT1 ( "--iostats" )		g_bIOStats = true;
 		OPT1 ( "--cpustats" )		g_bCpuStats = true;
+		OPT1 ( "--mockstack" )		{ bMeasureStack = true; g_bOptNoLock = true; g_bOptNoDetach = true; }
 #if _WIN32
 		OPT1 ( "--install" )		{ if ( !g_bService ) { ServiceInstall ( argc, argv ); return 0; } }
 		OPT1 ( "--delete" )			{ if ( !g_bService ) { ServiceDelete (); return 0; } }
@@ -21460,6 +21463,20 @@ int WINAPI ServiceMain ( int argc, char **argv ) EXCLUDES (MainThread)
 	if ( i!=argc )
 		sphFatal ( "malformed or unknown option near '%s'; use '-h' or '--help' to see available options.", argv[i] );
 
+	StringBuilder_c sStack;
+	DetermineNodeItemStackSize ( sStack );
+	DetermineFilterItemStackSize ( sStack );
+	DetermineMatchStackSize ( sStack );
+
+	if ( bMeasureStack )
+	{
+		if ( !g_bService )
+			{
+			sStack << "export NO_STACK_CALCULATION=1\n";
+			fprintf ( stdout, "%s", sStack.cstr() );
+		}
+		return 0;
+	}
 	SetupLemmatizerBase();
 	g_sConfigFile = sphGetConfigFile ( szCmdConfigFile );
 #if _WIN32
@@ -21759,10 +21776,6 @@ int WINAPI ServiceMain ( int argc, char **argv ) EXCLUDES (MainThread)
 
 	CacheCPUInfo();
 
-	DetermineNodeItemStackSize();
-	DetermineFilterItemStackSize();
-	DetermineMatchStackSize();
-
 	// initialize timeouts since hook will use them
 	auto iRtFlushPeriodUs = hSearchd.GetUsTime64S ( "rt_flush_period", 36000000000ll ); // 10h
 	SetRtFlushPeriod ( Max ( iRtFlushPeriodUs, 3 * 1000000 ) ); // min 3S

+ 15 - 11
src/stackmock.cpp

@@ -549,7 +549,7 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS StackSizeTuplet_t FullTextStackSize_c::MockMeasure
 
 
 template<typename MOCK, int FRAMEVAL=0, int INITVAL=0>
-ATTRIBUTE_NO_SANITIZE_ADDRESS void DetermineStackSize ()
+ATTRIBUTE_NO_SANITIZE_ADDRESS void DetermineStackSize (StringBuilder_c& sExport)
 {
 	int iFrameSize = FRAMEVAL;
 	int iInitSize = INITVAL;
@@ -573,8 +573,10 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void DetermineStackSize ()
 #endif
 		}
 		iFrameSize = tNewSize.m_iEval;
-		if ( bMocked )
+		if ( bMocked ) {
 			sphLogDebug ( "Frame %s is %d (mocked, as no env MANTICORE_%s=%d found)", szReport, iFrameSize, szEnv, iFrameSize );
+			sExport.Sprint ( "export MANTICORE_", szEnv, "=", iFrameSize, "\n" );
+		}
 		else
 			sphLogDebug ( "Frame %s %d (from env MANTICORE_%s)", szReport, iFrameSize, szEnv );
 	} else
@@ -598,8 +600,10 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void DetermineStackSize ()
 #endif
 		}
 		iInitSize = tNewSize.m_iCreate;
-		if ( bMocked )
+		if ( bMocked ) {
 			sphLogDebug ( "Starting %s is %d (mocked, as no env MANTICORE_START_%s=%d found)", szReport, iInitSize, szEnv, iInitSize );
+			sExport.Sprint ( "export MANTICORE_START_", szEnv, "=", iInitSize, "\n");
+		}
 		else
 			sphLogDebug ( "Starting %s %d (from env MANTICORE_START_%s)", szReport, iInitSize, szEnv );
 	} else
@@ -611,7 +615,7 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void DetermineStackSize ()
 }
 
 
-void DetermineNodeItemStackSize()
+void DetermineNodeItemStackSize( StringBuilder_c& sExport )
 {
 	// some values for x86_64: clang 12.0.1 relwithdebinfo = 768, debug = 4208. gcc 9.3 relwithdebinfo = 16, debug = 256
 #ifdef KNOWN_CREATE_SIZE
@@ -619,7 +623,7 @@ void DetermineNodeItemStackSize()
 #else
 	DetermineStackSize<CreateExprStackSize_c>
 #endif
-		();
+		(sExport);
 
 	// some values for x86_64: clang 12.0.1 relwithdebinfo = 32, debug = 48. gcc 9.3 relwithdebinfo = 48, debug = 48
 #ifdef KNOWN_EXPR_SIZE
@@ -627,11 +631,11 @@ void DetermineNodeItemStackSize()
 #else
 	DetermineStackSize<EvalExprStackSize_c>
 #endif
-		();
-	DetermineStackSize<DeleteExprStackSize_c>();
+		(sExport);
+	DetermineStackSize<DeleteExprStackSize_c>(sExport);
 }
 
-void DetermineFilterItemStackSize ()
+void DetermineFilterItemStackSize ( StringBuilder_c& sExport )
 {
 	// some values for x86_64: clang 12.0.1 relwithdebinfo = 208, debug = 400. gcc 9.3 relwithdebinfo = 240, debug = 272
 #ifdef KNOWN_FILTER_SIZE
@@ -639,10 +643,10 @@ void DetermineFilterItemStackSize ()
 #else
 	DetermineStackSize<FilterCreationMeasureStack_c>
 #endif
-		();
+		(sExport);
 }
 
-void DetermineMatchStackSize()
+void DetermineMatchStackSize(StringBuilder_c& sExport)
 {
 #ifdef KNOWN_MATCH_SIZE
 #ifdef START_KNOWN_MATCH_SIZE
@@ -653,6 +657,6 @@ void DetermineMatchStackSize()
 #else
 	DetermineStackSize<FullTextStackSize_c, 0>
 #endif
-		();
+		(sExport);
 }
 

+ 3 - 3
src/stackmock.h

@@ -76,6 +76,6 @@ inline std::pair<int, CSphString> EvalStackForExpr ( const StackSizeParams_t & t
 	return { iStackNeeded, {} };
 }
 
-void DetermineNodeItemStackSize();
-void DetermineFilterItemStackSize();
-void DetermineMatchStackSize();
+void DetermineNodeItemStackSize ( StringBuilder_c& sExport );
+void DetermineFilterItemStackSize ( StringBuilder_c& sExport );
+void DetermineMatchStackSize ( StringBuilder_c& sExport );