스택 크기를 어떻게 구하나요?

yeilho의 이미지

현재 내 프로세스가 얼마나 스택을 사용하는지 어떻게 알수 있나요?

/proc/pid/status 를 보면 VmStk 라는 필드가 있는데 그 정보를 보면 되는지 아님 다른 정보를 어떻게 구할수 있는지 정보 부탁드립니다.

그리고 vfork 를 사용한다면 각각의 쓰레드가 얼마나 스택을 사용하는지 알 수 있나요?

감사합니다.

a287848의 이미지

VMSTK 사이즈가 stack 사이즈 맞습니다.

http://kldp.org/node/18897

Thread stack에 대한 답변은 pthread 의 경우

http://kldp.org/node/89847

해당 링크를 보시면되겠네요

Dig it.

Dig it.

tj의 이미지

thread에선 pthread_attr_getstack()으로 stack top 구하고 %rsp나 %esp 값 읽어서 빼면 나오고, 아니면 그냥 로컬 변수 주소 빼면 되요. 어라 질문을 다시 읽어보니 밖에서 구하고 싶으신 건가요? 그러면 ptrace로 붙어서 읽어오는 방법밖엔 생각이 안나네요.

yeilho의 이미지

네 기본적으로는 밖에서 구할려구 합니다.

저도 어디선가 리눅스 기본 스택 사이즈가 10MB 라는 글을 보았습니다. 그런데 VMSTK값을 보면 전혀 그렇게 안보이네요.

그리고 해당 프로그램 안에서도 제가 실제로 쓰레드를 만든후 로컬 변수를 생성해도 사이즈가 VMSTK가 변하지 않던데 혹시 왜그런지 아시나요?
esp를 읽는 것도 생각해봤는데 시작주소를 32비트인경우 0xC0000000 라고 봐도 되나요?

마지막으로 vfork를 사용하면 스택이 어떻게 관리되는지 궁금하네요. (이부분은 제가 찾아보고 답변을 올려보겠습니다.)

이래저래 적다보니 너무 질문이 많아졌네요.

감사합니다.

Linux rules!!!

Linux rules!!!

a287848의 이미지

VMSTK 나 VMRSS를 다 올려주시면 답변하는데에 더 도움이 되지 않을까 싶네요.

쓰레드를 만든후 로컬 변수를 생성해도 사이즈가 변하지 않는다고 하신건 Debugger 에서 breakpoint 를 잡고하신건가요?

breakpoint 를 잡았다면 어느시점에서 잡은건지 assembler 기준으로 확인해봐야할듯 합니다.

아시겠지만 로컬변수는 함수 진입점에서 stack을 늘리잖아요.

esp를 0xc000000 기준으로 하셨는데 스택 시작 위치는 Linux 의 경우 Kernel 버젼이나 gblic 버젼에 따라서

다릅니다. 실행파일이 LD 에 의해서 Load 되고 환경변수들을 메모리에 복사해줄때

파일 이름등에 의해서 실제 스텍의 시작위치가 바뀔수 있거든요.

그외 해킹의 이유로 stack address randomization 이 커널 2.6대에는 포함되어 있습니다.

스택주소는 inline assembler 넣어서 직접 구하시는게 제일확실합니다.

Dig it.

Dig it.

yeilho의 이미지

답변 감사드립니다.

아래는 proc 에서 뽑은 내용입니다. 제가 만든 쓰레드와 프로세스가 출력하는 값이 Vm 경우에는 차이가 없어서 그냥 하나만 올립니다.

$ cat /proc/15522/status
Name:   test_app
State:  S (sleeping)
Tgid:   15522
Pid:    15522
PPid:   15210
TracerPid:      0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 256
Groups: 4 20 24 46 106 121 122 1000
VmPeak:    20676 kB
VmSize:    20676 kB
VmLck:         0 kB
VmHWM:       832 kB
VmRSS:       832 kB
VmData:     8452 kB
VmStk:        84 kB
VmExe:         8 kB
VmLib:      1724 kB
VmPTE:        48 kB
Threads:        2
SigQ:   0/16382
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000180000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed:   00000000,0000000f
Cpus_allowed_list:      0-3
Mems_allowed:   1
Mems_allowed_list:      0
voluntary_ctxt_switches:        2
nonvoluntary_ctxt_switches:     17

참고로 스택 크기 값은 디버거에서 본게 아니고 단순히 proc에서 뽑은 값으로 비교 했습니다. (실제 제가 밖에서 스택 값을 구현해야 되어서요.)
제가 궁금한 부분은 VmStk가 제가 원하는 값인지 잘 모르겠습니다. 느낌으로는 로컬 변수를 잡으면 바뀌어야 될것 같은데 값이 변하지 않아서요. (참고로 로컬 변수를 여러개 잡았는데 각각의 크기는 4096*16 으로 해서 잡았습니다.)

방금 lxr 커널 소스를 찾아보니 아래 처럼 나오는데 stack_vm이 업데이트가 안되는건가요?

  39        seq_printf(m,
  40                "VmPeak:\t%8lu kB\n"
  41                "VmSize:\t%8lu kB\n"
  42                "VmLck:\t%8lu kB\n"
  43                "VmHWM:\t%8lu kB\n"
  44                "VmRSS:\t%8lu kB\n"
  45                "VmData:\t%8lu kB\n"
  46                "VmStk:\t%8lu kB\n"
  47                "VmExe:\t%8lu kB\n"
  48                "VmLib:\t%8lu kB\n"
  49                "VmPTE:\t%8lu kB\n",
  50                hiwater_vm << (PAGE_SHIFT-10),
  51                (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
  52                mm->locked_vm << (PAGE_SHIFT-10),
  53                hiwater_rss << (PAGE_SHIFT-10),
  54                total_rss << (PAGE_SHIFT-10),
  55                data << (PAGE_SHIFT-10),
  56                mm->stack_vm << (PAGE_SHIFT-10), text, lib,
  57                (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);

Linux rules!!!

Linux rules!!!

a287848의 이미지


void make100bytes(int param){
char buf[4096];
memset(buf, 0 ,100);

if(param > 0) {
printf("making additional stack frame\n");
sleep(3);
make100bytes(param - 1);
}
}

int main(){
make100bytes(100);
}

위와 같이 test라는 이름으로 프로그램 짜고 proc/$(pid)/status 를 주기적을 열어보니

watch -n 1 "cat /proc/`ps -ef | grep test | grep -v grep | awk '{print $2}'`/status"

VMRSS기준으로 44Kbytes가 증가되기전까지는 VMSTAK이 88kbytes로 변화가 없다가 그 이후로는

stack 의 크기가 계속증가되네요.

미리 일정양을 할당해놓는것 처럼 보이는데.............

esp 는 그렇지 않은데 왜 그렇게 일정 크기 까지는 status 에 반영이 안되는지 저도 한번 살펴보겠습니다.
(반영이 안되는건지 다른 이유가 있는지...)

일단 제약이 있지만 proc/status 만으로도 외부 구현이 가능할듯 싶네요.

더불어

Quote:
저도 어디선가 리눅스 기본 스택 사이즈가 10MB 라는 글을 보았습니다. 그런데 VMSTK값을 보면 전혀 그렇게 안보이네요.

기본스택 사이즈가 10MB라는 말은 Process Address space에

Stack 크기를 잡아줄때 maximum stack 크기를 10MB로 잡는다는 예기입니다.

따라서 VMSTK 로는 알수가 없겠지요.

Dig it.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.