'Language'에 해당되는 글 69건

  1. 2017.03.08 Bash print call stack at ERR(trap)
  2. 2015.10.19 [Java] Java main thread vs. user thread vs. daemon thread.
  3. 2015.10.19 [C/C++] Small tip - Argument passed to main() function.
  4. 2015.09.06 [Python] binding function parameter default value.
  5. 2015.04.28 [C/C++] Template with value
  6. 2015.03.19 [C/C++] sizeof array
  7. 2015.02.11 [Macro] '##' macro operator
  8. 2014.07.25 'malloc' and 'Segmentation fault'
  9. 2014.07.25 [GCC] Initialize array...
  10. 2014.01.15 Compile time에 결정되는 것들 - static final primitives!

Bash print call stack at ERR(trap)

Language/Bash 2017.03.08 22:03


At head of script file:

(CODE-1)
trap 'on_error "${FUNCNAME[@]} ${BASH_LINENO[@]} $LINENO"' ERR
trap 'on_exit' EXIT

Someone may wonder why don't write code like below because it is easier to handle arguments.

(CODE-2)
trap 'on_error "$LINENO ${FUNCNAME[@]} ${BASH_LINENO[@]}"' ERR
trap 'on_exit' EXIT

I don't know there is any documented information related with this. But, results of my experiments are saying that (CODE-2) doens't work as expected.
In case of (CODE-2), my test shows that only latest function-stack information is passed to 'on_error' trap function.
I don't have any idea about the reason. More investigation is required for this.
But anyway, (CODE-1) works well.
So, you can use those arguments to print function call stack at bash.
You may need to use 'BASH_SOURCE' array too, if your bash uses other files, too.



And there is one interesting case. See follow code.

<< Test environment >>
bash: GNU bash, version 4.3.46(1)-release (x86_64-pc-linux-gnu)
OS: Linux XXXX 4.4.0-64-generic #85-Ubuntu SMP Mon Feb 20 11:50:30 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

-------------------------- TEST-1 -----------------------------
<< a.sh >>
function on_err() {
    echo "error"
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

myval=$(echo u | grep p)  # global variable


$ bash -eE a.sh
error
exit

-------------------------- TEST-2 -----------------------------

<< a.sh >>
function on_err() {
    echo "error"
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

function f0() {
    local myval=$(echo u | grep p)  # local variable in function
}

f0

$ bash -eE a.sh
exit

---------------------------------------------------------------

Even if errtrace is enabled(-E option), 'error' is NOT printed at TEST-2.
Then, is this means 'ERR' is NOT trapped at TEST-2? That is, does 'on_err' not executed?
Let's have a look following code.

-------------------------- TEST-3 -----------------------------

<< a.sh >>
function on_err() {
    echo "error"
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

function f0() {
    myval=$(echo u | grep p)  # NOT local variable anymore.
}

f0

$ bash -eE a.sh
error
exit

-------------------------- TEST-4 -----------------------------

<< a.sh >>
function on_err() {
    echo "error" 1>&2  # echo to standard error.
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

function f0() {
    local myval=$(echo u | grep p)  # local variable
}

f0

$ bash -eE a.sh
error
exit

-------------------------- TEST-5 -----------------------------


function on_err() {
    echo "error" 1>&2  # echo to stderr
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

myval=$(echo u | grep p)  # assign to global variable.


$ bash -eE a.sh
error
error
exit


-------------------------- TEST-6 -----------------------------


function on_err() {
    true  # There is no echo
}

function on_exit() {
    echo "exit"
}

trap on_err ERR
trap on_exit EXIT

myval=$(echo u | grep p)  # asign to global variable


$ bash -eE a.sh
exit

---------------------------------------------------------------

It's very interesting, isn't it?
Further investigation will be continued for this issue.



신고

'Language > Bash' 카테고리의 다른 글

Bash print call stack at ERR(trap)  (0) 2017.03.08
Trackback 0 : Comment 0

[Java] Java main thread vs. user thread vs. daemon thread.

Language/Java 2015.10.19 23:01

StackOverlow 의 아래 답변을 참고하자.

http://stackoverflow.com/questions/2213340/what-is-daemon-thread-in-java


정리하면, JVM은 main thread가 끝나더라도, 아직 수행중인 다른 thread - non daemon thread(user thread) - 가 있다면, 중지되지 않는다.

즉, process가 계속해서 돈다.

C/C++ 처럼, main thread가 exit될 때 process를 종료시키려면, 모든 child thread 속성을 daemon thread로 설정해야 한다.


Thread t = new Thread(...)

t.setDaemon(true);


남아 있는 모든 thread가 Daemon thread일 경우, JVM은 중지된다.

다만, 이런식으로 thread가 급작스레 종료하는 것은 상당히 불안정한 결과를 가져 올 수 있으므로 주의해야 한다.


다시 말하면, 단 하나라도 종료되지 않은 user thread (non-daemon thread) 가 존재할 경우, JVM은 종료되지 않고, 모든 다른 thread (Daemon thraed 포함)역시 계속해도 수행된다.



신고
Trackback 0 : Comment 0

[C/C++] Small tip - Argument passed to main() function.

Language/C&C++ 2015.10.19 22:56

In general, main function is used as below.


int main(int argc, const char *argv[]) {

}


But, it can be expanded like below


int main(int argc, const char *argv[], const char **envp) {

        while (*envp) {

                printf("%s\n", *envp++);

        }

}


By this way, we can use environment variables easily.

=> This matches parameters of execle() and execvpe() at Linux.



신고

'Language > C&C++' 카테고리의 다른 글

[C/C++] Small tip - Argument passed to main() function.  (0) 2015.10.19
[C/C++] Template with value  (0) 2015.04.28
[C/C++] sizeof array  (0) 2015.03.19
[Macro] '##' macro operator  (0) 2015.02.11
'malloc' and 'Segmentation fault'  (0) 2014.07.25
[GCC] Initialize array...  (0) 2014.07.25
Trackback 0 : Comment 0

[Python] binding function parameter default value.

Language/Python 2015.09.06 06:11

function 을 define하는 시점에 default value를 binding한다.

(Spec.을 찾아본건 아니고.. 시험적으로...)



[test.py]


_DEFVAL = 10


def set_def(val):

    global _DEFVAL

    _DEFVAL = val


def prdef(val=_DEFVAL):

    print '+++ ' + str(val) + '\n'


prdef()

set_def(0)

prdef()


============== outputs ==============

+++ 10


+++ 10


신고

'Language > Python' 카테고리의 다른 글

[Python] binding function parameter default value.  (0) 2015.09.06
Trackback 0 : Comment 0

[C/C++] Template with value

Language/C&C++ 2015.04.28 22:10

#include <stdio.h>


template<int N> class A {

public:

        A() { a = N;}

        int a;

};


int

main() {

        A<10> *a = new A<10>();

        printf("%d\n", a->a);

        return 0;

}


type이 아니라, 변수 값을 전달할 수도 있다. 이 경우 장점은?

compile time에 값이 정해지므로 compiler가 code를 optimize할 수 있다.



예.


[ a. cpp ]

#include <stdio.h>


template<int N> class A {

public:

        A(int n) { mN = n; }

        void speak() {

                if (N > 5)

                        printf("I'm BIG\n");

                else

                        printf("I'm SMALL\n");

        }

        int mN;

};


int

main() {

        A<10> *a = new A<10>(10);

        A<2> *b = new A<2>(2);

        a->speak();

        b->speak();

        return 0;

}


<< objdump >>

...

        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (N > 5)

                        printf("I'm BIG\n");

   c: bf 00 00 00 00       mov    $0x0,%edi

  11: e8 00 00 00 00       callq  16 <_ZN1AILi10EE5speakEv+0x16>

                else

                        printf("I'm SMALL\n");

        }

  16: c9                   leaveq 

  17: c3                   retq   


...


        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (N > 5)

                        printf("I'm BIG\n");

                else

                        printf("I'm SMALL\n");

   c: bf 00 00 00 00       mov    $0x0,%edi

  11: e8 00 00 00 00       callq  16 <_ZN1AILi2EE5speakEv+0x16>

        }

  16: c9                   leaveq 

  17: c3                   retq   


...






[ b. cpp ]

#include <stdio.h>


template<int N> class A {

public:

        A(int n) { mN = n; }

        void speak() {

                if (mN > 5)

                        printf("I'm BIG\n");

                else

                        printf("I'm SMALL\n");

        }

        int mN;

};


int

main() {

        A<10> *a = new A<10>(10);

        A<2> *b = new A<2>(2);

        a->speak();

        b->speak();

        return 0;

}



<< objdump >>

...

        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (mN > 5)

   c: 48 8b 45 f8           mov    -0x8(%rbp),%rax

  10: 8b 00                 mov    (%rax),%eax

  12: 83 f8 05             cmp    $0x5,%eax

  15: 7e 0c                 jle    23 <_ZN1AILi10EE5speakEv+0x23>

                        printf("I'm BIG\n");

  17: bf 00 00 00 00       mov    $0x0,%edi

  1c: e8 00 00 00 00       callq  21 <_ZN1AILi10EE5speakEv+0x21>

  21: eb 0a                 jmp    2d <_ZN1AILi10EE5speakEv+0x2d>

                else

                        printf("I'm SMALL\n");

  23: bf 00 00 00 00       mov    $0x0,%edi

  28: e8 00 00 00 00       callq  2d <_ZN1AILi10EE5speakEv+0x2d>

        }

  2d: c9                   leaveq 

  2e: c3                   retq   


...


        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (mN > 5)

   c: 48 8b 45 f8           mov    -0x8(%rbp),%rax

  10: 8b 00                 mov    (%rax),%eax

  12: 83 f8 05             cmp    $0x5,%eax

  15: 7e 0c                 jle    23 <_ZN1AILi2EE5speakEv+0x23>

                        printf("I'm BIG\n");

  17: bf 00 00 00 00       mov    $0x0,%edi

  1c: e8 00 00 00 00       callq  21 <_ZN1AILi2EE5speakEv+0x21>

  21: eb 0a                 jmp    2d <_ZN1AILi2EE5speakEv+0x2d>

                else

                        printf("I'm SMALL\n");

  23: bf 00 00 00 00       mov    $0x0,%edi

  28: e8 00 00 00 00       callq  2d <_ZN1AILi2EE5speakEv+0x2d>

        }

  2d: c9                   leaveq 

  2e: c3                   retq   

...




===============================================


위의 코드를 보면, template 의 value를 사용할 경우, 'if'문에서, 사용되지 않는 코드가 compile시 object에 반영되지 않고 삭제되어 버리는 것을 알 수 있다.

즉 compile time에 충분히 optimize되어 버린다. (if 문의 condition이 compile time에 결정될 수 있으므로...)

신고

'Language > C&C++' 카테고리의 다른 글

[C/C++] Small tip - Argument passed to main() function.  (0) 2015.10.19
[C/C++] Template with value  (0) 2015.04.28
[C/C++] sizeof array  (0) 2015.03.19
[Macro] '##' macro operator  (0) 2015.02.11
'malloc' and 'Segmentation fault'  (0) 2014.07.25
[GCC] Initialize array...  (0) 2014.07.25
Trackback 0 : Comment 0

[C/C++] sizeof array

Language/C&C++ 2015.03.19 21:35

[[ Tested on GCC 4.x ]]


static void

test01_00(char buf[TEST01_SZ]) {

        printf("In func: %lu\n", sizeof(buf));

}


static void

test01(void) {

        char buf[TEST01_SZ];

        printf("In local: %lu\n", sizeof(buf));

        test01_00(buf);

}


int

main(int argc, const char *argv[]) {

        test01();

        return 0;

}


<< Run on 64bit linux >>

$ ./a.out

In local: 16   <== array size

In func: 8     <== pointer size


'sizeof(<array>)' works as expected in the scope where it is declared. But, array that is declared as parameter, is regarded same as 'pointer' (as you can see above).

I don't think this is defined in C specification.

So, I think it is just one of special characteristics of GCC.

Is it interesting,isn't it?


즉 array를 선언한 곳에서 sizeof(<array>)는 기대한 대로 동작하는데, argument로 넘긴 array의 경우, pointer와 동일하게 취급하는 것을 알 수 있다.

개인적인 생각으로, 이것이, C spec 사항일 것 같지는 않다.

그러니, 그냥 GCC 특성 중 하나라고 생각한다....

꽤나 재미있는 내용이라, 일단 적어 둔다. ^_^

신고

'Language > C&C++' 카테고리의 다른 글

[C/C++] Small tip - Argument passed to main() function.  (0) 2015.10.19
[C/C++] Template with value  (0) 2015.04.28
[C/C++] sizeof array  (0) 2015.03.19
[Macro] '##' macro operator  (0) 2015.02.11
'malloc' and 'Segmentation fault'  (0) 2014.07.25
[GCC] Initialize array...  (0) 2014.07.25
Trackback 0 : Comment 0

[Macro] '##' macro operator

Language/C&C++ 2015.02.11 21:54

* '##' macro operator (improved)


<token> ## <token>

: The ## operator takes two separate tokens and paste them together to form a single token.


즉:


#define test(x) aa ## _x

#define test(x) aa##_x


위의 두가지 모두 결과는 'aa_x' 로 같다.

('##' 사용시 중간에 공백은 token delimiter 의 역할을 하게 된다.)

신고

'Language > C&C++' 카테고리의 다른 글

[C/C++] Template with value  (0) 2015.04.28
[C/C++] sizeof array  (0) 2015.03.19
[Macro] '##' macro operator  (0) 2015.02.11
'malloc' and 'Segmentation fault'  (0) 2014.07.25
[GCC] Initialize array...  (0) 2014.07.25
[Linux] Using named pipe in linux (주의할 점)  (0) 2014.01.09
Trackback 0 : Comment 0

'malloc' and 'Segmentation fault'

Language/C&C++ 2014.07.25 15:39

'Segmentation fault' is very familiar error for C developer.

Then, when this runtime error is issued?

At the moment of accessing not-allocated-memory?

This may be right, but this is NOT strict enough.

'Segmentation fault' is issued by kernel through signal to notify that,

"You - user process - try to access not-permitted memory area. And usually, this happens when it tries to access not-allocated-memory - for the user process (In case of ARM architecture, it is triggered by Data Abort cpu exception).


Let's see below code.

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, const char *argv[]) {
        int i = 0;
        char *s = malloc(1);
        s += 1;
        for (i = 0; i < 1024 * 1024 * 1024; i++) {
                printf("%d\n", i);
                s[i] = 4;
        }
        return 0;
}

Do you think when this process is stopped by 'Segmentation fault' signal?

"i == 0" ? (that is at the first moment of trying to access not-allocated-memory-by-malloc).


It, is totally up to malloc implementation.

But, at above case, this is definitely NO.

The reason is, kernel(linux) allocate memory for user process at least 1-page.

So, above code will run even if i > 1024 especially on the Linux machine.


And, there are various implementation(algorithm) of malloc.

So, we cannot expect exact value of i for above code.

Important thing to know here is, answer the question - "What exactly does 'Segmentation fault' mean?"


신고

'Language > C&C++' 카테고리의 다른 글

[C/C++] sizeof array  (0) 2015.03.19
[Macro] '##' macro operator  (0) 2015.02.11
'malloc' and 'Segmentation fault'  (0) 2014.07.25
[GCC] Initialize array...  (0) 2014.07.25
[Linux] Using named pipe in linux (주의할 점)  (0) 2014.01.09
[c/c++] file copy using 'sendfile' on linux.  (0) 2013.12.17
Trackback 0 : Comment 0

[GCC] Initialize array...

Language/C&C++ 2014.07.25 13:04

See https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Designated-Inits.html


And here is one more tips.

Sometimes, you may want to initialize all array element with same value.

Then, you can do it as follows if you are using GCC.


static const int arr[10] = {[0 ... (sizeof(arr)/sizeof(arr[0]) - 1)] = 10};



신고
Trackback 0 : Comment 0

Compile time에 결정되는 것들 - static final primitives!

Language/Java 2014.01.15 12:43

Java에서는 selective compile이 되지 않는다.

대신, compile time에 결정되는 것들을 이용해서 selective compile과 비슷한 효과를  만들어 낼 수 있다.

예를 들면,


Config.jar
----------
class Config {
...
    public static final boolean DEBUG = false;
...
}


Main.java
---------
...
if (Config.DEBUG) System.out.println("debug line...");
...

자, 그러면 어디서 어디까지 Compile time 에 결정되는가?

openJDK 1.6에서 test를 해 보면, 아래의 것들에 대해서는 compile time에 결정되는다는 것을 확인했다.


primitive types (int, boolean, long...) + String.


여기서 의외의 부분이 'String'인데...

실제, 아래와 같이 static final String 변수로 test해 보면, 이것을 확인할 수 있다.

Config.jar
----------
class Config {
    ...
    public static final String MODE = "debug";
    ...
}


Main.java
---------
...
if (Config.MODE.equals("debug")) System.out.println("debug mode...");
...

생각해보면, String class자체가 constant class이므로 - 한번 생성되면, 내용이 바뀌지 않는 class - 위와 같은 compile time check가 가능하지 않을까... 생각이 든다.


아래는 위의 내용에 대한 상세 test이다.

test/lib/Config.java -------------------- package test.lib; public class Config { public static final int TEST_INT_0 = 1; public static final boolean TEST_BOOL_0 = false; public static final String TEST_STR_0 = "test-str-0"; public static int TESTV_INT_0 = 1; public static boolean TESTV_BOOL_0 = false; public static String TESTV_STR_0 = "test-str-0"; } ===> export to 'test0.jar' package test.lib; public class Config { public static final int TEST_INT_0 = 10; public static final boolean TEST_BOOL_0 = true; public static final String TEST_STR_0 = "test-str-1"; public static int TESTV_INT_0 = 10; public static boolean TESTV_BOOL_0 = true; public static String TESTV_STR_0 = "test-str-1"; } ===> export to 'test1'jar Main.java ---------- import test.lib.Config; public class Main { public static void main(String[] args) { if (Config.TEST_STR_0.equals("test-str-0")) System.out.println("Config:TEST_STR_0 : IF path - test-str-0"); else System.out.println("Config:TEST_STR_0 : ELSE path - test-str-0"); if (Config.TEST_INT_0 > 5) System.out.println("Config:TEST_INT_0 : IF path - > 5"); else System.out.println("Config:TEST_INT_0 : ELSE path - > 5"); if (Config.TEST_BOOL_0) System.out.println("Config:TEST_BOOL_0 : IF path - true"); else System.out.println("Config:TEST_BOOL_0 : ELSE path - "); if (Config.TESTV_STR_0.equals("test-str-0")) System.out.println("Config:TESTV_STR_0 : IF path - test-str-0"); else System.out.println("Config:TESTV_STR_0 : ELSE path - test-str-0"); if (Config.TESTV_INT_0 > 5) System.out.println("Config:TESTV_INT_0 : IF path - > 5"); else System.out.println("Config:TESTV_INT_0 : ELSE path - > 5"); if (Config.TESTV_BOOL_0) System.out.println("Config:TESTV_BOOL_0 : IF path - true"); else System.out.println("Config:TESTV_BOOL_0 : ELSE path - "); } } ========================================== $ javac -classpath test0.jar Main.java $ java -classpath .:test0.jar Main Config:TEST_STR_0 : IF path - test-str-0 Config:TEST_INT_0 : ELSE path - > 5 Config:TEST_BOOL_0 : ELSE path - true Config:TESTV_STR_0 : IF path - test-str-0 Config:TESTV_INT_0 : ELSE path - > 5 Config:TESTV_BOOL_0 : ELSE path - true $ $ java -classpath .:test1.jar Main Config:TEST_STR_0 : IF path - test-str-0 <--- 바뀌지 않음. (변수 값이 compile time에 이미 binding되어 있음.) Config:TEST_INT_0 : ELSE path - > 5 <--- 상동 Config:TEST_BOOL_0 : ELSE path - true <--- 상동 Config:TESTV_STR_0 : ELSE path - test-str-0 Config:TESTV_INT_0 : IF path - > 5 Config:TESTV_BOOL_0 : IF path - 참고 : TESTV_XXX_0를 없애면, test0.jar 혹은 test1. jar를 'java'의 'classpath' 에 명시해 주지 않더라도 정상수행 된다. ex. $ java Main 왜냐하면, 이미 모든 code가 compile time에 binding어 있는 상태으므로, Runtime에는 더 이상 'test.lib.Config' 를 참조하지 않기 때문이다.

위와 같은 static final 변수를 runtime binding하기 위한 방법의 한 예로 reflection을 들 수 있다.

reflection을 이용해서 해당 변수 field를 접근하면, static final로 선언된 변수이지만, runtime binding이 가능하다.

신고
Trackback 0 : Comment 0
◀ PREV : [1] : [2] : [3] : [4] : [5] : ... [7] : NEXT ▶

티스토리 툴바