Runtime: PInvoke๋ฅผ ํ†ตํ•œ ์˜ˆ์™ธ

์— ๋งŒ๋“  2017๋…„ 07์›” 26์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: dotnet/runtime

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

using System;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("libupcall.so")]
    public static extern void register_callback(Callback cb);

    [DllImport("libupcall.so")]
    public static extern void upcall();

    public static void MyStaticCallback(int val)
    {
        throw new Exception("error");
    }

    public delegate void Callback(int var);
    static Callback cbMyStaticCallback = MyStaticCallback;  

    static void Main(string[] args)
    {
        try {
            register_callback(MyStaticCallback); 
            upcall();                

        } catch (Exception e) {
            Console.WriteLine("Catch clause caught : {0} \n", e.Message);
        }
    }
}

libupcall.so๋Š” ๋‹ค์Œ C ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

#include <stdio.h>

typedef void (*callback)(int val);

callback gCB;

extern void register_callback(callback cb)
{
    printf("register_callback:%p ----\n", (void *)cb);
    gCB = cb;
}
extern void upcall()
{
    static int c = 0;
    printf("upcall ----\n");
    gCB(c++);
}

dotnet run์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์˜ˆ์™ธ์™€ ํ•จ๊ป˜ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

twoflower@js2-desktop:~/dev/complexexception$ sudo dotnet run
register_callback:0x7f3a041f407c ----
upcall ----

Unhandled Exception: System.Exception: error
   at Program.MyStaticCallback(Int32 val) in /home/twoflower/dev/complexexception/Program.cs:line 14
   at Program.upcall()
   at Program.Main(String[] args) in /home/twoflower/dev/complexexception/Program.cs:line 24
twoflower@js2-desktop:~/dev/complexexception$ 

์—ฌ๊ธฐ์— corefile bt๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

* thread dotnet/coreclr#1: tid = 0, 0x00007fda93b26428 libc.so.6`__GI_raise(sig=6) + 56 at raise.c:54, name = 'dotnet', stop reason = signal SIGABRT
  * frame #0: 0x00007fda93b26428 libc.so.6`__GI_raise(sig=6) + 56 at raise.c:54
    frame dotnet/coreclr#1: 0x00007fda93b2802a libc.so.6`__GI_abort + 362 at abort.c:89
    frame dotnet/coreclr#2: 0x00007fda9326258c libcoreclr.so`??? + 124
    frame dotnet/coreclr#3: 0x00007fda9326148b libcoreclr.so`??? + 235
    frame dotnet/coreclr#4: 0x00007fda92f0b893 libcoreclr.so`??? + 531
    frame dotnet/coreclr#5: 0x00007fda92f0cd71 libcoreclr.so`??? + 593
    frame dotnet/coreclr#6: 0x00007fda92fcaae3 libcoreclr.so`??? + 51
    frame dotnet/coreclr#7: 0x00007fda93ecb263 libgcc_s.so.1`_Unwind_RaiseException(exc=0x0000000002467530) + 115 at unwind.inc:113
    frame dotnet/coreclr#8: 0x00007fda9446790c libstdc++.so.6`__cxa_throw + 92
    frame dotnet/coreclr#9: 0x00007fda9322749d libcoreclr.so`??? + 77
    frame dotnet/coreclr#10: 0x00007fda92fd781e libcoreclr.so`??? + 273
    frame dotnet/coreclr#11: 0x00007fda88e4b7b2 libupcall.so`upcall + 45 at upcall.c:16
    frame dotnet/coreclr#12: 0x00007fda19d85ae6
    frame dotnet/coreclr#13: 0x00007fda19d8588e
    frame dotnet/coreclr#14: 0x00007fda92fd67b7 libcoreclr.so`??? + 124
    frame dotnet/coreclr#15: 0x00007fda92eec630 libcoreclr.so`??? + 1264

Main ํ•จ์ˆ˜์˜ catch ๋ธ”๋ก์ด ์˜ˆ์™ธ๋ฅผ catchํ•˜์ง€ ์•Š๋Š” ์ •์ƒ์ ์ธ ๋™์ž‘์ž…๋‹ˆ๊นŒ?

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๊ทธ ์ด์œ  ์ค‘ ํ•˜๋‚˜๋Š” ๊ด€๋ฆฌ๋˜๋Š” ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœํ•œ ๊ธฐ๋ณธ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์˜ˆ์™ธ๋ฅผ ์ „ํŒŒํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‹ค์ œ๋กœ ์•Œ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ์–ด๋–ค ์ข…๋ฅ˜์ธ์ง€ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. C ์ฝ”๋“œ, C++ ์ฝ”๋“œ, ASM ์ฝ”๋“œ ๋˜๋Š” ๋‹ค๋ฅธ ์–ธ์–ด ์ฝ”๋“œ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ”„๋ ˆ์ž„์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์˜ˆ๋ฅผ ๋“ค์–ด C++์ธ ๊ฒฝ์šฐ ์Šคํƒ ๊ฐœ์ฒด์˜ ์†Œ๋ฉธ์ž๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋˜๋Š” ์ž ๊ธด ์ž ๊ธˆ ๋“ฑ์„ ํฌ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฏธ๋ฆฌ ์ •์˜๋œ C++ ์˜ˆ์™ธ๋ฅผ throwํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋ฉด ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๊ฐ€ ์ด๋ฅผ ์‚ผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜๋„์น˜ ์•Š๊ฒŒ. ๋˜๋Š” ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ค€๋น„๊ฐ€ ๋˜์ง€ ์•Š์€ ์ผ๋ถ€ ๋Ÿฐํƒ€์ž„์ด ์ค‘๋‹จ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  3 ๋Œ“๊ธ€

๋„ค์ดํ‹ฐ๋ธŒ ๊ฒฝ๊ณ„๋กœ ๊ด€๋ฆฌ๋˜๋Š” ์˜ˆ์™ธ ๊ต์ฐจ(๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ์—์„œ ์ฝœ๋ฐฑ์ด ํ˜ธ์ถœ๋˜๊ณ  ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ์™€ ๊ฐ™์ด)๋Š” ์˜๋„์ ์œผ๋กœ dotnet ์ฝ”์–ด์—์„œ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ์—์„œ ํ˜ธ์ถœํ•˜๋Š” ์ฝœ๋ฐฑ์˜ ๋ชจ๋“  ์˜ˆ์™ธ๋ฅผ ํฌ์ฐฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ์ด์œ  ์ค‘ ํ•˜๋‚˜๋Š” ๊ด€๋ฆฌ๋˜๋Š” ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœํ•œ ๊ธฐ๋ณธ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์˜ˆ์™ธ๋ฅผ ์ „ํŒŒํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‹ค์ œ๋กœ ์•Œ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ์–ด๋–ค ์ข…๋ฅ˜์ธ์ง€ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. C ์ฝ”๋“œ, C++ ์ฝ”๋“œ, ASM ์ฝ”๋“œ ๋˜๋Š” ๋‹ค๋ฅธ ์–ธ์–ด ์ฝ”๋“œ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ”„๋ ˆ์ž„์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์˜ˆ๋ฅผ ๋“ค์–ด C++์ธ ๊ฒฝ์šฐ ์Šคํƒ ๊ฐœ์ฒด์˜ ์†Œ๋ฉธ์ž๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋˜๋Š” ์ž ๊ธด ์ž ๊ธˆ ๋“ฑ์„ ํฌ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฏธ๋ฆฌ ์ •์˜๋œ C++ ์˜ˆ์™ธ๋ฅผ throwํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋ฉด ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๊ฐ€ ์ด๋ฅผ ์‚ผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜๋„์น˜ ์•Š๊ฒŒ. ๋˜๋Š” ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ค€๋น„๊ฐ€ ๋˜์ง€ ์•Š์€ ์ผ๋ถ€ ๋Ÿฐํƒ€์ž„์ด ์ค‘๋‹จ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งค์šฐ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰