नए टूल की मदद से WebAssembly को डीबग करना

Ingvar Stepanyan
Ingvar Stepanyan

अब तक की सड़क

एक साल पहले, Chrome ने Chrome DevTools में नेटिव WebAssembly डीबग करने के लिए, शुरुआती तौर पर सहायता देने का एलान किया है.

हमने पैदल चलने की बुनियादी सहायता दी और आने वाले समय में हमारे लिए ओपन सोर्स मैप की जगह DWARF जानकारी के इस्तेमाल के अवसरों के बारे में बात की:

  • वैरिएबल के नामों को ठीक करना
  • प्रिटी-प्रिंटिंग प्रकार
  • सोर्स भाषाओं में एक्सप्रेशन का आकलन करना
  • ...और भी बहुत कुछ!

आज, हम वादा की गई सुविधाओं को लागू करने और Emscripten और Chrome DevTools की टीमों ने इस साल, खास तौर पर C और C++ ऐप्लिकेशन के लिए हुई प्रोग्रेस को दिखाने के लिए उत्साहित हैं.

शुरू करने से पहले, कृपया ध्यान रखें कि यह अब भी नए वर्शन का बीटा वर्शन है. आपको अपने जोखिम पर सभी टूल के नए वर्शन का इस्तेमाल करना होगा. अगर आपको कोई समस्या होती है, तो https://bugs.chromium.org/p/chromium/issues/entry?template=DevTools+issue पर शिकायत करें.

चलिए, पिछली बार वाले उसी आसान C उदाहरण से शुरुआत करते हैं:

#include <stdlib.h>

void assert_less(int x, int y) {
  if (x >= y) {
    abort();
  }
}

int main() {
  assert_less(10, 20);
  assert_less(30, 20);
}

इसे कंपाइल करने के लिए, हम सबसे नए Emscripten का इस्तेमाल करते हैं और मूल पोस्ट की तरह ही -g फ़्लैग पास करते हैं, ताकि डीबग की जानकारी शामिल की जा सके:

emcc -g temp.c -o temp.html

अब हम जनरेट किए गए पेज को localhost एचटीटीपी सर्वर से दिखा सकते हैं (उदाहरण के लिए, serve के साथ) और उसे नए Chrome कैनरी में खोलें.

इस बार हमें एक हेल्पर एक्सटेंशन की भी ज़रूरत होगी, जो Chrome DevTools के साथ इंटिग्रेट होता हो. साथ ही, यह WebAssembly फ़ाइल में कोड में बदली गई, डीबग करने से जुड़ी सभी जानकारी को समझने में मदद करता हो. कृपया इस लिंक पर जाकर, इसे इंस्टॉल करें: goo.gle/wasm-debugging-extension

ऐसा हो सकता है कि आप DevTools एक्सपेरिमेंट में, WebAssembly डीबग करने की सुविधा को भी चालू करें. Chrome DevTools खोलें, DevTools पैनल के सबसे ऊपर दाएं कोने में मौजूद गियर () आइकॉन पर क्लिक करें, एक्सपेरिमेंट पैनल पर जाएं और WebAssembly डीबगिंग: DWARF सहायता चालू करें पर क्लिक करें.

DevTools सेटिंग का एक्सपेरिमेंट पैनल

सेटिंग बंद करने पर, DevTools सेटिंग लागू करने के लिए, अपने-आप को फिर से लोड करने का सुझाव देगा. इसलिए, आइए ऐसा ही करते हैं. एक बार के सेटअप में बस इतना ही.

अब सोर्स पैनल पर वापस जाकर, अपवाद पर रोकें (⏸ आइकॉन) को चालू करें. इसके बाद, अपवादों पर रोकें को चुनें और पेज को फिर से लोड करें. आपको एक अपवाद पर DevTools रुका हुआ दिखेगा:

सोर्स पैनल का स्क्रीनशॉट, जो &#39;रोके गए अपवादों पर रोकें&#39; को चालू करने का तरीका दिखाता है

डिफ़ॉल्ट रूप से, यह Emscripten से जनरेट किए गए ग्लू कोड पर रुक जाता है. हालांकि, दाईं ओर आपको कॉल स्टैक व्यू दिख सकता है, जो गड़बड़ी के स्टैकट्रेस को दिखाता है. साथ ही, शुरू की गई मूल सी लाइन पर नेविगेट किया जा सकता है abort:

`assert_less` फ़ंक्शन में DevTools को रोका गया और स्कोप व्यू में `x` और `y` की वैल्यू दिखाई जा रही हैं

अब, स्कोप व्यू में देखने पर, C/C++ कोड में वैरिएबल के मूल नाम और वैल्यू देखी जा सकती हैं. साथ ही, आपको यह पता लगाने की ज़रूरत नहीं है कि $localN जैसे गुमराह करने वाले नामों का क्या मतलब है और वे आपके लिखे गए सोर्स कोड से कैसे जुड़े हैं.

यह सिर्फ़ पूर्णांक जैसे प्रिमिटिव वैल्यू पर ही नहीं, बल्कि स्ट्रक्चर, क्लास, अरे वगैरह जैसे कंपाउंड टाइप के कंपाउंड पर भी लागू होता है!

रिच टाइप की सहायता

आइए, इन्हें दिखाने के लिए एक मुश्किल उदाहरण देखते हैं. इस बार, हम नीचे दिए गए C++ कोड के साथ एक मैंडलब्रॉट फ़्रैक्टल बनाएंगे:

#include <SDL2/SDL.h>
#include <complex>

int main() {
  // Init SDL.
  int width = 600, height = 600;
  SDL_Init(SDL_INIT_VIDEO);
  SDL_Window* window;
  SDL_Renderer* renderer;
  SDL_CreateWindowAndRenderer(width, height, SDL_WINDOW_OPENGL, &window,
                              &renderer);

  // Generate a palette with random colors.
  enum { MAX_ITER_COUNT = 256 };
  SDL_Color palette[MAX_ITER_COUNT];
  srand(time(0));
  for (int i = 0; i < MAX_ITER_COUNT; ++i) {
    palette[i] = {
        .r = (uint8_t)rand(),
        .g = (uint8_t)rand(),
        .b = (uint8_t)rand(),
        .a = 255,
    };
  }

  // Calculate and draw the Mandelbrot set.
  std::complex<double> center(0.5, 0.5);
  double scale = 4.0;
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      std::complex<double> point((double)x / width, (double)y / height);
      std::complex<double> c = (point - center) * scale;
      std::complex<double> z(0, 0);
      int i = 0;
      for (; i < MAX_ITER_COUNT - 1; i++) {
        z = z * z + c;
        if (abs(z) > 2.0)
          break;
      }
      SDL_Color color = palette[i];
      SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
      SDL_RenderDrawPoint(renderer, x, y);
    }
  }

  // Render everything we've drawn to the canvas.
  SDL_RenderPresent(renderer);

  // SDL_Quit();
}

यह देखा जा सकता है कि यह ऐप्लिकेशन अब भी छोटा है-यह सिंगल फ़ाइल है जिसमें 50 लाइनों का कोड है-लेकिन इस बार मैं ग्राफ़िक के लिए एसडीएल लाइब्रेरी जैसे कुछ बाहरी एपीआई और C++ स्टैंडर्ड लाइब्रेरी के जटिल नंबर का भी इस्तेमाल कर रहा हूं.

मैं डीबग जानकारी शामिल करने के लिए इसे ऊपर दिए गए -g फ़्लैग के साथ कंपाइल करूंगा/करूंगी. साथ ही, मैं Emscripten को SDL2 लाइब्रेरी उपलब्ध कराने और बिना सोचे-समझे साइज़ की मेमोरी उपलब्ध कराने के लिए कहूंगा:

emcc -g mandelbrot.cc -o mandelbrot.html \
     -s USE_SDL=2 \
     -s ALLOW_MEMORY_GROWTH=1

ब्राउज़र में जनरेट किए गए पेज पर जाने पर, मुझे अलग-अलग रंगों के साथ खूबसूरत फ़्रैक्टल आकार दिखेगा:

डेमो पेज

DevTools खोलने पर, मुझे एक बार फिर से ओरिजनल C++ फ़ाइल दिखेगी. हालांकि, इस समय हमें कोड में कोई गड़बड़ी नहीं दिखेगी (वाह!), इसलिए आइए अपने कोड की शुरुआत में ही कुछ ब्रेकपॉइंट सेट करते हैं.

जब हम पेज को फिर से लोड करेंगे, तो डीबगर हमारे C++ सोर्स में ठीक से रुक जाएगा:

`SDL_Init` कॉल पर DevTools को रोका गया

हमें दाईं ओर अपने सभी वैरिएबल दिख सकते हैं. हालांकि, इस समय सिर्फ़ width और height ही शुरू किए गए हैं. इसलिए, जांचने की कोई ज़रूरत नहीं है.

चलिए, अपने मुख्य मैंडलब्रॉट लूप में एक और ब्रेकपॉइंट सेट करते हैं और प्रोसेस को फिर से शुरू करके आगे बढ़ते हैं.

DevTools को नेस्ट किए गए लूप में रोका गया

अब हमारे palette में कुछ रैंडम कलर भरे हुए हैं. हम अरे के साथ-साथ, अलग-अलग SDL_Color स्ट्रक्चर को बड़ा कर सकते हैं. साथ ही, उनके कॉम्पोनेंट की जांच करके, यह पुष्टि कर सकते हैं कि सब कुछ अच्छा दिख रहा है या नहीं (उदाहरण के लिए, "ऐल्फ़ा" चैनल हमेशा पूरी ओपैसिटी पर सेट होता है). इसी तरह, हम center वैरिएबल में स्टोर किए गए कॉम्प्लेक्स नंबर के असली और काल्पनिक भागों को बड़ा करके देख सकते हैं.

अगर आपको एक ऐसी प्रॉपर्टी ऐक्सेस करनी है जिसमें पूरी तरह से नेस्ट की गई प्रॉपर्टी है और स्कोप व्यू में जाकर उस प्रॉपर्टी पर जाना मुश्किल है, तो कंसोल इवैलुएशन का भी इस्तेमाल किया जा सकता है! हालांकि, ध्यान दें कि ज़्यादा जटिल C++ एक्सप्रेशन फ़िलहाल काम नहीं करते हैं.

`पैलेट[10].r` का नतीजा दिखाने वाला कंसोल पैनल

एक्ज़ीक्यूशन फिर से शुरू करें और यह देख सकते हैं कि अंदरूनी x कैसे बदल रहा है. इसके लिए, स्कोप व्यू में फिर से देखें, वॉच लिस्ट में वैरिएबल के नाम को जोड़कर, कंसोल में उसका आकलन करें या सोर्स कोड में वैरिएबल पर कर्सर घुमाएं:

सोर्स में `x` वैरिएबल पर टूलटिप, इसकी वैल्यू `3` दिखा रहा है

यहां से, हम C++ स्टेटमेंट पर सिलसिलेवार तरीके से या पूरी जानकारी देंगे और यह देख पाएंगे कि दूसरे वैरिएबल में भी क्या बदलाव आ रहे हैं:

`रंग`, `पॉइंट`, और अन्य वैरिएबल की वैल्यू दिखाने वाले टूलटिप और स्कोप व्यू

ठीक है, डीबग की जानकारी उपलब्ध होने पर, यह सबसे सही तरीके से काम करता है. हालांकि, अगर हम किसी ऐसे कोड को डीबग करना चाहें जिसे डीबग करने के विकल्पों की मदद से नहीं बनाया गया था, तो क्या होगा?

रॉ WebAssembly डीबग करना

उदाहरण के लिए, हमने Emscripten को स्रोत से कंपाइल करने के बजाय हमारे लिए पहले से बनी एसडीएल लाइब्रेरी उपलब्ध कराने के लिए कहा था. कम से कम इस समय डीबगर के पास इससे जुड़े सोर्स ढूंढने का कोई तरीका नहीं है. चलिए, फिर से SDL_RenderDrawColor के बारे में जानते हैं:

DevTools में `mandelbrot.vasm` का पुर्ज़ों को अलग करने वाला व्यू दिख रहा है

अब हम WebAssembly डीबग करने के बुनियादी अनुभव पर वापस आ गए हैं.

यह थोड़ी डरावना लग रहा है और ऐसा नहीं है जिससे ज़्यादातर वेब डेवलपर को निपटना पड़े, लेकिन कभी-कभी हो सकता है कि आप डीबग जानकारी के बिना बनाई गई लाइब्रेरी को डीबग करना चाहें. चाहे वह 3rd-पक्ष की लाइब्रेरी हो या जिस पर आपका कोई कंट्रोल न हो या आप उन गड़बड़ियों में से किसी एक में आ रहे हों जो सिर्फ़ प्रोडक्शन के दौरान होती हैं.

ऐसे मामलों में सहायता के लिए, हमने बुनियादी डीबगिंग अनुभव में भी कुछ सुधार किए हैं.

सबसे पहले, अगर आपने पहले रॉ WebAssembly डीबगिंग का इस्तेमाल किया है, तो आप शायद ध्यान दें कि अब पूरी तरह से डिसअसेंबल एक ही फ़ाइल में दिखाया गया है. अब यह अनुमान लगाना ज़रूरी नहीं है कि सोर्स एंट्री wasm-53834e3e/ wasm-53834e3e-7 किस फ़ंक्शन से मेल खाती है.

नया नाम जनरेट करने की स्कीम

हमने प्रॉडक्ट के डिसअसेंबल व्यू में भी नामों में सुधार किया है. पहले आपको सिर्फ़ अंकों वाले इंडेक्स दिखते थे या फ़ंक्शन के मामले में कोई नाम नहीं दिखता था.

अब हम डिवाइस को खोलने वाले दूसरे टूल की तरह ही नाम जनरेट कर रहे हैं. इसके लिए, WebAssembly के नाम वाले सेक्शन से मिले संकेतों, इंपोर्ट/एक्सपोर्ट पाथ और अगर सब कुछ काम नहीं करता है, तो $func123 जैसे आइटम के टाइप और इंडेक्स के आधार पर उन्हें जनरेट करते हैं. ऊपर दिए गए स्क्रीनशॉट में देखा जा सकता है कि कैसे, इससे पहले से ही थोड़े ज़्यादा पढ़ने लायक स्टैकट्रेस और डिस असेंबली पाने में मदद मिलती है.

जब किसी तरह की जानकारी उपलब्ध न हो, तो प्रिमिटिव के अलावा किसी भी वैल्यू की जांच करना मुश्किल हो सकता है. उदाहरण के लिए, पॉइंटर, सामान्य पूर्णांक के तौर पर दिखेंगे. उन्हें यह पता नहीं होगा कि उनके पीछे मेमोरी में क्या सेव है.

मेमोरी की जांच करना

पहले, सिर्फ़ WebAssembly मेमोरी ऑब्जेक्ट को बड़ा किया जा सकता था. इसे स्कोप में env.memory से दिखाया जाता था, ताकि अलग-अलग बाइट देखी जा सकें. इससे कुछ छोटी-छोटी स्थितियों में भी डेटा मिल जाता था, लेकिन इसे बड़ा करना ज़्यादा आसान नहीं था. साथ ही, इससे बाइट वैल्यू के अलावा, अन्य फ़ॉर्मैट में डेटा का दोबारा मतलब समझने की सुविधा नहीं मिलती थी. इसमें मदद के लिए हमने एक नई सुविधा भी जोड़ी है: एक लीनियर मेमोरी इंस्पेक्टर.

env.memory पर राइट क्लिक करने पर, अब आपको मेमोरी की जांच करें नाम का एक नया विकल्प दिखेगा:

स्कोप पैनल में `env.memory` पर मौजूद कॉन्टेक्स्ट मेन्यू. इसमें &#39;मेमोरी की जांच करें&#39; आइटम दिख रहा है

क्लिक करने पर, एक मेमोरी इंस्पेक्टर दिखेगा जिसमें आप हेक्साडेसिमल और ASCII व्यू में WebAssembly मेमोरी की जांच कर सकते हैं, खास पतों पर जा सकते हैं, और डेटा को अलग-अलग फ़ॉर्मैट में समझ सकते हैं:

DevTools में मेमोरी इंस्पेक्टर पैनल, जिसमें मेमोरी के हेक्स और ASCII व्यू दिखाए गए हैं

बेहतर स्थितियां और सावधानियां

WebAssembly कोड की प्रोफ़ाइल बनाना

DevTools खोलने पर, WebAssembly कोड को डीबग करने की सुविधा चालू करने के लिए, ऑप्टिमाइज़ न किए गए वर्शन में "अलग-अलग टीयर" कर दिया जाता है. यह वर्शन बहुत धीमा है. इसका मतलब है कि DevTools खुले होने पर, console.time, performance.now, और कोड की स्पीड को मापने के अन्य तरीकों पर भरोसा नहीं किया जा सकता. इसकी वजह यह है कि आपको मिलने वाले आंकड़े असल में परफ़ॉर्मेंस को नहीं दिखाते.

इसके बजाय, आपको DevTools परफ़ॉर्मेंस पैनल का इस्तेमाल करना चाहिए. यह कोड को पूरी रफ़्तार से चलाएगा और आपको अलग-अलग फ़ंक्शन में बिताए गए समय की पूरी जानकारी देगा:

प्रोफ़ाइलिंग पैनल, जिसमें अलग-अलग Wasm फ़ंक्शन दिखाए गए हैं

इसके अलावा, अपने ऐप्लिकेशन को DevTools बंद करके चलाया जा सकता है. साथ ही, कंसोल की जांच करने के लिए, उन्हें खोलें.

हम आने वाले समय में प्रोफ़ाइलिंग के तरीकों में सुधार करेंगे. फ़िलहाल, यह ज़रूरी है कि आप जागरूक रहें. अगर आपको WebAssembly टियरिंग स्थितियों के बारे में ज़्यादा जानना है, तो WebAssembly कंपाइलेशन पाइपलाइन पर हमारे दस्तावेज़ देखें.

अलग-अलग मशीन पर बनाना और डीबग करना (जिसमें Docker / होस्ट भी शामिल है)

डॉकर, वर्चुअल मशीन या रिमोट बिल्ड सर्वर पर काम करते समय, आपको ऐसी स्थितियों का सामना करना पड़ सकता है जहां बिल्ड के दौरान इस्तेमाल की गई सोर्स फ़ाइलों के पाथ, आपके फ़ाइल सिस्टम के पाथ से मेल नहीं खाते. इस मामले में, फ़ाइलें सोर्स पैनल में दिखेंगी, लेकिन लोड नहीं होंगी.

इस समस्या को ठीक करने के लिए, हमने C/C++ एक्सटेंशन के विकल्पों में पाथ मैपिंग की सुविधा लागू की है. इसका इस्तेमाल, आर्बिट्रेरी पाथ को फिर से मैप करने और DevTools की मदद से सोर्स ढूंढने के लिए किया जा सकता है.

उदाहरण के लिए, अगर आपकी होस्ट मशीन पर मौजूद प्रोजेक्ट, C:\src\my_project पाथ के तहत आता है, लेकिन उसे Docker कंटेनर में बनाया गया था, जिसमें उस पाथ को /mnt/c/src/my_project के तौर पर दिखाया गया था, तो डीबग करने के दौरान उन पाथ को प्रीफ़िक्स के तौर पर देकर, इसे फिर से मैप किया जा सकता है:

C/C++ डीबगिंग एक्सटेंशन के विकल्पों वाला पेज

मेल खाने वाला पहला प्रीफ़िक्स "विन". अगर आप C++ डीबगर के बारे में जानते हैं, तो यह विकल्प GDB में set substitute-path कमांड या LLDB की target.source-map सेटिंग जैसा है.

ऑप्टिमाइज़ किए गए बिल्ड को डीबग करना

किसी भी दूसरी भाषा की तरह, अगर ऑप्टिमाइज़ेशन बंद हो जाते हैं, तो डीबग करने की सुविधा सबसे सही तरीके से काम करती है. ऑप्टिमाइज़ेशन की मदद से, एक जैसे फ़ंक्शन को एक-दूसरे में इनलाइन किया जा सकता है, कोड का क्रम बदला जा सकता है या कोड के कुछ हिस्सों को हटाया जा सकता है. ये सभी काम डीबगर को भ्रमित कर सकते हैं. इस वजह से, आपको एक उपयोगकर्ता माना जा सकता है.

अगर आपको डीबग करने के ज़्यादा सीमित अनुभव पर कोई आपत्ति नहीं है और फिर भी ऑप्टिमाइज़ किया गया कोई बिल्ड डीबग करना है, तो ज़्यादातर ऑप्टिमाइज़ेशन, फ़ंक्शन इनलाइनिंग को छोड़कर उम्मीद के मुताबिक काम करेंगे. हम आने वाले समय में बाकी समस्याओं को ठीक करने के बारे में सोच रहे हैं. फ़िलहाल, किसी -O लेवल ऑप्टिमाइज़ेशन के साथ कंपाइल करते समय, कृपया -fno-inline का इस्तेमाल करके इसे बंद करें, जैसे:

emcc -g temp.c -o temp.html \
     -O3 -fno-inline

डीबग की जानकारी को अलग करना

डीबग करने की जानकारी में आपके कोड, तय किए गए प्रकार, वैरिएबल, फ़ंक्शन, दायरे और जगहों के बारे में बहुत सारी जानकारी सुरक्षित रखी जाती है-ऐसी हर चीज़ जो डीबगर के लिए काम की हो सकती है. इस वजह से, यह अक्सर कोड से बड़ा हो सकता है.

WebAssembly मॉड्यूल को तेज़ी से लोड करने और कंपाइल करने के लिए, आपको इस डीबग जानकारी को एक अलग WebAssembly फ़ाइल में बांटना पड़ सकता है. Emscripten में ऐसा करने के लिए, अपनी पसंद की फ़ाइल नाम के साथ -gseparate-dwarf=… फ़्लैग पास करें:

emcc -g temp.c -o temp.html \
     -gseparate-dwarf=temp.debug.wasm

इस मामले में, मुख्य ऐप्लिकेशन सिर्फ़ temp.debug.wasm फ़ाइल नाम सेव करेगा. साथ ही, DevTools खोलने पर हेल्पर एक्सटेंशन, फ़ाइल का पता लगा पाएगा और उसे लोड कर पाएगा.

ऊपर बताए गए ऑप्टिमाइज़ेशन के साथ जोड़े जाने पर, इस सुविधा का इस्तेमाल आपके ऐप्लिकेशन के करीब-करीब ऑप्टिमाइज़ किए गए प्रोडक्शन बिल्ड को शिप करने के लिए भी किया जा सकता है. साथ ही, बाद में इन्हें लोकल साइड फ़ाइल से डीबग भी किया जा सकता है. इस मामले में, हमें सेव किए गए यूआरएल को भी बदलना होगा, ताकि एक्सटेंशन को साइड फ़ाइल ढूंढने में मदद मिल सके, उदाहरण के लिए:

emcc -g temp.c -o temp.html \
     -O3 -fno-inline \
     -gseparate-dwarf=temp.debug.wasm \
     -s SEPARATE_DWARF_URL=file://[local path to temp.debug.wasm]

जारी रखने के लिए...

वाह! बहुत सारी नई सुविधाएं जोड़ी गई हैं!

उन सभी नए इंटिग्रेशन के साथ, Chrome DevTools न सिर्फ़ JavaScript के लिए, बल्कि C और C++ ऐप्लिकेशन के लिए भी एक बेहतर, असरदार, डीबगर बन गया है. इससे कई तरह की टेक्नोलॉजी में उपलब्ध, ऐप्लिकेशन लेना पहले से ज़्यादा आसान हो गया है और उन्हें शेयर किए गए क्रॉस-प्लैटफ़ॉर्म वेब पर लाया जा सकता है.

हालांकि, हमारा सफ़र अभी खत्म नहीं हुआ है. हम यहां से कुछ चीज़ों पर काम करेंगे:

  • डीबगिंग अनुभव में खुरदुरे किनारों को साफ़ करना.
  • कस्टम टाइप फ़ॉर्मैटर के लिए सहायता जोड़ना.
  • WebAssembly ऐप्लिकेशन के लिए प्रोफ़ाइल बनाने की सुविधा को बेहतर बनाने पर काम किया जा रहा है.
  • इस्तेमाल न होने वाले कोड को ढूंढना आसान बनाने के लिए, कोड कवरेज के लिए सहायता जोड़ना.
  • कंसोल के आकलन में एक्सप्रेशन के लिए सहायता को बेहतर बनाना.
  • ज़्यादा भाषाओं के लिए सहायता जोड़ी जा रही है.
  • …और ऐसे ही अन्य ट्रेंड!

इस दौरान, कृपया अपने कोड पर मौजूदा बीटा वर्शन को आज़माकर हमारी मदद करें और मिलने वाली किसी भी समस्या की शिकायत https://bugs.chromium.org/p/chromium/issues/entry?template=DevTools+issue पर करें.

झलक दिखाने वाले चैनलों को डाउनलोड करें

अपने डिफ़ॉल्ट डेवलपमेंट ब्राउज़र के तौर पर, Chrome के कैनरी, डेव या बीटा वर्शन का इस्तेमाल करें. झलक दिखाने वाले इन चैनलों से, आपको DevTools की नई सुविधाओं का ऐक्सेस मिलता है. साथ ही, सबसे नए वेब प्लैटफ़ॉर्म एपीआई टेस्ट करने और उपयोगकर्ताओं के ऐसा करने से पहले ही, अपनी साइट पर समस्याओं का पता लगाने में मदद मिलती है!

Chrome DevTools टीम से संपर्क करना

पोस्ट में मौजूद नई सुविधाओं और बदलावों या DevTools से जुड़ी किसी भी अन्य चीज़ के बारे में बताने के लिए, नीचे दिए गए विकल्पों का इस्तेमाल करें.

  • crbug.com के ज़रिए हमें कोई सुझाव या सुझाव सबमिट करें.
  • DevTools में ज़्यादा विकल्प   ज़्यादा दिखाएं   > सहायता > DevTools से जुड़ी समस्याओं की शिकायत करें पर जाकर, DevTools से जुड़ी समस्या की शिकायत करें.
  • @ChromeDevTool पर ट्वीट करें.
  • DevTools YouTube वीडियो या DevTools सलाह वाले YouTube वीडियो में नया क्या है, इस बारे में टिप्पणियां करें.