void test_json(const char* json) { auto old_limit = tl_heap->getMemoryLimit(); tl_heap->setMemoryLimit(tl_heap->getStatsCopy().usage() + 0x10000); auto caught = false; req::vector<Variant> buf; ASSERT_LE(tl_heap->getStatsCopy().usage(), tl_heap->getMemoryLimit()); ASSERT_FALSE(getSurpriseFlag(MemExceededFlag)); auto len = strlen(json); try { for (int i = 0; i < 100000; i++) { // call into SimpleParser Variant z; auto ok = JSON_parser(z, json, len, true, 0xffff, k_JSON_FB_LOOSE); ASSERT_TRUE(ok); ASSERT_FALSE(getSurpriseFlag(MemExceededFlag)); buf.push_back(z); } } catch (RequestMemoryExceededException& e) { caught = true; } EXPECT_TRUE(caught); tl_heap->setMemoryLimit(old_limit); tl_heap->resetCouldOOM(); }
// Xenon data is gathered for logging per request, "if we should" // meaning that if Xenon's Surprise flag has been turned on by someone, we // should log the stacks. If we are in XenonForceAlwaysOn, do not clear // the Surprise flag. The data is gathered in thread local storage. // If the sample is Enter, then do not record this function name because it // hasn't done anything. The sample belongs to the previous function. void Xenon::log(SampleType t, c_WaitableWaitHandle* wh) const { if (getSurpriseFlag(XenonSignalFlag)) { if (!RuntimeOption::XenonForceAlwaysOn) { clearSurpriseFlag(XenonSignalFlag); } logNoSurprise(t, nullptr, wh); } }
// Xenon data is gathered for logging per request, "if we should" // meaning that if Xenon's Surprise flag has been turned on by someone, we // should log the stacks. If we are in XenonForceAlwaysOn, do not clear // the Surprise flag. The data is gathered in thread local storage. // If the sample is Enter, then do not record this function name because it // hasn't done anything. The sample belongs to the previous function. void Xenon::log(SampleType t) const { if (getSurpriseFlag(XenonSignalFlag)) { if (!RuntimeOption::XenonForceAlwaysOn) { clearSurpriseFlag(XenonSignalFlag); } TRACE(1, "Xenon::log %s\n", (t == IOWaitSample) ? "IOWait" : "Normal"); s_xenonData->log(t); } }