manywaypark's Blog
개발, 검색, 함수

nif(c/c++ shared object)를 erlang runtime에 올려서 쓰다보면 gdb를 사용할 일이 생긴다.

/usr/bin/erl은 shell script다.

그 내용을 보고 환경변수만 맞추어주면 된다. 아래처럼 한다.

# (emacs라면, M-x gdb 후에)

gdb --annotate=3 /usr/lib/erlang/erts-5.8.5/bin/beam.smp

......

(gdb) set environment ROOTDIR /usr/lib/erlang

(gdb) set environment BINDIR /usr/lib/erlang/erts-5.8.5/bin

(gdb) set environment EMU beam

(gdb) set environment LD_LIBRARY_PATH /path/to/lib:/usr/local/lib:/usr/lib  # optional, 은밀한(?) 곳에 so가 있다면 설정.

(gdb) cd /path/to/working/dir    # optional, 보통 beam.smp가 있는 곳으로 cwd가 바뀌므로 다시 설정한다.

(gdb) r -- -root /usr/lib/erlang -progname erl -- -home /path/to/home -- -sname optional-node-short-name -pa ./ebin

......

주의할 점은, erlang REPL에 들어가고 나면 마땅히 break point를 설정할 방법이 없으므로 REPL 진입전에 break point를 설정해야 한다는 것이다.


happy hackin'


2014-12-22 추가: 

참고 링크(이게 더 간단한가?) http://blog.dizzyd.com/blog/2009/12/18/running-erl-in-a-debugger/ 

요점은 bin/erl을 이렇게 바꾸고 실행한다.

if [ ! -z "$USE_GDB" ]; then gdb $BINDIR/erlexec --args $BINDIR/erlexec ${1+"$@"} else exec $BINDIR/erlexec ${1+"$@"} fi


erlang name clash

함수형 언어/Erlang 2014. 1. 15. 10:29 by manywaypark

code:clash()를 쓰면 이름 충돌에 관한 정보가 나온다.

code:get_path(), code:add_patha(), code:add_pathz() 등으로 조회, 추가 등을 할 수 있다.

erl 수행시 -pa, -pz  등의 옵션을 쓰는 방법도 있다.


ref: http://erlang.org/pipermail/erlang-questions/2012-February/064179.html


happy hackin'

[펌] Erlang BIF 만들기

함수형 언어/Erlang 2013. 11. 9. 22:33 by manywaypark

steps

1. run configure
2. add your bifs to erts/emulator/beam/bif.tab

bif re:grep/2 bif re:compile/1

3. create a C file

erts/emulator/beam/erl_bif_re.c

4. add your C file to erts/emulator/<arch>/Makefile

RUN_OBJS = $(OBJDIR)/erl_bif_re.o \

5. implement your bifs by stealing bits from existing erl_bif_*.c files
1
2
3
4
5
BIF_RETTYPE re_grep_2(BIF_ALIST_2){
  Eterm result;
  result = magic_function();
  BIF_RET(result);
}
6. run make; make install

notes

  • steps 0-3 need only be done once.
  • note that if you add
1
bif re:grep/2

to bif.tab there should be a erl_bif_re.c that implements

1
BIF_RETTYPE re_grep_2(BIF_ALIST_2);


from: https://erlangcentral.org/wiki/index.php/Adding_my_own_BIF


happy hackin'

erlang web frameworks

함수형 언어/Erlang 2013. 4. 10. 14:54 by manywaypark

erlang의 주요한 web framework들을 소개하는 좋은 자료가 있어 링크를 남김.

(저자는 yaws의 commiter임)

http://cufp.org/conference/sessions/2012/t2-erlang-web-frameworks-steve-vinoski-basho-techn


happy hackin'


Gambit-C Scheme 소개글

함수형 언어/Scheme 2013. 2. 14. 01:48 by manywaypark

Gambit-C Scheme은 gsi(interpreter), gsc(compiler)로 이루어져 있고, compiler는 C 코드를 생성해준다.

아래는 Scheme에 관한 간단한 튜토리얼 및 Gambit-C를 사용해서 native app을 개발하는 것을 설명한 링크이다.

http://www.devx.com/opensource/Article/42778

 

happy hackin'

eval을 써서 멋지게 해결했다고 생각했는데 실행파일을 만들어서 실행하거나, DrRacket에서 run 버튼으로 실행할 때 다음과 같은 오류가 났다.

fn-name: unbound identifier;

 also, no #%top syntax transformer is bound in: fn-name

eval을 쓸때 REPL에서하는 것과 그냥 실행하는 것에 차이가 있다 (phase에 따른 namespace의 문제. 자세한건 링크 참조).

빨리 해결하려는 맘에 (define ns (make-base-namespace)) (eval ... ... ns)의 형태로 변경하라는 예제를 보고 그렇게 했더니 아래와 같은 다른 에러가 났다. 아예 정의가 안됐다는 에러.

(나중에 찬찬히 읽어보니 make-base-namespaceracket/base module이 export하는 symbol들만 resolve가능하게 해주는 것이었다)

fn-name: undefined;

 cannot reference undefined identifier

해결책은 namespace anchor를 사용하는 것이었다. 참고 링크의 맨 마지막에 있다(역시 끝까지 읽어보는 것이 중요하다).

(define-namespace-anchor a)

(define ns (namespace-anchor->namespace a))

......

(eval ... ... ns)


ref: http://docs.racket-lang.org/guide/eval.html


happy hackin'

[참고] eval, apply

함수형 언어/Scheme 2013. 2. 7. 00:35 by manywaypark

http://www.cs.washington.edu/education/courses/cse341/12au/racket/eval-apply.html


happy hackin'

Erlang의 풍부한 표현 방법을 보여주기 위한 간단한 예제를 만들었다.
lists:map에 전달하는 첫번째 파라미터(함수) 부분의 표현 방법을 보면 된다. 

by_...
function은  리스트를 입력받아 각 요소가 홀수인지 짝수인지 판별한다 (에러 처리 포함).
@spec (by_...([integer() | any()]) -> [odd | even | error].

기본적으로 유념해야 할 것은,
  • if는 guard expression을 사용하고, case는 pattern matching을 사용한다.
  • if는 마지막에 truecase는 마지막에 underscore(_) 또는 Any를 사용하여 default(catch all) 조건을 만든다.
  • guard의 and는 comma(,)이고, or는 semicolon(;)이다.

자세한 것은 코드 참조.

%%% -*- mode: erlang; tab-width: 4; indent-tabs-mode: nil -*-
%%%-------------------------------------------------------------------
%%% File    : expressions.erl
%%% Author  : M.W. Park <manywaypark@gmail.com>
%%% Description : an erlang example (to explain expressions)
%%%               ref: http://www.erlang.org/doc/reference_manual/expressions.html
%%%
%%% Created : 2011-09-22 목요일 by M.W. Park
%%%-------------------------------------------------------------------

-module(expressions).
%% -export([]).
%% -import(, []).
-compile(export_all).

%% using guard inside 'if'
by_if(L) when is_list(L) ->
    lists:map(fun(X) ->
                      if
                          is_integer(X),
                          X rem 2 =:= 0 -> even;
                          is_integer(X) -> odd;
                          true          -> error
                      end
              end,
              L).

%% nested 'case'
by_case(L) when is_list(L) ->
    lists:map(fun(X) ->
                      case is_integer(X) of
                          true ->
                              case X rem 2 of
                                  0 -> even;
                                  _ -> odd
                              end;
                          _ -> error
                      end
              end,
              L).

%% 'case' w/ guards
by_case_with_guard(L) when is_list(L) ->
    lists:map(fun(X) ->
                      case X of
                          _ when is_integer(X),
                                 X rem 2 =:= 0 -> even;
                          _ when is_integer(X) -> odd;
                          _                    -> error
                      end
              end,
              L).

%% 'case' w/ exception
%% 'rem' operator may throw an exception.
by_case_with_ex(L) when is_list(L) ->
    lists:map(fun(X) ->
                      try 
                          case X rem 2 of
                              0 -> even;
                              _ -> odd
                          end
                      catch
                          _:_ -> error
                      end
              end,
              L).

%% pattern matching functions
'what?'(X) when is_integer(X), X rem 2 =:= 0 ->
    even;
'what?'(X) when is_integer(X) ->
    odd;
'what?'(_) ->
    error.

%% passing function name as a parameter
by_passing_fun(L) when is_list(L) ->
    lists:map(fun 'what?'/1, L).

%% anonymous function w/ guards
by_anonymous_fun(L) when is_list(L) ->
    lists:map(fun(X) when is_integer(X),
                          X rem 2 =:= 0 -> even;
                 (X) when is_integer(X) -> odd;
                 (_)                    -> error
              end,
              L).

%% mixture of anonymous function w/ a guard and 'case'
by_mix(L) when is_list(L) ->
    lists:map(fun(X) when is_integer(X) ->
                      case X rem 2 of
                          0 -> even;
                          _ -> odd
                      end;
                 (_) -> error
              end,
              L).

%%%-------------------------------------------------------------------
%%% Unit Tests
%%%-------------------------------------------------------------------
-include_lib("eunit/include/eunit.hrl").

-define(BASIC(FunName), ?_assertEqual([odd, even], FunName(lists:seq(1, 2)))).
-define(ERROR(FunName), ?_assertEqual([error, error], FunName([0.1, atom]))). 

by_if_test_() ->
    [
     ?BASIC(by_if),
     ?ERROR(by_if)
    ].

by_case_test_()->
    [
     ?BASIC(by_case),
     ?ERROR(by_case)
    ].

by_case_with_guard_test_() ->
    [
     ?BASIC(by_case_with_guard),
     ?ERROR(by_case_with_guard)
    ].

by_case_with_ex_test_() ->
    [
     ?BASIC(by_case_with_ex),
     ?ERROR(by_case_with_ex)
    ].

by_passing_fun_test_() ->
    [
     ?BASIC(by_passing_fun),
     ?ERROR(by_passing_fun)
    ].

by_anonymous_fun_test_() ->
    [
     ?BASIC(by_anonymous_fun),
     ?ERROR(by_anonymous_fun)
    ].

by_mix_test_() ->
    [
     ?BASIC(by_mix),
     ?ERROR(by_mix)
    ].

happy hackin'
Erlang Opcode
참고 문서에는 otp_src_R14B01/lib/compiler/src/beam_opcodes.erl에 있다고 설명하고있으나,
최신 소스에는 otp/dialyzer/test/options1_SUITE_data/src/compiler/beam_opcodes.erl에 있고 주석에 보면 beam_makeops를 이용해서 만들어졌다고 되어있다.
beam_makeopsotp/erts/emulator/utils에 있고 perl script이다.

erlang source(.erl)을 assembly code(.S)로 컴파일 할 수 있는데 아래처럼 compile flag에 "+'S'"를 추가 하면 된다.
파일 내용을 확인해보면 opcode들이 난무(?)한다. 
$ erlc "+'S'" foo.erl

BEAM file format
TBD - 아래 링크 참고

happy hackin'
 
refs:
결론부터 말하자면 복합키는 지원안된다 (erlang mnesia composite key 쯤으로 구글링하면 많이 나온다).
키에 tuple을 써서 비슷하게 만들 수 있다.
아래와 같이 레코드를 정의하고 쓰면 된다.
-record(id, {name=[], phone=[]}).
-record(person,  {pkey=#id{}, addr=[], note=[]}).

index 추가하면 되는 줄로 알고... 몇년전에 삽질했던 것을 오늘 또 했다. Orz...
다시 몇년 후를 기약(?)하며 오늘은 기록으로 남겨둔다.

happy hackin'

1 2 3 4 5 6 7 
분류 전체보기 (306)
잡담 (20)
함수형 언어 (65)
emacs (16)
java (18)
tips & tricks (154)
사랑 (1)
가사 (0)
독서 (4)
mobile (6)
비함수형 언어 (2)

공지사항

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

05-14 14:22