GitLab Backup

  • GitLab에 대한 모든 설정은 /etc/gitlab/gitlab.rb에서 관리할 수 있습니다.

  • 보편적인 방법으로 Omnibus package로 설치한 경우 백업은 다음과 같습니다.

    $ sudo gitlab-rake gitlab:backup:createDumping database tables:
    - Dumping table events... [DONE]
    - Dumping table issues... [DONE]
    - Dumping table keys... [DONE]
    - Dumping table merge_requests... [DONE]
    - Dumping table milestones... [DONE]
    - Dumping table namespaces... [DONE]
    - Dumping table notes... [DONE]
    - Dumping table projects... [DONE]
    - Dumping table protected_branches... [DONE]
    - Dumping table schema_migrations... [DONE]
    - Dumping table services... [DONE]
    - Dumping table snippets... [DONE]
    - Dumping table taggings... [DONE]
    - Dumping table tags... [DONE]
    - Dumping table users... [DONE]
    - Dumping table users_projects... [DONE]
    - Dumping table web_hooks... [DONE]
    - Dumping table wikis... [DONE]
    Dumping repositories:
    - Dumping repository abcd... [DONE]
    Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE]
    Deleting tmp directories...[DONE]
    Deleting old backups... [SKIPPING]

 

 

GitLab Restore

  • 생성된 백업파일은 기본적으로 /var/opt/gitlab/backups에 저장됩니다.

    • 로컬에 저장된 백업파일은 100% 안전하다고 할 수 없기때문에 반드시 외부 환경에 소산 보관해야 합니다.

    • GitLab서버와 FreeNAS와 같은 외장 스토리지 서버와 네트워크로 연결하는 (CIFS 등) 방법도 고려해야 합니다.

      • 네트워크 환경에서 백업 환경을 구축할 때, 대규모 환경에서는 SAN으로 구성하는 것이 좋은 대안이 될 수 있으나 소규모 환경에서는 비용문제가 많이 발생할 수 있기 때문에 내부 네트워크 환경에서 시행하는 것이 좋습니다.

      • 단, 같은 네트워크 환경에서 백업이 같이 이루어질 경우 네트워크 장비의 용량에 따라 내부 네트워크의 전체 속도가 떨어질 수 있기 때문에 네트워크 사용량이 적은 시간에 진행하거나 네트워크를 분리하는 방법도 고려하는 것이 좋습니다.

GitLab Service 중단 및 백업$ sudo gitlab-ctl stop unicorn
$ sudo gitlab-ctl stop sidekiq
# Verify
$ sudo gitlab-ctl status# 백업 파일이 하나일 경우
$ sudo gitlab-rake gitlab:backup:restore

# 백업 파일이 여러개 있을 경우
$ sudo gitlab-rake gitlab:backup:restore BACKUP=1493107454_2018_04_25_10.6.4-ce

  • 기본적인 백업 디렉토리에 백업 파일이 존재하면 자동으로 기존에 있던 데이터베이스가 삭제되고, 백업데이터로 변경됩니다.

    • 새롭게 설치한 GitLab 서버에도 다음과 같이 진행하면 기존에 사용하던 환경으로 마이그레이션이 완료됩니다.

  • 이때, 백업 당시에 사용했던 GitLab 버전과 사용중인 GitLab 버전이 다를 경우에는 복구가 진행되지 않기 때문에 버전과 동일한 백업 파일을 생성하여 진행할 수 있도록 합니다.

GitLab Service 시작 $ sudo gitlab-ctl restart
$ sudo gitlab-rake gitlab:check SANITIZE=true

콘솔 명령의 용도


콘솔 명령의 용도는 주로 다음과 같습니다.

1. 디버깅 정보를 화면에 UI로 표시
↓ 예 : stat fps / stat unit / stat unitgraph. 얼마나 처리 시간이 걸려 있는지를 표시한다.


↓ 예 : stat particles. 파티클 통계. 지금 얼마나 나와 있고, 얼마나 처리가 걸려 있는지를 표시합니다.



2. 디버깅에 그리기를 변경
↓ 예 : show bounds. 각 Actor의 바운딩 박스를 표시합니다.



3. 디버깅을 위한 움직임 전환
↓ 예 : ToggleDebugCamera. 디버깅 용 카메라를 자유롭게 움직일 수있다. 또한 화면 중앙에있는 Actor와 자료의 정보도 볼 수 있습니다.



4. 게임을하는 동안 작업을 수행 (예 : RestartLevel)

5. 편집기의 동작을 변경 (예 : culture = kr)

 

명령 사용 방법

명령을 입력하는 방법에는 여러 가지가 존재합니다. 주요 방법은 다음 네 가지입니다. 1 번과 2 번은 자주 사용하므로 기억합시다.

1. OutputLog (출력 로그) 창에서 사용
↓ 1 단계 : Output Log (출력 로그) 창을 표시한다.



↓ 2 단계 : 나온 창 하단에 입력한다.



2. 게임 실행 중에 Console Key를 누르면 나타나는 입력란
↓ 1 단계 : 프로젝트 설정 -> 입력 -> Console-> Console Keys 키를 추가합니다.
기본적으로 "`"를 사용합니다.


↓ 2 단계 : 게임 실행 중에 "`"키를 누르면 이렇게 명령 입력 필드가 표시됩니다.


3. Blueprint의 Execute Console Command 노드에서 입력



4. C ++에서 입력
다음의 방법으로 C ++에서도 명령을 보낼 수있다. PC는 PlayerController.

PC-> ConsoleCommand ( <Command>, true );

 

 

자주 사용하는 명령 목록

 

Basic

DumpConsoleCommands 콘솔 명령 목록을 Output Log로 출력한다. 모든 명령이 출력되는 것은 아니기 때문에 주의.


조작

Open <LevelName (MapURL)> 이전 설정을 그대로 유지하면서 지정된 수준을 연다. (Persistent Level의 대체)
Travel <LevelName (MapURL)> 모든 설정을 초기화하고 지정된 레벨을 연다. (Persistent Level의 대체)
RestartLevel 현재의 수준을 다시로드.
slomo <PlayRate> 슬로우 모션 / 빨리 감기하는 ex. slomo 0.5
quit 또는 exit 게임을 종료

 

일반적인 Debug 계 명령

getall <Class name> <Property name> 대상 클래스의 속성을 OutputLog 창에 한 칸에 출력한다.
obj list OutputLog 창에 각 개체의 수와 사용 메모리 양을 출력한다.

주회 플레이 메모리 누수 (개체 수 증가) 검사에 사용할 수있다.

DisableAllScreenMessages 2D 스크린에서 디버그 표시를 비활성화
stat levels 현재 로드된 Level보기. 로드에 걸린 시간도 표시된다.

녹색 : Unload 상태

빨간색 : Load 상태

ViewMode <ViewModeName> 그리기 방법을 전환합

ViewModeName에는 다음의 것이있다.

Lit / Unlit / Wireframe / LightingOnly / ShaderComplexity 등

ToggleDebugCamera 게임 중의 카메라를 떠나 디버깅 다른 카메라로 전환한다.

동시에 주시 지점의 자산 정보를 화면에 표시한다.

log list 로깅 카테고리
log <category> <level> category의 로깅 수준을 변경한다.
<로그 수준>
NoLogging
Fatal
Error
Warning
Display
Log
Verbose
VeryVerbose
All <편리 명령>
log LogStreaming Verbose <- 자산로드 관련 로그를 출력
ce <EventName> 표시되는 모든 레벨의 <EventName> 사용자 정의 이벤트를 호출한다.
KismetEvent <Object 이름 or *> <EventName> Blueprint의 이벤트를 직접 호출. <Object 이름>을 지정하는 장소에는 「*」을 지정하면 전체 BP에 날릴.

 

Memory

stat MemoryPlatform 종합적인 현재의 메모리 사용량과 남은 양 표시
stat MemoryAllocator  
stat Memory  
stat MemoryStaticMesh  
stat ParticleMem  
stat SceneMemory  
mem Detailed 로그에 메모리 사용량을 한꺼번에 출력
memreport (-full) 메모리 상태를 Saved / Profiling / MemReports 폴더 아래에 파일로 출력한다. 확장자는 memreport, 단순한 텍스트.
rhi.DumpMemory RHI 자원 메모리 덤프. 모든 항목이 mem Detailed에 포함되어 있는

rhi : Render Hardware Interface

 

Performance (공통)

stat fps 화면에 FPS를 표시
stat unit 화면에 Game 스레드 Draw 스레드, GPU 스레드 1 프레임 당 소요 시간을 표시
stat unitgraph stat unit의 내용을 그래프로 표시
stat Raw stat unitgraph의 내용을 필터링하지 않고 원시 데이터를 사용
stat hitches 히치를 감지하고 기록
stat dumphitches 히치시 로그를 덤프한다. 기본적으로 75ms 이상이지만 "t.HitchThreshold 0.075"고하여 값을 변경
stat game 전반적인 Tick 시간을 몇 가지 항목으로 분류 해 볼 수 있습니다. Navi Tick Time / Net Tick Time / Post Tick Component Update / World Tick Time etc ...
StartFPSChart / StopFPSChart Saved / Profiling / FPSChartStats 다음에 FPS 정보의 로그를 출력한다. 출력되는 CSV를 사용하여 그래프도있다.

 

Performance (CPU Time)

stat startfile / stat stopfile ※ Session Frontend를 사용할 상황에서는 Session Frontend에서 같은 조작이 가능

start로부터 stop까지의 프로파일 결과를 파일에 ue4stats 형식으로 출력

Output Log 출력 경로가 표시된다.

출력 된 파일은 Session Frontend (Editor에서 Window → Developer Tools → Session Frontend)의 Profiler 탭에서 볼 수있다.

아마 UFUNCTION되어있는 함수가 프로파일 대상이지만, C ++ 코드에 QUICK_SCOPE_CYCLE_COUNTER매크로를 빚는 경우 핀 포인트로 프로필있다.

공식 문서 : CPU Profiling

 

Performance (GPU Time)

ProfileGPU

GPU의 stats 정보를 그래프로 표시.
또한 Output Log 창에 프로파일 결과를 텍스트로 표시된다.
Ctrl + Shift +, (쉼표)로 단축키가 할당되어있다.

stat SceneRendering Draw call etc ...
stat Cnvas  
stat LightRendering  
stat ShadowRendering  
stat Particles  
ViewMode ShaderComplexity Viewport에서 Shader 부하가 걸려있는 곳을 붉게 표시
show <ElementName> ↓ ElementName에는 다음 항목이 사용할 수있다.

AmbientOcclusion
AntiAliasing
Bloom
Decals
DeferredLighting
DirectionalLights
PointLights
SpotLights
DynamicShadows
GlobalIllumination
LightFunctions
Particles
PostProcessing
ReflectionEnvironment
Refraction
Rendering
ScreenSpaceReflections
Landscape
Brushes
StaticMeshes
SkeletalMeshes
ShadowFrustums
(↑ 동적 그림자를 생성하는 후라스타무을 표시 .EditorViewport의 Show-> Advanced-> Shadow Frustums라도 표시 )
Landscape
Translucency
Tessellation

※ 그 밖에도있다. "show"만 입력하면 로그 창에 목록이 표시

※ Pause를 걸쳐 여러 Show 명령에서 표시 / 숨기기를하면 원인은 무엇 무거워지고 있는지 알기 쉽다.

공식 문서 : GPU Profiling

 

Maniac

ParticleSystemAudit Particle 모니터링
culture = [CultureID] 에디터 지역 / 언어 설정을 즉시 변경한다.

CultureID는 북미 / 영어라면 "en"



출처: https://microsoft.tistory.com/982 [::: 책 읽는 프로그래머 :::]

출처 : https://lifeisforu.tistory.com/360 [그냥 그런 블로그]


1. 들어가며


UE4 와 관련한 프로그래밍을 하면서 처음에 가장 헷갈리는 부분이 패키지와 애셋이라는 개념입니다. 그리고 이것은 나중에 C++ 코드를 통해 패키지나 애셋을 로드하다가 보면 머리가 아파집니다. 경로를 집어 넣으라고 하는데 뭐가 뭔지 알수가 없습니다.


사실 언리얼 공식 문서인 [ 애셋과 패키지 ] 에 그 개념들에 대해서 설명을 하고 있기는 하지만 좀 부족합니다. 아니 부족하다기 보다는 우리가 생각하는 애셋과 패키지가 아닙니다. 뭐랄까 아티스트나 디자이너 위주의 추상화된 개념이라 할 수 있습니다. 실제 API 들에서 명명하는 개념과는 다릅니다.


특히나 커맨드렛 같은 도구를 통해 애셋관리를 자동화할 때 이 문제는 심각해집니다. 애셋을 복사하고 싶은데 애셋을 복사하는 방법을 모릅니다. 그래서 어찌어찌 내가 애셋을 복사한다고 하는게 패키지를 복사하는 것이라는 것을 깨닫게 됩니다. 그런데 패키지를 복사한 후에 경로 문제 때문에 애셋을 로드하지 못하는 사태가 발생합니다.


많은 분들이 이런 문제들 때문에 골치가 아팠을 것이라 생각합니다. 그래서 이 문서에서는 그런 개념들에 대해 정리해 볼 계획입니다. 모쪼록 도움이 됐으면 좋겠네요.


2. 패키지와 애셋


여러분은 패키지라고 하면 무엇이 생각나십니까? 여러 개의 애셋을 하나로 묶어 놓은 ( Unity3D 에서와 같은 ) 번들을 생각하시는 분도 있을테고 배포하기 위해서 묶어 놓은 패키지를 생각하실 수 있을 것입니다. UE4 에디터에서 공식적으로 패키지라는 이름이 등장하는 것은 후자의 경우입니다. 쿠킹 패키징할 때의 패키지입니다.



하지만 코딩 문맥에서는 패키지라는 것은 그냥 "*.uasset" 파일입니다. UE3 에서는 어땠는지 모르겠지만 UE4 에서는 패키지와 애셋은 1:1 로 대응됩니다. 그럼 ".uasset" 파일을 칸텐츠 브라우저에서는 애셋이라 부르고 코드에서는 패키지라 부르는 것일까요? 여러분은 어떻게 생각하시나요?


아래의 칸텐츠 브라우저에 있는 "FirstPersonCharacter" 는 코딩문맥에서 보면 패키지인가요 애셋인가요?



답은 애셋입니다. 좀 더 명확하게 하기 위해서 익스플로러에서 이 파일을 복제해 보겠습니다.



보이시나요? 동일한 "*.uasset" 파일을 복사하게 되면 파일의 이름은 다른데 칸텐츠 브라우저에서의 이름은 동일합니다. 그러므로 제가 위에서 "*.uasset" 은 패키지이고 칸텐츠 브라우저에서는 애셋으로 표현된다고 말씀드린 것입니다. 절대 "FirstPersonCharacter2" 라는 이름으로 애셋이름이 변경되지 않습니다.


"에이~ 내가 해봤는데 칸텐츠 브라우저에서 애셋 복사하면 이름 바뀌던데?" 라고 반문하시는 분 있을 겁니다. 맞습니다. 칸텐츠 브라우저에서 애셋을 복사하면 패키지 복사와 함께 이름 변경까지 수행해 줍니다. 그러나 이는 칸텐츠 브라우저의 동작이지 패키지의 동작은 아니라는 겁니다. 그러므로 나중에 패키지를 코드를 통해 복사하게 되면 문제가 발생하는 겁니다.


정리하자면 패키지라는 것은 "*.uasset" 을 이야기하는 것이고 애셋이라는 것은 "*.uasset" 에 포함되어 있는 대표 오브젝트를 의미합니다. 편의상 이를 애셋이라는 이름으로 개념화한거죠. 여러분이 코드를 보실 때 주의하실 점은 "class UAsset" 과 같은 검색어를 날릴 필요는 없다는 것입니다. 존재하지 않습니다. UObject 를 상속한 어떠한 오브젝트라도 패키지의 대표 오브젝트가 될 수 있습니다.


3. Paths


이제 패키지와 애셋이 다르다는 것을 인지했으니 코드 상에서는 이에 어떻게 접근을 하는지 알아 보도록 하겠습니다. 위에서 한 것과 똑같은 동작을 코드에서 수행해 보도록 하겠습니다.


3.1. LongPackageName


일단 패키지를 로드하기 위해서는 어떤 경로를 사용해야 할까요? 여러 분이 칸텐츠 브라우저에서 애셋 위에 마우스를 올리시면 다음과 같은 툴팁을 보실 수 있습니다.



저기에서 "/Game" 이라는 이름으로 "Path" 가 시작되는 것이 보이실 겁니다. UE4 에서 사용하는 모든 칸텐츠의 경로는 저 "/Game" 이라는 접두어로 시작됩니다. 그것은 "/Content" 라는 이름에 대한 키처럼 사용됩니다. 아래 그림을 보시면 붉은색 박스가 게임 디렉토리이고 녹색 박스가 위에서 표현하고 있는 Path 입니다. 단지 "Content" 라는 이름이 "Game" 이라는 이름으로 변경되었을 뿐이죠. 




어쨌든 이 경로와 확장자를 제거한 패지키 이름을 합치면 그것을 LongPackageName 이라 부릅니다. 이 LongPackageName 에서는 "\" 가 아니라 "/" 를 디렉토리 분리자로 사용합니다.


UPackage* LoadPackage(UPackage* InOuter, const TCHAR* InLongPackageName, uint32 LoadFlags);


우리의 경우에는 "/Game/FirstPersonCPP/Blueprints/FirstPersonCharacter" 가 되겠죠. 


UPackage* SrcPackage = LoadPackage(nullptr, TEXT("/Game/FirstPersonCPP/Blueprints/FirstPersonCharacter"), 0);

3.2. Filename


앞에서 로드한 패키지를 "/Game/FirstPersonCPP/Blueprints/FirstPersonCharacter2" 이라는 이름으로 저장해 보도록 하겠습니다. 그런데 패키지를 저장하는 메서드는 Filename 이라는 인자를 요구하는군요.


bool SavePackageHelper(UPackage* Package, FString Filename, EObjectFlags KeepObjectFlags, FOutputDevice* ErrorDevice, FLinkerLoad* LinkerToConformAgainst, ESaveFlags SaveFlags)

Filename 이라는 인자를 요구하는 경우에는 절대 경로를 요구하는 것이라 보시면 됩니다. 확장자까지 확실히 붙어 있어야 합니다. 우리는 LongPackaeName 을 알고 있기 때문에 이를 절대 경로로 바꾸는 과정을 거치게 됩니다. 아래 코드를 살펴 보십시오. 어렵지 않을 것입니다.


FString DestLongPackageName = TEXT("/Game/FirstPersonCPP/Blueprints/FirstPersonCharacter2");
FString DestRelFilename = FPackageName::LongPackageNameToFilename(DestLongPackageName, ".uasset");
FString DestAbsFilename = FPaths::ConvertRelativePathToFull(DestRelFilename);
FPaths::MakePlatformFilename(DestAbsFilename);
 
SavePackageHelper(SrcPackage, DestAbsFilename);


FPaths::ConvertRelativePathToFull() 은 상대경로를 절대경로로 바꿔줍니다. 이 시점에서 DestAbsFilename 은 "C:/Users/lifeisforu/Documents/Unreal Projects/PackageTest/Content/FirstPersonCPP/Blueprints/FirstPersonCharacter2.uasset" 이 나옵니다.


하지만 이것은 Windows 플랫폼에 맞는 이름이 아니죠. 그래서 플랫폼에 맞게 분리자 문자( '/' )를 교정해 줍니다. FPaths::MakePlaformFilename() 이 그 역할을 합니다. 그러면 DestAbsFilename 은 "C:\Users\lifeisforu\Documents\Unreal Projects\PackageTest\Content\FirstPersonCPP\Blueprints\FirstPersonCharacter2.uasset" 이 됩니다.


이제 패키지를 저장하고 나서 보면... 짠!



위에서 나온 것과 같은 상황이 발생합니다. 애셋 이름과 패키지 이름이 다릅니다. 그냥 패키지만 복사하면 이게 정상입니다.


3.3. ObjectPath


이제 애셋의 이름을 정상적으로 고쳐줄 필요가 있겠군요. 그러나 package 관련 메서드들에는 절대 RenameAsset 과 관련한 이름이 존재하지 않습니다. 정말 우울한 일이죠. 애셋을 로드해야만 합니다.


여기에서 ObjectPath 라는 개념이 나옵니다. StaticLoadObject 는 "Name" 이라는 인자를 받습니다. "LongPackageName" 이나 "Filename" 이 아닌 그냥 "Name" 이라는 인자는, 그것이 오브젝트와 관련되어 있다면, 십중팔구 ObjectPath 라 생각하시면 됩니다.


ObjectPath 라는 것은 "{LongPackageName}.{AssetName}" 입니다. 애셋의 이름이 마치 확장자인 것처럼 사용됩니다. 그러나 프로그래머 관점에서는 클래스의 필드 이름 정도로 생각하시는 것이 좋을 것입니다. A 오브젝트의 B 필드에는 A.B 라는 식으로 접근하니 이해하기 편할 것입니다.


패키지 파일은 복사했지만 애셋 이름은 고친적이 없으니 이 애셋을 로드하기 위해서는 그 경로는 "/Game/FirstPersonCPP/Blueprints/FirstPersonCharacter2.FirstPersonCharacter" 입니다. 이를 "/Game/FirstPersonCPP/Blueprints/FirstPersonCharacter2.FirstPersonCharacter2" 로 고쳐야겠죠.


UPackage* DestPackage = LoadPackage(nullptr, *DestLongPackageName, 0);
FString ObjectPath = DestLongPackageName + ".FirstPersonCharacter";
UObject* Asset = StaticLoadObject( UObject::StaticClass(), nullptr, *ObjectPath);
 
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
TArray<FAssetRenameData> AssetsAndNames;
new(AssetsAndNames) FAssetRenameData(Asset, FPackageName::GetLongPackagePath(Asset->GetOutermost()->GetName()), TEXT("FirstPersonCharacter2"));
AssetToolsModule.Get().RenameAssets(AssetsAndNames);
 
SavePackageHelper(DestPackage, DestAbsFilename);


이제 애셋이름이 패키지 이름과 동일하게 생성되는 것을 확인할 수 있습니다.



4. 결론


정리하자면 다음과 같습니다.


    • 패키지 : uasset 파일.
    • 애셋 : 패키지를 대표하는 오브젝트.
    • LongPackageName : "/Game" 으로 시작하는 확장자를 배제한 패키지 이름.
    • Filename : 시스템에서의 절대 경로. FPackageName 과 FPaths 라는 유틸리티를 사용해서 LongPackageName 으로부터 변환할 수 있음.
    • ObjectPath : 패키지 이름과 애셋이름을 합친 경로. 애셋이름이 확장자처럼 사용됨.
    • 코드에서 패키지를 복사하려면 애셋 이름도 반드시 따로 변경해야 함.



출처 : https://lifeisforu.tistory.com/360 [그냥 그런 블로그]

jemalloc 라이브러리가 정상 작동하므로 솔루션에 포함되어 있는 test_threads 프로젝트를 빌드해본다.

별 설정 없이도 잘 빌드되고 실행된다.

….만, 이게 도대체 뭔 내용인지는 나도 잘 모르겠다. test_threads.cpp 파일에는 테스트용 코드가 잔뜩 있다. 다 읽어보기도 힘들어서 읽어보다가 관둿다. 대략 je_malloc, je_free 등의 함수를 이용하는 예제코드인 것 같다.

github에는 간단한 예제코드가 있다. ( https://github.com/jemalloc/jemalloc/wiki/Getting-Started )

….는 별로 도움이 되지 않았다.

그냥 쉽게 얘기하면 new/malloc 을 할 때 je_malloc 을 하면 되고 delete/free 를 할 때 je_free 를 하라면 되는 말.

그래서 new와 delete를 오버라이딩하는 클래스를 만든다.

#pragma once
class MemoryPool
{
public:
MemoryPool(void) {}
virtual ~MemoryPool(void) {}
void* operator new(size_t size)
{
return je_malloc(size);
}
void* operator new[](size_t size)
{
return je_malloc(size);
}
void operator delete(void* ptr)
{
je_free(ptr);
}
void operator delete[](void* ptr)
{
je_free(ptr);
}
private:
};
view rawMemoryPool.cpp hosted with ❤ by GitHub

new 를 사용하는 곳에서 이 오버라이딩 클래스를 상속 받게 해주면 끝.

그리고 헤더에서 #include <jemalloc/jemalloc.h> 를 넣어주고 추가 포함 디렉터리에는 jemalloc의 include 디렉토리를 지정해주고 빌드하면 된다.

이렇게하면 빌드가 성공하고 실행파일에 있는 위치에 jemalloc 빌드 후 생성된 .dll 파일을 같이 넣어주면 된다.

….인줄 알았는데 빌드가 안된다.

코드를 보니 jemalloc.h 파일에서

#include <string.h> 부분이 문제가 되었다. 이 문제에 대해 찾아보니…

https://stackoverflow.com/questions/15512790/error-about-finding-strings-h-in-htmlcxx

아마 유닉스쪽에서 쓰는 헤더파일일 거라고 한다.

해당 부분을

  1. #ifdef _WIN32
  2. #include <string.h>
  3. #else
  4. #include <strings.h>
  5. #endif

로 교체하면 잘 작동한다.

프로젝트의 구성속성을 보면 Debug, Debug-static 식으로 나뉘어 있는데, 전자는 .dll 파일을 쓰는 동적 링크, 후자는 .lib 파일을 쓰는 정적 링크이다. 각자 원하는 것으로 사용.

원글 : https://blog.dongbumkim.com/archives/5088


일단 https://github.com/jemalloc/jemalloc 에서 소스코드를 Clone 한다. (내 경우에는 D:\Library\jemalloc 으로 다운로드했다.)

master 브랜치를 다운로드하고 안에 들어가서 살펴보면 msvc 라는 디렉토리가 있고 그 안에 jemalloc_vc2015.sln 파일이 있다. Visual Studio 2015용 솔루션이 있으니 얼마나 감사한가.

솔루션을 열어보면 이미 jemalloc 프로젝트와 test_threads 프로젝트가 추가되어있다.

jemalloc 프로젝트를 빌드해보면…

C1083 포함 파일을 열 수 없습니다. 'jemalloc/internal/jemalloc_preamble.h': No such file or directory jemalloc d:\library\jemalloc\src\witness.c 2
오류와 함께 빌드가 되지 않는다. 실제로 저 경로에 가서 살펴보면 jemalloc_preamble.h 파일이 없다.

솔루션 파일에 추가되어 있는 ReadMe.txt 파일을 열어보면 다음과 같은 내용이 있다.
How to build jemalloc for Windows
=================================

1. Install Cygwin with at least the following packages:
* autoconf
* autogen
* gawk
* grep
* sed

2. Install Visual Studio 2015 with Visual C++

3. Add Cygwin\bin to the PATH environment variable

4. Open "VS2015 x86 Native Tools Command Prompt"
(note: x86/x64 doesn't matter at this point)

5. Generate header files:
sh -c "CC=cl ./autogen.sh"

6. Now the project can be opened and built in Visual Studio:
msvc\jemalloc_vc2015.sln

메뉴얼이 있으니 따라가야지.

Cygwin을 구글에서 검색해서 설치한다. Cygwin 설치법은 검색해서 찾자.

하나 참고해둘 것은 Cygwin은 설치프로그램을 실행해서 구성파일을 인터넷에서 다운로드하며 설치한다. 근데 이 과정이 무지막지하게 느리다. 기가인터넷이고 지랄이고 이런거 소용 없더라. 미러를 선택할 때 ftp.kaist.ac.kr을 선택했지만 그래도 느리다. 한참 설치하더니 몇가지 패키지가 설치 안되었다고 나온다. 설치프로그램을 다시 실행시켜서 미러를 ftp.jaist.ac.jp 로 바꾸고 다시 설치. 이 과정을 몇번 반복해서야 겨우 설치 완료했다.

Cygwin을 디폴트로 설치하고나서 설치프로그램의 검색창을 이용해 위 메뉴얼에 있는 autoconf, autogen, gawk, grep, sed를 설치해줘야 한다. 잊지말것.

아마 Cygwin을 처음 보거나 잘 쓰지 않는 사람이라면 이 과정에서 굉장히 스트레스 받을 것이다. 나도 Cygwin 설치에만 하루 넘게 걸렸다. 젠장…

이걸 설치하고 나서는 메뉴얼대로 제어판을 열고 ‘시스템’의 ‘고급 시스템 설정’의 ‘환경 변수’에 가서 ‘변수’ 중 Path 항목의 값에 Cygwin의 bin 경로를 추가해준다. 내 경우에는 C:\cygwin64\bin 을 추가해줬다.

이제 시작메뉴에서 ‘VS2015 x64 네이티브 도구 명령 프롬프트’를 실행한다.

경로를 jemalloc이 설치된 폴더로 이동한다. 내 경우에는 D:\Library\jemalloc 으로.

메뉴얼에 있는대로 sh -c “CC=cl ./autogen.sh” 를 입력한다.

각종 환경설정 사항을 체크하고 컴파일 과정이 지나간다. (다중프로세서 컴파일은 하지 않는듯하다. 적당히 웹서핑하며 몇분 기다리면 된다.)

이 화면이 나오면 컴파일이 끝난 것이다.

아까 jemalloc_preamble.h 파일이 없던 경로에 가보면 jemalloc_preamble.h 파일이 생성되어 있다.

이제 다시 Visual Studio 2015를 켜서 솔루션을 열고 jemalloc 프로젝트를 빌드해본다.

당연히 잘된다. ㅎㅎㅎ

결론 : Cygwin을 설치하는게 제일 애먹었다. 이것만 설치하고 나머지는 메뉴얼대로 설정하면 된다.



Gitlab 을 설치해서 사용하고 있는데, 업로드 파일 사이즈가 작아서 트레이닝을 위한 데이타 업로드가 되지 않는 문제가 발생하였다.

찾아보니 비슷한 문제로 고통 받는 사람들이 많았고 Github 에서도 동일한 문제가 있어서 git-lfs, BFG Repo-Cleaner 등과 같은 사용하고 있더라....

다행이 설치해서 사용하고 있어 아래처럼 설정을 바꾸니 문제가 해결 되었다.

Gitlab 설치 후 업로드 할 수 있는 사이즈 변경, port 변경과 같은 작업을 하기 위해서는 설정 파일을 수정해야 합니다.


### 설정 파일 위치 /etc/gitlab/gitlab.rb
### 설정 변경 내용 
# 파일 사이즈 변경
nginx[‘enable’] = true
nginx[‘client_max_body_size’] = ‘2G’
# 포트 변경 
unicorn[‘listen’] = ‘127.0.0.1’
unicorn[‘port’] = 8580






  • 북마크
  • 언리얼 엔진 4
  • 블렌더 
  • C++
    • C++ Primer -  C++ 추천 책. 방대한 컨텐츠
    • Learn C++ - SoloLearn의 C++ 학습 사이트/앱. 80편의 강좌
    • CodinGame - 게임 예제 퀴즈로 배우는 프로그래밍
    • Engineer4Free 강좌 - 47편 4.5시간 분량의 입문자용 강좌
    • Udemy Ben Tristem 튜토리얼 - C++ 가이드. 61편 7.5시간 분량, 완강되면 30시간 분량 예정
  • Game Design
    • Udemy 게임 기획 - 174편 39시간 분량의 Game Design 강좌
    • 유튜브 플레이리스트 - 324편, 기획자라면 볼만한 다양한 장르의 유튜브 영상들
    • 쩌는 게임기획서 이렇게 쓴다 - 기획서 작성 규칙, 조언, 프로세스 등 실무 경험자의 가이드
    • 게임 기획 튜토리얼 - 게임 기획이 무엇인지 기초부터 커버하는 가이드
    • 시선을 끄는 PPT - 직장에서 사용할 깔끔한 PPT 만드는 가이드
    • 라프 코스터의 재미이론 - 무엇이 게임을 재미있게 만드는지 연구한 책
    • 시나리오 라이팅 - 바라는대로 라이터가 쓰게 하는 가이드
    • UE4 레벨디자인 개요 - 25분 분량 에픽 게임즈의 실제 레벨디자인 과정 설명하는 가이드
    • 게임 데이터 모델링 - 게임 기획서를 게임으로 만드는 데이터 모델링과 ERD
    • 데이터 주도적 설계 - 짧은 분량의 게임 데이터 설계 팁
    • 테이블 사용한 게임 기획 - 기획서를 테이블로 작성해야 하는 이유
    • 게임 기획 입문 - 7분 분량 간단한 숫자야구 게임 기획
    • GDC - 게임 개발자 회의의 발표 영상
    • Game Maker's Toolkit - 상용 게임들의 게임 디자인을 분석하는 유튜브 채널
      • Secrets of Game Feel and Juice - 게임의 느낌: 마리오 게임에서 레벨 디자인과 배경을 제외하고 마리오만 조작해도 마찰력과 점프 등의 동작 덕분에 재미있다. 한마디로 조작감이 좋다. 게임을 다듬는 단계에서 조작감을 높이는 방법:
        • 화면 흔들기(즉각적인 피드백)
        • 액션 상황에서 화면 정지 (격투 게임, 젤다)
        • 어떤 방법이든 타격을 했을 때 타격을 했다는 피드백을 효과적으로 줘야 한다
        • 사운드 FX도 좋은 방법이다. 
        • 카메라 무빙 - 플레이어가 항상 중심에 있기 보다 액션을 보여주는 것이 더 좋다
        • 과장된 효과 - 과장된 총알, 과장된 폭발
        • 관련 영상
    • Thief vs AAA Gaming - 씨프의 레벨 디자인에 대한 분석, AAA 게임들에 대한 비판
      • 콘텐츠를 최대한 많이 채워넣으려는 AAA 게임과 달리 씨프는 콘텐츠의 제거를 메카닉으로 사용한다
      • 미니맵이 HUD에 뜨지 않고 현실적인 방법으로 지도를 손에 얻게 된다
      • 씨프는 퀘스트 마커를 사용하지 않고레벨 디자인으로 자연스럽게 길찾기가 가능하다.
      • AAA 게임은 레벨에 참신함을 주려고 드라마틱한 배경을 설정함. 그리고 중간중간에 탄약 상자를 제공하고 보스와 대결하기 전에는 항상 탄약 상자와 피 회복을 할 수 있는데 이것이 자연스럽지 않다. Too Gamey
      • 씨프는 현실적인 배경에 현실적인 아이템이 배치되어 있고 골드 등이 뜬금없이 배치되어 있는 것이 아니라 스토리와 연결되어있다.
      • 게임플레이와 스토리의 연결 - 어떤 남자가 준 지도를 통해 비밀 맨션에 들어감. 지도에 나와있지 않은 부분에 트랩이 배치되어 있는데 알고보니 맨션 주인이 개럿의 실력을 테스트 한 것. 지도에 나와있지 않은 부분을 탐험하면서 그 남자가 이상하고 무서운 사람이라는 느낌을 받게 된다. AAA 게임처럼 컷신이나 대화로 그가 무서운 사람임을 보여주지 않고 오직 게임과 플레이어의 대화만으로 스토리를 풀어나간다.
      • 2014 씨프와 오리지널 씨프 모두 로프 화살을 특정 문맥에서만 사용할 수 있다. 그러나 오리지널 씨프에서는 나무 천장에서만 로프 화살을 사용하게 하여 자연스럽게 하였다.
      • 오리지널 씨프는 바닥의 재질에 따라 소리를 다르게 하여 난이도를 조절하였다.
      • AAA 게임들은 최근 플레이어가 선택할 수 있는 요소를 늘리고 있는데, 씨프에서는 선택을 포기한 대신 더 자연스러운 스토리를 만들어 냄
      • AAA 게임은 플레이어에 더 많은 파워를 주려고 하고, 씨프의 주인공은 취약하다. 취약함이 서스펜스를 만든다.
      • 틀을 깨고 너의 디렉션에 맞는 일관적인 게임플레이, 그래픽, 사운드를 제작해라
    • 레벨 디자인의 기초 - 1시간 30분 7편 분량의 레벨 디자인 입문자 튜토리얼
  • Game Music
  • Problem Solving
    • 40개 개념 - 40개 중요한 알고리즘 개념을 설명한 글
    • 알고리즘 비쥬얼 - 알고리즘을 배우는 가장 직관적인 방법
    • 칸 아카데미 알고리즘 - 알고리즘의 기초를 배우는 가이드
    • 칸 아카데미 정보이론 - 알고리즘 공부에 도움이 될 수 있음
    • Cheat Sheet - 알고리즘 치트싯 모음
    • 프로그래밍 콘셉트 - 언어에 상관 없이 모든 프로그래머가 읽어야 할 책
    • 하버드 CS50x - CS 입문, 100+ 시간의 강좌
    • Clever Algorithms - 알고리즘 다루는 무료 책
    • r/dailyprogrammer - 난이도가 구분된 프로그래밍 퀴즈가 올라오는 서브레딧 
    • 97 Things Every Programer Should Know - 프로그래밍 입문자가 알아야할 것들
    • 프린스턴 알고리즘 1 2 - 100+시간
    • 스탠포드 알고리즘 1 2 - 100+시간
    • Programming Challenges - 문제 해결 능력을 훈련하는 책
    • 자료구조와 알고리즘은 프로그래머라면 필수로 알아둬야 함!
  • 게임 개발 관련 자료
  • 리소스
  • Content Creator 
    • 김포프 - EA에서 근무했든 김포프라는 사람의 Vlog. 게임 프로그래밍에 대한 동영상을 올린다
    • Game Maker's Toolkit - 상용 게임들의 게임 디자인을 분석하는 유튜브 채널
    • Extra Credits - 게임 개발에 대한 다양한 내용을 다루는 유튜브 채널
    • Peter Newton - AI 위주 언리얼 엔진 4 강좌를 올리는 유튜브 채널
    • zoombapup - AI를 주로 다루는 언리얼 엔진 4 강좌 유튜브 채널
    • Tom Looman - 에픽 게임즈의 프로그래머. 언리얼 엔진 관련 강좌를 올린다
    • Gleb Alexandrov - 블렌더 구루. 블렌더 위주 CG 관련 정보를 올린다
  • 게임 개발자 Career
  • 커뮤니티
  • 기타
    • Trello - 협업 도구. 개발의 진행 상황 파악할 때 유용한 웹앱
    • Roast My Game - 개발중인 게임 공유하고 피드백 받는 사이트
    • itch.io - 인디 게임 공유 사이트
    • GIT


  • 출처: http://202psj.tistory.com/879 [알레폰드의 IT 이모저모]



    비주얼 스튜디오에서 관리해야 되는 파일이 많아지면 많아 질 수록 원하는 파일을 찾는게 어려워진다.


    작업을 하다가 [F12] 정의로 이동으로 이동을 자주 하게 되는데 이럴때에 솔루션 탐색기가 해당 파일의 위치를 찾을 때 


    곤혹을 치를 때가 있는데 이럴때 도구 -> 옵션 -> 프로젝트 및 솔루션 -> 일반 )  


    솔루션 탐색기에서 활성 항목 추적  > 옵션을 키게 되면 내가 편집하는 파일을 솔루션 탐색기에서 


    자동으로 위치를 추적하게 되면서 작업의 효율성을 높이게 된다.

    한 사이트에서 개발한 프로그램이 가끔 이유없이 죽고 있었다.

    다른 사이트는 그런 일이 없는데 그 사이트에서만 발생하고 있는 일이었다.

    보통은 로그를 이용하여 원인을 파악하는데,

    그 사이트는 로그가 너무 많이 쌓여서 로그 유지 기간이 짧았고,

    반면 프로그램이 다운되는 일은 어쩌다 (한, 두 달에 한 번정도) 발생되는 일이라서 골치가 아팠는데

    이 기회에 Breakpad를 적용해서 해결해 보려고 마음 먹었다.

    1. Breakpad 소개

    Google breakpad home page : https://code.google.com/p/google-breakpad/

    Google Chrome처럼, 여러 플랫폼을 지원하는 프로그램을 위한 크래시 덤프를 다루기 위한 툴이다.

    Win32 개발자들이 접하는 minidump나, *nix 개발자들이 접하는 coredump를 breakpad 포맷(이라기보단 함수 맵)으로 변경하고, 이를 이용해서 플랫폼이 바뀌어도 같은 형태의 스택 트레이스(stack trace)를 볼 수 있게 해주는 툴이다.

    좀 더 세부적으로 보면 다음과 같은 부분으로 되어 있다.

    (개별 사용자 용) 크래시가 발생했을 때, 이를 breakpad 에서 사용하는 포맷으로 덤프를 남겨주는 부분: in-process 덤프만 있는 게 아니라, 다른 프로세스에서 dump를 남기는 방식(out-of-process dump)도 지원한다
    (Build-System 용) 디버그 정보를 읽어서 breakpad 내부 형식으로 바꾸는 부분 : Win32 pdb 나 –g 옵션을 넣고 빌드한 *nix 바이너리에서 심볼 데이터를 뽑아낸다
    (Crash Collector 용) 1에서 나온 정보를 가지고 2를 이용하여 스택 트레이스를 뽑아내는 부분

    사실 2, 3 부분은 Windows 환경에서만 프로그래밍 한다면 그다지 중요하지 않다. 어차피 breakpad 도 덤프 자체는 minidump를 쓰고 있고, breakpad 소개의 Build / User / CrashCollector system 다이어그램에 나온 과정도, 디버그 정보가 애초에 분리되어 빌드 되는 환경(/Z7 같은 걸 쓰면 모르겠지만)에선 그다지 더 편해질 건 없다.

    그렇지만 1에서 Windows named-pipe를 써서, 크래시가 발생한 프로세스가 아니라, 안전하게 동작 중인 프로세스에서 덤프를 남길 수 있다는 점(Out-of-process 덤프), 그리고 이 덤프 남기는 부분의 코드에서 제공하는 callback 지점들이 적당해서, 이걸 이용해서 간단하게(!) 실제 배치된 시스템의 덤프를 중앙의 서버로 모으는 작업을 간편하게 작성할 수 있었다.

    일단 out-of-process로 덤프를 남길 수 있기에, 크래시가 발생한 바이너리에서 할 수 없는 일들 – 메모리 신규 할당, heap 메모리 참조, 기타 등등 – 을 맘대로 해도 되기 때문에 웹 서버나 다른 서버로 덤프를 보내는 일이 쉬워진다.

    – rein’s world

    out-of-process

    breakpad 의 가장 큰 특징은 out-of-process 를 지원하는 것이다. 크래시를 처리하는 함수에서 앞에서 말한 다양한 기능을 추가한다면 제대로 동작하지 않을 수도 있다. 간단한 예로, 사용자에게 의견을 받는 윈도우를 띄운다고 할 때 메인 스레드의 메시지 루프가 깨지면 윈도우 자체를 볼 수 없게 된다.

    크래시가 발생한 프로세스 밖(out-of-process)에서 처리하면 이와 같은 문제를 줄일 수 있다. 그래서 크래시 발생을 처리하기 위해 보다 많은 것을 제공할 수 있다. 물론 in-process 도 지원하기 때문에 필요에 맞게 골라 쓰면 된다.

    크로스 플랫폼

    멀티플랫폼 지원을 고려한다면 breakpad 는 좋은 선택이 될 수 있다. breakpad 를 사용한다면 크로스 플랫폼에 대한 고민을 줄여줄 수 있다.

    – 야드버즈의 개발 로그

    breakpad를 현재 사용하고 있는 대표적인 프로그램은 Chrome Browser, Firefox Browser, Picasa, Google Earth 등이다.

    2. Breakpad 받기

    Breakpad는 SVN을 이용하여 내려 받을 수 있다.

    SVN은 서버까지 필요 없으므로 Windows용 tortoiseSVN을 설치하면 된다.

    tortoiseSVN을 설치했으면 다음과 같이 내려 받는다.

    1) Command 창을 열어 먼저 설치하고 싶은 폴더로 이동한뒤, 다음과 같이 실행한다.

    svn checkout http://google-breakpad.googlecode.com/svn/trunk/ google-breakpad-read-only

    그러면 google-breakpad-read-only 폴더가 생기면서 그 폴더로 checkout을 하고, 소스를 내려 받는다.

    2) 탐색기에서 설치하고 싶은 폴더를 만든 뒤, 마우스 오른쪽 버튼을 눌러 로 ‘SVN Checkout’을 선택한다.

    URL of Repository 항목에 ‘http://google-breakpad.googlecode.com/svn/trunk’ 를 넣고  OK를 누른다.

    그러면 그 폴더로 checkout을 하고, 소스를 내려 받는다.

    3. Breakpad build 하기

    1. 1. python 2.x버전 설치: breakpad는 gyp를 이용하여 빌드 시스템을 생성한다. gyp를 사용하기 위해서는 python 2.x버전이 필요하다. gyp가 아직 python 3.x버전과는 호환성 문제가 있는 것 같다. (gyp 자체 문제 + gyp 설정 파일문제가 복합적인듯 하다.)
    2. gyp 소스 가져오기: breakpad 소스 내에 gyp가 내장되어 있지만, 내장 gyp는 버전관리가 안되어 있는듯 하다. gyp 최신 버전이 적용이 안되어 있다. 현재 작성 시간 기준 gyp 최신 소스에는 Visual studio 2012까지 빌드 시스템을 생성할 수 있도록 되어있다. gyp 최신버전을 사용하기 위해서 gyp를 google 저장소에서 checkout하면 된다.
    3. gyp로 빌드 시스템 생성: src\client\windows 폴더에서 ..\..\tools\gyp\gyp.batbreakpad_client.gyp 를 실행하면 솔루션 파일과 프로젝트 파일이 생성되는 것을 볼 수 있다.
    4. Visual Studio로 빌드: 만들어진 솔루션 파일을 열어 그 안에 있는 build_all 프로젝트를 빌드하면 된다.

    4. Breakpad test

    테스트용 프로그램(crash_generation_app 프로젝트)이 솔루션에 포함돼 있으므로 따로 만들 필요는 없다. 이 테스트 프로그램을 이용하면 in-process 뿐만 아니라 out-of-process 미니덤프도 만들어 볼 수 있다. 여기에서는 out-of-process 미니덤프를 만드는 방법을 소개하겠다.

    프로그램을 실행하기에 앞서 C:\Dumps 폴더를 만들어야 한다. 이 폴더를 만들지 않으면 미니덤프를 저장하다가 실패한다.

    준비가 다 됐다면 프로그램을 실행해 보자. 제대로 된 out-of-process 를 테스트하기 위해서는 프로세스를 두 개 띄워야 한다. 두 번째 프로세스를 띄울 때 서버를 실행할 수 없다는 에러 메시지가 뜨지만 무시해도 좋다. 그런 다음 서버가 실행되지 않는 프로세스에서 Client -> Deref Zero 메뉴를 선택해 강제로 크래시를 발생시키면 C:\Dumps 폴더에 미니덤프 파일이 생성되는 것을 볼 수 있다.

    – 야드버즈의 개발 로그

    참고자료

    Breakpad 로 CrashReporter 만들기 – rein’s world

    원도우즈 환경에서 breakpad 사용하기 – 야드버즈의 개발 로그


    [추가]

    ../gyp/gyp.bat breakpad_client.gyp --no-circular-check

    위 옵션을 꼭 넣어야 솔루션파일이 만들어진다.


    출처

    https://arodream.wordpress.com/2015/04/17/google-breakpad%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-creash-dump-%EB%96%A8%EC%96%B4%EB%9C%A8%EB%A6%AC%EA%B8%B0/



    하나의 운영환경으로부터 더 나은 운영환경으로 옮아가는 과정을 뜻하는 정보통신 용어

    윈도95에서 윈도98로 업그레이드하거나, 윈도NT 서버에서 윈도2000 서버로 옮아가는 것과 같이 하나의 운영체계로부터 더 나은 다른 운영체계로 옮아가는 과정을 말한다. 크게는 윈도NT에서 유닉스를 기반으로 하는 운영체계로 옮아가는 과정이나 그 반대 과정, 새로운 하드웨어나 소프트웨어 또는 둘 다 바뀌는 환경으로 이주하는 것, 데이터를 하나의 저장장치에서 다른 저장장치로 옮기는 과정 등을 포함한다.

    이전의 운영체계에서 설정된 프로그램을 바꿀 필요 없이 현재의 응용프로그램을 새로운 환경에서도 계속 운영할 수 있고, 새로운 운영체계만이 가지고 있는 특성들을 이용할 수 있을 때 흔히 행해진다. 단일 시스템에서 다른 단일 시스템으로 옮아가는 소규모 마이그레이션에서부터 많은 시스템들이 새로운 응용프로그램이나 네트워크로 옮아가는 대규모 마이그레이션에 이르기까지 규모나 형식도 다양하다.

    그러나 데이터베이스의 경우 새로운 데이터베이스가 이전의 데이터베이스와 구성 요소가 다를 수도 있기 때문에 실행 파일들을 처리할 수 있는 프로그램이 필요한 경우도 있다. 따라서 이전의 데이터베이스를 마이그레이션할 때는 새로운 데이터베이스와 공통된 형식으로 데이터를 변환하는 작업이 필요하다

    출처: http://yeonorang99.tistory.com/entry/마이그레이션이란 [Park's test]

    + Recent posts