반응형

런타임(디버그)에 collision shape이 표시되도록 해 보자.

 

CollisionShape2D를 추가하고 크기를 조절한다.

 

Debug - Visible Collision Shapes를 체크한다.

 

현재 씬을 실행(디버그)하면 collision shape이 표시된다.

 

반응형
Posted by J-sean
:
반응형

Box2D DebugDraw를 사용해 보자.

 

b2Draw 클래스를 상속해 DebugDraw 클래스를 만들고 사용하면 된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <iostream>
#include "SDL.h"
#include "box2d/box2d.h"
 
class DebugDrawer : public b2Draw
{
public:
    DebugDrawer(SDL_Renderer* renderer) {
        this->renderer = renderer;
    }
private:
    SDL_Renderer* renderer;
    void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {}
    void DrawPoint(const b2Vec2& p, float sizeconst b2Color& color) {}
    void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {
        SDL_SetRenderDrawColor(renderer, 25500, SDL_ALPHA_OPAQUE);
        SDL_FRect* rect = new SDL_FRect{ vertices[0].x, vertices[0].y, vertices[1].x
            - vertices[0].x, vertices[3].y - vertices[0].y };
        SDL_RenderDrawRectF(renderer, rect);
    }
    void DrawCircle(const b2Vec2& center, float radius, const b2Color& color) {}
    void DrawSolidCircle(const b2Vec2& center, float radius, const b2Vec2& axis, const b2Color& color) {}
    void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) {}
    void DrawTransform(const b2Transform& xf) {}
};
 
int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindow("SDL Test", SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED, 640480, SDL_WINDOW_RESIZABLE);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -10);
    SDL_Surface* playerSurface = SDL_LoadBMP("player.bmp");
    SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, playerSurface);
 
    // World 정의
    b2Vec2 gravity(0.0f, 9.8f);
    b2World world(gravity);
 
    // DebugDraw 정의
    DebugDrawer* debugDrawer = new DebugDrawer(renderer);
    debugDrawer->SetFlags(b2Draw::e_shapeBit | b2Draw::e_jointBit |
        b2Draw::e_centerOfMassBit | b2Draw::e_aabbBit | b2Draw::e_pairBit);
    world.SetDebugDraw(debugDrawer);
 
    // Player 정의
    b2BodyDef playerBodyDef;
    playerBodyDef.type = b2_dynamicBody;
    playerBodyDef.position.Set(0.0f, 0.0f);
    playerBodyDef.linearVelocity = b2Vec2(50.0f, 0.0f);
    playerBodyDef.angularVelocity = 0.2f;
    b2Body* playerBody = world.CreateBody(&playerBodyDef);
    b2PolygonShape dynamicBox;
    dynamicBox.SetAsBox((float)playerSurface->/ 2, (float)playerSurface->/ 2);
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.3f;
    fixtureDef.restitution = 0.5f;
    playerBody->CreateFixture(&fixtureDef);
 
    // Ground 정의
    b2BodyDef groundBodyDef;
    groundBodyDef.position.Set(0.0f, 400.0f);
    b2Body* groundBody = world.CreateBody(&groundBodyDef);
    b2PolygonShape groundBox;
    groundBox.SetAsBox(500.0f, 0.0f);
    SDL_Rect groundRect = { 040050010 };
    groundBody->CreateFixture(&groundBox, 0.0f);
 
    // Wall 정의
    b2BodyDef wallBodyDef;
    wallBodyDef.position.Set(300.0f, 0.0f);
    b2Body* wallBody = world.CreateBody(&wallBodyDef);
    b2PolygonShape wallBox;
    wallBox.SetAsBox(0.0f, 480.0f);
    SDL_Rect wallRect = { 300010480 };
    wallBody->CreateFixture(&wallBox, 0.0f);
 
    float timeStep = 1.0f / 500.0f;
    int velocityIterations = 6;
    int positionIterations = 2;
 
    SDL_Event event;
    bool quit = false;
 
    while (!quit) {
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_QUIT:
                quit = true;
                break;
            case SDL_KEYDOWN:
                printf("Key pressed: %s\n", SDL_GetKeyName(event.key.keysym.sym));
                if (event.key.keysym.sym == SDLK_SPACE) {
                    playerBody->SetTransform(b2Vec2(0.0f, 0.0f), 0.0f);
                    playerBody->SetLinearVelocity(b2Vec2(50.0f, 0.0f));
                    playerBody->SetAngularVelocity(0.2f);
                }
                if (event.key.keysym.sym == SDLK_ESCAPE)
                    quit = true;
                break;
 
            default:
                break;
            }
        }
 
        world.Step(timeStep, velocityIterations, positionIterations);
 
        SDL_SetRenderDrawColor(renderer, 255255255, SDL_ALPHA_OPAQUE);
        SDL_RenderClear(renderer);
 
        // Ground 그리기
        SDL_SetRenderDrawColor(renderer, 22014020, SDL_ALPHA_OPAQUE);
        SDL_RenderFillRect(renderer, &groundRect);
 
        // Wall 그리기
        SDL_SetRenderDrawColor(renderer, 646464, SDL_ALPHA_OPAQUE);
        SDL_RenderFillRect(renderer, &wallRect);
 
        // Player 그리기        
        b2Vec2 playerPosition = playerBody->GetPosition();
        SDL_Rect destRect = { (int)playerPosition.x - playerSurface->/ 2,
            (int)playerPosition.y - playerSurface->/ 2, playerSurface->w, playerSurface->h };
        SDL_RendererFlip flip = SDL_FLIP_NONE;
        float angle = playerBody->GetAngle() * (180 / (float)M_PI);
        SDL_RenderCopyEx(renderer, texture, NULL&destRect, angle, NULL, flip);
 
        // 가장 마지막에 DebugDraw 그리기
        world.DebugDraw();
 
        SDL_RenderPresent(renderer);
    }
 
    // debugDrawer 해제
    delete debugDrawer;
 
    SDL_DestroyTexture(texture);
    SDL_FreeSurface(playerSurface);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
 
    return 0;
}
 

 

코드를 입력하고 빌드한다.

 

위 GIF 이미지에서 잘 보이지 않지만 모든 오브젝트의 Shape에 빨간 폴리곤이 그려진다.

 

실제로는 빨간 폴리곤이 잘 보인다.

 

※ 참고

Box2D b2Draw

 

반응형
Posted by J-sean
:
반응형

WinDbg는 타임스템프가 일치하지 않으면 심볼 파일을 로드하지 않는다. 모듈과 심볼이 일치하지 않아 정보가 정확하지 않을 수 있기 때문이다. 정확한 심볼을 구할 수 없다면 타임스템프가 다르더라도 가지고 있는 심볼을 강제 로드할 수 있다.

 

MyDrv모듈의 심볼이 없다. (Timestamp: Jun 10 2018 22:15:07)

 

심볼 파일을 확인해 보니 날짜가 다르다. 그래서 자동으로 로드되지 않았던 것이다.

 

.reload 명령어에 /i 옵션을 주고 심볼을 로드한다.

  • /i: 타임스템프를 무시한다.
  • 모듈 시작 주소: 9afd0000
  • 모듈 크기: 9afd7000 - 9afd0000 = 7000

이미지를 찾을 수 없다는 Win32 에러(0x2)가 나타나지만 무시한다.

Win32 Error Codes

 

다시 모듈을 확인해 보면 심볼이 로드되어 있다.

 

 

스텍 프레임에도 반영되어 표시된다.

물론 타임스템프가 다르기 때문에 정확한 정보를 표시하지 못할 수 있다.

 

이번엔 심볼 파일을 찾지 못하는 경우 어떻게 해결할 수 있는지 확인해 보자.

위 상황과는 약간 다르다. 같은 에러 메세지가 나타났지만 이번엔 정말 심볼을 로드하지 못한 것이다. 어떤 이유에 의해 심볼 파일의 경로가 바뀌거나 삭제되는 경우 심볼 파일을 찾지 못하게 된다.

 

WinDbg가 어떤 경로를 헤매고 다녔는지 얘기할 수 있게 해주자.

※ 다시 말할 수 없게 하려면 '!sym quiet'를 실행한다.

 

다시 한 번 .reload... 명령어를 실행하면 실패한 검색 경로가 모두 표시된다.

 

 

WinDbg가 원하는 검색 경로를 만들고 심볼 파일을 넣어준 후 심볼을 로드하면 해결된다.

 

2023.04.29 - [Reverse Engineering] - WinDbg 설치 하고 심볼 경로 설정하기(feat. 심볼 강제 로드)

 

반응형
Posted by J-sean
:
반응형

실행중인 프로그램이 특정 조건을 만족하면 메모리 덤프 파일을 생성하도록 해 보자.

 

문제가 있는(메모리 덤프를 생성할) 프로그램을 미리 실행시킨다.

 

Procdump.zip
0.70MB

위 파일을 다운로드하고 압축을 푼다.

 

ProcDump 폴더로 이동한다.

 

'procdump 프로세스명' 으로 실행하면 바로 미니 덤프를 생성한다.

 

 

미니 덤프가 생성되었다.

 

'-ma -c 20 -s 5' 옵션을 주고 실행한다.

-ma: 전체 덤프 생성

-c: 덤프 생성 CPU 사용율 임계값

-s: 덤프 생성 조건 연속 시간

= CPU 사용율이 20%이상으로 5초 지속되면 전체 덤프 파일을 생성한다.

 

CPU 사용률이 20%를 넘기자 카운트가 시작되고 5초 후 전체 덤프 파일이 생성된다.

 

전체 덤프 파일이 생성되었다.

 

 

덤프 파일을 분석하면 어디서 문제가 발생하는지 파악할 수 있다.

 

이번엔 '-ma -t' 옵션으로 실행한다.

-t: 프로세스가 종료되면 덤프 파일을 생성한다. (크래시 발생으로 비정상 종료되어도 덤프 파일 생성)

 

프로세스가 종료되자 전체 덤프 파일이 생성된다.

 

전체 덤프 파일이 생성되었다.

 

※ 참고

ProcDump

 

반응형
Posted by J-sean
:
반응형

아래 링크를 참조해 WinDbg를 설치한다.

Windows 디버거 설치

 

WinDbg를 실행하고 Settings를 클릭한다.

 

Debugging settings - Debugging paths - Default symbol path:에 위와같이 세팅한다.

심볼 파일이 디버깅 할 파일과 같은 경로에 있거나 path에 지정한 경로(I:\windbgsymbols)에 있으면 된다.

※ 기본 심볼 서버: https://msdl.microsoft.com/download/symbols

※ 기본 캐시 폴더: C:\ProgramData\dbg

 

Symbol path for Windows debuggers

 

디버깅할 파일을 로드하면 관련 심볼 파일도 로드된다.

 

심볼파일(.pdb)을 로드할 때 WinDbg는 타임 스템프 등을 고려한 버전 체크를 하는데 버전이 맞지 않으면 로드하지 않는다. 아래 명령을 사용하면 심볼파일의 버전에 관계없이 로드할 수 있다.

[한 모듈의 심볼파일만 로드]

.reload /i Module_Name

ex) .reload /i myapp.exe

[모든 모듈의 심볼파일 로드]

.reload /i

 

2023.07.02 - [Reverse Engineering] - WinDbg 버전(타임스템프) 일치하지 않는 심볼파일 로드하기

 

반응형
Posted by J-sean
:
반응형

유니티와 Visual Studio를 이용해 디버깅 해 보자.

 

Cube를 하나 생성하고 스크립트를 추가한다.

 

매 프레임마다 X축으로 1 이동하는 스크립트를 작성한다.

 

이동하는 코드에 브레이크 포인트를 설정한다. (F9)

 

디버깅을 시작한다. (Attach to Unity 버튼을 클릭하거나 F5를 누른다)

 

 

유니티에 C# 디버거가 연결되었다는 창이 뜬다. 'Enable debugging for this session' 버튼을 클릭한다.

 

오른쪽 하단에 'Debugger Attached' 표시(파란색 벌레)가 나타난다. Play 버튼을 클릭한다.

 

브레이크 포인트에서 실행이 멈춘다.

 

디버거와 유니티를 확인하며 디버깅을 진행한다.

 

 

유니티 실행시 처음부터 디버깅이 가능하게 설정할 수 도 있다. (Code Optimization On Startup을 Debug로 바꾼다)

 

반응형
Posted by J-sean
: