인간 관계에서 기억해 둘 만한 말

인간 관계에서 되새겨 볼 만한 말을 적어 봅니다.

  • 易地思之 (역지사지): 처지를 바꾸어서 생각하라.
  • 寬人嚴己 (관인엄기): 남에게는 관대하고 자신에게는 엄격하라.
  • 강자에게 강하고 약자에게 약해져라.
  • 出乎爾者 反乎爾者也 (출호이자 반호이자야): 너에게서 나온 것은 너에게로 돌아간다. – 맹자

72초 TV

72초 TV라는 회사에 대해 최근에 좀 알게 됐습니다. 그런데 경영 철학, 기업 성장 과정, 그리고 촬영 기법 등에서 배울 것이 있는 것 같습니다. 재밌게 본 동영상들 중 몇 개를 아래에 연결해 두었습니다.

제가 사용하는 비쥬얼 스튜디오 (Visual Studio) 설정

  • 글꼴 크기 15: Tools -> Options… -> Environment -> Fonts and Colors -> Size: 15
  • Visual C++ 6 키보드 매핑 스킴 선택: Tools -> Options… -> Environment -> Keyboard -> Apply the following additional keyboard mapping scheme: Visual C++ 6
  • Dark theme 선택: Tools -> Options… -> Environment -> Color theme: Dark
  • 현재 줄 강조 색을 64, 64, 그리고 128로: Tools -> Options… -> Environment -> Fonts and Colors -> Highlight Current Line (Active) -> Item background: -> Custom… -> 빨강, 녹색, 그리고 파랑을 각각 64, 64, 그리고 128로
  • 가상 공간 활성화: Tools -> Options… -> Text Editor -> All Languages -> Enable virtual space
  • 열 지침을 121열에 설정: Tools -> Extensions and Updates… -> Online -> Search Visual Studio Gallery (Ctrl+E) -> Editor Guidelines -> Download -> Install -> 121열에서 우클릭 -> Guidelines -> Add guideline

최근에 했던 괜찮은 게임

가나다 순입니다.

윈도용 C++ 프로그램이 예외 때문에 종료될 때 미니덤프로 정보를 남기는 방법

예외 때문에 종료될 때 미니덤프로 정보를 기록하려면 예외를 __try/__except나 SetUnhandledExceptionFilter로 잡아 낸 후 MiniDumpWriteDump를 부르면 됩니다. 그런데 일부 예외는 무시되므로, _set_invalid_parameter_handler, _set_purecall_handler, 그리고 signal 등을 추가로 사용해서 잡아 내야 합니다.

미니덤프를 사용하려면 dbghelp.lib를 링크해야 하고, 소스 코드, 실행 파일, 그리고 .pdb 파일을 보관해야 합니다. 또 아래 그림처럼 /DEBUG 플래그를 켜서 .pdb 파일을 만들어야 합니다.

linker_debugging

소스 코드는 아래와 같습니다.

void write_minidump(PEXCEPTION_POINTERS exception_pointers, bool normal_dump)
{
	char dump_file_name[256];
	SYSTEMTIME systemtime;
	GetSystemTime(&systemtime);
	sprintf(dump_file_name, "%04d-%02d-%02d_%02d-%02d-%02d_%04x_%04x.dmp",
		systemtime.wYear, systemtime.wMonth, systemtime.wDay, systemtime.wHour, systemtime.wMinute, systemtime.wSecond,
		GetCurrentProcessId(), GetCurrentThreadId());
	HANDLE file_handle = CreateFileA(dump_file_name, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
	if (file_handle == INVALID_HANDLE_VALUE)
		return;

	MINIDUMP_EXCEPTION_INFORMATION minidump_exception_information;
	minidump_exception_information.ThreadId = GetCurrentThreadId();
	minidump_exception_information.ExceptionPointers = exception_pointers;
	minidump_exception_information.ClientPointers = FALSE;

	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file_handle, normal_dump ? MiniDumpNormal :
		static_cast<MINIDUMP_TYPE>(MiniDumpWithFullMemory | MiniDumpWithHandleData | MiniDumpWithProcessThreadData |
		MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo), &minidump_exception_information, nullptr, nullptr);

	CloseHandle(file_handle);
}

LONG WINAPI handle_unhandled_exception(PEXCEPTION_POINTERS exception_pointers)
{
	write_minidump(exception_pointers, false);
	return EXCEPTION_EXECUTE_HANDLER;
}

void handle_invalid_parameter(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line,
	uintptr_t reserved)
{
	RaiseException(0, 0, 0, nullptr);
}

void handle_pure_call()
{
	RaiseException(0, 0, 0, nullptr);
}

void handle_signal(int signal)
{
	RaiseException(0, 0, 0, nullptr);
}

int _tmain(int argc, _TCHAR* argv[])
{
	if (!IsDebuggerPresent())
	{
		SetUnhandledExceptionFilter(handle_unhandled_exception);
		_set_invalid_parameter_handler(handle_invalid_parameter);
		_set_purecall_handler(handle_pure_call);
		signal(SIGABRT, handle_signal);
	}

	// ...

	return 0;
}

참고: