DLL과 가상메모리 주소

kyj_kr의 이미지

DLL과 같은 공유 라이브러리 같은 경우, 최초 로딩시에 실제 메모리 상에 올라가고 이후 다른 프로세스에서 로딩을 시도하면 그냥 실제메모리-가상메모리 간 매핑만 시켜주기만 하면 되는게 공유가 되는 원리 아닌가요?

그런데,

1. 프로세스 A가 실행되며 X.dll을 로드한다.
따라서 X.dll은 A의 가상 메모리 영역에 맵핑되면서 물리 메모리에 할당된다.

2. 프로세스 B가 실행되며 X.dll을 로드한다.
이미 1단계에서 X.dll이 물리 메모리에 올라 있으므로 그대로 참조할 수 있도록
프로세스 B의 가상 메모리 영역에 맵핑만 한다.

이 상황에서 유의할 것이 X.dll 이 할당된 가상 메모리 주소이다.
프로세스 A와 B가 동일한 주소에 할당한다. 이것이 DLL 공유가 가능한 이유이다.
다시 말해서 두 프로세스가 동일한 DLL을 동일한 가상 주소에 맵핑했기 때문에,
페이지 단위로 공유가 가능하다는 것이다.

[출처] http://egloos.zum.com/sweeper/v/1792902

구글 검색 중에 이런 글을 보게 되었는데, 위 글 내용중에 "프로세스 A와 B가 동일한 주소에 할당한다. 이것이 DLL 공유가 가능한 이유이다."라는 문구가 이해가 가질 않습니다. 왜냐하면, 프로세스A와 프로세스B가 동일한 가상메모리 주소에 할당하지 않고, 그냥 실제메모리와 매핑만 잘시켜주면 그게 DLL 공유가 가능한 이유 아닌가요?

ifree의 이미지

프로그램마다 할당되는 메모리 영역이 다르기 때문에 다른 메모리 영역의 dll 에는 접근할 수 없습니다.

chanik의 이미지

그 블로그의 언급이 맞는 것 같습니다.

DLL 코드가 프로세스마다 서로 다른 가상메모리 주소로 매핑될 경우라도, DLL 코드에 변경만 없다면 실제메모리 공간 공유에는 문제가 생기지 않겠으나,

실상은 DLL 로드시 매핑주소가 달라지면 DLL 코드중 점프명령 등도 따라 수정되는 코드재배치(relocation)가 이뤄지므로 DLL 코드를 담고 있는 메모리페이지에 거의 필연적으로 쓰기가 발생하게 됩니다. 그 결과로 Copy-on-write protection에 의해 해당 페이지는 새 메모리페이지로 복사이동되므로 더이상 타 프로세스와 공유될 수 없게 되고요.

즉, 해당 DLL이 동일 가상주소로(default base address로) 로드된 프로세스들끼리는 DLL 코드페이지 전체가 공유되지만, 다른 주소로 로드된 프로세스의 경우엔 CoW가 발생하지 않은 페이지들만 공유되는 것 같습니다. 잘 아는 것은 아니고, 잠시 호기심이 생겨 아래의 MS 자료를 참고하여 얻은 결론입니다.

Loading Applications and DLLs
https://docs.microsoft.com/en-us/windows/win32/memory/memory-protection

Quote:
DLLs are created with a default base address. Every process that uses a DLL will try to load the DLL within its own address space at the default virtual address for the DLL. If multiple applications can load a DLL at its default virtual address, they can share the same physical pages for the DLL. If for some reason a process cannot load the DLL at the default address, it loads the DLL elsewhere.

Copy-on-write protection forces some of the DLL's pages to be copied into different physical pages for this process, because the fixes for jump instructions are written within the DLL's pages, and they will be different for this process. If the code section contains many references to the data section, this can cause the entire code section to be copied to new physical pages.


kyj_kr의 이미지

작성하신분 덕에 이해가 되었네요!

핵심은 Dll code의 relocation과 Cow군요.

예상치도 못했는데 개운한 느낌 얻고 갑니다.

감사합니다!

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.