fork(5) download
  1. // ConsoleTestRun03.cpp : 頑健なテスト駆動ルーチン
  2. //
  3. // / GS / GL / analyze - / W3 / Gy / Zc:wchar_t / Zi / Gm - / O2 / Fd"Release\vc140.pdb" / Zc : inline / fp : precise / D "WIN32" / D "NDEBUG" / D "_CONSOLE" / D "_UNICODE" / D "UNICODE" / fp : except / errorReport : prompt / WX - / Zc : forScope / Gd / Oy - / Oi / MD / Fa"Release\" /EHsc /nologo /Fo"Release\" /FAcs /Fp"Release
  4. //
  5. #ifdef _MSC_VER
  6. #include "stdafx.h"
  7. #include <float.h>
  8. #include <excpt.h>
  9. #else
  10. #include <stdexcept>
  11. #include <execinfo.h>
  12. #include <unistd.h>
  13. #endif
  14.  
  15. #include <string>
  16.  
  17. #include <errno.h>
  18. #include <iostream>
  19. #include <iomanip>
  20.  
  21. #include <algorithm>
  22. #include <functional>
  23. #include <chrono> // std::chrono::seconds
  24. #include <ratio>
  25.  
  26. #include <thread>
  27. #include <future>
  28. #include <exception>
  29.  
  30. #include <cstdlib>
  31. #include <cstring>
  32. #include <memory>
  33. #include <csignal>
  34. //#include <new>
  35. //#include <cmath>
  36. //#include <cfloat>
  37. #include <vector>
  38. #include <random>
  39.  
  40.  
  41. //環境依存関数のラッピング
  42. #define TestStatusStoreValue(x,y) #x #y
  43. #ifdef _MSC_VER
  44. #define myStrCopy(dest,src) strcpy_s(dest,src)
  45. #define myStrCat(dest,src) strcat_s(dest,src)
  46. #else
  47. #define myStrCopy(dest,src) strcpy(dest,src)
  48. #define myStrCat(dest,src) strcat(dest,src)
  49. #endif
  50. //テスト検証 補助用関数
  51. void memDump(void * a, int offset, int len) {
  52. void * curSP;
  53. #ifdef _MSC_VER
  54. __asm {
  55. mov curSP, esp
  56. }
  57. #else
  58. __asm__("mov %%esp,%0" : "=A" (curSP));
  59. #endif
  60. unsigned int *x = ((unsigned int *)(((int)a + offset) & 0xfffffff0)); // 4バイト
  61. unsigned int *e = ((unsigned int *)((char *)a + offset + len));
  62. if ((void *)x > (void *)((char*)curSP - 16)) x = (unsigned int *)(((int)curSP - 16) & 0xfffffff0);
  63. if ((void *)x > (void *)((char*)&a - 16)) x = (unsigned int *)(((int)&a - 16) & 0xfffffff0);
  64. if ((void *)e < (void *)&x) e = (unsigned int *)&x;
  65. std::cout << std::hex << std::endl;
  66. std::cout.width(16); std::cout.fill('0');
  67. std::cout << curSP << std::endl;
  68. std::cout << a << std::endl;
  69. std::cout << &a << std::endl;
  70. do {
  71. std::cout << std::setw(12) << std::setfill('0') << x << ": ";
  72. std::cout << std::setw(8) << std::setfill('0') << x[0]
  73. << ' ' << std::setw(8) << std::setfill('0') << x[1]
  74. << ' ' << std::setw(8) << std::setfill('0') << x[2]
  75. << ' ' << std::setw(8) << std::setfill('0') << x[3] << std::endl;
  76. x += 4;
  77. } while (x <= e);
  78. }
  79.  
  80. //要素数9個固定ソートasm版
  81. #ifdef _MSC_VER
  82. #define CONDSWAPA(p,q) __asm{ \
  83. __asm mov eax,[ebp+p*4] \
  84. __asm mov ebx,[ebp+q*4] \
  85. __asm cmp eax,ebx \
  86. __asm cmovl ebx,eax \
  87. __asm cmovl eax,[ebp+q*4] \
  88. __asm mov [ebp+p*4],eax \
  89. __asm mov [ebp+q*4],ebx \
  90. }
  91. #define CONDSWAPC(p,q) __asm{ \
  92. __asm mov ecx,[ebp+p*4] \
  93. __asm mov edx,[ebp+q*4] \
  94. __asm cmp ecx,edx \
  95. __asm cmovl edx,ecx \
  96. __asm cmovl ecx,[ebp+q*4] \
  97. __asm mov [ebp+p*4],ecx \
  98. __asm mov [ebp+q*4],edx \
  99. }
  100. #else
  101. // for linux gcc/x86
  102. #define CONDSWAPA(p,q) __asm__ ( \
  103.   "mov %0, %%eax;" \
  104.   "mov %1, %%ebx;" \
  105.   "cmp %%ebx, %%eax;" \
  106.   "cmovl %%ebx,%0 ;" \
  107.   "cmovl %%eax,%1 ;" \
  108.   :"+r"(d[p]),"+r"(d[q]): \
  109.   : "%eax", "%ebx", "memory" );
  110. #define CONDSWAPC(p,q) __asm__ ( \
  111.   "mov %0, %%ecx;" \
  112.   "mov %1, %%edx;" \
  113.   "cmp %%edx, %%ecx;" \
  114.   "cmovl %%edx,%0 ;" \
  115.   "cmovl %%ecx,%1 ;" \
  116.   :"+r"(d[p]),"+r"(d[q]): \
  117.   : "%ecx", "%edx", "memory" );
  118. #endif
  119. //#undef CONDSWAPA
  120. //#undef CONDSWAPC
  121. //#define CONDSWAPA(p,q) {register unsigned int w;if(d[p]>d[q]){w=d[p];d[p]=d[q];d[q]=w;}}
  122. //#define CONDSWAPC(p,q) {register unsigned int w;if(d[p]>d[q]){w=d[p];d[p]=d[q];d[q]=w;}}
  123. #define ASMSORT4(a,b,c,d) \
  124.   CONDSWAPA(a,b); \
  125.   CONDSWAPC(c,d); \
  126.   CONDSWAPC(b,c); \
  127.   CONDSWAPA(a,b); \
  128.   CONDSWAPC(c,d);
  129.  
  130.  
  131. int sort9l(void *v) {
  132. int *d = (int *)v;
  133. #ifdef _MSC_VER
  134. #pragma warning(disable : 4731)
  135. __asm {
  136. push ebp
  137. mov ebp, d
  138. }
  139. #endif
  140. ASMSORT4(0, 1, 2, 3);
  141. ASMSORT4(4, 5, 6, 7);
  142.  
  143. CONDSWAPA(0, 4);
  144. CONDSWAPC(1, 5);
  145. CONDSWAPA(2, 6);
  146. CONDSWAPC(3, 7);
  147.  
  148. CONDSWAPA(7, 8);
  149.  
  150. CONDSWAPC(5, 7);
  151. CONDSWAPA(4, 6);
  152. CONDSWAPC(1, 3);
  153. CONDSWAPA(0, 2);
  154.  
  155. CONDSWAPC(3, 5);
  156. CONDSWAPA(2, 4);
  157.  
  158. ASMSORT4(0, 1, 2, 3);
  159. ASMSORT4(4, 5, 6, 7);
  160.  
  161. CONDSWAPA(3, 4);
  162. CONDSWAPA(2, 3);
  163. CONDSWAPA(4, 5);
  164. CONDSWAPA(3, 4);
  165. #ifdef _MSC_VER
  166. __asm {
  167. pop ebp
  168. }
  169. #pragma warning(default : 4731)
  170. #endif
  171. return 0;
  172. }
  173. //順列生成しながら降順ソートをテストする
  174. template<typename T, typename U,typename V> int testByGenPerm(size_t n, T testData, int(*testFunc)(V)) {
  175. unsigned int i, k, c[9 + 1];
  176. for (i = 0; i <= n; i++) c[i] = i;
  177. int iter = 0;
  178. k = 1;
  179. while (k < n) {
  180. if (k & 1) { i = c[k]; }
  181. else { i = 0; }
  182. {U w; w = testData[k]; testData[k] = testData[i]; testData[i] = w; } //1件のデータ生成のオーバヘッドを最小化
  183. if ((*testFunc)(testData)) return 1;
  184. iter++;
  185. for (k = 1; k < n; k++) if (testData[k - 1] < testData[k]) return 1;//降順でなければFailed
  186. for (k = 1; (c[k] == 0); k++) { c[k] = k; }
  187. c[k]--;
  188. }
  189. std::cout << n << "個のデータを" << iter << "回 ソート実行完了." << std::endl;
  190. return 0;
  191. }
  192. //ここまでテスト検証 補助用関数
  193.  
  194. /////ここから非テストコード毎の宣言
  195. int testCase1(void);
  196. int testCase2(void);
  197. int testCase3(void);
  198. int testCase4(void);
  199. int testCase5(void);
  200. int testCase6_Ok(std::vector<int> & toBeSortedData);
  201. int testCase6_NG(std::vector<int> & toBeSortedData);
  202. int testCase7(std::vector<float> & toBeSortedData);
  203. /////ここまで非テストコード
  204. /////ここから非テストコード毎の検証コード
  205. int verifyCase1() { return testCase1(); }
  206. int verifyCase2() { return testCase2(); }
  207. int verifyCase3() { return testCase3(); }
  208. int verifyCase4() { return testCase4(); }
  209. int verifyCase5() { return testCase5(); }
  210. template<typename T> int verifySort(int(*testFunc)(std::vector<T> &)) {
  211. std::vector<T> toBeSrtedData{ 2,3,5,7,11,13,17,19,23 };
  212. return testByGenPerm<std::vector<T>, T, std::vector<T> &>(9, toBeSrtedData, testFunc);
  213. }
  214. int verifyCase6_Ok() { //整数9個の9の階乗 全件テスト
  215. return verifySort<int>(&testCase6_Ok);
  216. }
  217. int verifyCase6_NG() { //整数9個の9の階乗 全件テスト
  218. return verifySort<int>(&testCase6_NG);
  219. }
  220. int verifyCase7() { //float 9個、1万種類 ランダムテスト
  221. const int n = 9;
  222. std::random_device rnd; // 非決定的な乱数生成器でシード生成機を生成
  223. std::mt19937 mt(rnd()); // メルセンヌツイスターの32ビット版、引数は初期シード
  224. std::uniform_real_distribution<double> rand100(0.0, 1024.0); // [0, 1024] 範囲の一様乱数
  225. int iter;
  226. for (iter = 0; iter < 2000; iter++) {
  227. std::vector<float> toBeSrtedData;
  228. for (int i = 0; i < n; ++i) {
  229. toBeSrtedData.push_back((float)(rand100(mt)));
  230. }
  231. testCase7(toBeSrtedData); //降順テストの実装を呼び出す
  232. if (toBeSrtedData[0] < toBeSrtedData[1]
  233. || toBeSrtedData[1] < toBeSrtedData[2]
  234. || toBeSrtedData[2] < toBeSrtedData[3]
  235. || toBeSrtedData[3] < toBeSrtedData[4]
  236. || toBeSrtedData[4] < toBeSrtedData[5]
  237. || toBeSrtedData[5] < toBeSrtedData[6]
  238. || toBeSrtedData[6] < toBeSrtedData[7]
  239. || toBeSrtedData[7] < toBeSrtedData[8]) {//降順ソートできていなければ、中断
  240. //memDump(toBeSrtedData.data(), 0, 4 * 9);
  241. return 1;
  242. }
  243. }
  244. std::cout << std::endl << iter << " times sort done" << std::endl;
  245. return 0;
  246. }
  247. /////ここまで検証コード列を順次実行
  248.  
  249.  
  250. //テストドライバ
  251. typedef int verifyFunction(void);
  252. struct MyCexception : std::exception {
  253. const char* what() const noexcept { return "C exception throwed\n"; }
  254. } myCexception;
  255. void myTerminate()
  256. {
  257. throw myCexception;
  258. }
  259. struct MyAbortException : std::exception {
  260. const char* what() const noexcept { return "Abort signal Exception.\n"; }
  261. } myAbortException;
  262. void myAbortSignalHandler(int signum)
  263. {
  264. throw myAbortException;
  265. }
  266. struct MyIntSignalException : std::exception {
  267. const char* what() const noexcept { return "Interrupted Signal Exception.\n"; }
  268. } myIntSignalException;
  269. void myIntSignalHandler(int signum)
  270. {
  271. throw myIntSignalException;
  272. }
  273. struct MySEVSignalException : std::exception {
  274. const char* what() const noexcept { return "SIGSEGV 11 Signal Exception.\n"; }
  275. } mySEVSignalException;
  276. void mySEVSignalHandler(int signum)
  277. {
  278. throw mySEVSignalException;
  279. }
  280. struct MyFPESignalException : std::exception {
  281. const char* what() const noexcept { return "SIGFPE Signal Exception.\n"; }
  282. } myFPESignalException;
  283. void myFPESignalHandler(int signum)
  284. {
  285. throw myFPESignalException;
  286. }
  287.  
  288. class MyWorker {
  289. verifyFunction *targetFunc;
  290. char * testStatusDonePoint;
  291. char * testStatus;
  292. volatile bool running;
  293. double elapsedTime;
  294. int returnCode;
  295. char resultMessage[4096];
  296. public:
  297. static int timeLimit; // sleep関数用に、整数でミリ秒単位の許容走行時間の上限
  298. MyWorker(verifyFunction *targetFunc) :targetFunc(targetFunc) {
  299. this->testStatusDonePoint = NULL;
  300. this->testStatus = TestStatusStoreValue(a, __LINE__);
  301. this->running = false;
  302. this->elapsedTime = NAN;
  303. this->returnCode = -1;
  304. myStrCopy(this->resultMessage, "not begin.");
  305. }
  306. static void initTimeFacter();
  307. void RunWithGuardedCPPException() {
  308. this->testStatus = this->testStatusDonePoint = TestStatusStoreValue(b, __LINE__);
  309. myStrCopy(this->resultMessage, "begin.");
  310. this->running = true;
  311. try {
  312. std::chrono::high_resolution_clock::time_point startTime = std::chrono::high_resolution_clock::now();; // 計測スタート時刻
  313. this->returnCode = this->targetFunc(); // テスト対象関数呼び出し
  314. this->running = false;
  315. std::chrono::high_resolution_clock::time_point endTime = std::chrono::high_resolution_clock::now();; // 計測終了時刻
  316. std::chrono::duration<double> elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(endTime - startTime);
  317. this->elapsedTime = elapsed_seconds.count() ; //秒単位 浮動小数点数の走行時間計算
  318. this->testStatus = this->testStatusDonePoint = TestStatusStoreValue(c, __LINE__);
  319. }
  320. catch (std::exception &ex) {
  321. myStrCopy(this->resultMessage, ex.what());
  322. }
  323. catch (...) {
  324. myStrCopy(this->resultMessage, "An exception was caught in catch (...).");
  325. }
  326. this->running = false;
  327. }
  328. void RunWithGuardedNonCPPException() {
  329. std::terminate_handler unexpected_handlerBackup1 = std::set_terminate(myTerminate);
  330. std::unexpected_handler unexpected_handlerBackup2 = std::set_unexpected(myTerminate);
  331. std::signal(SIGINT, myIntSignalHandler);
  332. std::signal(SIGABRT, myAbortSignalHandler);
  333. std::signal(SIGSEGV, mySEVSignalHandler);
  334. std::signal(SIGFPE, myFPESignalHandler);
  335. #ifdef _MSC_VER
  336. union uint32by4bit {
  337. unsigned int fUint32;
  338. struct {//エンディアン依存ビットフィールド
  339. unsigned int f0 : 4;
  340. unsigned int f1 : 4;
  341. unsigned int f2 : 4;
  342. unsigned int f3 : 4;
  343. unsigned int f4 : 4;
  344. unsigned int f5 : 4;
  345. unsigned int f6 : 4;
  346. unsigned int f7 : 4;
  347. } xbit;
  348. } exceptionCode;
  349. _EXCEPTION_POINTERS *xp;
  350. __try {
  351. #endif
  352. #ifdef _MSC_VER
  353. _set_errno(0);
  354. #else
  355. errno = 0;
  356. #endif
  357. RunWithGuardedCPPException();
  358. if (errno != 0) { // check MATH error
  359. #pragma warning(disable : 4996)
  360. myStrCopy(this->resultMessage, strerror(errno)); //warning C4996: 'strerror': This function or variable may be unsafe.
  361. }
  362. else if (this->returnCode == 0) {
  363. myStrCopy(this->resultMessage, "Done & sucess.");
  364. }
  365. else {
  366. myStrCopy(this->resultMessage, "Done & but Failed.");
  367. }
  368. #ifdef _MSC_VER
  369. }
  370. // __except will only catch an C-SEH- exception here
  371. __except (exceptionCode.fUint32 = GetExceptionCode(),
  372. xp = GetExceptionInformation(),
  373. EXCEPTION_EXECUTE_HANDLER) {
  374. // if the exception was not caught by the catch(...) inside fail()
  375. #pragma warning(disable : 4996)
  376. myStrCopy(this->resultMessage, "An exception was caught in __except ......... ");
  377. #pragma warning(default : 4996)
  378. resultMessage[43] = exceptionCode.xbit.f0 + (exceptionCode.xbit.f0 < 10 ? '0' : 'A' - 10);
  379. resultMessage[42] = exceptionCode.xbit.f1 + (exceptionCode.xbit.f1 < 10 ? '0' : 'A' - 10);
  380. resultMessage[41] = exceptionCode.xbit.f2 + (exceptionCode.xbit.f2 < 10 ? '0' : 'A' - 10);
  381. resultMessage[40] = exceptionCode.xbit.f3 + (exceptionCode.xbit.f3 < 10 ? '0' : 'A' - 10);
  382. resultMessage[39] = exceptionCode.xbit.f4 + (exceptionCode.xbit.f4 < 10 ? '0' : 'A' - 10);
  383. resultMessage[38] = exceptionCode.xbit.f5 + (exceptionCode.xbit.f5 < 10 ? '0' : 'A' - 10);
  384. resultMessage[37] = exceptionCode.xbit.f6 + (exceptionCode.xbit.f6 < 10 ? '0' : 'A' - 10);
  385. resultMessage[36] = exceptionCode.xbit.f7 + (exceptionCode.xbit.f7 < 10 ? '0' : 'A' - 10);
  386. //struct _EXCEPTION_RECORD *rec = xp->ExceptionRecord;
  387. //std::stringstream ss;
  388. //ss << std::hex
  389. // << "An exception was caught in __except." << std::endl
  390. // << " code:" << rec->ExceptionCode
  391. // << " flags:" << rec->ExceptionFlags
  392. // << " addr:" << rec->ExceptionAddress
  393. // << " params:" << rec->NumberParameters
  394. // << std::endl;
  395. //return ss.str().c_str();
  396. };
  397. #endif
  398. this->running = false;
  399. };
  400.  
  401. void operator()() {
  402. this->RunWithGuardedNonCPPException();
  403. }
  404. bool isRunning() {
  405. return this->running;
  406. }
  407. static int getTimeLimit() {
  408. return timeLimit;
  409. }
  410. double getElapsedTime() {
  411. return this->elapsedTime;
  412. }
  413. char * getResultData() {
  414. if (this->running) return "running yet.";
  415. if (this->testStatus != this->testStatusDonePoint) {
  416. myStrCat(resultMessage, "?!\n may be hacked return.");
  417. }
  418. return resultMessage;
  419. }
  420. };
  421.  
  422. int MyWorker::timeLimit; //ミリ秒 整数単位の許容走行時間の上限
  423. void MyWorker::initTimeFacter() {
  424. float testData[9] = { 2.0, 3.0, 5.0 , 7.0, 11.0,13.0, 17.0,19.0,23.0 };
  425. std::chrono::high_resolution_clock::time_point startTime = std::chrono::high_resolution_clock::now(); // 高解像で計測スタート時刻
  426. testByGenPerm<float *,float,void *>(9, (float *)testData,&sort9l);
  427. std::chrono::high_resolution_clock::time_point endTime = std::chrono::high_resolution_clock::now();; // 計測終了時刻
  428. std::chrono::duration<double> elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(endTime - startTime);
  429. MyWorker::timeLimit = (int)(elapsed_seconds.count() * 1000 * 2.0f);
  430. std::cout << "参考処理の走行許容時間は " << elapsed_seconds.count() << "秒/test。" << std::endl;
  431. std::cout << "このマシン環境での走行許容時間は " << MyWorker::timeLimit << "ミリ秒/test。" << std::endl;
  432. }
  433.  
  434. class TestCaseClass {
  435. verifyFunction *targetFunc;
  436. char * title;
  437. int timeOut;
  438. char resultMessage[1024];
  439. long elapsedTime;
  440. public:
  441. TestCaseClass(verifyFunction *pTargetFunc, char * pTitle, int pTimeOut)
  442. :targetFunc(pTargetFunc), title(pTitle), timeOut(pTimeOut) {
  443. }
  444. void run() {
  445. std::cout << (this->title) << ":" << std::endl;
  446. MyWorker currentWorker(this->targetFunc);
  447. std::thread targetThread(std::ref(currentWorker)); //currentWorker.RunWithGuardedNonCPPException();
  448. #ifdef LINUXOS
  449. usleep(this->timeOut * 1000);
  450. #else
  451. std::this_thread::sleep_for(std::chrono::milliseconds(this->timeOut));
  452. #endif
  453. if (currentWorker.isRunning()) {
  454. targetThread.detach(); //テスト対象のスレッドの管理を外す。
  455. myStrCopy(this->resultMessage, "time over.");
  456. //テスト対象のネイティブ・スレッドは残存して走行し続けている。
  457. }
  458. else {
  459. targetThread.join(); //テスト対象のスレッドの管理を終える。
  460. myStrCopy(this->resultMessage, currentWorker.getResultData());
  461. }
  462. std::cout.setf(std::ios_base::fixed); std::cout.width(12); std::cout.precision(3);
  463. std::cout << (currentWorker.getElapsedTime()) << "mSec. " << (this->resultMessage) << std::endl;
  464. }
  465. };
  466.  
  467. int main(int argc, char *argv[])
  468. {
  469. {
  470. MyWorker::initTimeFacter();
  471. }
  472. //関数名:期待するexception,走行時間許容時間
  473. {TestCaseClass(verifyCase1, "verifyCase1: integer zero divide", 16).run(); }
  474. {TestCaseClass(verifyCase2, "verifyCase2: float zero divide or Nan", 16).run(); }
  475. {TestCaseClass(verifyCase3, "verifyCase3: DOMAIN Error", 16).run(); }
  476. {TestCaseClass(verifyCase4, "verifyCase4: stack over flow", 32).run(); }
  477. {TestCaseClass(verifyCase5, "verifyCase5: vector subscript out of range", MyWorker::timeLimit).run(); }
  478. {TestCaseClass(verifyCase6_NG, "verifyCase6_NG: hacking return ", MyWorker::timeLimit).run(); }
  479. {TestCaseClass(verifyCase6_Ok, "verifyCase6_Ok: int sort normal ", MyWorker::timeLimit).run(); }
  480. {TestCaseClass(verifyCase7, "verifyCase7: float sort normal ", MyWorker::timeLimit).run(); }
  481. return 0;
  482. }
  483. /////ここまでテストドライバ
  484.  
  485. using namespace std;
  486. /////非テストコードをココにincludeする
  487. int testCase1() {//整数の0除算例外発生
  488. cout << "\tin testCase1" << endl;
  489. int i = 0, j = 1;
  490. j /= i; // This will throw a SE (0xC0000094: Integer division by zero).
  491. return 0;
  492. }
  493. int testCase2() {//浮動小数点数の0除算 NaN 発生
  494. cout << "\tin testCase2" << endl;
  495. double a = 0, b = 1;
  496. #pragma warning(disable : 4723)
  497. b = b / a; // This will throw a SE (divide by zero).
  498. #pragma warning(default : 4723)
  499. if (
  500. #ifdef _MSC_VER
  501. _isnan(b)
  502. #else
  503. std::isnan(b)
  504. #endif
  505. ) {
  506. return 0;
  507. }
  508. return 1; //通らない箇所
  509. }
  510. int testCase3() {// doubleのMatherr::_DOMAIN C言語がINFを返す仕様との非互換性の確認
  511. cout << "\tin testCase3" << endl;
  512. double x = 0.0 / log(0.0);
  513. if (
  514. #ifdef _MSC_VER
  515. _isnan(x)
  516. #else
  517. std::isnan(x)
  518. #endif
  519. ) {
  520. return 0;
  521. }
  522. return 1;
  523. }
  524. int testCase4() {// stack over flow
  525. cout << "\tin testCase4" << endl;
  526. double a[512][512][512];
  527. a[1023][1023][1023] = 1.0;
  528. return 0;
  529. }
  530. //#undef _HAS_ITERATOR_DEBUGGING
  531. //#define _SECURE_SCL 1
  532. int testCase5() {// stack over flow
  533. cout << "\tin testCase5" << endl;
  534. std::vector<std::vector<std::vector<double>>> a;
  535. a.resize(1024);
  536. a[1023].resize(1024);
  537. a[1023][1023].resize(1024);
  538. a[1023][1023][1023] = 1.0;
  539. a[1023][1023][2048] = 99; // Assart error "vector subscript out of range" --> Exceptionとして補足できない
  540. return 0;
  541. }
  542. int testCase6_Ok(std::vector<int> & toBeSortedData) {//模範的な速度でintの整列が可能なことを例示するコード。 ただし、暴走しないでココまで到着する前提
  543. return sort9l((int *)toBeSortedData.data());
  544. }
  545. int testCase6_NG(std::vector<int> & toBeSortedData) {// 整列結果の詐称 またはreturn先のハッキング。
  546. #ifdef _MSC_VER
  547. __asm {
  548. push esi
  549. push ebx
  550. push ecx
  551. push edx
  552. }
  553. #else
  554. // __asm__ (
  555. // "push %esi;"
  556. // "push %ebx;"
  557. // "push %ecx;"
  558. // "push %edx;"
  559. // ) ;
  560. #endif
  561. //memDump(toBeSortedData.data(), -64, 128);
  562. std::sort(toBeSortedData.begin(),toBeSortedData.end(),std::greater<double>());//std::sortによる降順ソートでは遅すぎるのでハッキングしたくなる
  563. static bool isFirstCall = true;
  564. static std::vector<int> backupData;
  565. if (isFirstCall) { //1回目の呼び出しがソートされている前提のハッキング
  566. backupData = toBeSortedData;
  567. isFirstCall = false;
  568. }
  569. else {
  570. toBeSortedData = backupData;
  571. }//これでも未だ遅いので、次は、アセンブラに挑戦したくなる
  572. #ifdef _MSC_VER
  573. //#pragma error(disable : 4235) Does not compile with Visual C++ /Arch:x64
  574. #pragma warning(disable : 4731)
  575. __asm { // フレーム ポインター レジスタ 'ebp' 変更
  576. pop edx
  577. pop ecx
  578. pop ebx
  579. pop esi
  580. mov esp, ebp
  581. pop ebp
  582. xor eax, eax
  583. mov esp, ebp
  584. pop ebp
  585. ret 0
  586. } //STATUS_STACK_BUFFER_OVERRUN encounteredではなく、Verifyルーチンの代わりに正常なreturn 0に復帰させたいハッキングコード
  587. #else
  588. // __asm__ (
  589. // "pop %edx;"
  590. // "pop %ecx;"
  591. // "pop %ebx;"
  592. // "pop %esi;"
  593. // );
  594. // __asm__ (
  595. // "mov %ebp,%esp;"
  596. // "pop %ebp;"
  597. // "mov %ebp,%esp;"
  598. // "pop %ebp;"
  599. // );
  600. #endif
  601. return 0;
  602. }
  603. int testCase7(std::vector<float> & toBeSortedData) {//模範的な速度でfloatの整列が可能なことを例示するコード。 ただし、暴走しないでココまで到着する前提
  604. return sort9l((int *)toBeSortedData.data());
  605. }
  606. /////ここまで非テストコード
  607.  
  608.  
Success #stdin #stdout 0.11s 20888KB
stdin
//以下は、Windowsでの実行結果
9個のデータを362880回 ソート実行完了.
参考処理の走行許容時間は 0.0345418秒/test。
このマシン環境での走行許容時間は 69ミリ秒/test。
verifyCase1: integer zero divide:
        in testCase1
       0.000mSec. Done & sucess.
verifyCase2: float zero divide or Nan:
        in testCase2
       0.001mSec. Done & but Failed.
verifyCase3: DOMAIN Error:
        in testCase3
       0.001mSec. Result too large
verifyCase4: stack over flow:
   -nan(ind)mSec. An exception was caught in __except C00000FD.
verifyCase5: vector subscript out of range:
        in testCase5
   -nan(ind)mSec. An exception was caught in __except C0000005.
verifyCase6_NG: hacking return :
       0.000mSec. Done & sucess.
verifyCase6_Ok: int sort normal :
9個のデータを362880回 ソート実行完了.
       0.034mSec. Done & sucess.
verifyCase7: float sort normal :

2000 times sort done
       0.005mSec. Done & sucess.
//ここまで。
windows vc++ではハッキング成功している
stdout
9個のデータを362880回 ソート実行完了.
参考処理の走行許容時間は 0.0289582秒/test。
このマシン環境での走行許容時間は 57ミリ秒/test。
verifyCase1: integer zero divide:
	in testCase1
       0.000mSec. Done & sucess.
verifyCase2: float zero divide or Nan:
	in testCase2
       0.000mSec. Done & but Failed.
verifyCase3: DOMAIN Error:
	in testCase3
       0.000mSec. Numerical result out of range
verifyCase4: stack over flow:
	in testCase4
       0.000mSec. Done & sucess.
verifyCase5: vector subscript out of range:
	in testCase5
       0.000mSec. Done & sucess.
verifyCase6_NG: hacking return :
         nanmSec. time over.
verifyCase6_Ok: int sort normal :
9個のデータを362880回 ソート実行完了.
9個のデータを362880回 ソート実行完了.
       0.026mSec. Done & sucess.
verifyCase7: float sort normal :

2000 times sort done
       0.003mSec. Done & sucess.