[Android] 안드로이드 mk 파일에서 로그 찍기. 컴부리 이야기

안드로이드 프로젝트를 하다보면 Android.mk 파일이 많은 것을 볼 수 있는데, 이 mk 파일에서 특정 변수 값이나 정보를 찍고 싶을 때가 있다.
그럴 때는 $(info xxx) 을 사용하면 된다.

예를 들어,
mk 파일에
TEST_VALUE="Branden"

이 있다면, 이 TEST_VALUE 값을 찍으려면 mk 파일에 다음과 같이 해주면 된다.

TEST_VALUE="Branden"
$(info $(TEST_VALUE))

이렇게 하면 Branden 이 찍히게 되는 것이다.

얼마나 아프게 해야 이짓을 그만둘까... 나에 관한 작은 이야기

난 정말 못된 놈이다.
다른 이들의 아픔 따위는 안중에 없다.

말로는 도덕군자인양 모든 것을 이해하고 아량이 넓은 척을 엄청나게 하지만, 속으로는 오로지 내 실리만 체울려고 하고 있다. 이 거짓같은 그리고 위선적인 내 생각을 난 다른 이에게 솔직하게 말하지 못한다.
왜냐? 난 비겁하고 겁쟁이니깐.

도대체 얼마나 많은 사람들의 눈에서 눈물을 뽑아내야 내가 정신을 차릴까?

이 글을 써놓고서도 얼마 안가서 내 욕심만 체울려고 다른 이에게 아픔을 주겠지...

난 정말 뭐지...

난 날 모르겠다...

2012 년 새해 첫날에 적는 날적이 (구정에 적는...). 나에 관한 작은 이야기

드디어 2012년 새해가 밝았다. 음력 설이 오늘이다. 난 이제 36살이 되었고, 아직 뭔가 이루어 놓은 것은 없다는 생각이 많이 든다.

물론 난 특정한 날에 별로 의미를 많이 두는 편이 아니라서, 이번 구정이라고 새로운 출발이다, 뭐다 하는 그런 것을 하지는 않겠지만, 왠지 이번 해에는 뭔가 내가 큰일을 해낼것 같은 느낌이 강하게 든다.

이 새벽에 음악을 들으며, 그리고 많은 생각을 하면서 조용하게 날이 밝기를 기다리는 이 느낌이 좋다.

2012년에는 정말 최선을 다해서 살 수 있도록 다시 나를 다잡아보자.

상철아 진지해져라. 그리고 진심을 다해라!


닥치고 정치. 책에 관한 작은이야기

먼저 이 책을 읽고 느낀 것은, 이 책은 감동적이다 라는 것이다.

무엇이 감동인고 하니, 정치에 전혀 관심이 없었던 나에게도 와~ 정치판이 이렇구나 하는 생각을 들게 했다는 것이다.

사실 얼마전 우연찮게 SBS 에서하는 힐링캠프에 박근혜, 문재인이 나온 것을 본적이 있다. 그러면서 어 뭔가 현재의 정치판을 이해할 필요가 있다고 생각이 들어서 (그리고 누가 한번쯤 읽어봄으로써 요즘 정치판이 돌아가는 상황을 정리하는 것도 괜찮지 않냐는 권유(?) 에 의해서) 이 책을 선택하게 되었다.

일단 김어준이라는 사람에 대해서 굉장한 호기심이 생겼다. 어떻게 이런 것을 다 알고 있을까? 물론 많은 관심을 갖으면 가능하다고 할 수 있겠지만, 이렇게 용감하게 자신의 생각을 책으로 펴내기까지는 쉽지 않았으리나는 생각이 든다.

보수든 진보든 암튼 현세대를 살아가는 우리에게는 꼭 한번은 읽어봐야 할 책임에는 틀림없는 것 같다.


왜 나는 너를 사랑하는가. 책에 관한 작은이야기

아~~주 오래전에 조금 읽다가 이상하게 눈에 정말로 안들어와서 그만둔 책을 다시 읽었다.

난 왜 이 책이 베스트셀러인지 잘 이해가 안된다.

물론 남녀의 연애감정을 아주 깊숙히 파고 들어서 책을 읽다가 보면, "아하 정말 그러네" 라고 탄식을 지르게 하기도 하지만, 이 책은 뭐랄까 나에게는 조금 무겁게 다가왔다.

그래서 책을 정말 무슨 의무감에 의해서 어쩔 수 없이 다 읽었다는 느낌을 벗어버릴 수 없었다.

암튼 나에게는 잘 안맞는 책이다. 물론 연애감정의 깊숙한 내면까지 숙고하기를 원하는 사람이라면 읽어도 좋을 책인 것만은 틀림없는 것 같다.


2012년 새로운 시작을 어린왕자와 함께... 나에 관한 작은 이야기

얼마전에 걸렸던 감기가 아직도 낫지 않아서 계속 애를 먹고 있다 ㅠㅠ
원래 감기 잘 안걸리는데... 이번에는 좀 혹독한 목감기가 걸려서 엄청 고생하고 있다는.
약에 수면제가 있는지, 약만 먹었다 하면 잠이 완전 쏟아지는...그래서 자다가 이렇게 새벽에 일어나 버렸다.

새벽에 잠에서 깼는데 갑자기 어린왕자가 생각났다.
나의 어린왕자는 아직도 내 꿈속에 살아 있었던걸까?


Justin Bieber - Baby (저스틴 비버 - 베이비) 나에 관한 작은 이야기

아오~ 요즘 이 노래에 완전 빠져버렸당 ㅠㅠ

노래가 넘 신나고... 어린애들의 풋풋한 사람이 느껴지기도... (16살에 이런 느낌이면 너무 이른가? ^^).

You know you love me
I know you care
Just shout whenever
And I'll be there
You want my love
You want my heart
And we would never ever
ever be apart
Are we an item
Girl quit playin'
We're just friends
What are you sayin'
Said there's another
look right in my eyes
My first love broke my heart
for the first time
And I was like
Baby baby baby
Baby baby baby
Baby baby baby
I thought you'd
always be mine mine
Baby baby baby
Baby baby baby
Baby baby baby
I thought you'd always be mine
Oh oh For you
I would have done whatever
And I just can't believe
we ain't together
And I got the play cool
couse I'm losin' you
I'll buy you anything
I'll buy you anytring
Cause I'm in pieces
Baby fix me
And just shake me till you
wake me from this bad dream
I'm goin down down down
And I just can't believe
my first love
won't be around And I'm like
Baby baby baby
Baby baby baby
Baby baby baby
I thought you'd
always be mine mine
Baby baby baby
Baby baby baby
Baby baby baby
I thought you'd
always be mine mine
I'm 16
And I thought that you'd be mine
I used to tweet you and text you
And call you and hit you on
Facebook all the time
what now you're gone
So far along
that I cant even find you
You know that feeling
When you leave your love
And it's right behind you
Can't believe that you
did me wrong
We were on iChat all night long
Listening to our favorite song
She was wrong
I am gone
I thought I loved her
Never put no one above her
Yeah she was my lover
But now onto another like
Baby baby baby
Baby baby baby
Baby baby baby
I thought you'd
always be mine mine
Baby baby baby
Baby baby baby
Baby baby baby
I though you'd
always be mine mine
Yeah yeah yeah
Yeah yeah yeah
Yeah yeah yeah
Yeah yeah yeah
Yeah yeah yeah
Now I'm all gone gone gone
I'm gone
 

 


[Android] AudioFlinger binding 구조. 컴부리 이야기

AudioFlinger 가 어떻게 Service 로 등록되고 binding 되는지에 대한 내용입니다.

안드로이드는 부팅을 하면서 init.rc 에서 mediaserver 를 실행합니다. 이 mediaserver 는 Main_mediaserver.cpp 이므로 이 파일을 보면 다음과 같은 부분이 있습니다.

AudioFlinger::instantiate();

즉 audioflinger 을 instance 화 하겠다고 하면서 여기서 audioflinger service 를 생성하고 있습니다. Gingerbread (GB 라 함) 이전 안드로이드는 AudioFlinger::instantiate() 이것이 AudioFlinger.cpp 에 선언이 되어 있지만, GB 이후부터는 BinderService 에서 template 으로 이 부분을 처리하고 있습니다.

 

좀 더 살펴보면, AudioFlinger.h 에 다음과 같은 부분이 있습니다.

#include <binder/BinderService.h>

 

class AudioFlinger:

    public BinderService<AudioFlinger>,

    public BnAudioFlinger

{

위에서 나와있는 코드와 같이 AudioFlinger 는 결국은 BinderService, BnAudioFlinger 를 상속받아서 사용되고 있는 것을 알 수 있습니다. 그리고 BinderService.h 에 가보면 우리가 찾고 있던 instantiate() 가 다음과 같이 정의되어 있습니다.

template<typename SERVICE>
class BinderService
{
public:
   
static status_t publish() {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
    }

    static void publishAndJoinThreadPool() {
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm(defaultServiceManager());
        sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }

    static void instantiate() { publish(); }

    static status_t shutdown() {
        return NO_ERROR;
    }
};

 

즉 h 파일에서 함수 원형이 다 들어 있는 꼴로 되어 있습니다. 왜냐하면 BinderService 는 template 형식으로 사용되어서 이렇게 한 것 같습니다.

따라서 AudioFlinger::instantiate() 는 결국은 AudioFlinger 가 상속받은 BinderService 의 publish() 가 호출되는 것이 됩니다.

이 publish 함수를 보면,

    static status_t publish() {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
    }

이렇게 되어 있는데, 현재 AudioFlinger 에서 호출된 것이라서 위 코드는 결국은 다음과 같이 호출된 것과 같은 것이 됩니다 (즉, SERVICE 부분이 AudioFlinger 로 되는 것입니다).

 

    static status_t publish() {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(AudioFlinger::getServiceName()), new AudioFlinger());
    }

 

위 코드가 중요한 것은 new AudioFlinger() 에서 AudioFlinger 의 instance 를 생성하고, addService 를 통해서 ServiceManager 에 AudioFlinger 를 등록시킴으로써 AudioFlinger 의 binder 가 등록이 된다는 것입니다.

 

참고로 위 내용은 AudioFlinger 에서 onFirstRef() 함수가 안불리는 문제 때문에 추척한 것인데 (이것은 binding 이 되면 자동으로 호출되도록 되어 있음), 이것을 추적하기 위해서는 new AudioFlinger() 에서 AudioFlinger 쪽 생성자를 계속 추적해서 들어가보면 IAudioFlinger 를 통해서 BnInterface<IAudioFlinger> 를 통한 후 BpInterface 의 상속자인 BpRefBase 가 되고 이것의 생성자인 Binder.cpp 에 있는 BpRefBase() 에서 mRemote->incStrong(this); 가 호출되어 이 incStrong() 안에서 const_cast<RefBase*>(this)->onFirstRef(); 로 AudioFlinger::onFirstRef() 가 호출되는 것입니다.

 

위에서 언급한 Binder 구조에 대해서는 제가 인터넷에서 찾은 문서를 같이 첨부로 보내드립니다. 참조하시면 저의 난해한 이야기를 좀 더 수월하게 이해하실 수 있을 것입니다. ^^;

혹 잘못된 내용이 있으면 바로 알려주시면 감사하겠습니다. 제 짧은 소견이 안드로이드 바다를 이해하는데 조금이라도 도움이 되길 바라며....

 

이상입니다.

첨부파일 : How_Android_IPC_system_works.pdf


[Android] C, C++ 에서 call stack 보기. 컴부리 이야기

먼저 안드로이드가 제공하는 util 중에서 callstack 을 include 합니다.
#include <utils/CallStack.h>

그리고 콜스택을 찍으려고 하는 곳에 다음과 같이 넣습니다.
CallStack stack;
stack.update(0, 31);
stack.dump();

위에서 한 내용은 최대 call stack 을 31개까지 찍겠다 (최대값이 31 입니다) 라고 한 것입니다.
그런데 이렇게만 하면 안되고 CallStack.cpp 에서 dump() 함수에서 실제 call stack 을 LOGD 로 찍고 있는데 이것을 LOGE 로 바꿔줘야 call stack 이 로그로 출력이 됩니다.

이렇게 call stack 을 보면
01-01 00:38:12.860: ERROR/CallStack(188): #00  0x0x4018c100: <_ZN7android9CallStack6updateEii>+0x0x4018c0e1
01-01 00:38:12.860: ERROR/CallStack(188): #01  0x0x400deaae: <_ZN7android12AudioFlinger10onFirstRefEv>+0x0x400dea81
01-01 00:38:12.860: ERROR/CallStack(188): #02  0x0x400df826: <_ZTv0_n16_N7android12AudioFlinger10onFirstRefEv>+0x0x400df819
01-01 00:38:12.860: ERROR/CallStack(188): #03  0x0x4018da58: <_ZNK7android7RefBase9incStrongEPKv>+0x0x4018da31
01-01 00:38:12.860: ERROR/CallStack(188): #04  pc 0000093a  /system/bin/mediaserver
01-01 00:38:12.860: ERROR/CallStack(188): #05  0x0x4010452e: <__libc_init>+0x0x40104505

이런 식으로 찍히게 되는데, 자세히 보면 위에 내용이 무엇인지 알 수 있습니다.
제는 위 코드를 AudioFlinger.cpp 에서 audio flinger 가 binding 되는 순간에 불리는 onFirstRef() 안에서 찍었는데 그것을 감안해서 보면,
mediaserver -> RefBase 소스에서 incStrong() -> AudioFlinger 소스에서 onFirstRef() 이렇게 호출된 것을 볼 수 있습니다.

철학이 필요한 시간. 책에 관한 작은이야기

우리 회사 인문학 특강을 하러 온 강신주 선생(?)의 강의를 듣고, 꼭 이 분의 책을 사서 읽어봐야 겠다고 생각한 후 인터넷 서점에서 저자 이름으로 검색하니 이 책이 나왔다.

물론 다수의 책이 있었지만, 최신에 나온 책이라 이 책을 선택하게 되었다 (사실 덜 어렵지 않을까 하는 생각도 한몫했다는...).

이 책은 예전 자동차 선전에 나왔던가 하는 그런 문구가 아주 잘 어울리는 책이다. '조용하지만 강하다'.

정말이지 짧은 이야기 (강신주 선생이 읽었던 책 중에서 자신을 변화시킬 수 있는, 아니 최소한 자신이 갖고 있는 사고에 대해서 다시금 생각할 수 있게 해주는) 의 집합이지만, 깊은 울림이 있는 글이다.

내가 책을 읽으면서 다음에 다시 꼭 읽어봐야 겠다고 생각한 책은 별로 없는데, 이 책이 바로 그 중에 하나 (다시 읽어봐야 하는 책) 가 되었다. 지금 기억나는 다시 읽어야 할 책으로는, 모리타 아키오의 "나는 어떻게 미래를 지배했는가", 생떽쥐베리의 "어린왕자", 강신주의 "철학이 필요한 시간"....으... 더 많았는데 생각이 잘 안난다... 점심시간이라서 그런가...

암튼 이 책은 절대 강추이다.

1 2 3 4 5 6 7 8 9 10 다음